Skip to main content
Visitor II
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?

    This topic has been closed for replies.
    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

    WCareyAuthorAnswer
    Visitor II
    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);
    }

     

    Graduate 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.