Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions drivers/adc/adc_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: don't use camel case.


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)
{
Expand Down Expand Up @@ -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;
}
}
Comment on lines +462 to +467
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please move this after LL_ADC_SetResolution(), such that no special handling of STM32G0 is necessary.
I don't know of any Series which needs ADC to be enabled to set the resolution so this should be fine.
The HAL includes the following note regarding the LL_ADC_SetResolution macro:

ADC must be disabled or enabled without conversion on going...

LL_ADC_SetResolution(adc, resolution);
#endif

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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();

Expand Down