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 CCS Technical Support

SPI Problem with CS5463(related to FEB 2009 thread)
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
temtronic



Joined: 01 Jul 2010
Posts: 9241
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Dec 19, 2015 6:06 am     Reply with quote

general comments
hardware

You need to put some filter caps on the power supply. Something like 1000 mfd on the input, and 470 mfd on the output. As well a small heatsink would be nice. The 7805 has to drop +12 to +5, so about 7 volts. at say 100ma of current that's about 3/4 watt of power it has to dissipate (get rid of). The 7805 should be cool to touch, not even warm.

While not shown in the schematic it appears you have an LED on RB7 according to your code. Be sure you have a 500r to 1K resistor to limit the LED current.

software
Add some way to display the msb,mid,lsb variables. This way you can see what is being returned from the slave. I don't think make32() is 'busted', but it really helps to KNOW what the data is before that function is called !!
You could test make32() by using known values and seeing what is displayed. another simple debugging tool,to confirm that works.

Reread the cs datasheet and confirm register locations/descriptions and proper reset/reading of the device.pat particular attention to timing and sequence. For example if it needs 1 to 5us between commands, give it 3 us just to be sure. Once it works THEN you can use say 2us, then 1us but always confirm it works before 'making it go faster'.

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Dec 20, 2015 2:36 am     Reply with quote

Quote:
setup_spi(SPI_MASTER|SPI_SCK_IDLE_LOW|SPI_CLK_DIV_64|SPI_XMIT_H_TO_L); //set up spi module

Your code is using SPI mode 1. It's never going to work with that mode.
The CS5463 definitely uses mode 0.

Try this program and post the results. This program uses SPI mode 0
and it does a hardware reset of the CS5463 at the start, and it also tests
writing a value to the Cycle Count register and reading it back.
Code:

#include <16F877A.h>
#fuses HS, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=20M)
#use rs232(baud=9600, UART1, ERRORS) 

#define CS     PIN_A5
#define RESET  PIN_B5

#define CS5463_CYCLE_COUNT_REG  5

// SPI mode definitions for 16F and 18F PICs (not for PIC24).
#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_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(0xFF);
mid = spi_read(0xFF);
lsb = spi_read(0xFF);
output_high(CS);

retval = make32(0, msb, mid, lsb);

return(retval);
}

//-----------------------------
void reset_cs5463(void)
{
output_low(RESET);   // Do a short reset pulse
delay_ms(1);             
output_high(RESET);
delay_ms(100);       // Allow the chip time to initialize
}

//===============================
void main()
{
int32 ccr;
   
// Initialize control lines to cs5463.
output_high(CS);
output_high(RESET);
delay_ms(100);

reset_cs5463();   
   
output_high(PIN_B7);  // Blink LED
delay_ms(1000);
output_low(PIN_B7);
delay_ms(1000);
   
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);
   
// Read the chip, then write to it, then read it again.
ccr = CS5463_read_reg(CS5463_CYCLE_COUNT_REG);
printf("Cycle Count Register initial value = %lu\r\n",ccr);

printf("Write 0x123456 to Cycle Count Register \r\n");
CS5463_write_reg(CS5463_CYCLE_COUNT_REG, 0x12, 0x34, 0x56);

ccr = CS5463_read_reg(CS5463_CYCLE_COUNT_REG);
printf("Cycle Count Register value after writing = %lu\r\n",ccr);

printf("Done \n\r");

while(TRUE);
}
mka879



Joined: 30 Oct 2015
Posts: 34

View user's profile Send private message

PostPosted: Tue Dec 22, 2015 10:39 pm     Reply with quote

Thank you so much. I was considering to move to a different IC but finally get the IC working with the help of your (PCM Programmer) code with a slight modification. The code used to get the wrong value of a register the first time and after a couple of read instruction the value received used to be correct. I added the following function to initialize the serial port before entering into main() which removed this bug. Now I can go back to board and think where I went wrong in my problem solving methodology.
Code:

void sync_port(void)
{
   output_low(CS);
   spi_write(0xFF);
   spi_write(0xFF);
   spi_write(0xFF);
   spi_write(0xFE);
   output_high(CS);
}


You people are stars really!
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Wed Dec 23, 2015 1:59 am     Reply with quote

Well done. Big step forward. Smile

Key thing to learn is the 'approach'. If trying to do something, test the actual thing you are trying to do. Consider what PCM_Programmer's code did. Tested writing and reading from just one register in the chip (he chose one that will just store a value). So it allowed you to get the code to actually talk to the chip working. Whenever there is a code problem, you have to 'simplify' down to a 'minimum' operation like this, then get this working, before trying to step forwards.

As a 'comment', consider whether your CS5463_write_reg command might be much easier to use, if it just used a single int32 value passed to it, and split this up itself internally (look at make8). So it'd be used as:
Code:

printf("Write 0x123456 to Cycle Count Register \r\n");
CS5463_write_reg(CS5463_CYCLE_COUNT_REG, 0x123456);


Would make it less likely that accidents would occur with values.

Have fun. Very Happy
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 23, 2015 8:59 am     Reply with quote

Does the code below correctly show your modification ?
Quote:
void main()
{
int32 ccr;

// Initialize control lines to cs5463.
output_high(CS);
output_high(RESET);
delay_ms(100);

reset_cs5463();

sync_port();

mka879



Joined: 30 Oct 2015
Posts: 34

View user's profile Send private message

PostPosted: Thu Dec 24, 2015 11:56 am     Reply with quote

PCM programmer wrote:
Does the code below correctly show your modification ?
Quote:
void main()
{
int32 ccr;

// Initialize control lines to cs5463.
output_high(CS);
output_high(RESET);
delay_ms(100);

reset_cs5463();

sync_port();


We have vacations till Sunday. I will post the exact modification on Monday as the code is in my office's computer.
mka879



Joined: 30 Oct 2015
Posts: 34

View user's profile Send private message

PostPosted: Sun Dec 27, 2015 10:28 pm     Reply with quote

"sync_port();" is the modification that enable to read correct values every time the circuit is powered on.

Code:
void main()
{
   int32 vol,cur,ccr;
   output_high(RESET);
   output_high(CS);
   
   output_high(pin_b7);
   delay_ms(1000);
   output_low(pin_b7);
   delay_ms(1000);
   
   setup_spi(SPI_MASTER|SPI_SCK_IDLE_LOW|SPI_CLK_DIV_64|SPI_XMIT_L_TO_H);  //set up spi module
   
   sync_port(); // modification to ensure correct reading of registers
   
   while(TRUE)
   {
      ccr = CS5463_read_reg(CS5463_CYCLE_COUNT_REG);
      printf("Cycle Count Register = %lu\r\n",ccr);
      delay_ms(5000);
   }

}
mka879



Joined: 30 Oct 2015
Posts: 34

View user's profile Send private message

PostPosted: Sun Dec 27, 2015 10:49 pm     Reply with quote

Ttelmah wrote:
Well done. Big step forward. Smile

Key thing to learn is the 'approach'. If trying to do something, test the actual thing you are trying to do. Consider what PCM_Programmer's code did. Tested writing and reading from just one register in the chip (he chose one that will just store a value). So it allowed you to get the code to actually talk to the chip working. Whenever there is a code problem, you have to 'simplify' down to a 'minimum' operation like this, then get this working, before trying to step forwards.

As a 'comment', consider whether your CS5463_write_reg command might be much easier to use, if it just used a single int32 value passed to it, and split this up itself internally (look at make8). So it'd be used as:
Code:

printf("Write 0x123456 to Cycle Count Register \r\n");
CS5463_write_reg(CS5463_CYCLE_COUNT_REG, 0x123456);


Would make it less likely that accidents would occur with values.

Have fun. Very Happy


Hmmm.... very good advice. These tips and advices will certainly help me to become a better programmer Smile
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 Previous  1, 2
Page 2 of 2

 
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