View previous topic :: View next topic |
Author |
Message |
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
spi read problems |
Posted: Tue Jun 24, 2008 11:07 am |
|
|
Hi,
I am having a problem reading in multiple bytes of data from the master PIC.
master code:
Code: |
void main()
{
const char data[9]={"pl_10000"};
set_tris_a(0b00100000);
set_tris_b(0b00000001);
set_tris_c(0b00000000);
setup_spi(spi_master|spi_l_to_h|spi_clk_div_16);
while (TRUE)
{
output_low(PIN_B2); // slave select
for (i=0;i<9;i++)
{
spi_write(data[i]);
delay_us(2);
}
delay_ms(1);
}
} |
and the slave code:
Code: |
void main()
{
init2();
setup2();
setup_spi(spi_slave|spi_l_to_h|spi_clk_div_16);
for (i=0;i<commandlength;i++)
{
xferdata[i]=spi_read(0);
}
}
|
I am using the following:
pic18f4550 (x2)
compiler version 4.073
when I am in debug mode, the value of xferdata comes up as random symbols and every so often the correct value appears. I have checked the data and clock sent by the master and seen on the slave input and everything looks correct but it will not read the data correctly. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 24, 2008 11:39 am |
|
|
1. Get rid of the TRIS. Let the compiler handle it.
2. Don't put constants in lower case. It confuses them with variables.
The C standard is to put constants in upper case.
Quote: | setup_spi(spi_slave|spi_l_to_h|spi_clk_div_16); |
3. The slave doesn't create a clock. The clock (and it's speed) is
entirely determined by the master. Don't put a clock constant in
the slave setup statement. The bits in the constant will be OR'ed with
the other constants, and will change the slave setup into something
that you do not want. For example, in your statement above, the
following constants will be OR'ed together, which gives 0x25.
Code: |
#define SPI_SLAVE 0x24
#define SPI_CLK_DIV_16 1
#define SPI_L_TO_H 0
|
What does 0x25 do when it's programmed into the SSPCON1 register ?
The lower 4 bits define the mode. What does 0x05 do ? Answer:
Quote: | 0101 = SPI Slave mode, clock = SCK pin, SS pin control disabled, SS can be used as I/O pin (3) |
The slave select pin has been unintentionally disabled. |
|
|
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
|
Posted: Tue Jun 24, 2008 12:06 pm |
|
|
I made the corrections and no change, I am still receiving garbage in xferdata despite having the correct data to be read on the pins. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 24, 2008 12:11 pm |
|
|
Post complete (but stripped down) versions of the Master and Slave code.
In other words, show the #include, #fuses, #use delay(), etc. The
code should be compilable without errors. Don't put in any unnecessary
setup code (for unused modules, etc.). |
|
|
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
|
Posted: Tue Jun 24, 2008 12:22 pm |
|
|
master:
Code: |
#include <18F4550.h>
#nolist
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOBROWNOUT,MCLR
#use delay(clock=48000000)
#use FAST_IO(A)
#use FAST_IO(B)
#use FAST_IO(C)
#include <SPIm_main.h>
#include <string.h>
void main()
{
SETUP_SPI(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
while (TRUE)
{
setup();
output_low(PIN_C6);
output_toggle(JMP);
for (i=0;i<9;i++)
{
spi_write(data[i]);
delay_us(2);
}
delay_ms(1);
output_high(PIN_C6);
}
}
|
slave:
Code: |
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOBROWNOUT,MCLR
#use delay(clock=48000000)
#use FAST_IO(A)
#use FAST_IO(B)
#use FAST_IO(C)
void main()
{
init2();
setup2();
SETUP_SPI(SPI_SLAVE|SPI_L_TO_H);
while(!spi_data_is_in());
for (i=0;i<COMMANDLENGTH;i++)
{
xferdata[i]=spi_read(0);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 24, 2008 12:24 pm |
|
|
When I said "let the compiler set the TRIS", that also means you should
leave off the #use fast_io statements.
But, I'll fix that and look at your code. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 24, 2008 12:35 pm |
|
|
In fact, you should delete all the #use fast_io statements and test
the code that you just posted. Then post the results. |
|
|
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
|
Posted: Tue Jun 24, 2008 12:43 pm |
|
|
After removing the fast_io on the slave side, the problem still exists. I am forced to leave the tris set up on the master side because the pins are not set correctly to the hardware spi definition from the data sheet.
Another interesting thing that I noticed during debugging is that the SPPBUFF is staying at 0x00 and the overflow flag is being set but it is telling me that the buffer is empty. |
|
|
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
|
Posted: Tue Jun 24, 2008 12:47 pm |
|
|
correction. removing the tris and fast_io on the master side works as well but the rest is still true. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 24, 2008 1:22 pm |
|
|
Look at the CCS example program for a hardware SPI slave.
Quote: | c:\Program Files\picc\Examples\Ex_spi_slave.c |
It checks to see if "data is in" (ie, buffer is full) before it reads a byte.
It does the test for each byte.
But your code calls the spi_data_is_in() routine one time, and then
assumes that you can read the data bytes continuously after that.
That won't work.
2nd thing: You have give the spi_read() function a parameter of 0.
This causes the code to load the SPI buffer with 0. This will clobber
your incoming data. Look at the CCS example file, Ex_spi_slave.c.
They don't use any parameter with the read operation in a slave.
Basically, details are important.
while(!spi_data_is_in());
for (i=0;i<COMMANDLENGTH;i++)
{
xferdata[i]=spi_read(0);
} |
|
|
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
|
Posted: Tue Jun 24, 2008 1:42 pm |
|
|
this is the change:
while(!spi_data_is_in())
{
}
for (i=0;i<COMMANDLENGTH;i++)
{
xferdata[i]=spi_read();
}
but still the same results. I am able to send a single binary byte but the minute i try to send multiple bytes it screws up. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 24, 2008 1:47 pm |
|
|
You need to move the test inside the loop, so it's performed before
each individual call to spi_read(). |
|
|
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
|
Posted: Tue Jun 24, 2008 1:52 pm |
|
|
negative. still garbage. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 24, 2008 2:02 pm |
|
|
I don't have the time to spend on this right now. I've got to get some
boards out today. I don't have the time to connect two PicDem2-Plus
boards together and make it all work.
My suggestions are:
1. Only send 1 byte for the test. Don't send 9 bytes.
Change both the master and slave programs to reflect this.
2. Reduce the SPI clock speed on the master. Use this divisor:
|
|
|
tom.ayars
Joined: 23 Jun 2008 Posts: 14
|
|
Posted: Tue Jun 24, 2008 2:05 pm |
|
|
Thank you very much for your time. Hopefully we can continue this topic at a later time. |
|
|
|