2013-10-22 09:49 AM
Hello,
is it possible to configure a DMA job to toggle an GPIO when the ADC conversion finishes? I'am usingTimer8 to Trigger ADC1 conversion andDMA2 Stream0Channel0 to copy the conversion result (DR-Register) to internal RAM. Now, for testing purpose only, i want to toggle Pin C5 at the end of the ADC conversion using this DMA config:st_DMA_ADCtoRAM.DMA_PeripheralBaseAddr = (uint32_t)GPIOC_BASE + 0x18;
// 0x18 = BSRR-Register Offset
st_DMA_ADCtoRAM.DMA_Memory0BaseAddr = (uint32_t)au32_TestOut;
st_DMA_ADCtoRAM.DMA_DIR = DMA_DIR_MemoryToPeripheral;
st_DMA_ADCtoRAM.DMA_BufferSize = 2;
with:
#define TESTHIGH (1<< 5 )
#define TESTLOW (1<<(5+16))
au32_TestOut[0] = TESTHIGH;
au32_TestOut[1] = TESTLOW;
but this doesn't work.DMA2 Stream4Channel0 deosn't work either:
DMA_Cmd(DMA2_Stream4, DISABLE);
DMA_DeInit(DMA2_Stream4);
st_TESTtoGPIO_Config.DMA_Channel = DMA_Channel_0;
st_TESTtoGPIO_Config.DMA_PeripheralBaseAddr = (uint32_t)GPIOC_BASE + 0x18;
// 0x18 = BSRR-Register Offset
st_TESTtoGPIO_Config.DMA_Memory0BaseAddr = (uint32_t)au32_TestOut;
st_TESTtoGPIO_Config.DMA_DIR = DMA_DIR_MemoryToPeripheral;
st_TESTtoGPIO_Config.DMA_BufferSize = 2;
st_TESTtoGPIO_Config.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
st_TESTtoGPIO_Config.DMA_MemoryInc = DMA_MemoryInc_Enable;
st_TESTtoGPIO_Config.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
st_TESTtoGPIO_Config.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
st_TESTtoGPIO_Config.DMA_Mode = DMA_Mode_Circular;
st_TESTtoGPIO_Config.DMA_Priority = DMA_Priority_Low;
st_TESTtoGPIO_Config.DMA_FIFOMode = DMA_FIFOMode_Disable;
st_TESTtoGPIO_Config.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
st_TESTtoGPIO_Config.DMA_MemoryBurst = DMA_MemoryBurst_Single;
st_TESTtoGPIO_Config.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream4, &st_TESTtoGPIO_Config);
DMA_Cmd(DMA2_Stream4, ENABLE);
2013-10-22 11:13 AM
If it's triggering off TIM8, couldn't you just use another channel with a slightly retarded phase wrt to the ADC start?
2013-10-24 11:31 PM
I could do that, but then i need an equation to calculate conversion time and need to setup up antoher TIM and DMA. Despite that I would like to know why the easy way isn't working.
2013-10-25 02:58 AM
Sounds more convoluted than easy. It wouldn't require another TIM+DMA, merely a second channel on the same TIM8 that's triggering the conversion. The phase relationship between the start pulse and the end-of-conversion is fixed (sample + conversion) and documented, the timer can also toggle a pin.
So is the DMA unit indicating some fault condition? There is a lot of code missing, precluding a quick dynamic analysis.2013-10-28 01:18 PM
Here is the completeinitialization:
int
i;
for
(i=0; i<133; i++)
{
au16_ADCresult_Buffer[0][i] = 0x0000;
}
for
(i=0; i<133; i++)
{
au16_ADCresult_Buffer[1][i] = 0x0000;
}
au32_TestOut[0] = TESTHIGH;
au32_TestOut[1] = TESTLOW;
//###################################################
//# #
//# generate Clock and SI Signal #
//# #
//###################################################
// Target Clock = 1MHz --> Timer1 must be 2MHz --> 500ns
//GPIO config: CLK, SI, and Test pins
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
st_GpioArrayCtrl.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5;
st_GpioArrayCtrl.GPIO_Mode = GPIO_Mode_OUT;
st_GpioArrayCtrl.GPIO_OType = GPIO_OType_PP;
st_GpioArrayCtrl.GPIO_Speed = GPIO_Speed_100MHz;
st_GpioArrayCtrl.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &st_GpioArrayCtrl);
// Timer1 init
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
//Clock enable
st_Timer1Config.TIM_ClockDivision = TIM_CKD_DIV1;
//-> 168MHz
st_Timer1Config.TIM_Prescaler = 8u;
//-> 21MHz
st_Timer1Config.TIM_Period = 10u;
//-> 2,1MHz
st_Timer1Config.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &st_Timer1Config);
TIM_ARRPreloadConfig(TIM1, ENABLE);
//Timer1 as master trigger for other timers:
TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
//On compare match trigger slaves -> ever ~500ns
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
//Enable master functionality
//''Waveform''
au32_Signal[0] = CLKLOW | SILOW;
au32_Signal[1] = SIHIGH;
au32_Signal[2] = CLKHIGH;
au32_Signal[3] = SILOW;
au32_Signal[4] = CLKLOW;
for
(i=1; i<128; i++)
{
au32_Signal[3+(i*2)] = CLKHIGH;
au32_Signal[4+(i*2)] = CLKLOW;
}
au32_Signal[259] = CLKHIGH;
au32_Signal[260] = CLKLOW;
au32_Signal[261] = CLKHIGH;
// DMA init (DMA2, Channel6, Stream5)
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_Cmd(DMA2_Stream5, DISABLE);
DMA_DeInit(DMA2_Stream5);
st_DMAtoGPIO_Config.DMA_Channel = DMA_Channel_6;
st_DMAtoGPIO_Config.DMA_PeripheralBaseAddr = (uint32_t)GPIOC_BASE + 0x18;
// 0x18 = BSRR-Register Offset
st_DMAtoGPIO_Config.DMA_Memory0BaseAddr = (uint32_t)au32_Signal;
st_DMAtoGPIO_Config.DMA_DIR = DMA_DIR_MemoryToPeripheral;
st_DMAtoGPIO_Config.DMA_BufferSize = 262u;
st_DMAtoGPIO_Config.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
st_DMAtoGPIO_Config.DMA_MemoryInc = DMA_MemoryInc_Enable;
st_DMAtoGPIO_Config.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
// 32bit
st_DMAtoGPIO_Config.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
st_DMAtoGPIO_Config.DMA_Mode = DMA_Mode_Circular;
st_DMAtoGPIO_Config.DMA_Priority = DMA_Priority_VeryHigh;
st_DMAtoGPIO_Config.DMA_FIFOMode = DMA_FIFOMode_Disable;
st_DMAtoGPIO_Config.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
st_DMAtoGPIO_Config.DMA_MemoryBurst = DMA_MemoryBurst_Single;
st_DMAtoGPIO_Config.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream5, &st_DMAtoGPIO_Config);
TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);
//###################################################
//# #
//# Start ADC Sampling and DMA #
//# #
//###################################################
// ADC Frequency = 1MHz
// Timer8 init
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
//Clock enable
st_Timer8Config.TIM_ClockDivision = TIM_CKD_DIV1;
//Timer1 as master --> 500ns
st_Timer8Config.TIM_Prescaler = 0u;
//-> 500ns
st_Timer8Config.TIM_Period = 1u;
//-> 1us
st_Timer8Config.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM8, &st_Timer8Config);
TIM_ARRPreloadConfig(TIM8, ENABLE);
//Timer8 is slave of Timer1:
TIM_SelectInputTrigger(TIM8, TIM_TS_ITR0);
TIM_SelectSlaveMode(TIM8, TIM_SlaveMode_External1);
TIM_SelectOutputTrigger(TIM8, TIM_TRGOSource_Update);
//Trigger ADC conversion
//ADC1 init
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
//input pin = PC1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
st_GpioAdc.GPIO_Pin = GPIO_Pin_1;
st_GpioAdc.GPIO_Mode = GPIO_Mode_AN;
st_GpioAdc.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &st_GpioAdc);
st_AdcInit1.ADC_Mode = ADC_Mode_Independent;
st_AdcInit1.ADC_Prescaler = ADC_Prescaler_Div2;
st_AdcInit1.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
st_AdcInit1.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&st_AdcInit1);
st_AdcInit2.ADC_Resolution = ADC_Resolution_12b;
st_AdcInit2.ADC_ScanConvMode = DISABLE;
// 1 Channel
st_AdcInit2.ADC_ContinuousConvMode = DISABLE;
// Conversions triggered
st_AdcInit2.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
st_AdcInit2.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T8_TRGO;
//Timer 8 starts conversion
st_AdcInit2.ADC_DataAlign = ADC_DataAlign_Right;
st_AdcInit2.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &st_AdcInit2);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);
//DMA Init
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_Cmd(DMA2_Stream0, DISABLE);
DMA_DeInit(DMA2_Stream0);
DMA_DoubleBufferModeConfig(DMA2_Stream0, (uint32_t)au16_ADCresult_Buffer[1], DMA_Memory_0);
//Call before DMA_Init(...)!!!!
DMA_DoubleBufferModeCmd(DMA2_Stream0, ENABLE);
//Call before DMA_Init(...)!!!!
st_DMA_ADCtoRAM.DMA_Channel = DMA_Channel_0;
st_DMA_ADCtoRAM.DMA_PeripheralBaseAddr = (uint32_t)ADC1_BASE + 0x4C;
//0x4C = Dataregister Offset
st_DMA_ADCtoRAM.DMA_Memory0BaseAddr = (uint32_t)au16_ADCresult_Buffer[0];
st_DMA_ADCtoRAM.DMA_DIR = DMA_DIR_PeripheralToMemory;
st_DMA_ADCtoRAM.DMA_BufferSize = 131;
/*
st_DMA_ADCtoRAM.DMA_PeripheralBaseAddr = (uint32_t)GPIOC_BASE + 0x18; // 0x18 = BSRR-Register Offset
st_DMA_ADCtoRAM.DMA_Memory0BaseAddr = (uint32_t)au32_TestOut;
st_DMA_ADCtoRAM.DMA_DIR = DMA_DIR_MemoryToPeripheral;
st_DMA_ADCtoRAM.DMA_BufferSize = 2;
*/
st_DMA_ADCtoRAM.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
st_DMA_ADCtoRAM.DMA_MemoryInc = DMA_MemoryInc_Enable;
st_DMA_ADCtoRAM.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
st_DMA_ADCtoRAM.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
st_DMA_ADCtoRAM.DMA_Mode = DMA_Mode_Circular;
st_DMA_ADCtoRAM.DMA_Priority = DMA_Priority_Low;
st_DMA_ADCtoRAM.DMA_FIFOMode = DMA_FIFOMode_Disable;
st_DMA_ADCtoRAM.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
st_DMA_ADCtoRAM.DMA_MemoryBurst = DMA_MemoryBurst_Single;
st_DMA_ADCtoRAM.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &st_DMA_ADCtoRAM);
ADC_DMACmd(ADC1, ENABLE);
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
//###################################################
//# #
//# Cycle Finish Timer Interrupt #
//# #
//###################################################
// Timer5 init
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_Cmd(TIM2, DISABLE);
st_Timer2Config.TIM_ClockDivision = TIM_CKD_DIV1;
st_Timer2Config.TIM_Prescaler = 0;
st_Timer2Config.TIM_Period = 261u;
st_Timer2Config.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &st_Timer2Config);
TIM_ARRPreloadConfig(TIM2, ENABLE);
//Timer7 is slave of Timer1:
TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);
//Interrupt init
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
st_ISR_Config_for_Timer2.NVIC_IRQChannel = TIM2_IRQn;
st_ISR_Config_for_Timer2.NVIC_IRQChannelPreemptionPriority = 0;
st_ISR_Config_for_Timer2.NVIC_IRQChannelSubPriority = 0;
st_ISR_Config_for_Timer2.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&st_ISR_Config_for_Timer2);
//###################################################
//# #
//# Start #
//# #
//###################################################
DMA_Cmd(DMA2_Stream5, ENABLE);
// DMA: RAM->GPIO
DMA_Cmd(DMA2_Stream0, ENABLE);
//DMA: ADC->RAM
ADC_SoftwareStartConv(ADC1);
TIM_Cmd(TIM2, ENABLE);
//Cycle finish
TIM_Cmd(TIM8, ENABLE);
//ADC&DMA Trigger
TIM_Cmd(TIM1, ENABLE);
//Master-Timer Clk & SI
2013-10-28 02:32 PM
Is there an example of DMA reading injected channels?
My DMA stopped working while changing to TIM4 and dualalternate trigger mode.//###################################################
//# #
//# Start ADC Sampling and DMA #
//# #
//###################################################
// ADC Frequency = 1MHz
//Timer 4 init
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
//Clock enable
TIM_Cmd(TIM4, DISABLE);
st_Timer4Config.TIM_ClockDivision = TIM_CKD_DIV1;
st_Timer4Config.TIM_Prescaler = 0;
st_Timer4Config.TIM_Period = 2u;
st_Timer4Config.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &st_Timer4Config);
TIM_ARRPreloadConfig(TIM4, ENABLE);
//Timer4 is Slave of Timer1:
TIM_SelectInputTrigger(TIM4, TIM_TS_ITR0);
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1);
TIM_SelectOutputTrigger(TIM4, TIM_TRGOSource_Update);
//Trigger ADC Conversion
//ADC Pin GPIO
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
//input pin = PC1
st_GpioAdc.GPIO_Pin = GPIO_Pin_1;
st_GpioAdc.GPIO_Mode = GPIO_Mode_AN;
st_GpioAdc.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOC, &st_GpioAdc);
//ADC1&2 Common Init
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
st_AdcInitCommon.ADC_Mode = ADC_DualMode_AlterTrig;
st_AdcInitCommon.ADC_Prescaler = ADC_Prescaler_Div2;
st_AdcInitCommon.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
st_AdcInitCommon.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&st_AdcInitCommon);
//ADC1 init
st_Adc1Init.ADC_Resolution = ADC_Resolution_12b;
st_Adc1Init.ADC_ScanConvMode = DISABLE;
st_Adc1Init.ADC_ContinuousConvMode = DISABLE;
st_Adc1Init.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
st_Adc1Init.ADC_ExternalTrigConv = 0;
st_Adc1Init.ADC_DataAlign = ADC_DataAlign_Right;
st_Adc1Init.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &st_Adc1Init);
ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);
ADC_ExternalTrigInjectedConvEdgeConfig(ADC1, ADC_ExternalTrigInjecConvEdge_Rising);
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T4_TRGO);
//ADC2 Init
st_Adc2Init.ADC_Resolution = ADC_Resolution_12b;
st_Adc2Init.ADC_ScanConvMode = DISABLE;
st_Adc2Init.ADC_ContinuousConvMode = DISABLE;
st_Adc2Init.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
st_Adc2Init.ADC_ExternalTrigConv = 0;
st_Adc2Init.ADC_DataAlign = ADC_DataAlign_Right;
st_Adc2Init.ADC_NbrOfConversion = 1;
ADC_Init(ADC2, &st_Adc2Init);
ADC_InjectedChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);
ADC_ExternalTrigInjectedConvEdgeConfig(ADC2, ADC_ExternalTrigInjecConvEdge_Rising);
ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_T4_TRGO);
//DMA Init
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
DMA_Cmd(DMA2_Stream0, DISABLE);
DMA_DeInit(DMA2_Stream0);
DMA_DoubleBufferModeConfig(DMA2_Stream0, (uint32_t)&au16_ADCresult_Buffer[1][0], DMA_Memory_0);
//Call before DMA_Init(...)!!!!
DMA_DoubleBufferModeCmd(DMA2_Stream0, ENABLE);
//Call before DMA_Init(...)!!!!
st_DMA_ADCtoRAM.DMA_Channel = DMA_Channel_0;
st_DMA_ADCtoRAM.DMA_PeripheralBaseAddr = (uint32_t)ADC1_BASE + 0x3C;
//0x3C = Injected Channel 1 Offset
st_DMA_ADCtoRAM.DMA_Memory0BaseAddr = (uint32_t)&au16_ADCresult_Buffer[0][0];
st_DMA_ADCtoRAM.DMA_DIR = DMA_DIR_PeripheralToMemory;
st_DMA_ADCtoRAM.DMA_BufferSize = 61;
st_DMA_ADCtoRAM.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
st_DMA_ADCtoRAM.DMA_MemoryInc = DMA_MemoryInc_Enable;
st_DMA_ADCtoRAM.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
st_DMA_ADCtoRAM.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
st_DMA_ADCtoRAM.DMA_Mode = DMA_Mode_Circular;
st_DMA_ADCtoRAM.DMA_Priority = DMA_Priority_Low;
st_DMA_ADCtoRAM.DMA_FIFOMode = DMA_FIFOMode_Disable;
st_DMA_ADCtoRAM.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
st_DMA_ADCtoRAM.DMA_MemoryBurst = DMA_MemoryBurst_Single;
st_DMA_ADCtoRAM.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &st_DMA_ADCtoRAM);
//DMA2 Init
DMA_Cmd(DMA2_Stream2, DISABLE);
DMA_DeInit(DMA2_Stream2);
DMA_DoubleBufferModeConfig(DMA2_Stream2, (uint32_t)&au16_ADCresult_Buffer[1][64], DMA_Memory_0);
//Call before DMA_Init(...)!!!!
DMA_DoubleBufferModeCmd(DMA2_Stream2, ENABLE);
//Call before DMA_Init(...)!!!!
st_DMA_ADCtoRAM2.DMA_Channel = DMA_Channel_1;
st_DMA_ADCtoRAM2.DMA_PeripheralBaseAddr = (uint32_t)ADC2_BASE + 0x3C;
//0x3C = Injected Channel 1 Offset
st_DMA_ADCtoRAM2.DMA_Memory0BaseAddr = (uint32_t)&au16_ADCresult_Buffer[0][64];
st_DMA_ADCtoRAM2.DMA_DIR = DMA_DIR_PeripheralToMemory;
st_DMA_ADCtoRAM2.DMA_BufferSize = 61;
st_DMA_ADCtoRAM2.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
st_DMA_ADCtoRAM2.DMA_MemoryInc = DMA_MemoryInc_Enable;
st_DMA_ADCtoRAM2.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
st_DMA_ADCtoRAM2.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
st_DMA_ADCtoRAM2.DMA_Mode = DMA_Mode_Circular;
st_DMA_ADCtoRAM2.DMA_Priority = DMA_Priority_Low;
st_DMA_ADCtoRAM2.DMA_FIFOMode = DMA_FIFOMode_Disable;
st_DMA_ADCtoRAM2.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
st_DMA_ADCtoRAM2.DMA_MemoryBurst = DMA_MemoryBurst_Single;
st_DMA_ADCtoRAM2.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream2, &st_DMA_ADCtoRAM2);
ADC_DMACmd(ADC1, ENABLE);
ADC_DMACmd(ADC2, ENABLE);
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_Cmd(ADC2, ENABLE);