View previous topic :: View next topic |
Author |
Message |
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 |
|
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Mon Feb 09, 2009 3:38 pm |
|
|
Oh yeah forgot to mention that I noticed that. Was just getting 0 for a while but then noticed it, I have it as 2 now, this is when I get -128. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 09, 2009 3:42 pm |
|
|
Print the entire int32 returned value in Hex and see what you get.
Here are the required changes to do that:
Quote: |
temp32 = CS5463_read_reg(CS5463_TEMP_REG);
// temp8 = make8(temp32, 3); // Get upper byte of temp32
printf(lcd_putc, "\f Temp32 = %LX", temp32);
|
|
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Mon Feb 09, 2009 3:58 pm |
|
|
I get 000000. It's either really cold here and I haven't noticed or its not measuring the temperature.
One other thing I did to modify your code was to send a command to start conversions. In the data sheet it said that it measures the temperature during continuous conversions. Quote: | Code: | while(1)
{
CS5463_write_command(0xE8);
temp32 = CS5463_read_reg(CS5463_TEMP_REG);
//temp8 = make8(temp32, 0); // Get upper byte of temp32
//printf(lcd_putc, "\f Temp = %d", temp8);
printf(lcd_putc, "\f Temp32 = %LX", temp32);
delay_ms(500);
}
} |
|
It also says Quote: | Once a temperature characterization
is performed, the temperature sensor can then be
utilized to assist in compensating for temperature drift. |
I am unsure if this means that it for that particular use it needs characterization(which I assume means setting the temp offset) or if this is needed for any measurements to be done? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 09, 2009 4:13 pm |
|
|
It might be that temperature data is only available as a side effect of
some other operation (such as reading or using the ADC). I don't have
time to research this now. I've got to do some work for the company. |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Mon Feb 09, 2009 4:17 pm |
|
|
Thats ok you don't have to worry I will see what happens when I get it doing proper calculations and post an update later this week. |
|
|
spelltwister
Joined: 12 Feb 2009 Posts: 1
|
|
Posted: Thu Feb 12, 2009 10:25 am |
|
|
Greetings,
I believe I have followed everything done here and am still having problems :/ I have scoped all values that are being sent from the uC (HCS08QG) and they are correct. However, I am only getting 0 from the cirrus chip. I had RESET float and tied it high. This got rid of the error of random pulses being sent out of the cirrus chip. Thx ;D
I've tried using the auto Chip Select feature and manual chip select feature to drive the CS pin high after each byte and I've tried driving it high after each operation (cs_low, read, 3 writes, cs_high). I have the signal coming in at about 4464 Hz. I have also tried running at 1 MHz. Same results.
Summary of what is done:
Code: |
void reset_spi(){
write_spid(0xFF);
write_spid(0xFF);
write_spid(0xFF);
write_spid(0xFE);
}
char read_spid(void){
write_spid(0xFF);
while(!(SPIS & 0x80));//wait for full buffer
return SPID;
}
void page_and_read_register(char page, char ra, char* buff){
if(page != cur_page){
change_page(page);
cur_page = page;
}
write_spid(ra<<1);//which page to read
buff[0] = read_spid();//SYNC0
buff[1] = read_spid();
buff[2] = read_spid();
}
main(){
int counter = 0; //look at many registers
char data[5];
reset_spi();
write_command(0xE4);//continuous conversions
while(1){
page_and_read_register(0, counter, data);
if(counter++ >= 15)//cycle thru registers 0 - 15 to see if anything has data
counter = 0;
}
|
I have tried setting the register I'm reading to V_Instant, Temp, config, etc and they all give back the same nothingness. I am using a logic analyzer also to see the waves leaving and entering the cirrus chip and uC. The waves leaving the uC see OK, but the cirrus chip seems like it's doing nothing. I tested the clock on the cirrus chip and it correctly reports 4.096MHz.
Any help is greatly appreciated!!![/code] |
|
|
matt1eg
Joined: 05 Feb 2009 Posts: 14
|
|
Posted: Thu Feb 12, 2009 12:05 pm |
|
|
Hi
I'm no expert but looking through your code I can see some problems, although I have only worked with PICs and CCS compiler, I am not familiar with uC 'HCS08QG' at all, and are you using CCS compiler? If not My advice may not suit your application completely.
Quote: | Code: | write_command(0xE4);//continuous conversions |
|
will not do continuous conversions you need 0xE8. Also here
Quote: | Code: | write_spid(ra<<1);//which page to read
buff[0] = read_spid();//SYNC0
buff[1] = read_spid();
buff[2] = read_spid();
|
|
you need to send the SYNC1 command where as you are not sending anything.
I would just start by trying to read one register at a time no cycling through them.
Where in your code are storing the bytes you have read?
I would of also said that you need to set up the SPI. In mine you can see I use
Quote: | Code: | setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16); |
|
where the SPI_Mode is defined by
Quote: | Code: | #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) |
|
You need to make sure data is being clocked in and out at the times. The timing diagram in the CS5463 datasheet shows you the timings.
This
Quote: | Code: | void reset_spi(){
write_spid(0xFF);
write_spid(0xFF);
write_spid(0xFF);
write_spid(0xFE);
|
|
won't reset its an attempt to reinitialise but you need to drive CS pin high then low with the above code to do this. You need to have a seperate reset and cs pin. You have said that you use the reset pin thats good I use this at start up and then I just use CS low to initialise comms then when I'm done drive it high.
I do this after each command is carried out, e.g. when I do a read I set it low then do the read (write the register and read 3 bytes of data) then set it high. This works fine for me.
Like I said I am no expert but I think the pointers above should help. |
|
|
avarachan
Joined: 24 Sep 2009 Posts: 3 Location: Buffalo, NY
|
CS5463 with microchip 18f67j60 |
Posted: Mon May 24, 2010 12:42 pm |
|
|
Hi,
I am working with the CS5463 and microchip 18f67j60. I have already gotten CS5463 working with pic 18f2620, but at 4 MHz. My new processor has a crystal of 25MHz. I can write data to the CS5463, signal looks good, I am following all the initialization, synchronization etc, as I did with 18f2620. The problem is I can't get data out from the CS5463. It always reads zero. Though, intermittently I can see a pulse on the SDO of CS5463.
Any suggestions would be greatly appreciated.
Thanks
AVC |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 24, 2010 1:08 pm |
|
|
The SPI clock from the PIC's MSSP hardware module is derived from
the oscillator of the PIC. If you increase the PIC oscillator frequency,
then you increase the SCLK frequency.
Download the CS5463 data sheet:
http://www.cirrus.com/en/pubs/proDatasheet/CS5463_F2.pdf
Look at the SPI specifications on page 11. It has a fairly low SCLK
frequency of only 2 MHz, maximum.
Quote: |
Serial Port Timing
Serial Clock Frequency SCLK - - 2 MHz (Max)
|
If you increase your PIC frequency from 4 MHz to 25 MHz, without
changing your setup_spi() statement, you will easily create an SCLK
signal for which the frequency is too high.
To fix this, you need to change the SPI clock divisor in the setup_spi()
statement. Look in the .h file for your PIC:
Quote: | c:\program files\picc\devices\18f67j60.h |
Look in this section of that file:
Quote: | // Constants used in SETUP_SPI() are: |
Then choose a new divisor constant that, when divided into 25 MHz,
will give you an SCLK of 2 MHz or less. Edit your setup_spi() statement
and put in the new clock divisor. |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
Design |
Posted: Sat Jun 11, 2011 8:46 am |
|
|
Dear All, did you implemented the design on page 9 of the datasheet? Can you please send me the BOM because I did not find it.
Thanks in advance |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Thu Mar 14, 2013 8:22 am |
|
|
I am using the pic18f4550 with 20mhz cystal. Do. Need to connect the cpuclk pin on the cs5463(pin2) to the pic pin 13, altough i have the crystal to the PIC? |
|
|
|