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 master to multiple slaves

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







SPI master to multiple slaves
PostPosted: Mon Jun 16, 2008 1:28 pm     Reply with quote

Guys,

I'm trying to get a master to write to x amount of slaves, getting a response. I can get the slaves to respond by toggling pins.
However i cant seem to get the master to respond and am at a lost end.

The SS lines are polled separately and i have tried with just one slave with the same results.

Any help is appreciated.
Thanks in advance Smile

Master Code
Code:

void init()
{
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
   //enable_interrupts(INT_RTCC);
   //enable_interrupts(INT_SSP);
   //enable_interrupts(GLOBAL);

   set_tris_a(0x00);
   output_a(0x00);

}

void main()
{
   init();
   delay_ms(100);


 while(1)
 {
    if(!cards_ok)
   {
      cards_ok = poll_cards();
   }
   else
   {
      switch(card_no)
      {
      case 0: output_low(PIN_A3);

      case 1: output_high(PIN_A3);
            delay_ms(400);
            output_low(PIN_A3);
            delay_ms(400);

      case 2:   output_high(PIN_A3);
            delay_ms(200);
            output_low(PIN_A3);
            delay_ms(200);
            output_high(PIN_A3);
            delay_ms(200);
            output_low(PIN_A3);
            delay_ms(200);
      }
   }
 }
}

byte poll_cards()
{
 byte i;

     output_low(card1_ss);
   for(i=0; i<10; i++)
   {
      card_ack = spi_read(0x01);
      delay_ms(1);   
      if(card_ack == 0x10)
      {
         card1_success = 1;
         card_no++;
         break;
      }
   }
     output_high(card1_ss);

     output_low(card2_ss);
   for(i=0; i<10; i++)
   {
      card_ack = spi_read(0x02);
      delay_ms(1);   
      if(card_ack == 0x11)
      {
         card2_success = 1;
         card_no++;
         break;
      }
   }
     output_high(card2_ss);
     return card_no;
}


Slave Code
Code:

#int_SSP
void  SSP_isr(void)
{
   spi_data_in = 1;
}

void init()
{
   setup_spi(SPI_SLAVE|SPI_L_TO_H|SPI_SS_DISABLED);
   //enable_interrupts(INT_RTCC);
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   set_tris_a(0x00);
   output_a(0x00);

}

void main()
{
 init();
 delay_ms(100);

 while(1)
 { 
   if(data_ok)
   {
      toggle_pins();
   }
   
   if(spi_data_in && (SPI_DATA_IS_IN()))
   {
      disable_interrupts(INT_SSP);
   
      if(!SS)
      {
         data = spi_read();
         delay_ms(1);
         if(data == 0x02) // value changed for different slave
         {
            spi_write(0x11); // value changed for different slave
            delay_ms(1);
            data_ok = 1;
         }   
      }   
   }
   spi_data_in = 0;
   enable_interrupts(INT_SSP);
  }
}

void toggle_pins(void)
{
   output_high(PIN_A3);
   delay_ms(500);
   output_low(PIN_A3);
   delay_ms(500);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 16, 2008 1:36 pm     Reply with quote

Quote:
Master Code:
byte poll_cards()
{
byte i;

output_low(card1_ss);


Slave Code:
setup_spi(SPI_SLAVE|SPI_L_TO_H|SPI_SS_DISABLED);

What's wrong in the code above ?
Guest








PostPosted: Mon Jun 16, 2008 1:43 pm     Reply with quote

Hi,

I am using a pin on PORTE instead of the SPI SS line, so i thought i would need to disable that option.

I hope that clears that bit up Smile
Ttelmah
Guest







PostPosted: Tue Jun 17, 2008 2:29 am     Reply with quote

With SPI, data goes _both ways at once_. Now, when you perform 'spi_read(0x02)', 2 gets sent, and you receive back the _last_ byte that was in the slave devices buffer. If the slave if setup to respond to the '2', and return an acknowledge byte for this, you have to perform two transfers. So:
Code:

SPI_WRITE(2); //_send_ the '2' byte, and ignore the returned byte
delay_us(20);  //You _must_ have enough time here for the slave
//to load the response
SPI_WRITE(0); //send a 'dummy' byte, to allow the slave response
//to be read.
RESPONSE=SPI_READ(); //read the byte which the slave sent.


I suspect this is the first problem.
Depending on the clock rates involved, the delay may need to be a lot more. Your slave, has to detect the interrupt, call the handler, return from the handler, go round the loop, and detect the bit has been set, then load the response. Probably in the order of 100+ instructions. At 4MHz, 100+uSec.....
Secondly, what happens in the slave, when the select line goes high?. Does it need _time_ to handle this?. Between your two transmissions, you are raising and lowering the line, for just one instruction cycle. What will the effect of this be?. Depending on the position in the loop, this may be seen or not, and would increase delays.
Finally, 1mSec delay in the slave!. What on earth for?...... This will really slow the response.

Best Wishes
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