Skip to main content
Associate III
April 24, 2024
Solved

How to flush Tx/Rx FIFOs in SPI DMA

  • April 24, 2024
  • 2 replies
  • 1884 views

What is the procedure to flush Tx and Rx FIFOs when using SPI DMA in STM32H563ZI?

Best answer by WCarey

My master uses the SS pin (active low) to start and stop the SPI transfers. So, I configure the SS pin as a rising edge interrupt  GPIO on the slave and if there's any data left on TX/Rx DMA channels, I abort the SPI.

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{

if (GPIO_Pin == GPIO_PIN_15)
{
if (READ_BIT(hDMASPIRx.Instance->CBR1, DMA_CBR1_BNDT) > 0 ||
READ_BIT(hDMASPITx.Instance->CBR1, DMA_CBR1_BNDT) > 0)
{
HAL_SPI_Abort(&hSPI);
}

 

2 replies

Technical Moderator
April 24, 2024

Hello @WCarey ,

Both RxFIFO and TxFIFO content is kept flushed and cannot be accessed when SPI is disabled (SPE = 0).

You can refer to the "38.4.13 Disabling the SPI " in the STM32H5 Reference Manual RM0492:

"When SPI is disabled, RxFIFO is flushed. To prevent losing unread data, the user must ensure that RxFIFO is empty when disabling the SPI, by reading all remaining data (as indicated by the RXP, RXWNE and RXPLVL fields in the SPI_SR register)." 

This post may help you on SPI RxFIFO and TxFIFO Flush.

In HAL library, there is a function "HAL_SPIEx_FlushRxFIFO" to Flush the RX fifo.

stm32h5xx_hal_driver/Src/stm32h5xx_hal_spi_ex.c at afcafe6d4f21a18d898400705addd9c94fba8660 · STMicroelectronics/stm32h5xx_hal_driver · GitHub

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
WCareyAuthorBest answer
Associate III
April 30, 2024

My master uses the SS pin (active low) to start and stop the SPI transfers. So, I configure the SS pin as a rising edge interrupt  GPIO on the slave and if there's any data left on TX/Rx DMA channels, I abort the SPI.

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{

if (GPIO_Pin == GPIO_PIN_15)
{
if (READ_BIT(hDMASPIRx.Instance->CBR1, DMA_CBR1_BNDT) > 0 ||
READ_BIT(hDMASPITx.Instance->CBR1, DMA_CBR1_BNDT) > 0)
{
HAL_SPI_Abort(&hSPI);
}

 

David Littell
Senior II
April 30, 2024

So now you've succeeded in creating a race between the SS rising edge interrupt and the normal completion of the SPI DMA.  Are you trying to compensate for not having a proper protocol over SPI that allows the DMA to be configured for the correct number of transfers?  If so, good luck.