cancel
Showing results for 
Search instead for 
Did you mean: 

How to do ADC -> DMA in double buffer mode configuration

elso
Associate III

Hi All,

I am trying to implement a code on STM32H723 Nucleo-144 where the ADC uses DMA configured in double buffer mode. I cant find any examples on how to do it. I have tried to analyze the ADC to DMA in circular mode code, but I struggle to convert it to double buffer mode. The option to use DMA in double buffer mode doesnt exist in the .ioc file as of my knowledge. Anyone who knows how to do it?

 

I am not an expert on this, so please be patient with me 🙂

Best regards! 

1 ACCEPTED SOLUTION

Accepted Solutions

Certainly, copy data should be faster than ADC 5 MHz conversion clock, can say for sure.

View solution in original post

9 REPLIES 9
MasterT
Senior III

Seems it's not written yet, don't see in HAL driver package.

Last time I created double buffer dma-spi function for H743 just to have 32k, other-ways  using Half Complete and Transfer Complete you can get only 16k samples.  There is no more any advantage except overcome dma 16-bits counter limits, so it doesn't worse a trouble. If memory size allows, easy way to have double buffer in software, using common HT & TC interrupts to accumulate a big buffer >32k  of samples by small chunks.

For educational purposes look into HAL, there is:

HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength);

The reason I need it is due to the 16-bits counter limit 🙂

I want it to work as a ping-pong buffer for MDMA. Tried doing a SW trigger of the DMA Ping pong buffer, but was too slow.

What do you mean "too slow" - having adc running at 5 Msps, 16k accumulated in 3.28 milliseconds - eternity in uCPU word.

The case is that I want to sample with 5 Msps and 8 bit resolution. When a trigger is called, I need 40 ms of data = 200 000 B, and store it on a SD card. The trigger should stop all ADC and DMA actions.

Before the trigger is called I will need to continuously store the last 40 ms of data. The DMA is limited to 64kB due to the counter. So I need to copy the data in the DMA buffers to a bigger buffer without loosing any data. I tried to copy data in SW by reacting to the SW interrupt of the DMA. But the new interrupt came before all data was copied, eg. data lost. Maybe I have performed this the wrong way?

Certainly, copy data should be faster than ADC 5 MHz conversion clock, can say for sure.

It worked! It was alot faster! Had to just figure out why my interrupts acted strange, and the software version got fast enough.

elso_0-1702498039920.png

Blue is Time to copy.

Orange toggles between half full and full interrupts.

Piranha
Chief II

Guys, check your math... 2^16 is 64k, not 32k.

In double-buffer mode the address of the inactive buffer can be modified on-the-fly. That way you can swap (rotate) any number of 64k sample sized blocks and don't need any copying at all.

Good catch, the problem only I needed  65536 samples exact for FFT,  and it's not working. So instead of 65k - 1, I downgraded array to 32768 sharp, to keep my perfectionism happy.

 Anyway, OP wants 200k, so software "multibuffer" is only option left.

 Strange things to keep 16-bits register since F1, when new uCPU's have a lot of memory and 32-bits dma CNTR is necessary

Not only the DMA counters should be 32-bit, but also all timers and GPIO ports should have been 32-bit since the beginning. And a normal interrupts for all pins in every port, not the current limited selection of pins through the EXTI.