diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 471d91b49e2..ac311460e9b 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -407,6 +407,44 @@ static void adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio, uint32_t shi } #endif /* CONFIG_SOC_SERIES_STM32xxx */ +/* + * Enable ADC peripheral, and wait until ready if required by SOC. + */ +static int adc_stm32_enable(ADC_TypeDef *adc) +{ + if (LL_ADC_IsEnabled(adc) == 1UL) { + return 0; + } + LL_ADC_Enable(adc); + +#if defined(CONFIG_SOC_SERIES_STM32L4X) || \ + defined(CONFIG_SOC_SERIES_STM32L5X) || \ + defined(CONFIG_SOC_SERIES_STM32WBX) || \ + defined(CONFIG_SOC_SERIES_STM32G0X) || \ + defined(CONFIG_SOC_SERIES_STM32G4X) || \ + defined(CONFIG_SOC_SERIES_STM32H7X) || \ + defined(CONFIG_SOC_SERIES_STM32WLX) + /* + * Enabling ADC modules in L4, WB, G0 and G4 series may fail if they are + * still not stabilized, this will wait for a short time to ensure ADC + * modules are properly enabled. + */ + uint32_t count_timeout = 0; + + while (LL_ADC_IsActiveFlag_ADRDY(adc) == 0) { + if (LL_ADC_IsEnabled(adc) == 0UL) { + LL_ADC_Enable(adc); + count_timeout++; + if (count_timeout == 10) { + return -ETIMEDOUT; + } + } + } +#endif + + return 0; +} + static int start_read(const struct device *dev, const struct adc_sequence *sequence) { @@ -513,9 +551,7 @@ static int start_read(const struct device *dev, while (LL_ADC_IsEnabled(adc) == 1UL) { } LL_ADC_SetResolution(adc, resolution); - LL_ADC_Enable(adc); - while (LL_ADC_IsActiveFlag_ADRDY(adc) != 1UL) { - } + adc_stm32_enable(adc); #elif !defined(CONFIG_SOC_SERIES_STM32F1X) && \ !defined(STM32F3X_ADC_V2_5) LL_ADC_SetResolution(adc, resolution); @@ -530,7 +566,8 @@ static int start_read(const struct device *dev, LL_ADC_Disable(adc); while (LL_ADC_IsEnabled(adc) == 1UL) { } -#endif /* CONFIG_SOC_SERIES_STM32L0X */ +#endif + #if defined(CONFIG_SOC_SERIES_STM32G0X) || \ defined(CONFIG_SOC_SERIES_STM32G4X) || \ defined(CONFIG_SOC_SERIES_STM32H7X) || \ @@ -580,11 +617,11 @@ static int start_read(const struct device *dev, #endif /* CONFIG_SOC_SERIES_STM32H7X */ default: LOG_ERR("Invalid oversampling"); - LL_ADC_Enable(adc); + adc_stm32_enable(adc); return -EINVAL; } /* re-enable ADC after changing the OVS */ - LL_ADC_Enable(adc); + adc_stm32_enable(adc); #else if (sequence->oversampling) { LOG_ERR("Oversampling not supported"); @@ -606,7 +643,7 @@ static int start_read(const struct device *dev, } adc_stm32_calib(dev); /* re-enable ADC after calibration */ - LL_ADC_Enable(adc); + adc_stm32_enable(adc); #else LOG_ERR("Calibration not supported"); return -ENOTSUP; @@ -628,7 +665,7 @@ static int start_read(const struct device *dev, #elif defined(CONFIG_SOC_SERIES_STM32F1X) LL_ADC_EnableIT_EOS(adc); #elif defined(STM32F3X_ADC_V2_5) - LL_ADC_Enable(adc); + adc_stm32_enable(adc); LL_ADC_EnableIT_EOS(adc); #else LL_ADC_EnableIT_EOCS(adc); @@ -975,32 +1012,10 @@ static int adc_stm32_init(const struct device *dev) } #endif - LL_ADC_Enable(adc); - -#if defined(CONFIG_SOC_SERIES_STM32L4X) || \ - defined(CONFIG_SOC_SERIES_STM32L5X) || \ - defined(CONFIG_SOC_SERIES_STM32WBX) || \ - defined(CONFIG_SOC_SERIES_STM32G0X) || \ - defined(CONFIG_SOC_SERIES_STM32G4X) || \ - defined(CONFIG_SOC_SERIES_STM32H7X) || \ - defined(CONFIG_SOC_SERIES_STM32WLX) - /* - * Enabling ADC modules in L4, WB, G0 and G4 series may fail if they are - * still not stabilized, this will wait for a short time to ensure ADC - * modules are properly enabled. - */ - uint32_t countTimeout = 0; - - while (LL_ADC_IsActiveFlag_ADRDY(adc) == 0) { - if (LL_ADC_IsEnabled(adc) == 0UL) { - LL_ADC_Enable(adc); - countTimeout++; - if (countTimeout == 10) { - return -ETIMEDOUT; - } - } + err = adc_stm32_enable(adc); + if (err < 0) { + return err; } -#endif config->irq_cfg_func();