|
|
View previous topic :: View next topic |
Author |
Message |
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
Another SPI problem (CS5463) |
Posted: Fri Feb 06, 2009 4:02 pm |
|
|
Hi
Sorry that its another SPI problem, I have searched through the forum to look for a solution but no luck.
I am using a PIC18F4520 on a Millennium development board with and am trying to connect it to a CS5463 power monitor chip. This mounted on a 24 pin adapter and set up on breadboard with jumpers going to PORT headers. All is running at 5V and with a 20MHz oscillator for PIC and 4.096 crystal for CS5463.
I am attempting to set the registers on the power IC and then do a read. The data sheet for this can be found at http://www.cirrus.com/en/pubs/proDatasheet/CS5463_F2.pdf. To test the connection I am simply trying to read back one of the registers I am writing to. The values of this is diplayed on a LCD.
I'm sure I have set everything up ok but I don't get any result returned. I have tested to see if the chip select goes low with a multimeter and it does, also used that to try and see if data is being clocked in and out. It appears to clock in data to the SDI pin on CS5463 but nothing is getting clocked out of it.
I am not using interrupts at the minute, but am planning to once I get this all working, I assume I can do it this way? Am quite new to PIC programming and have never used spi before (have porobably bitten off more than I can chew)
Any help would greatly appreciated, Sorry if I have missed an obvious details just say if I have.
The code I am using is below. I am using ccs version 4.057
Code: | #include <18F4520.H>
#fuses HS,NOPROTECT,NOBROWNOUT,NOWDT,NOSTVREN,NOLVP,PUT
#use delay(clock=20000000)
#include "Lcd2.c"
#include <stdio.h>
#define SEL_BUT PIN_D4 //Sets which button to use for display select
#define RESET PIN_E2
#define CS PIN_A5
#define SDO PIN_C5
#define SDA PIN_C4
#define INT PIN_B0
#byte SSPSTAT = 0x80 //Configures MSSP
#byte SSPCON1 = 0x20 //Enables MSSP and configures it
#byte INTCON = 0xD0 //Enables external interrupts
#byte PIR1 = 0x00 //Sets SSP flag
#byte PIE1 = 0x8 //Enables MSSP interrupts
#byte IPR = 0x00 //Sets MSSP interrupt priroty low
#byte RCON = 0x80 //Enables priority interrupts
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
void main()
{
int Current_Dis; //Sets the screen to be printed
int Max_Dis = 3; //Sets the maximum number of different displays to print
float Amps = 0; //Current Measurement
float Volts = 0; //Voltage Measurement
float Power = 0; //Active Power
float Reactive = 0; //Average Reactive Power
float PF = 0; //Power Factor
int H_Byte,M_Byte,L_Byte,junk;
disable_interrupts(global); //disables all unmasked interrupts
set_tris_a(0xFF); //Sets port A as all inputs
set_tris_b(0x1); //Sets RB0 as input
set_tris_c(0x10); //Sets up serial I/O
set_tris_e(0x4); //Sets RE2 as output
output_high(CS);
//setup_spi
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);
//Chip select to low to initialise CS5463
output_low(CS);
//Sync commands
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF);
junk =spi_read();
spi_write(0xFE);
junk =spi_read();
//Set Mask register
spi_write(0x74); //write command and address of register (0,W/R,5bitaddress,0)
junk =spi_read();
spi_write(0x00); //3 bytes of data to set 24bits of mask register (Set for no interrupts)
junk =spi_read();
spi_write(0x00);
junk =spi_read();
spi_write(0x00);
junk =spi_read();
//Set Config register
spi_write(0x40);
junk =spi_read();
spi_write(0x00); //3 bytes of data to set 24bits of config register (set low to high pulse for interrupts)
junk =spi_read();
spi_write(0xC);
junk =spi_read();
spi_write(0x00);
junk =spi_read();
//Set Mode register
spi_write(0x64);
junk =spi_read();
spi_write(0x00); //Sets High pass filters on Voltage and Current lines, sets automatic line frequency measurements
junk =spi_read();
spi_write(0x00);
junk =spi_read();
spi_write(0x61);
junk =spi_read();
//Set Control register
spi_write(0x78);
junk =spi_read();
spi_write(0x00); //Disables CPUCLK
junk =spi_read();
spi_write(0x00);
junk =spi_read();
spi_write(0x4);
junk =spi_read();
//Start calculations
spi_write(0xE0); //Command to do single command for continuous use 0xE8
junk =spi_read();
while(1)
{
//Read Calculations
// spi_write(0x56); //Read the Vrms Register
// H_Byte = spi_read(0xFF); //Reads high byte and writes sync1
// M_Byte = spi_read(0xFF); //Reads middle byte and writes sync1
// L_Byte = spi_read(0xFF); //Reads low byte and writes sync1
//////////////////////////////////////////TEST ROUTINE//////////////
Know that H_Byte and M_Byte should = 0x00 and L_Byte should = 0x4
//Read Control Register
spi_write(0x64);
H_Byte = spi_read(0xFF); //Reads high byte and writes sync1
M_Byte = spi_read(0xFF); //Reads middle byte and writes sync1
L_Byte = spi_read(0xFF); //Reads low byte and writes sync1
//////////////////////////////////////////////////////////////////
lcd_init();
printf(lcd_putc, "\f**Power Monitor*");
delay_ms(3000); //Hold for start screen
Current_Dis = 1; //Sets first screen
if(input(SEL_BUT)){ //Checks to see if button is pushed
Current_Dis++; //If it is then current display changes to next
delay_ms(100); // Delay to further debounce switch
if(Current_Dis > Max_Dis) // Circulates diplays
Current_Dis = 1;
switch (Current_Dis){ // switch statements to say which diplay to print
Case 1 : delay_ms(100); // Next screen
printf(lcd_putc, "\fCurrent %.2fA \nVoltage %.2fV", Amps, Volts);
Break;
Case 2 : delay_ms(100); // Next screen
printf(lcd_putc, "\fPower %.3fkW \nReactive %.3fW", Power, Reactive);
Break;
Case 3 : delay_ms(100); // Next screen
printf(lcd_putc, "\fPF %.3f ", PF);
Break;
Case 4 : delay_ms(100); //Next screen
printf(lcd_putc, "\fHigh Mid Low \n %d %d %d", H_Byte, M_Byte, L_Byte);
}
}
}
} |
Last edited by matt1eg on Sun Feb 08, 2009 9:31 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 06, 2009 4:52 pm |
|
|
Quote: | #byte SSPSTAT = 0x80 //Configures MSSP
#byte SSPCON1 = 0x20 //Enables MSSP and configures it
#byte INTCON = 0xD0 //Enables external interrupts
#byte PIR1 = 0x00 //Sets SSP flag
#byte PIE1 = 0x8 //Enables MSSP interrupts
#byte IPR = 0x00 //Sets MSSP interrupt priroty low
#byte RCON = 0x80 //Enables priority interrupts |
This is wrong. The #byte directive is used to tell the compiler the
address of the register. These are not the register addresses for
the 18F4520. Look in this table in the 18F4520 data sheet to find the
correct register addresses:
Quote: | TABLE 5-1: SPECIAL FUNCTION REGISTER MAP FOR PIC18F2420/2520/4420/4520 DEVICES |
Quote: | Sync commands
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF); |
I'm not sure what you're doing here, but your spi_read() operations will
not generate a clock, because you don't have parameter specified.
There will be no SCLK during the spi read operation with your code above. |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Sat Feb 07, 2009 6:06 am |
|
|
Hi thanks for your reply. I thought that where I had used #byte I was setting the registers . I can fix that. I'm guessing then if they had not been set then the MSSP shouldn't even be enabled and the clock etc won't be configured properly?
Where I have Quote: | Code: | Sync commands
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF); |
|
I am attempting to send 3 sync commands (as specified in the CS5463 datasheet), however I am not wanting to read anything at that point and I thought that when the master initiates a write data is automatically clocked in and out of the slave and master and so I just discard the data sent to PIC.
Here Quote: | Code: | //Read Control Register
spi_write(0x64);
H_Byte = spi_read(0xFF); //Reads high byte and writes sync1
M_Byte = spi_read(0xFF); //Reads middle byte and writes sync1
L_Byte = spi_read(0xFF); //Reads low byte and writes sync1 |
|
I am passing a value. A book on embedded programming I read said that this way it would write the value passed (0xFF) and read what ever was sent back and set it to in this case H_Byte. The first write (0x64) should tell the CS5463 to load the 'Control Register'(of cs5463) to the buffer to be ready to send out. However just gping over that myself if that is write my code will not have the same number of reads as there are writes so should look like Code: | //Read Control Register
spi_write(0x64);
H_Byte = spi_read(0xFF); //Reads high byte and writes sync1
M_Byte = spi_read(0xFF); //Reads middle byte and writes sync1
L_Byte = spi_read(0xFF); //Reads low byte and writes sync1
junk = spi_read(); |
But that involves using a 'blank' read again which as you have said is incorrect.
Think I've got the wrong end of the stick
Thanks again |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Sat Feb 07, 2009 6:09 am |
|
|
Just thought the Quote: | Code: | setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16); |
| line is setting up the MSSP module isn't it so I was actually trying to do it twice. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Feb 07, 2009 12:32 pm |
|
|
That's right. The setup_spi() statement will setup the hardware SPI
module. I can't help you to write a driver today. I can possibly
help some more on tomorrow afternoon. |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Sat Feb 07, 2009 12:53 pm |
|
|
If you can I would be very grateful. |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Sat Feb 07, 2009 3:53 pm |
|
|
Here is modified code for first mistake
Code: | #include <18F4520.H> //PIC Header File
#fuses HS,NOPROTECT,NOBROWNOUT,NOWDT,NOSTVREN,NOLVP,PUT,MCLR,NOPBADEN //Sets fuses
#use delay(clock=20000000) //Specifies what oscillator is being used
#include "Lcd2.c" //Includes Lcd2 file
#include <stdio.h> //Includes standard I/O header file
#define SEL_BUT PIN_D4 //Sets which button to use for display select
#define RESET PIN_E2 //Defines E2 as RESET pin
#define CS PIN_A5 //Defines A5 as Chip Select pin
#define SDO PIN_C5 //Defines C5 as Serial Data Out pin
#define SDA PIN_C4 //Defines C4 as Serial Data In Pin
#define INT PIN_B0 //Defines B0 as Interrupt pin
//Addresses of SFRs specified in datasheet
#byte SSPSTAT = 0xFC7
#byte SSPCON1 = 0xFC6
#byte INTCON = 0xFF2
#byte PIR1 = 0xF9E
#byte PIE1 = 0xF9D
#byte IPR1 = 0xF9F
#byte RCON = 0xFD0
#byte TRISE = 0xF96
#byte ADCON1 = 0xFC1
//SPI Mode definitions
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
//Start of main program
void main()
{
//Variable definitions
int Current_Dis; //variable for screen to be printed
int Max_Dis = 4; //Sets the maximum number of different displays to print
float Amps = 0; //Current measurement
float Volts = 0; //Voltage measurement
float Power = 0; //Active Power
float Reactive = 0; //Average Reactive Power
float PF = 0; //Power Factor
float Amps_1; //Unconverted Current measurement
float Volts_1; //Unconverted Voltage measurement
float Power_1; //Unconverted Active Power measurement
float Reactive_1; //Unconverted Reactive Power measurement
float PF_1; //Uncoverted Power Factor measurement
float Full_Scale_V = 176.78;
float Ratio_V = 100;
int H_Byte; //High Byte
int M_Byte; //Middle Byte
int L_Byte; //Low Byte
int junk; //Discarded data
//Register setup
SSPSTAT = 0x80; //Configures MSSP
SSPCON1 = 0x20; //Enables MSSP and configures it
INTCON = 0xD0; //Enables external interrupts
PIR1 = 0x00; //Sets SSP flag
PIE1 = 0x8; //Enables MSSP interrupts
IPR1 = 0x00; //Sets MSSP interrupt priroty low
RCON = 0x80; //Enables priority interrupts
TRISE = 0x00; //Sets RE2 as output
ADCON1 = 0xF; //Turns off A/Ds
//Set I/O
set_tris_a(0xFF); //Sets port A as all inputs
set_tris_b(0x1); //Sets RB0 as input
set_tris_c(0x10); //Sets up serial I/O
set_tris_e(0x4); //Sets RE2 as output
output_high(CS); //Chip select high to 'disconnect' comms with CS5463
//setup_spi
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);
output_low(CS); //Chip select to low to initialise comms with CS5463
//Sync commands
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF);
junk =spi_read();
spi_write(0xFF);
junk =spi_read();
spi_write(0xFE);
junk =spi_read();
//Set Mask register
spi_write(0x74); //write command and address of register (0,W/R,5bitaddress,0)
junk =spi_read();
spi_write(0x00); //3 bytes of data to set 24bits of mask register (Set for no interrupts)
junk =spi_read();
spi_write(0x00);
junk =spi_read();
spi_write(0x00);
junk =spi_read();
//Set Config register
spi_write(0x40);
junk =spi_read();
spi_write(0x00); //3 bytes of data to set 24bits of config register (set low to high pulse for interrupts)
junk =spi_read();
spi_write(0xC);
junk =spi_read();
spi_write(0x00);
junk =spi_read();
//Set Mode register
spi_write(0x64);
junk =spi_read();
spi_write(0x00); //Sets High pass filters on Voltage and Current lines, sets automatic line frequency measurements
junk =spi_read();
spi_write(0x00);
junk =spi_read();
spi_write(0x61);
junk =spi_read();
//Set Control register
spi_write(0x78);
junk =spi_read();
spi_write(0x00); //Disables CPUCLK
junk =spi_read();
spi_write(0x00);
junk =spi_read();
spi_write(0x4);
junk =spi_read();
//Start calculations
spi_write(0xE0); //Command to do single command for continuous use 0xE8
junk =spi_read();
// output_high(CS); //Chip select to low to disable comms with CS5463
//Read Calculations
// output_low(CS);
// spi_write(0x56); //Read the Vrms Register NOTE to self: can just read H_Byte then
// H_Byte = spi_read(0xFF); //Reads high byte and writes sync1 read next register, lower
// M_Byte = spi_read(0xFF); //Reads middle byte and writes sync1 2 bytes will be discarded.
// L_Byte = spi_read(0xFF); //Reads low byte and writes sync1 For better accuracy use
// Volts_1 = H_Byte/(2^8); //Sets Volts_1 to percentage of full scale 'make16' to join H_Byte and
// Volts = Volts_1 * Full_Scale_V * Ratio_V; //Sets Volts to actual voltage on line M_Byte and use to calcualte value
// output_high(CS);
//////////////////////////////////////////TEST ROUTINE//////////////////////////////////////////////////////////////////////////////////////////////
//Know that H_Byte and M_Byte should = 0x00 and L_Byte should = 0x4
//Read Control Register
// output_low(CS);
spi_write(0x64); //write command and register address to write to
H_Byte = spi_read(0xFF); //Reads high byte and writes sync1
M_Byte = spi_read(0xFF); //Reads middle byte and writes sync1
L_Byte = spi_read(0xFF); //Reads low byte and writes sync1
output_high(CS);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
lcd_init();
printf(lcd_putc, "\f**Power Monitor*");
delay_ms(3000); //Hold for start screen
Current_Dis = 1; //Sets first screen
for(;;)
{
if(input(SEL_BUT)){ //Checks to see if button is pushed
Current_Dis++; //If it is then current display changes to next
delay_ms(100); // Delay to further debounce switch
if(Current_Dis > Max_Dis) // Circulates diplays
Current_Dis = 1;
} //if
switch (Current_Dis){ // switch statements to say which diplay to print
Case 1 : delay_ms(100); // Next screen
printf(lcd_putc, "\fCurrent %.2fA \nVoltage %.2fV", Amps, Volts);
Break;
Case 2 : delay_ms(100); // Next screen
printf(lcd_putc, "\fPower %.3fkW \nReactive %.3fW", Power, Reactive);
Break;
Case 3 : delay_ms(100); // Next screen
printf(lcd_putc, "\fPF %.3f ", PF);
Break;
Case 4 : delay_ms(100); //Next screen
printf(lcd_putc, "\fHigh Mid Low \n %d %d %d", H_Byte, M_Byte, L_Byte);
} //switch
} //for
} //Main
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 08, 2009 2:18 pm |
|
|
Quote: | #define RESET PIN_E2 |
You're not setting this pin to a high level. It's probably floating on the
CS5463. That might be why you're reading 0xFF from the chip.
Quote: | //Register setup
SSPSTAT = 0x80; //Configures MSSP
SSPCON1 = 0x20; //Enables MSSP and configures it
INTCON = 0xD0; //Enables external interrupts
PIR1 = 0x00; //Sets SSP flag
PIE1 = 0x8; //Enables MSSP interrupts
IPR1 = 0x00; //Sets MSSP interrupt priroty low
RCON = 0x80; //Enables priority interrupts
TRISE = 0x00; //Sets RE2 as output
ADCON1 = 0xF; //Turns off A/Ds
//Set I/O
set_tris_a(0xFF); //Sets port A as all inputs
set_tris_b(0x1); //Sets RB0 as input
set_tris_c(0x10); //Sets up serial I/O
set_tris_e(0x4); //Sets RE2 as output
|
This section of code should be deleted. You don't need to set the
TRIS. The compiler will do it for you, provided that you use CCS functions.
There is no need to write directly to the SSP registers. The setup_spi()
function does that for you. It also sets up the correct TRIS on the SPI
pins.
There is no need to turn off the A/D. It's off by default. There is no
reason to enable interrupts. You don't have an interrupt service routine.
And then, CCS has functions to do this anyway. There is no need to
do direct register access for interrupt functions. Use CCS functions to
do it, if required. |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Sun Feb 08, 2009 3:00 pm |
|
|
Hadn't thought about the reset pin at all will sort that. I am (was atleast anyway) planning to put in interrupts thats the only reason I had enabled them, meant to disable them for mean time though.
I have used a misleading comment at ADCON1. That line is to set RA5 pin to digital, in the data sheet it says that on power-up/reset this is set to analogue and i need it as digital.
Do I need to specify anywhere when the data is sampled (SMP bit of SSPSTAT)?
Thanks again for you time and help |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 08, 2009 3:12 pm |
|
|
Quote: |
I have used a misleading comment at ADCON1. That line is to set RA5
pin to digital, in the data sheet it says that on power-up/reset this is set
to analogue and i need it as digital.
|
The compiler already does it for you. See the start-up code from the .LST
file below. It sets the lower 4 bits of ADCON1 = 0x0F.
Quote: | .................... void main()
.................... {
0004: CLRF TBLPTRU
0006: BCF RCON.IPEN
0008: CLRF FSR0H
000A: CLRF FSR0L
000C: MOVF ADCON1,W
000E: ANDLW C0
0010: IORLW 0F
0012: MOVWF ADCON1
0014: MOVLW 07
0016: MOVWF CMCON |
Quote: | Do I need to specify anywhere when the data is sampled (SMP bit of SSPSTAT)? |
Setting the correct SPI mode should take care of whatever is required. |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Sun Feb 08, 2009 3:20 pm |
|
|
I'll delete that line as well then. I will test this tomorrow when I get to the lab, fingers crossed it will work now.
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Feb 08, 2009 6:08 pm |
|
|
If your code doesn't work, then try this one. This should display the
temperature (about 24 degrees C, at room temperature). By looking
at the CS5463 data sheet and AN220 from Microchip, I think this code
has a chance to work.
Code: |
#include <18F4520.H>
#fuses HS,NOWDT,NOBROWNOUT,PUT,NOLVP
#use delay(clock=20000000)
#include "Lcd2.c"
#define CS PIN_A5
#define RESET PIN_E2
#define CS5463_CONFIG_REG 0
#define CS5463_TEMP_REG 19
// SPI modes
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
//--------------------------------
void CS5463_write_command(int8 command)
{
output_low(CS);
spi_write(command);
output_high(CS);
}
//---------------------------------
void CS5463_write_reg(int8 reg, int8 msb, int8 mid, int8 lsb)
{
output_low(CS);
spi_write((reg << 1) | 0x40); // OR with Write bit
spi_write(msb);
spi_write(mid);
spi_write(lsb);
output_high(CS);
}
//---------------------------------
int32 CS5463_read_reg(int8 reg)
{
int8 msb, mid, lsb;
int32 retval;
output_low(CS);
spi_write(reg << 1);
msb = spi_read(0x00);
mid = spi_read(0x00);
lsb = spi_read(0x00);
output_high(CS);
retval = make32(0, msb, mid, lsb);
return(retval);
}
//===============================
void main()
{
int32 temp32;
int8 temp8;
output_high(CS);
output_high(RESET);
delay_ms(100); // CS5463 osc start-up time is 60 ms typ.
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);
lcd_init();
while(1)
{
temp32 = CS5463_read_reg(CS5463_TEMP_REG);
temp8 = make8(temp32, 3); // Get upper byte of temp32
printf(lcd_putc, "\f Temp = %d", temp8);
delay_ms(500);
}
}
|
|
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Sun Feb 08, 2009 6:49 pm |
|
|
Thats superb thanks very much. Wasn't expecting that amount of help .
Will try that out tomorrow as well. If that works then least I know there are no hardware errors. Then I can at least work on my code knowing only it is wrong if nothing happens (stubborness and small sense of acheivement as my motivation).
I may resort to modifying yours though, I only have so much hair left to pull out, that is of course if you don't mind me using it as a base. |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Mon Feb 09, 2009 3:01 pm |
|
|
Hi
Tested both versions today, yours worked with a little bit of moding. I changed Quote: | Code: | int32 CS5463_read_reg(int8 reg)
{
int8 msb, mid, lsb;
int32 retval;
output_low(CS);
spi_write(reg << 1);
msb = spi_read(0xFF);
mid = spi_read(0xFF);
lsb = spi_read(0xFF);
output_high(CS);
retval = make32(0, msb, mid, lsb);
return(retval);
} |
|
The 0xFF are sync commands that are required when no data is to be written. When reading the temp register it seemed to go a bit weird though. Get a value of -128 for MSB which corresponds to 0 degrees C?! (I'm assuming so as anyway as its a 2's complement and MSB is 0b1000000 and other 2 bytes are 0x00). Reading other registers that have default non zero values produces correct results so I'm not sure why its not measuring the temp but its not really an issue wasn't planning on using it.
Using your code as an example I simplified my own to just do a read and with some modifying got it to it as well but its a bit temperamental. Going to start afresh and with my own to tidy it up and attempt to use some ISRs. Hopefully all will be good.
Thanks again for your help |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 09, 2009 3:25 pm |
|
|
I think my byte extraction in that sample program is wrong:
Quote: | temp8 = make8(temp32, 3); // Get upper byte of temp32 |
The topmost byte is always 0x00, in the returned value from the
CS5463_read_reg() routine. Because the CS5463 returns a 24-bit
value (and it's right justified), the 2nd from the top in the return value
is the one that needs to be extracted. Example:
Code: | temp8 = make8(temp32, 2); // Get byte 2 (of bytes 0-3) of temp32 |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|