CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Another SPI problem (CS5463)
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
matt1eg



Joined: 05 Feb 2009
Posts: 14

View user's profile Send private message

Another SPI problem (CS5463)
PostPosted: Fri Feb 06, 2009 4:02 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 06, 2009 4:52 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Feb 07, 2009 6:06 am     Reply with quote

Hi thanks for your reply. I thought that where I had used #byte I was setting the registers Embarassed . 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? Confused

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 Confused

Thanks again
matt1eg



Joined: 05 Feb 2009
Posts: 14

View user's profile Send private message

PostPosted: Sat Feb 07, 2009 6:09 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Feb 07, 2009 12:32 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Feb 07, 2009 12:53 pm     Reply with quote

If you can I would be very grateful.
matt1eg



Joined: 05 Feb 2009
Posts: 14

View user's profile Send private message

PostPosted: Sat Feb 07, 2009 3:53 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 08, 2009 2:18 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 08, 2009 3:00 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 08, 2009 3:12 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 08, 2009 3:20 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 08, 2009 6:08 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Feb 08, 2009 6:49 pm     Reply with quote

Thats superb thanks very much. Wasn't expecting that amount of help Shocked Very Happy .

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

View user's profile Send private message

PostPosted: Mon Feb 09, 2009 3:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 09, 2009 3:25 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
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