AnsweredAssumed Answered

ADC and DMA double buffer

Question asked by sledz.artuom on Apr 24, 2013
Latest reply on Apr 25, 2013 by sledz.artuom
Hi, all.
I working at ADC sampler implementation. ADC sampler has a next flow:
       
  1. Timer 1 generate sample rate at 200kHz.
  2.    
  3. At every Timer 1 CC2 interrupt ADC1,ADC2,ADC3 take a sample.
  4.    
  5. DMA is used to transfer sampled data to RAM.
  6.    
  7. Every 50 usec sampled frame of 3 channels should be processed.
When I use DMA at normal mode, then sampled frame is OK.
But when I enable circular DMA mode i get garbage.
Although when I enable DMA double feature I receive the same garbage.
The final target is to use double buffer, so when one will be at sampling stage and the second one at processing stage.

Is anyone faced this problem?

Initiation code:
/* Enable DMA for ADC transfer */
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  
 /* Enable ADC1,ADC2 for capacitor sensing */
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 | RCC_APB2Periph_ADC3, ENABLE);
 
 /* Select DMA Channel 0 for ADC transfer  */
 DMA_InitStructure.DMA_Channel            = DMA_Channel_0;
 DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t)AdcParams.AdcBuf1;
 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC->CDR;
 DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory;
 DMA_InitStructure.DMA_BufferSize         = ADC_SAMLPER_BUFFER_SIZE;
 DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
 DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
 DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
 DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;
 DMA_InitStructure.DMA_Priority           = DMA_Priority_High;
 DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;        
 DMA_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_Full;
 DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;
 DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;
 
 DMA_Init(DMA2_Stream0, &DMA_InitStructure);
 
 /* DMA2_Stream0 enable */
 DMA_Cmd(DMA2_Stream0, DISABLE);
  
 /* Configure double DMA mode.
    - Assign second ADC buffer.
    - Set Memory 0 as current memory address
    - This function can be called only when the DMA Stream is disabled.
 */
 DMA_DoubleBufferModeConfig(DMA2_Stream0,(uint32_t)AdcParams.AdcBuf2,DMA_Memory_0);
  
 /* Enable DMA double mode. This function can be called only when the DMA Stream is disabled.*/
 DMA_DoubleBufferModeCmd(DMA2_Stream0, ENABLE);
  
 /* DMA2_Stream0 enable */
 DMA_Cmd(DMA2_Stream0, ENABLE);
  
 /* ADC Common Init */
 ADC_CommonInitStructure.ADC_Mode             = ADC_TripleMode_RegSimult;
 ADC_CommonInitStructure.ADC_Prescaler        = ADC_Prescaler_Div2;
 ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_1;
 ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_12Cycles;
 ADC_CommonInit(&ADC_CommonInitStructure);
  
 /* ADC1 Configuration */
 ADC_InitStructure.ADC_Resolution           = ADC_Resolution_12b;
 ADC_InitStructure.ADC_ScanConvMode         = DISABLE;//;
 ADC_InitStructure.ADC_ContinuousConvMode   = DISABLE;
 ADC_InitStructure.ADC_ExternalTrigConv     = ADC_ExternalTrigConv_T1_CC2;
 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_RisingFalling;
 ADC_InitStructure.ADC_DataAlign            = ADC_DataAlign_Right;
 ADC_InitStructure.ADC_NbrOfConversion      = 1;
  
 ADC_Init(ADC1, &ADC_InitStructure);
 
 /* ADC1 regular channels 10-11 configuration */
 ADC_RegularChannelConfig(ADC1,  ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
 
 /* Enable ADC1 DMA */
 ADC_DMACmd(ADC1, ENABLE);
  
 /* ADC2 Configuration */
 ADC_InitStructure.ADC_NbrOfConversion      = 1; /* Set ADC to single conversion */
 ADC_InitStructure.ADC_ExternalTrigConv     = ADC_ExternalTrigConv_T1_CC1;
 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
 ADC_Init(ADC2, &ADC_InitStructure);
 
 /* ADC2 regular channels 0 configuration */
 ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);
  
 ADC_Init(ADC3, &ADC_InitStructure);
 ADC_RegularChannelConfig(ADC3, ADC_Channel_2, 1, ADC_SampleTime_3Cycles);
               
 /* Enable ADC1,ADC2,ADC3 */
 ADC_Cmd(ADC1, ENABLE);
 ADC_Cmd(ADC2, ENABLE);
 ADC_Cmd(ADC3, ENABLE);

Outcomes