According to documentation, many of STM32's supports DMA in Double-Buffer (or also known as Multi-Buffer) mode. In HAL, there are two functions for this feature: HAL_DMAEx_MultiBufferStart
and HAL_DMAEx_MultiBufferStart_IT
in stm32xxxx_hal_adc_ex
file. But in any SDK (H7, F7, F4 etc.), there are not single example of usage of those two functions. How to get this double-buffering DMA working together with ADC?
STM32 ADC DMA Double/Multi Buffer example
7.2k views Asked by GAMELASTER At
3
There are 3 answers
0
On
I`ve configure DMA in Double buffer mode for I2S interface. My sequence looks like this:
/*Starting with DMA in single buffer mode*/
HAL_I2S_Transmit_DMA(&hi2s3, Addr, Size);
/* Pause current DMA by disconnecting it from periphery (in my case - i2s interface) */
HAL_I2S_DMAPause(&hi2s3);
/* Mask all DMA interrupt, deal with internal state machine of dma handle */
HAL_DMA_Abort(hi2s3.hdmatx);
/* Set callback for XferCplt/XferHalfCplt interrupt for second buffer (I just set it to the same, that I`ve already have for first buffer) */
hi2s3.hdmatx->XferM1CpltCallback = hi2s3.hdmatx->XferCpltCallback;
hi2s3.hdmatx->XferM1HalfCpltCallback = hi2s3.hdmatx->XferHalfCpltCallback;
/*Configure DMA in Double Buffer mode*/
HAL_DMAEx_MultiBufferStart_IT(hi2s3.hdmatx,
(uint32_t)Addr,
(uint32_t)&hi2s3.Instance->DR,
(uint32_t)(Addr + (Size >> 1)),
Size >> 1);
/*Connect periphery to newly configured DMA in double buffer mode*/
HAL_I2S_DMAResume(&hi2s3);
Hope this will help.
I never used the functions you mentioned for double buffer technique. I simply create a buffer, which has double the size of a "normal" buffer and use the DMA Callback functions HAL_ADC_ConvCpltCallback and HAL_ADC_ConvHalfCpltCallback for the decision which half of the buffer needs to be processed.
On an "HAL_ADC_ConvCpltCallback" Interrupt the upper half of the Double Buffer is processed while the ADC is writing its data in the lower half and vice versa ...
So: if I want e.g. to process my data in blocks of 100 samples, I create a buffer with 200 samples
and start the ADC with
For processing the data in the lower half the start pointer is
for the upper half the start pointer is
and the count of data, that need to be processed is of course "ADC_DMABufferSize" ...