AnsweredAssumed Answered

Board to board bi-directional SPI+DMA data corruption issues

Question asked by Godshall.Robert on Jul 17, 2014
I have two discovery cards setup for bi-directional SPI. On the slave, I'm using SPI3 with DMA1 support (TX stream = CH0_S5, RX=CH0_S0). I have the TX stream flow control configured as DMA_FlowCtrl_Peripheral (tried both, this makes most sense to me due to nature of SPI & DMA) and the RX stream as DMA_FlowCtrl_Memory (also tried both). Regardless of RX flow control config, and with TX as peripheral control, I observe the following:
- When the master xfers zeros and the slave xfers non-zeros, the both sides get the proper data, tho the first slave TX byte is either zero (1st xfer) or the last buffered value - I expect this based on the spec.
- The result is the same (disregarding TX buffer notes) when the slave xfers zeros and the master xfers non-zeros
- However, when both xfer non-zero data, the slave RX buffer is mostly corrupted as well as the data that the slave shifts out (as observed on logic analyzer and in master RX buffer - both of which agree with each other). 


This leads me to suspect that the TX & RX stream accesses to SPI3->DR are somehow colliding. Does this make sense? I infer from the datasheet that full bi-directional xfers with DMA support should be possible; have I misinterpreted the spec?


Some possibly pertinent notes on setup: 
- running master clk very slow (333kHz)
- running all buses at full speed - this is required by other aspects of this system (SYSCLK = 168MHz)
- with slave RX in DMA_FlowCtrl_Mode, buffer size [NDTR] is 8 (as is #bytes xfered by master)
- in either slave RX flow control case, RX TCIF interrupt is triggered. However, the slave TX TCIF is not triggered when configured in peripheral flow control mode; as such, I am clearing any TX flags and resetting the TX stream in the RX IRQ handler
- my code is based on the std peripheral lib v1.3 example SPI_DataExchangeDMA; changes include interrupts, hard NSS behavior, triggering methods
- Slave register values after init but before first xfer:
  - SPI3: 
    - SPI3_CR1: 0x00000050
    - SPI3_CR2: 0x00000003
  - DMA1
    - DMA1_S0CR: 0x00002C15 (slave RX stream, memory flow control mode)
    - DMA1_S5CR: 0x00022C75 (slave TX stream, peripheral flow control mode)


I can manage if either the master or slave must xfer zeros while the other xfers real data, but this doubles my comms period. Fully bi-directional data is my goal. Any input or suggestions would be helpful.

Thanks!

Outcomes