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 CCS Technical Support

SPI slave not receiving data from master

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



Joined: 20 Mar 2007
Posts: 1

View user's profile Send private message

SPI slave not receiving data from master
PostPosted: Tue Mar 20, 2007 3:19 am     Reply with quote

Hi,

We have tried to set up a PIC18F4520 (on an eval board) as a slave in SPI mode and a DSP as a master. For some reason the PIC does not receive anything in its SSPBUF even though it is interrupted. When we look at the BF flag in the SSPSTAT register it never gets set. However if we use a PIC18F452 (on the same eval board) the code works perfectly so we know we are not configuring the slave as a master by accident plus the two devices are pin compatible. Comparing the register set for the two devices the only differrence appears to be the BF flag not being set but as to why it is bot being set is a mystery. We are not using the /SS select line and am running at 1.25Mbps. Does anyone know of why a 18F4520 should not work in this mode and has example code they can share where they have successfully used one as a slave.

I hope someone can help or its a case of surgically removing the 18F4520 and replacing it with a 18F452 on the actual target.
Sad
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Mar 20, 2007 4:45 am     Reply with quote

Which compiler version are you using?

Post a very short but complete and compilable program demonstrating your problem.
mskala



Joined: 06 Mar 2007
Posts: 100
Location: Massachusetts, USA

View user's profile Send private message

PostPosted: Tue Mar 20, 2007 6:52 am     Reply with quote

I can't see why both won't work the same except for oscillator differences or compiler issues.

I just recently implemented a slave on an 18F4520 to test something else. This code uses 2 transactions to make the PIC look like a 128-byte RAM.
I am using SS, though.

Send (128-255) followed by the value to write, writes to reg 0-127.
Send (0-127) followed by any value to read a reg.

Output is to an LCD emulator, you don't need this. Also I used pin B2 to show that I was getting interrupts on scope. Everything works fine.

Code:

#include <18F4520.h>
#device HIGH_INTS=TRUE

// using internal 8MHz osc

#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
#use delay(clock=8000000)

#define SPI_MODE_0_0 0x4000    //CKP=0  CKE=1  clock idle=low,  xmit on idle edge
#define SPI_MODE_0_1 0x0000    //CKP=0  CKE=0  clock idle=low,  xmit on active edge
#define SPI_MODE_1_0 0x0010    //CKP=1  CKE=1  clock idle=high, xmit on idle edge
#define SPI_MODE_1_1 0x4010    //CKP=1  CKE=0  clock idle=high, xmit on active edge


#define VFD_RW PIN_E0
#define VFD_E PIN_E1
#define VFD_RS PIN_E2
#define LED_PIN PIN_C0

#define STATE_SPI_IDLE 0
#define STATE_SPI_WREG 1
#define STATE_SPI_RREG 2
#define STATE_SPI_FIN 3
static int8 spi_st;

//  These work only for PIC18 devices
#byte   SSPBUF = 0xFC9
#byte   SSPCON = 0xFC6
#byte   I2CBUF = 0xFC8
#byte   SSPSTAT = 0xFC7

// Now the SSP handler code.
#DEFINE   READ_SSP()     (SSPBUF)
#DEFINE   WAIT_FOR_SSP() while((SSPSTAT & 1)==0)
#DEFINE   WRITE_SSP(x)   SSPBUF=(x)
#DEFINE   CLEAR_WCOL()   SSPCON=SSPCON & 0x3F


// Variables used for the command buffer.
#define CMD_BUF_SIZE 16
static int8 cmd_buf[CMD_BUF_SIZE];
static int8 cmd_buf_beg;
static int8 cmd_buf_end;
#define cmd_ready (cmd_buf_beg != cmd_buf_end)


static int8 current_reg;
static int8 current_data;

static int8 r[128];

void vfd_w_inst(int8 value)
{
   output_low(VFD_RS);
   output_low(VFD_RW);
   output_high(VFD_E);
   output_d(value);
   output_low(VFD_E);
}


void vfd_w_data(int8 value)
{
   output_high(VFD_RS);
   output_low(VFD_RW);
   output_high(VFD_E);
   output_d(value);
   output_low(VFD_E);
}


void initdisp()
{
   vfd_w_inst(0x3c);  // function set, necessary first command
   delay_us(2);
   vfd_w_inst(0x0c);  // display on, no cursor, no blink
   delay_us(2);
   vfd_w_inst(0x01);  // clear display
   delay_us(2);
   vfd_w_inst(0x03);  // cursor home
   delay_us(2);
   vfd_w_inst(0x06);  // entry mode set
   delay_us(2);
}


void displaynumber2(int8 num)   // displays 8-bit number in decimal always 3 dig
{
    int8 copy,a,b,c;

    a=num/100;
    copy=num-(a*100);
    b=copy/10;
    c=copy-(b*10);
    vfd_w_data(a+48);
    vfd_w_data(b+48);
    vfd_w_data(c+48);
}

#int_timer0
void timer0_isr()
{                        // blinking LED on off every approximately 1 second
   
   led_timer++;
   if (led_timer>15) {
      output_bit(LED_PIN,led);
      led=1-led;
   led_timer=0;
   }
}

#int_ssp HIGH      // pre-empts other interrupts
void spi_isr()
{
   int8 val;

   output_high(PIN_B2);
   switch (spi_st) {
      case STATE_SPI_IDLE:
         current_reg=spi_read();
         if (current_reg>0x7f) {
            spi_st=STATE_SPI_WREG;
            WRITE_SSP(0);
         } else {
            spi_st=STATE_SPI_RREG;
            current_data=r[current_reg];    // save val for creating command after next int
            WRITE_SSP(current_data);        // write buffer for next byte transfer but don't wait
         }
output_low(PIN_B2);
         break;
      case STATE_SPI_WREG:
         current_data=spi_read();
         r[current_reg&0x7f]=current_data;
         cmd_buf[cmd_buf_end++]=current_reg;
         if (cmd_buf_end>=CMD_BUF_SIZE)
            cmd_buf_end=0;
         cmd_buf[cmd_buf_end++]=current_data;
         if (cmd_buf_end>=CMD_BUF_SIZE)
            cmd_buf_end=0;
         spi_st=STATE_SPI_IDLE;     // main prog should do something now
 output_low(PIN_B2);
         break;
      case STATE_SPI_RREG:
         val=spi_read();          // SPI read without writing buf, which was loaded before
         cmd_buf[cmd_buf_end++]=current_reg;
         if (cmd_buf_end>=CMD_BUF_SIZE)
            cmd_buf_end=0;
         cmd_buf[cmd_buf_end++]=current_data;
         if (cmd_buf_end>=CMD_BUF_SIZE)
            cmd_buf_end=0;
         spi_st=STATE_SPI_IDLE;
output_low(PIN_B2);
         break;
      default:
         break;

   } //end switch

}


void main()
{
   int8 i;

   setup_oscillator(OSC_8MHZ);
   led=0;
   spi_st=STATE_SPI_IDLE;

   output_low(PIN_B2);   // this is my Int Service Routine flag

   cmd_buf_beg = 0;
   cmd_buf_end = 0;
   setup_spi(SPI_MODE_0_0|SPI_SLAVE);

   delay_ms(100);
   initdisp();

   vfd_w_data('R');
   vfd_w_data('e');
   vfd_w_data('a');
   vfd_w_data('d');
   vfd_w_data('y');

   setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);  // at 8MHz, it times out (256 counts) in 32.768ms

   clear_interrupt(INT_SSP);
   enable_interrupts(INT_SSP);    // interrupt on SPI transaction
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);

   while (1) {
      if (cmd_ready) {
         vfd_w_inst(0x03);  // cursor home
         if (cmd_buf[cmd_buf_beg]>0x7f) {
            vfd_w_data('W');
            vfd_w_data('r');
            vfd_w_data('i');
            vfd_w_data('t');
            vfd_w_data('e');
         } else {
           vfd_w_data('R');
            vfd_w_data('e');
            vfd_w_data('a');
            vfd_w_data('d');
            vfd_w_data(' ');
         }
         vfd_w_data(' ');
         displaynumber2(cmd_buf[cmd_buf_beg++]);
         vfd_w_data(' ');
    vfd_w_data('V');
         vfd_w_data('a');
         vfd_w_data('l');
         vfd_w_data(' ');
         displaynumber2(cmd_buf[cmd_buf_beg++]);
         if (cmd_buf_beg>=CMD_BUF_SIZE)
            cmd_buf_beg=0;
      } else {
        delay_ms(2);
     }
   }
}
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