SPI Issues

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI Issues

2,853 Views
BCast
Contributor I
Hello, I am using two 9S12E64 MCUs one as Slave and one as Master.  They are able to communicate with each other and as far as I know I am not having problems with the master, but I am having trouble getting the slave to send the desired data to the master.  Here is my master code.
 
Bit1_PutVal(0);
 delay(100);
 
 while(!SPISR_SPTEF);          // instruction
 (void)SM1_SendChar(0x05);
 while(!SPISR_SPIF);   
 delay(20000);
 
 while(!SPISR_SPTEF);           //dummy data to recieve 0xaa from slave
  (void)SM1_SendChar(0x00);
 while(!SPISR_SPIF);   
 delay(20000);
 
Bit1_PutVal(1); 
 
On the slave side, the slave reads 0x05 as an instruction to send 0xaa to the master.  My question is when do I put 0xaa into the SPIDR to where it will be sent when the master sends 0x00?  This is my slave code:
 
while(!(SPISR & 0x80));
       tester = SPISR;
        char0 = SPIDR;
if(char0 == 5){
       (void)SS1_SendChar(0xaa);
}
while(!(SPISR & 0x80));
What is wrong with my code?  How do I get 0xaa into the SPIDR before the second clock cycle?
 
Thanks for the help!
Labels (1)
0 Kudos
5 Replies

473 Views
ProcessorExpert
Senior Contributor III
Dear Customer,
Is it possible to send us a project demonstrating your problem (support@processorexpert.com)? We will check your project and bean settings and user code and we will try to solve your problem using Processor Expert' beans. According to your description you combine methods of Processor Expert and direct access to registers and it isn't good way.
Best Regards, Jan Pospisilik,Processor Expert Support
0 Kudos

472 Views
bigmac
Specialist III
Hello,
 
What are your CPOL and CPHA settings - I presume they match for both ends?  Note that, if you have CPHA = 0, you will need to raise and then lower the /SS signal [presumably Bit1_PutVal()] prior to sending the second byte.  The byte value to be returned by the slave must be loaded to its buffer prior to /SS becoming low again.
 
For the CPHA = 1 case, the /SS signal may remain low, and the return byte value must be loaded to the buffer prior to the first clock edge associated with the second byte.  Your slave code would likely be doing this.
 
For your master send function, after the SPIF flag is set, I would suggest you read the SPI data register in order to clear the flag, and to prevent an over-run condition.  An overrun may be preventing you from correctly receiving the next return byte.
 
Regards,
Mac
 
 
 
0 Kudos

472 Views
BCast
Contributor I
Thank you for your response,
 
Yes, the master and slave match in CPOL and CPHA (both are equal to 1).  I have made the change you suggested in the master code, but I have noticed no change in results.
 
Bit1_PutVal(0);                     //put SS low
 delay(10);
 
 while(!SPISR_SPTEF);         //instruction
  (void)SM1_SendChar(0x05);
 while(!SPISR_SPIF);
 delay(100);
 slave_data = SPIDR;   
 delay(10000);
 
 while(!SPISR_SPTEF);           //address
 (void)SM1_SendChar(0x00);
 while(!SPISR_SPIF);
 delay(100);
 slave_data = SPIDR;   
 delay(10000);
 
 Bit1_PutVal(1);        //Put SS high
 delay(10000);
 

bigmac wrote:
 
 
For the CPHA = 1 case, the /SS signal may remain low, and the return byte value must be loaded to the buffer prior to the first clock edge associated with the second byte.  Your slave code would likely be doing this.
 
Is writing the SPIDR prior to the second byte the same as writing to the buffer?  This is my slave code thus far.
 for(;:smileywink:{
while(!SPISR_SPIF);       //first byte recieved
       if(SPIDR == 5)
       {
          clear_spif= SPISR;
         instruction = SPIDR;
         clear_sptef = SPISR;
         SPIDR = 0xaa;          //send 0xaa during second cycle
        }
 
while(!SPISR_SPIF);       //second byte recieved.

}  
 
Could you possibly provide me with an outline code or steps?  I am really struggling with when/how to clear the flags and when to read/write to SPIDR on the slave side.  When reading the MISO pin on the o-scope I find that sometimes 0xaa is first cycle of the next instruction (cycle 3, 5, 7....), I dont understand why that is happening.
 
Thanks again!       
0 Kudos

472 Views
bigmac
Specialist III
Hello,
 
Sorry for the confusion - I did mean the data register SPIDR when referring to the "buffer".
 
For the master function, the delay(100) prior to reading the data register is superfluous since the return data will be immediately available when SPIF becomes set.
 
For the slave function, here is my suggested (but untested) code -
 
for ( ; ; ) {
  while (!SPISR_SPIF);      // Wait for first byte received
  instruction = SPIDR;      // Also clears flag
  if (instruction == 5)
     SPIDR = 0xaa;          // Send 0xaa during second cycle
  else
     SPIDR = 0;
 
  while(!SPISR_SPIF);      // Wait for second byte received
  instruction = SPIDR;     // Clear flag (ignore received value)

This code assumes that the COP timer is disabled.  If not, you will need to reset the COP timer during the wait loops.  Ultimately, you will probably want to use interrupts for the slave processing, so you can do other things whilst waiting for SPIF to become set.
 
Regards,
Mac
 
0 Kudos

472 Views
BCast
Contributor I
Bigmac,
 
Thanks again for your advice, it was very helpful.  Turns out that the Process Expert beans were the problem.  As soon as I deleted the beans the code you suggested worked.  The next step would be to implement this code using interrupts.
0 Kudos