Electronic – STM32 SPI w/ DMA “BUSY” flag set

dmastm32

My software appears to be working as expected, but the BSY flag is not clearing in the SPI register.

Background:

I am trying to get SPI working with DMA on the STM32. After figuring out that the DMA is picky about which channel you use for which peripheral, I got things working as expected. I read somewhere that it's important to ensure the SPI BuSY flag is cleared before starting another transfer. I am examining the registers using the ST/LINK v2 and for whatever reason, the SPI BSY flag is remaining set and if I have an IF statement in my code to confirm that it's cleared before continuing, the code hangs. I'm aware of the "Heisenbug" of observing the SPI_SR/DR registers with a debugger.

At first I tried using full duplex with SPI and the two DMA channels with the pins connected together and a TX and RX array. After the transfer, the RX array is a perfect copy of the TX array. Thinking that the issue may have been an expected clock-edge missing, I disconnected the two pins and set the SPI to TX only and commented out all of the RX DMA and SPI code. The issue persists.

Two things to note are that the BUSY flag is often the only thing set in the SR register. However, if I disabled the check for the BUSY flag and start the DMA transfer again, upon subsequent calls to the interrupt service routine, the RXNE and TXE buffers seem to arbitrarily change between 1 and 0, with the expected state of them both being empty being more common and the SPI_DR seems to sometimes get an arbitrary value. I don't see the overrun flag set.

Why doesn't the BUSY flag get cleared?

Best Answer

What exactly is throttling the SPI transfers? If you're using DMA directly (rather than triggered by a timer or something else), then as soon as the SPI is free, the DMA peripheral would start another transfer. As a result, being busy all the time would be expected.

According to the manual for the STM32F1xx series, section 25.3.7 (other series should have similar behavior):

When communication is not continuous, the BSY flag is low between each communication.

When communication is continuous:

● in master mode, the BSY flag is kept high during all the transfers