cancel
Showing results for 
Search instead for 
Did you mean: 

How to flush Tx/Rx FIFOs in SPI DMA

WCarey
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions
WCarey
Associate III

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);
}

 

View solution in original post

3 REPLIES 3
Imen.D
ST Employee

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

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
WCarey
Associate III

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);
}

 

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.