SPI confusion

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

SPI confusion

3,937 Views
hassoon
Contributor I
I'm hoping someone can point me in the right direction -
this is my first encounter with SPI, I have a 1Mhz stream of data requests from a remote 'master' device for which I've coded a SPI handler for my SLAVE hc9s12  which sorts & buffers the data perfectly. My problem occurs when certain data packets from the master require a response. A series of null bytes are sent effectively for me to populate with my returned data, here I make a write to the Tx data reg before the next master Tx, if I scope the MISO expecting to see my data on the next byte shift I only see an echo of the master data, (null byte in this case). I've also noticed If there is no software interaction the SPI module only echoes the data at MOSI I would at least expect there to be a 1 byte lag ?
In fact if I view the data reg real time It seems I can't actually write my data into it, i guess this could be overwritten though by the incoming data at MOSI.
 
Can anyone confirm if this is correct either way ?
 
confused...
 
Labels (1)
0 Kudos
Reply
10 Replies

1,553 Views
hassoon
Contributor I
thanks for the interest,
CHPA is left at default value '1' as the master issues the data at the 1st edge, clocking in on the 2nd edge.
CPOL is clear at the clock edge is active high, & SS is driven low for each byte, returning high after the 8th bit.
This appears to be working. If I monitor in realtime memory, when I make a right to the SPI Tx register this data never appears in memory location weird.... nor does it get passed to the shift register, I am begining to suspect a SPI failure on some level.
 
for completeness this is my reg config:
 
// SPI0 setup
 SPI0BR |=0x02;               // set baud rate to 1MHz
 CHPA_SET                     // data clocked in on 2nd edge
 ENABLE_SPI
 CPOL_CLEAR                // clock polarity active high, idles low  
 ENABLE_SPI_INT           // interrupt control
 
0 Kudos
Reply

1,553 Views
bigmac
Specialist III
Hello,
 
By reading (monitoring) the SPI data register, you will see the byte value last received, and not the send value within the send buffer.  It is not possible to monitor the send value once it is in the send buffer.
 
If the return value is entered to the buffer in a timely manner, I can't see a specific reason why it should not be transmitted.  Perhaps you should now post your code for the SPI slave transaction.
 
Do you clear the SPIF flag after each transaction?  An overrun condition might prevent the data from being returned.  It is certainly important to clear this flag at the master end.
 
I notice you are initialising the SPI bit rate.  This is not necessary for the slave end since the master will dictate the clock rate used.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-03-07 09:20 PM
0 Kudos
Reply

1,553 Views
hassoon
Contributor I
my SPI Tx routine is as follows:
 
if(Tx_required)
{
     while(!(SPI0SR & 0x20)); 

    // load data into reg
    SPI0DR=some_data;

     // clear SPTEF
     SPI0SR;
}
 
a flag is set in my SPI Rx handler when a response is required, it is expected that the next MOSI byte will be null around 10uS later, the idea is I can load the Tx reg in this quiet period.
 
I've even tried loading the Tx reg in the Rx handler on the condition that the next byte will be null, that didn't work either.
 
FYI the SPIF is cleared in my SPI handler by reading the SPI0SR, I think this is OK.
 
0 Kudos
Reply

1,553 Views
bigmac
Specialist III
Hello,
 
The SPIF flag is cleared by first reading SPI0SR (when the flag is set), and then reading SPI0DR.  But I presume you are already doing this to ascertain the received byte value.
 
The SPTEF flag is automatically set and cleared, to indicate when further (return) data may be loaded to the send buffer.  No specific action is required.  If the interrupt occurs as a result of the SPIF flag becoming set, the send buffer will always be ready to accept a return byte, without the need to check the SPTEF flag.  It is very desireable that the return byte be loaded to the buffer from within the SPI ISR.
 
I am still considering the possibility that your problem may be one of tiiming.  Perhaps you should verify, using an oscilloscope, that the clock line remains idle for a period of 10 microseconds between the sending of each byte, and that the SS line also remains high for a similar period.  This would give a period of about 18 microseconds between successive SPI interrupts at the slave MCU.
 
You did not mention the bus frequency you are using.  For example, using a 30MHz bus, an interrupt would occur every 540 cycles.  In practice, the SPI ISR execution should occupy a fraction of these cycles, and must definitely never exceed this number of cycles under worst case conditions.  The return data would need to be loaded to the transmit buffer well within 300 cycles from the SPIF flag becoming set (not necessarily the commencement of the ISR code, which might be delayed).
 
This would be the case if the SPI is the only interrupt.  If you have other interrupts, these will potentially delay the SPI interrupt by their execution cycles, and may possibly multiple interrogations for SPI return data.  Of course, you may choose to allow the use of nested interrupts, but the additional complexity of their implementation and control will add furher cycles to the processing of each SPI interrupt.  It is quite possible that, to allow for these additional delay considerations, you may need to increase the period between SPI transactions to well beyond 10 microseconds.
 
Perhaps you could try increasing the gap, and see whether this improves your current difficulty.
 
Regards,
Mac
 


Message Edited by bigmac on 2008-03-10 10:59 PM
0 Kudos
Reply

1,553 Views
hassoon
Contributor I
Sorted, thanks to everyone for their input, enabling me to verify my configuration. There are some key points I did misunderstand, however I have just been provided with a 2nd protoype board & my code works, the relief !!!
I have since changed the uP I was currently working on, again the new uP works also. It seems I had defective hardware, I'm not sure why the SPI module failed though ?
 
again thanks to everyone for their support.
0 Kudos
Reply

1,554 Views
bigmac
Specialist III
Hello,
 
Depending on the CPHA setting used, the return data should be written to the SPI data register prior to the SS input becoming active low, or prior to the first clock edge.  Check that the SS signal returns to high after each byte is sent.
 
Also keep in mind that a second return byte may be queued whilst the first is sent.  This might help with some of the slave timing issues.
 
Incoming data does not over-write the queued send data since different registers (at the same address) are actually used for receive and send.
 
Regards,
Mac
 
0 Kudos
Reply

1,554 Views
JimDon
Senior Contributor III
The issue of the SS line is not necessarily that way. The SPI devices I have talked to require that the select line NOT be raised while executing a command. In other words, the master sends a command to the device and expects a response from the salve, all the while keeping the select line low. This is because slave devices often uses the select line to reset the command state machine.

It is true that you will need to write the data before the edge of the clock where the data is expected. It is also correct that there are two registers, and in fact you should see the date you wrote being clocked out. It is possible you missed this in the set of the SPI module.

Do you have a specification of the protocol that the master follows? In SPI there is not a hard standard as to protocol and clock edge.

0 Kudos
Reply

1,554 Views
bigmac
Specialist III
Sorry Jim, I must disagree ...
 
For a setting of CPHA = 0, the SS line must be raised at the completion of each byte transfer, for the slave SPI to operate correctly.  This is explicitly stated in the data sheet.  Obviously this may not necessarily apply if the slave is other than a MCU, but it does apply in this instance.
 
Regards,
Mac
 
 
0 Kudos
Reply

1,553 Views
JimDon
Senior Contributor III
Well, my point was more general - the master may not raise the SS line as in some cases the protocol does not expect that the SS line will be raised for the slave to respond to a command. If it is the case, that the master does not do this, then there is little that can be done to change this.

It is also possible the the wrong  mode has been selected in the registers at initialization. If the master does not lower the SS line, then you will have to use CPHA=1. It is possible to select the wrong mode and still receive data correctly. If you have CPHA=0, try CPHA=1 and invert CPOL from what you had it.

If this does not work, then you may have to bit bang.







0 Kudos
Reply

1,553 Views
peg
Senior Contributor IV
OK OK

The OP should make himself a little clearer..

Do you have a point to point connection from Freescale MPU to Freescale MPU?

If this is the case it WILL work given the correct setup at each end. (No need to resort to bit-banging).

0 Kudos
Reply