cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F412 SPI DMA data bit-shifted

ohmjke
Associate II

Hi.

First of all, the essence of my problem is already described here - https://community.st.com/s/question/0D50X00009XkiXu/spi-dma-data-corruption?t=1567119350874

In my case bug happens randomly and not very often. It could be one corrupted transaction among hundreds-thousands.

For example, how it is should work:0690X000009akJJQAY.png

First byte always is 0xAA.

Here is an example of corruption:

0690X000009akJTQAY.png

You can see that CLK signal has already started, but data on MOSI is delayed by 5 bits (not constant, can be 4, 3...).

My code: https://pastebin.com/X3CfdH4q

And settings: https://pastebin.com/GKWTC1QH

15 REPLIES 15

Read out and check or post content of SPI registers.

JW

ohmjke
Associate II

I have checked content before this calls:

SPI_I2S_DMACmd(spi, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE);

DMA_Cmd(dma_rx_stream, ENABLE);

DMA_Cmd(dma_tx_stream, ENABLE);

And after end of transaction (DMA_IT_TCIF2 bit is set).

0690X000009anC6QAI.png

Data in DR register "after" - 0xE1.

Content of RX memory buffer (should be AA 48 11 89 ..... FF FF FF FF):

0690X000009anH1QAI.png

How entire transaction looks:

0690X000009anL8QAI.png

The beginning of it (in this case I send all 0xFF bytes):

0690X000009anMzQAI.png

And the end:

0690X000009anN4QAI.png

Looks OK.

Does the transfer *before* the "failed" one exhibit any irregularity, e.g. incorrect/incomplete last byte transferred, or any outstanding clocks?

JW

It seemed that you misunderstood me (or I don't understand you now).

There is no "before" and "after" transfers.

It is one transfer, I just read out SPI regs before DMA request and after end of the transfer (just in case).

Content of registers looks fine to me too.

> There is no "before" and "after" transfers.

You reset the whole mcu between transfers?

You've been talking about hundreds-thousands transactions. I don't believe you've performed hundreds-thousands system resets and observed single transfers between them.

JW

S.Ma
Principal

When using DMA on SPI, you need to be careful in the timing and events. If here we are talking about SPI Master, my advice are:

  • DMA TX main purpose is to generate the SCK clocks (and push out data). It should not have an interrupt nor callback
  • SPI should be in bi-directional mode (the other ones have time contrains)
  • DMA RX should be the one triggering the transfer complete and the next possible block transfer.
  • Always set DMA RX before TX (which kicks in the clocks)

If some of these points are not covered, dig more in your code, or try modify the source accordingly.

Yes, you are right. I didn't reset mcu.

The last transfer before corrupted one was fine, so as next after it.

Yes, in my case mcu works as master.

  1. TX stream do not have neither enabled interrupt nor used callback.
  2. Yes, we use "SPI_Direction_2Lines_FullDuplex".
  3. DMA_IT_TC interrupt enabled for RX stream. DMA and SPI will disable after this interrupt is happened.
  4. Already done.

> The last transfer before corrupted one was fine,

How do you know? Post scope/LA pictures.

JW