Showing results for 
Search instead for 
Did you mean: 

How to stop transmission with SPI Master in Circular DMA Mode?

Associate II


I need to transfer more data, than I could afford to store in memory with an SPI Master. So I thought to use the circular DMA to update the data using HAL_SPI_TxHalfCpltCallback and HAL_SPI_TxCpltCallback.

But how can I stop the SPI transmission at the right time? I see no possibility to for example stop after the next complete buffer transfer. When I issue HAL_DMA_Abort and HAL_SPI_Abort in HAL_SPI_TxCpltCallback, the transmission will of course still go on for a couple of bytes.

I am using a STM32H743 with CubeMX Firmware Package 1.5.0

Does anyone here have an idea how to do this?


There's probably no easy way to accomplish this.

You might stop the transfer in the last Half-complete DMA interrupt, (or, if the maximum interrupt latency requires it, maybe even earlier at the previous Complete DMA interrupt), after DMA stops, read out NDTR, and transfer the outstanding data using non-circular DMA transfer.


Associate II

Too late for you, but I hope to help folks who want to stop SPI Circular precisely. There's no clean way with ST HAL library. You have to do some hacky things. It maybe a good idea not to use the ST SPI code, and just roll your own. Here are the broad strokes:

- Use TXRX mode. Don't use RX only mode, because you can't control reliably when to stop the clock.

- Set DMA in circular mode for both TX and RX.

- Set TSIZE non-zero.

- Set TSER to non-zero to reload the TX.

- Keep setting TSER at the right time to keep the transfer going. Towards the end, you can do some math and set TSER to zero. The transfer will stop after the current TX iteration. If your math is right, the transfer will stop where you like.

TSER and the initial TSIZE don't need to relate to the RX buffer size. They can be any thing. That way, you can control how the transfer ends flexibly.