Skip to main content
Puzamoya
Associate II
September 18, 2014
Question

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

  • September 18, 2014
  • 7 replies
  • 1471 views
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.

    This topic has been closed for replies.

    7 replies

    Tesla DeLorean
    Guru
    September 18, 2014
    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 VenmoUp vote any posts that you find helpful, it shows what's working..
    Puzamoya
    PuzamoyaAuthor
    Associate II
    September 18, 2014
    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
    PuzamoyaAuthor
    Associate II
    September 19, 2014
    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
    PuzamoyaAuthor
    Associate II
    September 19, 2014
    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);

    Tesla DeLorean
    Guru
    September 19, 2014
    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 VenmoUp vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    September 19, 2014
    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 VenmoUp vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    September 19, 2014
    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 VenmoUp vote any posts that you find helpful, it shows what's working..