cancel
Showing results for 
Search instead for 
Did you mean: 

How to restart DMA in the fastest way?

kolcantas
Associate II
Posted on June 18, 2014 at 08:49

Dear Community!

I'm using DMA to transfer the ADC1 results (100 consecutive data) to some incremented memory address. DMA is in Normal mode (not circular), it is transfering 100 data, repeatedly over time. After the first transfer I found out if I fully reinitialize the DMA, the next transfers are also working. The problem is that it takes ''a lot of time'', which is too much in my application. Instead of fully reinitializing the DMA I tried to clear Transfer Complete flag and reload NDTR register, but no luck so far. At this moment this part of code looks something like this:

DMA_Cmd(DMA2_Stream0, DISABLE);

// Wait until DMA is disabled
while( DMA_GetCmdStatus(DMA2_Stream0) );

DMA2_Stream0 -> NDTR = DATA_BUFFER_SIZE;
DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0);

DMA_Cmd(DMA2_Stream0, ENABLE);

What is the fastest way to reinitialize DMA? What variables/flags have to be set/cleared exactly? #adc #dma
3 REPLIES 3
kolcantas
Associate II
Posted on August 05, 2014 at 13:25

It seems I found the solution: first you have to disable the ADC before reconfiguring the DMA.

Now the code is the following (not yet optimized, but working):

ADC_Cmd(ADC1, DISABLE);
DMA_Cmd(DMA2_Stream0, DISABLE);
// Wait until DMA is disabled
while( DMA_GetCmdStatus(DMA2_Stream0) );
// Clear flag(s) - if any interrupt is enabled, clear the IT flags as well!
DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0);
DMA_Cmd(DMA2_Stream0, ENABLE);
ADC_Cmd(ADC1, ENABLE);

Posted on August 06, 2014 at 10:53

And why exactly you don't use the circular mode of DMA?

JW
kolcantas
Associate II
Posted on August 06, 2014 at 13:09

In my application I'm measuring an analog signal continuously - ADC is continuously triggered by a Timer -, but I only need some consecutive data at a given time; at this time I restart the DMA in normal mode and so only the data I need are stored by the DMA.

Other option would be to use DMA in circular mode - as you mentioned -, but in this case I had to disable the ADC when I don't need the data. The first solution seems for me simpler, and as far as I remember the datasheet mentions that to disable the ADC, the user has to disable FIRST the DMA.

Maybe using the ADC in non-continuous mode could be another solution. Is it any better solution to periodically restart the ADC than the DMA?