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 problem btw 18f458 and 18f2221

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Avarachan
Guest







SPI problem btw 18f458 and 18f2221
PostPosted: Thu Mar 20, 2008 3:12 pm     Reply with quote

Hi,

I am using s/w spi on 18f458(master) and hw spi on 18f2221(Slave). Compiler is V4.032.

problem: I am trying to communicate to and fro bw the pics. I send two bytes from master to slave. I can read it and print it at slave. The waveforms look good too. following this, the slave sends two bytes to master.
1. The waveform on SDO is totally wrong. ie, wrong data.
>> I send 0xCB and 0xAA from master, and 0xEA and 0x2B from slave. But SDO on slave gives out 0xAA and 0x00.

2. slave SSPBUF shows 0xAA right after I write 0xEA. The waveform on SDO corresponds to AA.

master code:

#include <18f458.h>
#device *=16 adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT
#use delay(clock=16000000)
#use spi(MASTER, DI=PIN_C2, DO=PIN_C1, CLK=PIN_C0, BITS=8, MODE=0, MSB_FIRST)

void main ()
{
set_tris_c(0b10011100)
while(1)
{
j=spi_xfer(0xCB);
i=spi_xfer(0xAA);
delay_ms(1000);
}
}



slave code:

#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)


void main()
{
int a = 0, b=0;
int i,j;

setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(1)
{

a = spi_read(0);
b = spi_read(0);

spi_write(0xea);
spi_write(0x2b);

printf(" %x %x", a,b);
}
}


Any hints/ help greatly appreciated.
Thx
Avarachan
Ttelmah
Guest







PostPosted: Thu Mar 20, 2008 4:12 pm     Reply with quote

With SPI, both transfers take place _at the same time_.
When the master clocks a byte to the slave, it _at the same time_, clocks back, whatever is in the slaves SPI buffer register. All the transactions are initiated, and controlled by the master. So, to send a byte 'back', the slave must write it into the buffer _before_ the master begins it's transfer. So:
Code:

#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)

   
void main(void) {
   int a = 0, b=0;
   int i,j;

   setup_spi(SPI_SLAVE | SPI_L_TO_H);
   while(1) {

      while (!spi_data_is_in()) {
         //Do anything else you want here, while waiting for the master
      }
      a = spi_read();
      while (!spi_data_is_in()) {
         //Do anything else you want here, while waiting for the master
      }
      b = spi_read(0xea);
      //You must load the return byte _before_ the next
      //master transfer

      while (!spi_data_is_in()) {
         //Do anything else you want here, while waiting for the master
         //When it reads your returned byte, you _will_receive another
         //byte, so 'data_is_in' will again go true.
      }
      spi_read(0x2b); //You should read the byte
      //and immediately put the next byte in the buffer

      while (!spi_data_is_in()) {
         //Do anything else you want here, while waiting for the master
         //When it reads your returne byte, you _will_receive another
         //byte, so 'data_is_in' will again go true. This will show it has
         //transferred the byte.
      }
      //You should read again here, to clear the dummy 'forward' byte
      //sent by the master, when it read your bytes, and clear the flag
      //otherwise the ends will ge out of sync.
      spi_read();
      printf(" %x %x", a,b);
   }
}


Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 20, 2008 4:15 pm     Reply with quote

In the slave pic, the \SS pin is enabled by default. If you want to disable
it, you have to specifically "OR" in the SPI_SS_DISABLED constant.
Your Master PIC is not controlling a Slave Select pin, so you should
either add that feature to the master, or disable it in the slave.
Guest








PostPosted: Fri Mar 21, 2008 2:23 pm     Reply with quote

Quote:
master code:

#include <18f458.h>
#device *=16 adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT
#use delay(clock=16000000)
#use spi(MASTER, DI=PIN_C2, DO=PIN_C1, CLK=PIN_C0, BITS=8, MODE=0, MSB_FIRST)

void main ()
{
set_tris_c(0b10011100)
while(1)
{
j=spi_xfer(0xCB);
i=spi_xfer(0xAA);
delay_ms(1000);
}
}



slave code:

#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)


void main()
{
int a = 0, b=0;
int i,j;

setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(1)
{

a = spi_read(0);
b = spi_read(0);

spi_write(0xea);
spi_write(0x2b);

printf(" %x %x", a,b);
}
}


Thanks, Ttelmah and PCM prgrammer for responding.

To Ttelmah:
In my attempt to cut the code as short as possible for you guys, I missed out few lines. so my original code is

master code:
Code:
#include <18f458.h>
#device *=16 adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,NOPUT
#use delay(clock=16000000)
#use spi(MASTER, DI=PIN_C2, DO=PIN_C1, CLK=PIN_C0, BITS=8, MODE=0, MSB_FIRST)

void main ()
{
set_tris_c(0b10011100)
while(1)
{
output_low(PDO7);// slave select
j=spi_xfer(0xCB);
i=spi_xfer(0xAA);
a=spi_xfer(0x00); // expects first byte from slave
b=spi_xfer(0x00); // expects second byte from slave
output_high(PDO7);
delay_ms(1000);
}
}


slave code:
Code:

#include <18f2221.h>
#device *=16 adc=10
#fuses INTRC,WDT1024,NOLVP,NOPROTECT,NOXINST
#use delay(clock=8000000)


void main()
{
int a = 0, b=0;
int i,j;

setup_spi(SPI_SLAVE | SPI_L_TO_H);
while(1)
{

a = spi_read(0);
b = spi_read(0);
spi_write(0xea);
spi_write(0x2b);

printf(" %x %x", a,b);
}
}

To PCM programmer:

I did have the /SS line controlled by the master, though I accidentally forgot to post it. So getting back to square one, I can get half part working. ie slave prints CB and AA. But everything else from there goes wrong as stated in my previous post
Quote:

I am trying to communicate to and fro bw the pics. I send two bytes from master to slave. I can read it and print it at slave. The waveforms look good too. following this, the slave sends two bytes to master.
1. The waveform on SDO is totally wrong. ie, wrong data.
>> I send 0xCB and 0xAA from master, and 0xEA and 0x2B from slave. But SDO on slave gives out 0xAA and 0x00.

2. slave SSPBUF shows 0xAA right after I write 0xEA. The waveform on SDO corresponds to AA.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 21, 2008 3:18 pm     Reply with quote

My advice is to look at the CCS example files for an SPI slave:
Quote:

c:\Program Files\picc\Examples\Ex_spi_slave.c
c:\Program Files\picc\Examples\Ex_spi.c



Also, this thread has code that demonstrates an SPI slave
but it's done using one board (because it's a demonstration).
http://www.ccsinfo.com/forum/viewtopic.php?t=26888
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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