AnsweredAssumed Answered

SPI in SLAVE mode - please clarify MOSI (i.e. Tx) behaviour when DR is not written

Question asked by waclawek.jan on Feb 7, 2017
Latest reply on Mar 23, 2017 by Amel N

When an SPI in SLAVE is clocked continuously (with NSS active) and DR is *not* written upon every TXE set, there are several possible scenarios for MOSI behaviour after the last explicitly written data bit is transmitted:

  1. MOSI is set permanently at a predetermined level (0 or 1)
  2. MOSI remains permanenlty at the last transmitted bit's level
  3. MOSI is threestated
  4. MOSI "echoes" the received data on MISO, delayed by N SCK clocks
  5. MOSI transmits the last written data as if they would be written repeatedly
  6. unspecified/undocumented


Currently, the behaviour of SPI in STM32 (namely STM32F40x) is undocumented in this regard. Hereby, I would like to ask ST to properly document this behaviour in the Reference Manuals.



STM32s' SPIs in slave configuration are often used with masters with continuous clocking and no option for byte/word framing (e.g. various Cortex-A based SoC) (the 'F4xx itself, when used as a master, has no practically usable provision for framing, too). Also, often the highest possible clock is used, primarily to reduce data transfer latency rather than to increase bulk data rate. This means, that data are transferred quickly but with ample time between valid data. As slave is not in control of clock, to minimize latency for slave-to-master signalling, clock has to be continuous. Usually, data are packetized and a "neutral" non-start-of-packet character is transferred between packets.


Due to need for continuous high-speed clock, it's usually impractical to impossible to use polled or interrupt-based transmission in the slave, and DMA is the only viable option.


There are two possibilities how to use DMA - continuously in circular mode, or discontinuously, per demand. Note, that there's seldom any provision to throttle the master, so we need to assume a continuous uninterrupted SCK  thus TXE being set regularly.


In the case of circular DMA, when requirement for Tx-to-master arises in slave's program, the processor has to disable interrupts, get the current NDTR, calculate a suitable displacement so that DMA won't start to read the partially written data, write the data with wraparound (using mem-to-mem DMA for this may not be of much help due to the need for wraparound) and enable the interrupts. And, after the data have been transmitted to the master, the processor needs to clear the data from the DMA so that it won't get transmitted the circular-DMA gets around to the same spot in the buffer.  For this, the program would probably set a timer to be interrupted at the moment when transmission finishes, and then store a string of "neutral" characters to the buffer, again under disabled interrupts. This all is an overly complicated procedure which may occupy significant amounts of the mcu's resources. (A scatter-gather-capable DMA would alleviate all this and simplify the procedure but the general-purpose DMA in STM32's is not such.)


In case of single-shot DMA, when requirement for Tx-to-master arises in slave's program, the processor simply sets the DMA's source pointer to the data wherever they already are, sets NDTR and enables the transmission. When transmission ends, possibly in NDTR interrupt, SPI is set to transfer the "neutral characters", if this is needed at all (the observed but undocumented behaviour allows to omit this by adding the "neutral" character to the end of transmitted data). However, this implies the slave transmitter has a known behaviour when clocked without DR having explicitly written.




Jan Waclawek