2026-03-27 5:40 AM - last edited on 2026-03-27 5:55 AM by mƎALLEm
Hello everyone,
I am currently working with the STM32G431CBT6 and designing a custom ESC using the DRV8301 gate driver. My application requires a total of 9 ADC channels:
ADC1 → 4 channels
ADC2 → 5 channels
I configured both ADCs in independent mode with DMA (circular) using STM32CubeMX.
When I start ADC with DMA using the following function:
void ADC_Start_System(void)
{
// 1. Calibration
HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED);
HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED);
HAL_Delay(10);
// 2. Start ADC1
if (HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1_buffer, 4) != HAL_OK)
Error_Handler();
// 3. Start ADC2
if (HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adc2_buffer, 5) != HAL_OK)
Error_Handler();
}
ADC1 + DMA works perfectly
MCU gets stuck when calling:
HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adc2_buffer, 5);
Calibration is performed before start
DMA is configured in circular mode
NVIC interrupts for DMA channels are enabled
Separate DMA channels used for ADC1 and ADC2
Buffers are correctly sized:
uint16_t adc1_buffer[4];
uint16_t adc2_buffer[5];
ADC mode is independent (not dual mode)
MCU: STM32G431CBT6
Toolchain: STM32CubeMX + HAL
Application: ESC (motor control)
No external trigger (software start used)
Continuous conversion mode enabled
Why does HAL_ADC_Start_DMA() work for ADC1 but cause the MCU to hang for ADC2?
Is there any known limitation or special requirement for using ADC2 with DMA on STM32G4 (especially when ADC1 is already running with DMA)?
Thanks in advance!
2026-03-27 8:37 AM
2026-03-27 8:42 AM
You didn't set the break point at the right line.
I said in my previous post, set it at if(status != HAL_OK) / line 68
HAL_ADC_Start_DMA() is not yet executed when you set the breakpoint at line 58!
2026-03-27 8:47 AM - edited 2026-03-27 8:48 AM
If it's stuck in the call, good luck getting a breakpoint after the call to be hit.
As suggested before, let it run, hit pause, see where it's at. Probably in an interrupt. Probably because you're converting too quickly. Slow down the sample rate.
2026-03-27 8:48 AM
2026-03-27 8:54 AM
So, the status is OK for ADC2.
I see in your code you're performing a direct access to the registers for ADC2:
Why is this?
2026-03-27 9:04 AM
I have written a bare metal function for testing , This is my bare metal function . Its working fine . I have not call this function during your test.
void ADC2_DMA_Start_BareMetal(void)
{
// 1. Disable DMA
DMA1_Channel2->CCR &= ~DMA_CCR_EN;
// 2. Setup DMA
DMA1_Channel2->CPAR = (uint32_t)&ADC2->DR;
DMA1_Channel2->CMAR = (uint32_t)adc2_buffer;
DMA1_Channel2->CNDTR = 5;
DMA1_Channel2->CCR =
DMA_CCR_MINC
| DMA_CCR_CIRC
| DMA_CCR_PSIZE_0
| DMA_CCR_MSIZE_0;
DMA1_Channel2->CCR |= DMA_CCR_EN;
// 3. Enable ADC DMA
ADC2->CFGR |= ADC_CFGR_DMAEN | ADC_CFGR_DMACFG;
// 4. Enable ADC
if (!(ADC2->CR & ADC_CR_ADEN))
{
ADC2->CR |= ADC_CR_ADEN;
while (!(ADC2->ISR & ADC_ISR_ADRDY));
}
// 5. Start conversion
ADC2->CR |= ADC_CR_ADSTART;
}