Showing results for 
Search instead for 
Did you mean: 

Occasional missing TxRxCpltCallback callback on SPI DMA transfer on the ARM-M4 of an STM32MP1

Associate II

We are experiencing an issue where, in approximately 1 in 1000 cases, we don't get a TxRxCpltCallback callback after starting a SPI DMA transfer from an ISR on the ARM-M4 (coprocessor). The transfer appears to have taken place as all the bytes are received in the Rx data buffer, and scope traces show the SPI transaction occurred successfully. However afterwards, whilst `hspi->hdmatx->State` is the expected `HAL_DMA_STATE_READY`, `hspi->hdmarx->State` is still `HAL_DMA_STATE_BUSY`.

To be clear, the vast majority of the time, it is working as expected, but it appears to be some kind of race condition where occasionally, the completion interrupt doesn't occur.

The use case is for reading a set of samples (18 bytes) from a multichannel ADC. An interrupt "data ready" is given, and we are using the `HAL_SPI_TransmitReceive_DMA()` function inside this minimal ISR. I've done quite a bit of profiling for this case, so I am confident we exit the ISR well before the SPI transaction has been completed. The system is lightly loaded, we are running this in an isolated test case, and I don't see any delayed interrupt handling. All observed SPI transactions are occurring promptly, in time with the interrupt.

Using the register polling `HAL_SPI_TransmitReceive()` API works without error (with us manually calling the callback afterwards), but unsurprisingly means we stay the ISR much longer and obviously not desirable.

Both Rx and Tx channels are on the same DMA. Advice on the web suggested making sure the Rx DMA has priority. This didn't resolve the issue. Nor did raising the interrupt priority for the Rx DMA stream interrupt. The "data ready" interrupt used to start the DMA has the lowest priority (my understanding is that it can be preempted) to make sure DMA interrupts aren't blocked.

Any advice? The sampling rate, whilst not particularly high (4kHz), is fast enough that I don't want the ISR to signal a task to perform the DMA and incur a context switch penalty.

Is there any reason it isn't safe to use the SPI DMA HAL functions inside an ISR? 

Any suggestions on interrupt priorities?

Thanks. JamesCC