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

Here is "prev" transfer:

0690X00000AQvttQAD.png

And Saleae Logic scope file (wrong transfer marked by timing markers):

Sorry I don't have the Saleae analyzer and don't intend to install the program. Can you please cut out the "previous" and "corrupt" transfer and place them next to each other?

[EDIT] Okay maybe it's not that necessary. Try to answer the following question first, and then perhaps mitigate it - if the signals are floating, try to set pullups/pulldowns as appropriate, especially to SCK [/EDIT]

Also, what is the SPI_ENABLE signal? And why are the SPI signals changing after the transfer ended?

Thanks,

JW

SPI_ENABLE is slave select line.

After end of the transfer I execute disable and deinit SPI (including clock disable - RCC_APB2PeriphClockCmd) and change MISO/MOSI/SCK pins to INput mode with pull-down.

You can see similar state-changing on start of the transfers too.

Combined previous--->corrupted transfers:

0690X00000AQvy5QAD.png

"Previous" closer view:

0690X00000AQvyAQAT.png

> After end of the transfer I execute disable and deinit SPI (including clock disable - RCC_APB2PeriphClockCmd) and change MISO/MOSI/SCK pins to INput mode with pull-down.

Okay, so don't do this. Leave the SPI on. And, as as you CPOL so that SCK is high on idle, don't use an pulldown, us a pullup to avoid any transition on SCK.

I'd say, the exact sequence how you re-enable the SPI includes a period, where the SPI is slave and its clock is floating, resulting in the internal clock-counter to be shifted out of 0 and remaining so even if switched to master. The bunch of pulses on MISO in the "corrupted transfer" at the moment when the _ENABLE signal goes low is IMO not a coincidence.

The SPI state machine is relatively fragile. SPI_CR1.SPE is always the last bit to be set.

I don't Cube.

JW

Thank you for your advice, I'll try with corrected init sequence.

By the way - I have disabled DMA and still got the same error.

> By the way - I have disabled DMA and still got the same error.

I'd expect that, the problem appears to be entirely in the SPI and the way how it counts bits.

JW