cancel
Showing results for 
Search instead for 
Did you mean: 

SPI DMA transmit complete interrupt to early

Nickelgrass
Senior II

Hello,

I have an STM32G441 and using DMA to transmit some SPI data. All works so far. The problem is the chipselect. I am using the software chipselect. So before I start the DMA I pull CS low. Then when the DMA complete interrupt fires I pull it high again. The problem is, it cuts off about 3 or 4 bytes. This is obvious because the DMA is done while there is still SPI data in the buffer. 

What is the go-to solution for this? How can I reliably get an interrupt when the DMA is done and the SPI is done transmitting all data? At the moment I simply start a timer when the DMA is done that triggers a second interrupt after a certain time that I measure with a logic analyzer. Seems a bit makeshift and has to be adjusted each time the baudrate is changed. I also noticed that all the SPI interrupts fire premature. So is it the only solution to waste a timer on the SPI?

2 REPLIES 2
TDK
Super User

You could use the HAL library which handles this correctly. Set CS high in the transmit complete callback.

If you want to do it yourself, you will need to poll the BSY flag to determine when the transfer is complete. The reference manual discusses this in some detail.

TDK_0-1770227148567.png

It's not an elegant or efficient solution, but that is what is available on this chip. Later families have better handling of the CS line and better ways to do this without polling.

If you feel a post has answered your question, please click "Accept as Solution".

Assume that the DMA complete interrupt happens when the DMA is complete. The SPI device transmit register got loaded and is in the process of shifting out the data, but the DMA is done, and DMA likely deposited a 32-bit pile of data, say, 3 or 4 bytes. DMA done, SPI busy.

You'll have to query the SPI device to determine when it is finished shifting out/in the data.