cancel
Showing results for 
Search instead for 
Did you mean: 

Triggering ADC/DMA with Timer2 (STM32WB55)

JayDev
Senior II

Hello!

I had a project where I'm trying to get the ADC/DMA to trigger with timer 2 but I seem to be missing part of the puzzle to getting it up and working.

I originally had the ADC/DMA running with "Continuous Conversion" mode set in the ADC, which was fine and I could get the ADC values just fine in the HAL_TIM_PeriodElapsedCallback() routine. I also setup my timer setup to toggle a bit at the desired frequency, so all those pieces seem to be working.

The problem for me came when I tried to piece them altogether so I have my timer triggering the conversions so i can take samples at a desired interval (if that makes sense). I disabled continuous conversion mode and set the external trigger conversion source to Timer 2 Trigger Out event. Unfortunately, I can't seem to get it to trigger like I expected it to.

I setup breakpoints in the following interrupts to see which one it popped up in:

HAL_ADC_ConvCpltCallback()

HAL_TIM_PeriodElapsedCallback()

Unfortunately, it didn't seem to come up in either.

I figure I'm either looking in the wrong interrupt (entirely possible) or I don't have something setup correctly (which seems more likely to me).

I'm going to include screenshots of my setup (in case that helps). I'll also include the basic code I'm running.

It's pretty basic, but this is essentially what I'm running to try and start up the ADC/DMA/Timer (besides all the generated inits and such)

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&AD_RES, 1);
HAL_TIM_Base_Start_IT(&htim2);
 
 
 
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
     //Toggle bit here / breakpoint
}
 
 
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
     //Toggle bit here / breakpoint
}
 
 
 
 
static void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_FALLING;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_6;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
 
  /* USER CODE END ADC1_Init 2 */
 
}
 
 
 
static void MX_TIM2_Init(void)
{
 
  /* USER CODE BEGIN TIM2_Init 0 */
 
	/* Timer calculator */
	// Timer = (prescalar * preload) / clock
	//	0.000025 = (10 * 80) / 32000000 = 25 us
  /* USER CODE END TIM2_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
 
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 800;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
 
 
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMAMUX1_CLK_ENABLE();
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 6, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
}
 
 

I think I'm pretty close but just missed something (likely something pretty obvious). Let me know if you see anything or can point me in the right direction. Thanks!

0693W000003RMCZQA4.jpg0693W000003RMCUQA4.jpg0693W000003RMCAQA4.jpg0693W000003RMC0QAO.jpg

1 ACCEPTED SOLUTION

Accepted Solutions
JayDev
Senior II

Ok, I actually figured out the problem and, as I thought, I was pretty close. Had to change:

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

to

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

One little line but it apparently makes all the difference. It was the "Trigger Event Selection TRGO" section of the timer for any cubers that might come across this. Hope it helps!

View solution in original post

1 REPLY 1
JayDev
Senior II

Ok, I actually figured out the problem and, as I thought, I was pretty close. Had to change:

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

to

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

One little line but it apparently makes all the difference. It was the "Trigger Event Selection TRGO" section of the timer for any cubers that might come across this. Hope it helps!