cancel
Showing results for 
Search instead for 
Did you mean: 

DMA2 (Can't Configure Seperate Streams for ADC1 and ADC2)

Puzamoya
Associate II
Posted on September 18, 2014 at 17:44

I have the STM32F407 Discovery board.

I am configuring two streams using DMA and ADC

The first stream uses Stream 0 channel 0 of the DMA 2 ie ADC1 which reads the value of ADC chanel 9 1N9 and gets sent to circular buffer and send as audio 8Khz.

The second stream uses Stream 2 channel 1 of DMA2 ie ADC2 which reads values of ADC channels 2N - 0,1,5,6,7,8 at 1Khz. using DR and Tim3 TRGOut as the trigger.

If I configure each stream independently it works (ie I have not configured the other).

If I configure both DMA2/Streams/ADCX. The first configured DMA2_streamX_Interupt handler does not fire.

7 REPLIES 7
Posted on September 18, 2014 at 18:02

Stream 2 channel 2 of DMA2 ie ADC2

No

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Puzamoya
Associate II
Posted on September 18, 2014 at 19:09

Sorry Clive I meant to write Channel 1 not channel 2

I'm definitly using Stream0Channel0 for ADC1 and Stream2Channel1for ADC2

I may have to post my code tomorrow when I get to work!

Thanks

Robin

Puzamoya
Associate II
Posted on September 19, 2014 at 11:10

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6ol&d=%2Fa%2F0X0000000bw9%2F7NmJPG.h17dP47_pxnK4eZyqUkM8m8kcVN75A0aV9iw&asPdf=false
Puzamoya
Associate II
Posted on September 19, 2014 at 11:13

My DMA2 stream 2 channel 1 Code

GPIO_InitTypeDef       GPIO_InitStructure;

DMA_InitTypeDef       DMA_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

ADC_CommonInitTypeDef ADC_CommonInitStructure;

ADC_InitTypeDef       ADC_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

/* disable ADC */

ADC_Cmd(ADC2, DISABLE);

/* Deinitializes the ADC peripheral registers */

ADC_DeInit();

/* Enable and set ADC DMA Interrupt priority */

NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ADC_DMA_INT_PRIORITY;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* Enable ADC's, DMA2 and GPIO clocks ****************************************/

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

RCC_AHB1PeriphClockCmd(ANALOG_1_GPIO_CLK | ANALOG_2_GPIO_CLK | ANALOG_3_GPIO_CLK | ANALOG_4_GPIO_CLK |  ANALOG_5_GPIO_CLK |  ANALOG_6_GPIO_CLK , ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);

/* DMA2 Stream0 channel0 configuration **************************************/

DMA_InitStructure.DMA_Channel = DMA_Channel_1;

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC2->DR;;

DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADCConvertedValue;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

DMA_InitStructure.DMA_BufferSize = (uint32_t)countof(ADCConvertedValue);

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_HalfFull;

DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

DMA_Init(DMA2_Stream2, &DMA_InitStructure);

DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_HTIF2);

DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TCIF2);

DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TEIF2);

DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_DMEIF2);

DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_FEIF2);

/* enable interrupts */

DMA_ITConfig(DMA2_Stream2, DMA_IT_TC, ENABLE);

/* enable DMA */

DMA_Cmd(DMA2_Stream2, ENABLE);

/* Configure ADC Channel pins as analog input ******************************/

GPIO_InitStructure.GPIO_Pin = ANALOG_1_PIN;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(ANALOG_1_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ANALOG_2_PIN;

GPIO_Init(ANALOG_2_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ANALOG_3_PIN;

GPIO_Init(ANALOG_3_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ANALOG_4_PIN;

GPIO_Init(ANALOG_4_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ANALOG_5_PIN;

GPIO_Init(ANALOG_5_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = ANALOG_6_PIN;

GPIO_Init(ANALOG_6_GPIO_PORT, &GPIO_InitStructure);

/* ADC Common Init **********************************************************/

/* 22.5Mhz ADC clock */

ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;

ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

ADC_CommonInit(&ADC_CommonInitStructure);

/* ADC Init ****************************************************************/

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

ADC_InitStructure.ADC_ScanConvMode = ENABLE;

ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

/* set trigger to timer 2 */

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

ADC_InitStructure.ADC_NbrOfConversion = (uint32_t)countof(ADCConvertedValue);

ADC_Init(ADC2, &ADC_InitStructure);

/* ADC1 regular channel1 configuration *************************************/

ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 1, ADC_SampleTime_3Cycles);

ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 2, ADC_SampleTime_3Cycles);

ADC_RegularChannelConfig(ADC2, ADC_Channel_5, 3, ADC_SampleTime_3Cycles);

ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 4, ADC_SampleTime_3Cycles);

ADC_RegularChannelConfig(ADC2, ADC_Channel_7, 5, ADC_SampleTime_3Cycles);

ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 6, ADC_SampleTime_3Cycles);

/* enable temperature sensor */

//ADC_TempSensorVrefintCmd(ENABLE);

/* Enable DMA request after last transfer (Single-ADC mode)  */

ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);

/* Enable ADC2 */

ADC_Cmd(ADC2, ENABLE);

/* Enable ADC2 DMA */

ADC_DMACmd(ADC2, ENABLE);

/* setup TIM3 for ADC trigger */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

/* set to 40Khz */

TIM_TimeBaseStructure.TIM_RepetitionCounter = (uint8_t)0;

TIM_TimeBaseStructure.TIM_Period = (uint32_t)(((uint32_t)SystemCoreClock/(uint32_t)168000) - (uint32_t)1);

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = (uint16_t)0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); 

TIM_Cmd(TIM3, ENABLE);

Posted on September 19, 2014 at 19:14

/* Deinitializes the ADC peripheral registers */

ADC_DeInit();

Wouldn't do that or the Common stuff twice.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 19, 2014 at 19:27

Yikes none of the numbers/comments here make any sense with respect to stated specification.

/* setup TIM3 for ADC trigger */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* set to 40Khz */
TIM_TimeBaseStructure.TIM_RepetitionCounter = (uint8_t)0;
TIM_TimeBaseStructure.TIM_Period = (uint32_t)(((uint32_t)SystemCoreClock/(uint32_t)168000) - (uint32_t)1);
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = (uint16_t)0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); 
TIM_Cmd(TIM3, ENABLE);

For 1 KHz periodicity // APB1 assumed at DIV4, TIMCLK thus DIV2 TIM_TimeBaseStructure.TIM_Period = ((SystemCoreClock / 2) / 1000) - 1; You're trying to compute the number of clock ticks at 84 MHz in the Period of a 1 KHz signal. 84000 ticks won't fit in 16-bit, so lets hope you picked a 32-bit timer, or you'll need to use a prescaler of 2-1 to get to 42000-1
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on September 19, 2014 at 19:32

No TIM3 definitely 16-bit

TIM_TimeBaseStructure.TIM_Prescaler = 2 - 1;// DIV2 of (SystemCoreClock / 2)

TIM_TimeBaseStructure.TIM_Period = ((SystemCoreClock / 4) / 1000) - 1;
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..