|
|
View previous topic :: View next topic |
Author |
Message |
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sat Dec 19, 2015 6:06 am |
|
|
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
|
|
Posted: Sun Dec 20, 2015 2:36 am |
|
|
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
|
|
Posted: Tue Dec 22, 2015 10:39 pm |
|
|
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: 19552
|
|
Posted: Wed Dec 23, 2015 1:59 am |
|
|
Well done. Big step forward.
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. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 23, 2015 8:59 am |
|
|
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
|
|
Posted: Thu Dec 24, 2015 11:56 am |
|
|
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
|
|
Posted: Sun Dec 27, 2015 10:28 pm |
|
|
"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
|
|
Posted: Sun Dec 27, 2015 10:49 pm |
|
|
Ttelmah wrote: | Well done. Big step forward.
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. |
Hmmm.... very good advice. These tips and advices will certainly help me to become a better programmer |
|
|
|
|
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
|