2025-06-28 2:27 AM
Hello everyone,
I'm currently working with an STM32F746 microcontroller as an SPI slave using DMA for data reception.
The SPI master sends fixed-size packets of 512 bytes, and everything works fine most of the time. However, occasionally, a few bytes (e.g., 4 bytes) seem to get lost during transmission or reception. After that, the SPI slave continues receiving data, but everything becomes misaligned by that number of lost bytes. This causes the following packets to be parsed incorrectly and fail CRC checks.
I need a way to recover synchronization after such a misalignment — that is, to detect when a packet is no longer aligned to the expected 512-byte structure, and then find the correct boundary again so I can resume proper packet parsing.
Has anyone encountered a similar issue? I’d appreciate it if you could share any ideas or solutions on how to resynchronize the SPI DMA stream after a data loss event.
Thanks in advance and have a great day!
Solved! Go to Solution.
2025-07-14 10:59 PM
Thank you all for your help, but it ultimately didn't work out, so I ended up solving it in a completely different way. Perhaps the previous suggestions weren't the right fit for my specific problem, or maybe I implemented them incorrectly.
I've now written the code to continuously accumulate incoming data into a buffer and then retrieve the packet only after verifying the correct STX and ETX values.
Although it's late, I appreciate your help. Thanks, everyone.
2025-06-28 7:18 AM
Use a CS signal to drive the slave. When CS goes high, have the slave re-initialize the SPI if necessary to re-sync to the start of the buffer. You can set the CS pin to trigger an interrupt through EXTI when it goes high.
2025-06-29 6:03 AM
I’d like to confirm if I understood the suggested method correctly.
When some bytes are lost and the data stream becomes misaligned:
1. Disable DMA and SPI
2. Clear the RX buffer to remove any remaining data
3. Re-enable DMA and SPI
4. When the CS line goes HIGH, call HAL_SPI_TransmitReceive_DMA() to re-sync to the start of the buffer
Is this correct?
2025-06-29 7:02 AM
Yes. There's likely an Abort call you can make here to do most of this.
2025-06-29 8:14 AM
Hi @JIN3473 ,
Maybe worth looking at whether you can implement, or tweak (if already implemented), impedance matched termination for your MISO and clock signals? Perhaps your application can tolerate these occasional errors, but I'd take them as a sign that maybe you need to clock a bit slower or improve the waveforms; if you have control over the driving source's edge rate (how hard it drives the signal high/low), that might help with no need for any circuit changes.
2025-06-29 5:39 PM
I implemented my SPI recovery mechanism as shown below:
However, the SPI communication doesn’t resume at all — not even after the reset.
It seems that HAL_SPI_TransmitReceive_DMA must be called before the master starts communication, or else the SPI slave never activates and the CS line doesn’t function as expected.
From this behavior, I suspect that this function must be executed in advance, and that trying to resynchronize based on the CS pin later (via timer or polling) is too late.
Therefore, I’m starting to believe that timing-based recovery like this is not viable, as the slave needs to be ready before the master asserts CS and begins transmission.
Does anyone have a better suggestion for how to recover from misaligned packets when using SPI DMA in slave mode?
2025-07-14 10:59 PM
Thank you all for your help, but it ultimately didn't work out, so I ended up solving it in a completely different way. Perhaps the previous suggestions weren't the right fit for my specific problem, or maybe I implemented them incorrectly.
I've now written the code to continuously accumulate incoming data into a buffer and then retrieve the packet only after verifying the correct STX and ETX values.
Although it's late, I appreciate your help. Thanks, everyone.