cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 - DMA Double Buffering Callbacks Configuration

aangeletos9
Associate
Posted on October 24, 2016 at 17:44

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

#double-buffer #dma #stm32f4

2 REPLIES 2
slimen
Senior
Posted on October 27, 2016 at 17:55

Hello, 

For more details about 

configuration the DMA controller for double buffer, I recommend you to r

eview the 

http://www.st.com/content/ccc/resource/technical/document/reference_manual/3d/6d/5a/66/b4/99/40/d4/DM00031020.pdf/files/DM00031020.pdf/jcr:content/translations/en.DM00031020.pdf

, in DMA controller (DMA) section: 10.3.9 Double buffer mode) 

Regards

Garnett.Robert
Senior III

Hi

With many of the peripherals the HAL drivers are a pain. They simply don't have the flexibility to use the features of the periperals that are available. Double buffering is one of these. It would be quite simple to add parameters to the HAL_ADC_Start_DMA to include both double buffer addresses, and a flag indicating whether to use DB or not. If the DB flag is set to DB off the second address is not used.

Another example of HAL not being up to the job is with the USART set to Modbus timeout mode. To get this to work you have to set the registers yourself after figuring out what to do from the reference manual.

Another aspect that is poor is the setting of interrupts. HAL always sets the Half Transfer interrupt for DMA to enable so that you generate an unnecessary interrupt if you don't want to do anything at half transfer. I always end up having to comment out the setting of the HT interrupt.

Cube MX and the HAL drivers are good tools, but the HAL drivers have a lot of limitations that too often result in the developer having to bit bang registers to get things to work.