2025-09-22 5:17 AM
Hi everyone,
I am currently trying to use the ADC with DMA on my STM32H7S78-DK. To do so, I am following this guide: https://community.st.com/t5/stm32-mcus/stm32h7r-s-how-to-configure-an-adc-dma-transfer-in-circular-mode/ta-p/737149.
I've made little changes to the code compared to the guide. I am attaching my project.
The problem is that the program ends up in the Error_Handler() when the HAL_ADC_Start_DMA() (or the HAL_ADCEx_Calibration_Start()) function is executed.
During the execution of the HAL_ADC_Start_DMA(), the ADC_Enable() function returns HAL_ERROR:
/* Enable the ADC peripheral */
tmp_hal_status = ADC_Enable(hadc);
/* Start conversion if ADC is effectively enabled */
if (tmp_hal_status == HAL_OK)
Inside the ADC_Enable() function, the execution lead to this part (ADC_ENABLE_TIMEOUT limit reached):
if ((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
{
/* New check to avoid false timeout detection in case of preemption */
if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
{
/* Update ADC state machine to error */
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
/* Set ADC error code to ADC peripheral internal error */
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
return HAL_ERROR;
}
}
I am a bit new to STM32H7S programming and I don't understand why the ADC can't enable.
Do you have any idea ?
2025-09-22 5:26 AM - edited 2025-09-22 5:28 AM
Debug the program. When it ends up in Error_Handler, show the stack trace.
Actually, step through HAL_ADCEx_Calibration_Start and find out the reason it's returning an error instead of HAL_OK.
2025-09-22 6:32 AM
How do I do to get the stack trace in STM32CubeIDE?
I put some breakpoints in HAL_ADCEx_Calibration_Start and the problem comes from the call to ADC_Enable.
Inside this loop, the program does not enter the first if and ends up in the second one after a certain time:
while (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
{
/* If ADEN bit is set less than 4 ADC clock cycles after the ADCAL bit
has been cleared (after a calibration), ADEN bit is reset by the
calibration logic.
The workaround is to continue setting ADEN until ADRDY is becomes 1.
Additionally, ADC_ENABLE_TIMEOUT is defined to encompass this
4 ADC clock cycle duration */
/* Note: Test of ADC enabled required due to hardware constraint to */
/* not enable ADC if already enabled. */
if (LL_ADC_IsEnabled(hadc->Instance) == 0UL)
{
LL_ADC_Enable(hadc->Instance);
}
if ((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT)
{
/* New check to avoid false timeout detection in case of preemption */
if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_RDY) == 0UL)
{
/* Update ADC state machine to error */
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
/* Set ADC error code to ADC peripheral internal error */
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
return HAL_ERROR;
}
}
}
Feel free to ask me for more details, I'm not sure if that's clear.