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

spi read problems
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
tom.ayars



Joined: 23 Jun 2008
Posts: 14

View user's profile Send private message

spi read problems
PostPosted: Tue Jun 24, 2008 11:07 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 11:39 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 12:06 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 12:11 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 12:22 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 12:24 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 12:35 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 12:43 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 12:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 1:22 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 1:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 1:47 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 1:52 pm     Reply with quote

negative. still garbage.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 2:02 pm     Reply with quote

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:
Code:
       SPI_CLK_DIV_64
tom.ayars



Joined: 23 Jun 2008
Posts: 14

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 2:05 pm     Reply with quote

Thank you very much for your time. Hopefully we can continue this topic at a later time.
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  Next
Page 1 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