cancel
Showing results for 
Search instead for 
Did you mean: 

ADC DMA Buffers not Updating (multi-peripheral with timer trigger)

M_Vance88
Associate

Hello,
I am working on an STM32F7 project where I need to sample multiple ADC peripherals using DMA triggered by a timer.

Problem: No ADC data is being written to ADC_BUF or ADC3_BUF even though main loop runs (buffers ADC_BUF and ADC3_BUF remains zero while counter increases)

Current Setup:
ADC1: 1 Channel, DMA2 Stream 0, triggered by TIM2 TRGO UPDATE

ADC3: 2 Channels, DMA2 Stream 1, triggered by TIM2 CC2

DMA: Circular mode, DMAContinuousRequests enabled

TIM2: 10 Hz update event

Mode: ContinuousConvMode is Disabled, ScanConvMode is Enabled

What do I need to change to fix this?

/* USER CODE BEGIN PV */
volatile uint16_t ADC_BUF[ADC_BUF_LEN];
volatile uint16_t ADC3_BUF[ADC_BUF_LEN];
uint16_t counter = 0;
/* USER CODE BEGIN PV */
/* USER CODE BEGIN 2 */
HAL_CAN_Start(&hcan1);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC_BUF, ADC_BUF_LEN);
HAL_ADC_Start_DMA(&hadc3, (uint32_t*)ADC3_BUF, ADC_BUF_LEN);
HAL_TIM_Base_Start(&htim2); 
/* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6);
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_7);
}
/* USER CODE END 4 */

// ADC1 Settings
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = ENABLE;
// ADC3 Settings
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc3.Init.Resolution = ADC_RESOLUTION_12B;
  hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc3.Init.ContinuousConvMode = DISABLE;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_CC2;
  hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc3.Init.NbrOfConversion = 2;
  hadc3.Init.DMAContinuousRequests = ENABLE;
// TIM2 Settings
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 7200-1;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 1000-1;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

I'm new to stm32 so please let me know if you need any additional information!  Any insights to get my buffers working would be greatly appreciated!

1 REPLY 1
Saket_Om
ST Employee

Hello @M_Vance88 

I would suggest first testing with only one ADC + one DMA + one timer trigger to make sure the basic acquisition chain is working correctly. Once you confirm that a single ADC is filling its buffer properly, you can then add the second ADC and its trigger step by step.
You can also refer to the following example as a starting point for a timer-triggered ADC with DMA configuration:
https://github.com/STMicroelectronics/STM32CubeWB/tree/master/Projects/P-NUCLEO-WB55.Nucleo/Examples/ADC/ADC_SingleConversion_TriggerTimer_DMA

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.
Saket_Om