AnsweredAssumed Answered

Problems with DMAx_Streamy_IRQHandler

Question asked by fontanellaz.matthias on Nov 19, 2016
Latest reply on Nov 20, 2016 by Clive One
Hi

I'm using a STM32F407G-Disc1 with Atollic TrueStuido Lite.
I have some issues with DMA IRQ's. I set up DMA to copy values from ADC->DR to memory. I would also like to use DMA's Transfer Complete interrupt. 

#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

uint16_t ADCConvertedValues[3];
InitTriggerClk()
{
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_TIM1, ENABLE);


         /* Init structure for timer */
         TIM_TimeBaseInitTypeDef  TIM1_InitStruct;


         /* Period = f_cpu / (1 + prescaler) / f_pwm; f_pwm = 200Hz  */
         TIM1_InitStruct.TIM_Prescaler = 4199;
         TIM1_InitStruct.TIM_Period = 99;
         TIM1_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
         TIM1_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
         TIM_TimeBaseInit (TIM1, &TIM1_InitStruct);






         /* Init structure for pwm */
         TIM_OCInitTypeDef  TIM1_OCInit;


         TIM1_OCInit.TIM_OCMode = TIM_OCMode_PWM1;
         TIM1_OCInit.TIM_OutputState = TIM_OutputState_Enable;
         TIM1_OCInit.TIM_OutputNState = TIM_OutputNState_Enable;
         TIM1_OCInit.TIM_Pulse = 50;  /* Duty cycle 10% (0 ... 16799)  */
         TIM1_OCInit.TIM_OCPolarity = TIM_OCPolarity_High;
         TIM1_OCInit.TIM_OCNPolarity = TIM_OCNPolarity_Low;
         TIM1_OCInit.TIM_OCIdleState = TIM_OCIdleState_Reset;
         TIM1_OCInit.TIM_OCNIdleState = TIM_OCNIdleState_Reset;


         TIM_OC2Init (TIM1, &TIM1_OCInit);
         TIM_OC2PreloadConfig (TIM1 , TIM_OCPreload_Enable);


         /* for Advanced timer enable the arr-register */
         TIM_ARRPreloadConfig (TIM1, ENABLE);


         /* for Advanced timer enable the PWM-output */
         TIM_CtrlPWMOutputs (TIM1, ENABLE);


         /* Start the timer */
         TIM_Cmd (TIM1, ENABLE);
}

InitDMA()
{
       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
     
          DMA_InitTypeDef       DMA_InitStructure;
       /* DMA2_Stream0 channel0 configuration **************************************/
       DMA_DeInit(DMA2_Stream0);
       DMA_InitStructure.DMA_Channel = DMA_Channel_0;
       DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
       DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0];
       DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
       DMA_InitStructure.DMA_BufferSize = (uint16_t)sizeof(ADCConvertedValues);//3;
       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_Stream0, &DMA_InitStructure);
       /* Enable DMA Stream Transfer Complete interrupt */
       DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
       /* DMA2_Stream0 enable */
       DMA_Cmd(DMA2_Stream0, ENABLE);


         NVIC_InitTypeDef NVIC_InitStruct;
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
         NVIC_InitStruct.NVIC_IRQChannel = DMA2_Stream0_IRQn;
         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
         NVIC_Init(&NVIC_InitStruct);
}

InitADC()
{
          GPIO_InitTypeDef GPIO_InitStructure;

       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
       GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
       GPIO_Init(GPIOA, &GPIO_InitStructure);

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
       ADC_InitTypeDef       ADC_InitStructure;
       ADC_CommonInitTypeDef ADC_CommonInitStructure;
     /* ADC Common Init **********************************************************/
            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);


            /* ADC1 Init ****************************************************************/
            ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
            ADC_InitStructure.ADC_ScanConvMode = ENABLE;  // Multiple Channels
            ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Triggering, so no continuous conversion
            ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
            ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC2;// Capture Compare Register from Channel2 of Timer1 triggers Conversion
            ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
            ADC_InitStructure.ADC_NbrOfConversion = 3;
            ADC_Init(ADC1, &ADC_InitStructure);


            /* ADC1 regular channel configuration ******************************/
            ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_84Cycles); // PA2
            ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_84Cycles); // PA3
            ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 3, ADC_SampleTime_84Cycles); // PA5


             /* Enable DMA request after last transfer (Single-ADC mode) */
            ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);


            /* Enable ADC1 DMA */
            ADC_DMACmd(ADC1, ENABLE);


              /* Enable ADC1 
            ADC_Cmd(ADC1, ENABLE);
}

int main(void)
{
     InitTriggerClk();
        InitDMA();
        InitADC();
     while(1)
     {
          if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
            {

               int a = ADCConvertedValues[0]; //when setting breakpoint here, I am                                                   reaching this point. So
                                                    DMA is setting it's TC-Flag
          }
     }
}

void DMA2_Stream0_IRQHandler(void)
{
  /* Test on DMA Stream Transfer Complete interrupt */
  if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
  {
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
     DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
  }
}


When i add the NVIC and it's IRGHandler i ended up in an infinit loop, calle by startup_stm32F4xx.s. Description to this defaulhanlder is: "his is the code that gets called when the processor receives an unexpected interrupt."

I have the same issue with DMAx_Streamy_IRQHandler with USARt and so on.

Does anyone have an idea how to solve this problem?

Thank you very very much!!

Outcomes