AnsweredAssumed Answered

HAL DMA ADC Interrupt stuck in IRQ Handler

Question asked by h.hammer on Jul 18, 2014
Latest reply on Sep 1, 2014 by Montassar BEN ROMDHANE
I'm having an issue where, if I enable the DMA IRQ, my application gets stuck on one of the error check statements within the HAL_DMA_IRQHandler

I'm trying to run conversions on four ADC1 channels, each going into memory using the DMA, and then repeating the process. Each time the transfer is complete, I want to run some code in the DMA interrupt.

The ADC seems to be converting correctly, and DMA seems to be moving the data where I want in memory.The problem occors when I enable the DMA interrupt using:

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 3);
HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);

If I understand correctly, the correct way of starting the ADC with DMA is using:

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&rawADC, 4);

where hadc1 is my ADC_HandleTypeDef, rawADC is my buffer and 4 is the number of conversions.

Am I correct in that HAL_ADC_ConvCpltCallback() is also the same callback for ADC DMA end of transfer?

This is my ADC and DMA config:------------------------

     __ADC1_CLK_ENABLE();
       
     GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
     
     /* Peripheral DMA init*/
     hdma_adc1.Instance = DMA2_Stream4;
     hdma_adc1.Init.Channel = DMA_CHANNEL_0;
     hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
     hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
     hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
     hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
     hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
     hdma_adc1.Init.Mode = DMA_CIRCULAR;
     hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
     hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
     HAL_DMA_Init(&hdma_adc1);
     
     __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
     
     HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
     HAL_NVIC_SetPriority(ADC_IRQn, 0, 3);
     HAL_NVIC_EnableIRQ(ADC_IRQn);


     __DMA2_CLK_ENABLE();
     HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
     HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 0, 3);
     HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn); /* Something goes wrong when enable this line */


     /* Configure ADC1 */
     ADC_ChannelConfTypeDef sConfig;
     
     hadc1.Instance = ADC1;
     hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
     hadc1.Init.Resolution = ADC_RESOLUTION12b;
     hadc1.Init.ScanConvMode = DISABLE;
     hadc1.Init.ContinuousConvMode = ENABLE;
     hadc1.Init.DiscontinuousConvMode = DISABLE;
     hadc1.Init.NbrOfDiscConversion = 1;
     hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
     hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
     hadc1.Init.NbrOfConversion = 4;
     hadc1.Init.DMAContinuousRequests = ENABLE;
     hadc1.Init.EOCSelection = EOC_SEQ_CONV;
     HAL_ADC_Init(&hadc1);


     /* Configure channel sample order*/
     sConfig.Channel = ADC_CHANNEL_13;
     sConfig.Rank = 4;
     sConfig.SamplingTime = ADCSAMPLES;
     HAL_ADC_ConfigChannel(&hadc1, &sConfig);


     sConfig.Channel = ADC_CHANNEL_10;
     sConfig.Rank = 1;
     HAL_ADC_ConfigChannel(&hadc1, &sConfig);


     sConfig.Channel = ADC_CHANNEL_11;
     sConfig.Rank = 2;
     HAL_ADC_ConfigChannel(&hadc1, &sConfig);


     sConfig.Channel = ADC_CHANNEL_12;
     sConfig.Rank = 3;
     HAL_ADC_ConfigChannel(&hadc1, &sConfig);

     HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&rawADC, 4);

Outcomes