AnsweredAssumed Answered

HAL_ADC_ConvCpltCallback called twice

Question asked by Gerber on Dec 2, 2015
Latest reply on Feb 16, 2016 by kostka.tim

Hi,

I have an issue with the ADC configuration below. ADC is triggered once (pulse = 5000, period 21000) by TIM3, but for some reason HAL_ADC_ConvCpltCallback is called twice.  

TIM3

/*TIM3 init*/
void TIM3_Init(void) {
 
    tim3.Instance = TIM3;
    tim3.Init.Period = 21000;
    tim3.Init.Prescaler = 84;
    tim3.Init.ClockDivision = 0;
    tim3.Init.CounterMode = TIM_COUNTERMODE_UP;
 
if (HAL_TIM_OC_Init(&tim3) != HAL_OK) {
}
 
  sTimChannelConfig.OCMode = TIM_OCMODE_TOGGLE;
  sTimChannelConfig.Pulse = 5000;
  sTimChannelConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
 
/* Common configuration for all channels */
  sTimChannelConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sTimChannelConfig.OCFastMode = TIM_OCFAST_DISABLE;
  sTimChannelConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
  sTimChannelConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
 
if (HAL_TIM_OC_ConfigChannel(&tim3, &sTimChannelConfig, TIM_CHANNEL_1) != HAL_OK) {
}
 
 
/* Output Compare Toggle Mode configuration: Channel2 */
sTimChannelConfig.OCMode = TIM_OCMODE_TIMING;
sTimChannelConfig.Pulse = 2500;
if (HAL_TIM_OC_ConfigChannel(&tim3, &sTimChannelConfig, TIM_CHANNEL_2) != HAL_OK) {
}
 
/* Output Compare Toggle Mode configuration: Channel3 */
sTimChannelConfig.OCMode = TIM_OCMODE_TIMING;
sTimChannelConfig.Pulse = 7500;
if (HAL_TIM_OC_ConfigChannel(&tim3, &sTimChannelConfig, TIM_CHANNEL_3) != HAL_OK) {
}
 
/* Start channel 2 in Active mode */
if (HAL_TIM_OC_Start_IT(&tim3, TIM_CHANNEL_1) != HAL_OK) {
}
/* Start channel 2 in Active mode */
if (HAL_TIM_OC_Start_IT(&tim3, TIM_CHANNEL_2) != HAL_OK) {
}
/* Start channel 3 in Active mode */
if (HAL_TIM_OC_Start_IT(&tim3, TIM_CHANNEL_3) != HAL_OK) {
    /* Starting Error */
}
}

ADC1 (multi-mode with ADC2)
void ADC1_Init(void) {
    hadc1.Instance = ADC1;
 
    hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
    hadc1.Init.Resolution = ADC_RESOLUTION12b;
    hadc1.Init.ScanConvMode = ENABLE;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.NbrOfDiscConversion = 0;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING;
    hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_CC1;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 2;
    hadc1.Init.DMAContinuousRequests = ENABLE;
    hadc1.Init.EOCSelection = EOC_SEQ_CONV;
 
    if (HAL_ADC_Init(&hadc1) != HAL_OK) {
        /* Initialization Error */
    }
 
    sConfig.Channel = ADC_CHANNEL_15;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
 
 
    sConfig.Channel = ADC_CHANNEL_VREFINT;
    sConfig.Rank = 2;
    sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
 
    /* Start the conversion process */
    if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*) &ADC1Converted, 2) != HAL_OK) {
    }
 
    /* enable interrupt */
    if (HAL_ADC_Start_IT(&hadc1) != HAL_OK) {
    }
 
    /**Configure the ADC multi-mode*/
    Multimode.Mode = ADC_DUALMODE_REGSIMULT;
    Multimode.DMAAccessMode = ADC_DMAACCESSMODE_2;
    Multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_5CYCLES;
    HAL_ADCEx_MultiModeConfigChannel(&hadc1, &Multimode);
}

DMA
if (hadc->Instance == ADC1) {
 
    /*##-1- Enable peripherals and GPIO Clocks #################################*/
    /* Enable GPIO clock */
 
    __GPIOC_CLK_ENABLE();
    /* ADC1 Periph clock enable */
    __ADC1_CLK_ENABLE();
    /* Enable DMA2 clock */
    __DMA2_CLK_ENABLE();
 
    /*ADC1 GPIO Configuration*/
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
    /*##-3- Configure the DMA streams ##########################################*/
    /* Set the parameters to be configured */
    hdma_adc1.Instance = DMA2_Stream0;
 
    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_VERY_HIGH;
    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 
    HAL_DMA_Init(&hdma_adc1);
 
    /* Associate the initialized DMA handle to the the ADC handle */
    __HAL_LINKDMA(hadc, DMA_Handle, hdma_adc1);
 
    /*##-4- Configure the NVIC for DMA #########################################*/
    /* NVIC configuration for DMA transfer complete interrupt */
    /* Peripheral interrupt init*/
    HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(ADC_IRQn);
 
    HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);


Callback
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1) {
 
        ADC2Buffered[ADC1BufferIndex] = ADC2Converted[0];
        ADC2BufferIndex = ADC2BufferIndex + 1;
 
        if (ADC2BufferIndex >= 200) {
            ADC2BufferIndex = 0;
        }
}

Now ADC1Buffered[] is filled with duplicated values because HAL_ADC_ConvCpltCallback is called twice per TIM3 trigger.

Any thoughts?

Outcomes