2025-08-14 9:23 PM - last edited on 2025-08-15 6:18 AM by Amel NASRI
Having faced the same problem, ended up in this thread. This is the same for HAL_SPI_Receive_DMA() as well, because it internally calls the transmitReceive function. So, it made me enable tx dma interrupt as well rx. Why on earth I have to enable tx dma when I just need rx dma? It does not even call the tx complete callback.
My workaround was to:
1-make tx dma interrupt priority higher than rx dma interrupt.
2-poll for tx dma complete in rx interrupt routine before proceeding to next transaction.
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
handleXferCplt(hspi);
}
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
handleXferCplt(hspi);
}
bool handleXferCplt(SPI_HandleTypeDef *hspi)
{
// stm hal forces to use both tx and rx dma becasue it calls tranmitReceive() internally for receive.
// however, dma tx transfer complete interrupt comes after rx complete. So, tx dma busy flag is still set and queued
// sessions cannot proceed. so wait for it to finish. this implies that tx dma priority must be higer than rx dma
// priority.
if (HAL_DMA_PollForTransfer(hspi->hdmatx, HAL_DMA_FULL_TRANSFER, 1) != HAL_OK)
{
HAL_DMA_Abort(hspi->hdmatx); // Abort the DMA transfer
}
...
Edit: moved from the old thread HAL_SPI_TransmitReceive_DMA() transmit interrupt always triggered after receive interrupt. This gives more chance for review and answering.
2025-08-15 6:57 AM
Hello @HSagh.1
Could you please precise which MCU product you are working on