diff --git a/drivers/adc/adc_stm32.c b/drivers/adc/adc_stm32.c index 656c4650f438c..7e1cddcd8b1fe 100644 --- a/drivers/adc/adc_stm32.c +++ b/drivers/adc/adc_stm32.c @@ -319,6 +319,40 @@ static void adc_stm32_calib(const struct device *dev) } #endif +static int adc_stm32_enable_and_wait_stabilisation(ADC_TypeDef *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; + + do { + if (LL_ADC_IsEnabled(adc) == 0UL) { + LL_ADC_Enable(adc); + } + countTimeout++; + if (countTimeout == 10) { + return -ETIMEDOUT; + } + } while (LL_ADC_IsActiveFlag_ADRDY(adc) == 0); + LL_ADC_ClearFlag_ADRDY(adc); +#else + if (LL_ADC_IsEnabled(adc) == 0UL) { + LL_ADC_Enable(adc); + } +#endif + return 0; +} + static int start_read(const struct device *dev, const struct adc_sequence *sequence) { @@ -425,6 +459,12 @@ static int start_read(const struct device *dev, } #elif !defined(CONFIG_SOC_SERIES_STM32F1X) && \ !defined(STM32F3X_ADC_V2_5) + if (LL_ADC_IsEnabled(adc) == 0) { + err = adc_stm32_enable_and_wait_stabilisation(adc); + if (err) { + return err; + } + } LL_ADC_SetResolution(adc, resolution); #endif @@ -464,7 +504,13 @@ static int start_read(const struct device *dev, adc_context_start_read(&data->ctx, sequence); - return adc_context_wait_for_completion(&data->ctx); + err = adc_context_wait_for_completion(&data->ctx); + + if (LL_ADC_IsEnabled(adc)) { + LL_ADC_Disable(adc); + } + + return err; } static void adc_context_start_sampling(struct adc_context *ctx) @@ -796,32 +842,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_and_wait_stabilisation(adc); + if (err < 0) { + return err; } -#endif config->irq_cfg_func();