cancel
Showing results for 
Search instead for 
Did you mean: 

Get no HAL_ADC_ConvCpltCallback from ADC in DMA mode

Riccardo Franceschetto
Associate III

Hi,

I'm implementing ADC on a STM32F469HI board (in particular LIZARD board from ACTRON).

I alreay implemented SPI comunication and UART (this one with DMA).

Now the focus is to get ADC Reading implemented with DMA also.

i set the timer 8 to trigger the ADC.

I get no error from initialization of the pheriperals.

I created a one element array to feed to the ADC so every time this get writed i assumed the callback from the conversion complete treats the data and so on like this.

The problem is i get no callback, i put a led to see if the callback gets executed.

the init code is as follows:

ADC init

void SIN_ADC1_Init()
{
 
  /* USER CODE BEGIN ADC1_Init 0 */
 
  /* USER CODE END ADC1_Init 0 */
 
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC1_Init 1 */
 
  /* USER CODE END ADC1_Init 1 */
 
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T8_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler(10);
  }
 
  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler(11);
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
}

ADC MSP init and de init

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hadc->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */
 
  /* USER CODE END ADC1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();
 
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PC0     ------> ADC1_IN10
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
    /* ADC1 DMA Init */
    /* ADC1 Init */
    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_LOW;
    hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {
      Error_Handler(42);
    }
 
    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
 
    /* ADC1 interrupt Init */
    HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(ADC_IRQn);
  /* USER CODE BEGIN ADC1_MspInit 1 */
  /* USER CODE END ADC1_MspInit 1 */
  }
 
}
 
/**
* @brief ADC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
   /* USER CODE BEGIN ADC1_MspDeInit 0 */
 
  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC1_CLK_DISABLE();
 
    /**ADC1 GPIO Configuration
    PC0     ------> ADC1_IN10
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
 
    /* ADC1 DMA DeInit */
    HAL_DMA_DeInit(hadc->DMA_Handle);
 
    /* ADC1 interrupt DeInit */
    HAL_NVIC_DisableIRQ(ADC_IRQn);
  /* USER CODE BEGIN ADC1_MspDeInit 1 */
 
  /* USER CODE END ADC1_MspDeInit 1 */
  }

DMA init

void SIN_DMA_Init(void)
{
 
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
  /* DMA2_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
 
 
}

TIMER 8 init

void SIN_TIM8_Init(void)
 
{
 
 
 
 /* USER CODE BEGIN TIM8_Init 0 */
 
 
 
 /* USER CODE END TIM8_Init 0 */
 
 
 
 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
 
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 
 
 
 /* USER CODE BEGIN TIM8_Init 1 */
 
 
 
 /* USER CODE END TIM8_Init 1 */
 
 htim8.Instance = TIM8;
 
 htim8.Init.Prescaler = 89;
 
 htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
 
 htim8.Init.Period = 99;
 
 htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 
 htim8.Init.RepetitionCounter = 0;
 
 htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
 
 if (HAL_TIM_Base_Init(&htim8) != HAL_OK)
 
 {
 
  Error_Handler(18);
 
 }
 
 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
 
 if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK)
 
 {
 
  Error_Handler(19);
 
 }
 
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
 
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 
 if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
 
 {
 
  Error_Handler(88);
 
 }
 
 /* USER CODE BEGIN TIM8_Init 2 */
 
 
 
 /* USER CODE END TIM8_Init 2 */
 
 
 
}

TIM8 msp init and deinit

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
    if(htim_base->Instance==TIM8)
  {
  /* USER CODE BEGIN TIM8_MspInit 0 */
 
  /* USER CODE END TIM8_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_TIM8_CLK_ENABLE();
    /* TIM8 interrupt Init */
    HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
  /* USER CODE BEGIN TIM8_MspInit 1 */
 
  /* USER CODE END TIM8_MspInit 1 */
  }
 
}
 
 
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
    if(htim_base->Instance==TIM8)
  {
  /* USER CODE BEGIN TIM8_MspDeInit 0 */
 
  /* USER CODE END TIM8_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM8_CLK_DISABLE();
 
    /* TIM8 interrupt DeInit */
    HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn);
  /* USER CODE BEGIN TIM8_MspDeInit 1 */
 
  /* USER CODE END TIM8_MspDeInit 1 */
  }
 
}
 
 

Interrupt in the stm32f4xx_it file

void ADC_IRQHandler(void)
{
  /* USER CODE BEGIN ADC_IRQn 0 */
 
  /* USER CODE END ADC_IRQn 0 */
  HAL_ADC_IRQHandler(&hadc1);
  /* USER CODE BEGIN ADC_IRQn 1 */
 
  /* USER CODE END ADC_IRQn 1 */
}
 
void TIM8_UP_TIM13_IRQHandler(void)
{
  /* USER CODE BEGIN TIM8_UP_TIM13_IRQn 0 */
 
  /* USER CODE END TIM8_UP_TIM13_IRQn 0 */
  HAL_TIM_IRQHandler(&htim8);
  /* USER CODE BEGIN TIM8_UP_TIM13_IRQn 1 */
 
  /* USER CODE END TIM8_UP_TIM13_IRQn 1 */
}
 
 
void DMA2_Stream0_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
 
  /* USER CODE END DMA2_Stream0_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_adc1);
  /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
 
  /* USER CODE END DMA2_Stream0_IRQn 1 */
}

Call to the adc start dma

#define ADC_BUF_LEN 4096
uint16_t adc1buffer[ADC_BUF_LEN];
 
void DevicePyro_Init( void )
{
  /* check for initialization */
 
    if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1buffer, ADC_BUF_LEN)  != HAL_OK )
      {
 
        Error_Handler(7);  //led for debug 
 
      }
 
}
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
 
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
}

1 ACCEPTED SOLUTION

Accepted Solutions
RomainR.
ST Employee

Hello @Riccardo Franceschetto (Community Member)

After review your code, ADC with DMA and TIM8 configuration are correct.

But I don't see the TIM8 start ?

Can you check my implementation below ?

#define ADC_BUF_LEN 4096
uint16_t adc1buffer[ADC_BUF_LEN];
volatile uint32_t adcFlag = 0x0;
 
 
void DevicePyro_Init( void )
{
	/* check for initialization */
  
	/**>R Start the Timer */
	if (HAL_StatusTypeDef HAL_TIM_Base_Start_IT(&htim8) != HAL_OK )
	{
		Error_Handler(7);  //led for debug 
	}
 
	if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1buffer, ADC_BUF_LEN)  != HAL_OK )
	{
		Error_Handler(7);  //led for debug 
	}
 
	/**> Wait for DMA Transfer complete */
	while (!adcFlag) {;}
	adcFlag = 0x0;
}
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	adcFlag = 0x1;
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
}

Best regards,

Romain,

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

5 REPLIES 5

Read out and check/post TIM, ADC and DMA registers content. Check in the sequence of events, if TIM runs, if ADC is set properly (see e.g. its flags and if triggering is set properly - note that observing ADC registers using debugger has side effect) and if DMA is set up and runs (NDTR decrements). If all this works and also DMA sets the TC flag in LISR as expected, then proceed through the usual interrup-doesn't-fire checklist.

JW

RomainR.
ST Employee

Hello @Riccardo Franceschetto (Community Member)

After review your code, ADC with DMA and TIM8 configuration are correct.

But I don't see the TIM8 start ?

Can you check my implementation below ?

#define ADC_BUF_LEN 4096
uint16_t adc1buffer[ADC_BUF_LEN];
volatile uint32_t adcFlag = 0x0;
 
 
void DevicePyro_Init( void )
{
	/* check for initialization */
  
	/**>R Start the Timer */
	if (HAL_StatusTypeDef HAL_TIM_Base_Start_IT(&htim8) != HAL_OK )
	{
		Error_Handler(7);  //led for debug 
	}
 
	if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1buffer, ADC_BUF_LEN)  != HAL_OK )
	{
		Error_Handler(7);  //led for debug 
	}
 
	/**> Wait for DMA Transfer complete */
	while (!adcFlag) {;}
	adcFlag = 0x0;
}
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
	adcFlag = 0x1;
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_9);
}

Best regards,

Romain,

In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thanks Romain,

I missed the TIM8 start like you suggested.

Now when i call HAL_TIM_Base_Start_IT(&htim8) i get into error handler.

You checked the config settings are right, so what could be?

also is the adcFlag you insert necessary?

RomainR.
ST Employee

Can you know precisely (using the debugger by step) the line of code which generates an error handler?

Regarding the adcFlag , you must synchronize the rest of your application with the DMA-ADC transfers, it is preferable yes.

Best regards,

Romain,

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Yes, the problem was i forgot to call the init for the timer 😂