cancel
Showing results for 
Search instead for 
Did you mean: 

ADC and DMA, again

dusan2
Associate III
Posted on April 18, 2013 at 12:55

The original post was too long to process during our migration. Please click on the attachment to read the original post.
8 REPLIES 8
Posted on April 18, 2013 at 16:39

I can't afford to expend much time on your project, I would suggest you simplify your DMA strategy so the buffer has two halves (ping/pong), and examine the content of the prior fill space under the HT/TC interrupts for the DMA.

TIM_TimeBaseInitStructure.TIM_Period = 840 - 1;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dusan2
Associate III
Posted on April 18, 2013 at 16:57

Unfortunatelly, the FIR filtering requires the existance of prior and ''future'' samples, and this implies the strategy with a circular buffer divided in quarters.

Regardless of the overall strategy, I am having difficulties already with running the dual & simultaneous mode ADCs and using the DMA to move results to a circular buffer. Filling the buffer once works fine (non-circular mode), but enabling the circular mode makes a mess.

I have checked the example source code in ''STM32F4xx_StdPeriph_Examples/ADC/ADC_DualModeRegulSimu/main.c'', but can not find any significant differences. The only thing I see is that the example code uses two consecutive conversions for each ADC, and mine uses only one conversion per ADC. Also, the buffer size in the example is only enough to accomodate four samples, while I use a longer buffer to accomodate 256 samples per quarter of the circular buffer.

Do you have any suggestions?

Thanks!

frankmeyer9
Associate II
Posted on April 18, 2013 at 17:29

Another idea.

Why not using two channels of one ADC, and sort them out after the DMA TC interrupt ? For DMA, a ping-pong like double buffering would be appropriate in this setup.

dusan2
Associate III
Posted on April 19, 2013 at 08:23

I need to sample two signals simultaneously, alternative sampling is not an option. Two ADCs must be used, both running in continuous mode (without external triggering at their optimum speed). But this is not the problem.

I can make DMA to save samples from both ADCs (ADC_CDR) into a buffer (1024 consecutive words) once. However, I can not make the DMA to save samples continuously into a circular buffer of this length. When I use the command

''

ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

''

the content of the buffer gets garbled as if consecutive samples are not stored into consecutive locations! ADC's are running and the pointer to the circular buffer gets incremented (''

DMA_GetCurrDataCounter(DMA2_Stream0);

''). Only the samples in the buffer are garbled.

What am I doing wrong?

dusan2
Associate III
Posted on April 23, 2013 at 14:11

Hi, Clive1!

I have found the reason for the garbled samples!

I have overlooked one basic thing: when breaking the execution of the program from within the IAR one does not also stop the DMA! It seems that the IAR then reads the content of the circular buffer while the DMA is still working, and this causes the mess. When the DMA is properly stopped either by the software of the STM32F407 or by clearing the enable bit for DMA from within the IAR debugger, the IAR debugger reads out the expected (correct) content of the circular buffer.

This might be a reminder to others as well: be careful to thoroughly stop the DMA before you rely on the results reported by a debugger.

I have another question, if you have time.

Is it possible to use the DMA request from ADC twice? The DMA controller offers Stream 0 and Stream 4 for ADC1, and Stream 2 and Stream 3 for ADC2. I would like to use one of them to transfer samples from ADC into the circular buffer, and another to transfer samples from the circular buffer to DAC.

Thanks for your time, and regards

Posted on April 23, 2013 at 15:56

It's complicated by the fact that DAC1/2 are on the APB1, and the ADC1/2 on the APB2

I would imagine you could bond ADC1 to DMA2 Stream 0 Channel 0, and then use DMA2 Stream 4 Channel 0 to trigger a transfer related to ADC1 request, but to a different destination. This might require a mem-to-mem transfer due to the different bus connections. You'd need to experiment.

The alternative would be to pace with a TIM based trigger which had commonality between the ADC,DAC,DMA. Even with multiple timers, they are synchronous with each other, though you might have to adjust the phase.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dusan2
Associate III
Posted on April 24, 2013 at 12:16

Thanks for the suggestion, will experiment and report back.

I will use DMA2 Stream 0 Channel 0 to transfer samples from both ADCs into a circular buffer in memory, and DMA2 Stream 4 Channel 0 to transfer samples from another circular buffer to both DACs. At present, I see no reason for this not to work. However, up till now I have not been successful in transferring anything to DAC on ADC DMA request. All I got was a flag saying ''bus error''. I had no problems using Timer 2 to initiate the DMA transfer to DACs though.

As I said I will experiment some more...

Posted on April 24, 2013 at 21:53

I could see extending this code [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/stm32f207%20ADC%2bTIMER%2bDMA%20%20Poor%20Peripheral%20Library%20Examples&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx&currentviews=14]Here

Instead of IQ, figure Left and Right audio channels, paced via TIM2 TRGO

To use DAC_Trigger_T2_TRGO to pace the DMA out the DACs via DAC_DHR12RD (Dual Right Aligned) or whatever is appropriate.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..