AnsweredAssumed Answered

STM32F407 - DMA Double Buffering Callbacks Configuration

Question asked by angeletos.alex on Oct 24, 2016
Latest reply on Oct 27, 2016 by ForumSTM32.ForumSTM3
Hello everyone,

I am working on a project with the STM32F407 and I do need to implement SPI communication with DMA support (for both Tx/Rx ) using circular mode and double buffering.

I am working with HAL and I had to port parts of code from the "std peripheral library" to make it work. However, while I was looking at the source of the library and I saw that the library was configuring only the Rx callbacks and there was the following comment:
"Set the SPI Tx DMA transfer complete callback as NULL because the communication closing is performed in DMA reception complete callback ".

/* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
    if(hspi->State == HAL_SPI_STATE_BUSY_RX)
    {
      /* Set the SPI Rx DMA Half transfer complete callback */
      hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;</code></span></div>
 
      hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;</code></span></div>
    }
    else
    {
      /* Set the SPI Tx/Rx DMA Half transfer complete callback */
      hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;</code></span></div>
 
      hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;   //Xfer complete callback for memory0</code></span></div>
      hspi->hdmarx->XferM1CpltCallback = SPI_DMATransmitReceiveCplt; //Xfer complete callback for memory1</code></span></div>
    }
 
    /* Set the DMA error callback */
    hspi->hdmarx->XferErrorCallback = SPI_DMAError;</code></span></div>
 
    /* Enable the Rx DMA Stream */
    HAL_DMAEx_MultiBufferStart_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, (uint32_t)pRxData1, hspi->RxXferCount);</code></span></div>
 
    /* Enable Rx DMA Request */
    hspi->Instance->CR2 |= SPI_CR2_RXDMAEN;
 
    /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
    is performed in DMA reception complete callback  */
    hspi->hdmatx->XferCpltCallback = NULL;</code></span></div>
 
    if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
    {
      /* Set the DMA error callback */
      hspi->hdmatx->XferErrorCallback = SPI_DMAError;</code></span></div>
    }
    else
    {
      hspi->hdmatx->XferErrorCallback = NULL;</code></span></div>
    }

Doing so, the Rx part of the SPI works fine but when trying to send stuff from the MCU the tx complete callback never fires and no data are shown on the bus.
If I enable the Tx callbacks then communication works.

The question is: What is the right process to configure the DMA controller for double buffer?

Thanks in advance,

Alex

Outcomes