2015-02-15 12:59 PM
I am using SPI in slave mode with a mix of manual transmission/reception at the beginning of my message protocol (first 3 bytes manual), then DMA in the middle for the data transfer, then manual ACK/NAK byte response at the end based on the received CRC.
The first message goes through and slave code responds exactly as expected. However, when the master sends the second message, the first byte in response sent by the slave is incorrect, and the other response bytes are skewed/delayed by 1 byte. It appears as if the TXFIFO has an extra byte in it (that I didn't load, or didn't intentionally load), and this byte is sent before my ''good'' data.Setting a breakpoint at the beginning of the routine, I can see that the setup for SPI and DMA are identical for the first message which works, and second message that does not work.After I finish a message, I would like to clear the transmit and receive FIFOs to get a fresh start. Clearing the receive FIFO is not a problem (just read SPI1->DR four times and discard the results). Is there a way to clear the TXFIFO, or at least reset the internal TXFIFO pointer ?It is strange that I would have to do this at all since there shouldn't be any ''extra'' bytes in the TXFIFO anyway. Everything that I've loaded has been sent - no less - no more. I waited unit the DMA indicated that the transfer was complete, and that the BSY flag was set, indicating the last DMA byte was in flight, before the last manual byte was sent. A screen capture of my Total Phase Cheetah log is attached. The format is Master Sent/Slave SentThe first message is good. The slave response to the master 81 is AA. However, in the second message, when the master sends 81, the slave sends 15. I have no idea where this came from. I searched in memory in the areas close to the DMA buffer, but could not find it.Any help or insight would be appreciated.Thanks2015-02-15 02:42 PM
2015-02-15 11:54 PM
That's a symptomatic cure. I personally would work on finding the root cause of the problem - did you use the CRC mode of SPI, for example?
JW2015-02-16 06:10 PM
2015-03-09 05:49 AM
Hello,
I ran into similar problems and I think I know the root of the problem. The TXE flag is set as long as the TX FIFO is *not full*. So you're always stuffing too much data into the TX FIFO - and after the SPI transfer is completed, there's no way to get it out of there. The data that remained in the TX FIFO will be shifted out during the next SPI transfer. In my case (with an F303), I am using the DMA to provide /all/ data to the SPI. But if the transfer is prematurely ended by the master, the next three data bytes are already in the TX FIFO and these will be sent first at the next transfer. Indeed the only way around this is a peripheral reset on the SPI - apparently, there really is no other way to reset the TX FIFO and state! I'd call that a bug. (In fact, this FIFO implementation is the worst I've ever seen...) Tilmann