drivers: adc: stm32: Add function to enable ADC consistently
Use a wrapper for LL_ADC_Enable that also waits for ADRDY if required by the SoC to make sure it's properly enabled everywhere this is done. Signed-off-by: Alexander Mihajlovic <a@abxy.se>
This commit is contained in:
parent
1cd1f41d3a
commit
e521c7d49e
1 changed files with 48 additions and 33 deletions
|
@ -407,6 +407,44 @@ static void adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio, uint32_t shi
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SOC_SERIES_STM32xxx */
|
#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,
|
static int start_read(const struct device *dev,
|
||||||
const struct adc_sequence *sequence)
|
const struct adc_sequence *sequence)
|
||||||
{
|
{
|
||||||
|
@ -513,9 +551,7 @@ static int start_read(const struct device *dev,
|
||||||
while (LL_ADC_IsEnabled(adc) == 1UL) {
|
while (LL_ADC_IsEnabled(adc) == 1UL) {
|
||||||
}
|
}
|
||||||
LL_ADC_SetResolution(adc, resolution);
|
LL_ADC_SetResolution(adc, resolution);
|
||||||
LL_ADC_Enable(adc);
|
adc_stm32_enable(adc);
|
||||||
while (LL_ADC_IsActiveFlag_ADRDY(adc) != 1UL) {
|
|
||||||
}
|
|
||||||
#elif !defined(CONFIG_SOC_SERIES_STM32F1X) && \
|
#elif !defined(CONFIG_SOC_SERIES_STM32F1X) && \
|
||||||
!defined(STM32F3X_ADC_V2_5)
|
!defined(STM32F3X_ADC_V2_5)
|
||||||
LL_ADC_SetResolution(adc, resolution);
|
LL_ADC_SetResolution(adc, resolution);
|
||||||
|
@ -530,7 +566,8 @@ static int start_read(const struct device *dev,
|
||||||
LL_ADC_Disable(adc);
|
LL_ADC_Disable(adc);
|
||||||
while (LL_ADC_IsEnabled(adc) == 1UL) {
|
while (LL_ADC_IsEnabled(adc) == 1UL) {
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SOC_SERIES_STM32L0X */
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
#if defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||||
defined(CONFIG_SOC_SERIES_STM32H7X) || \
|
defined(CONFIG_SOC_SERIES_STM32H7X) || \
|
||||||
|
@ -580,11 +617,11 @@ static int start_read(const struct device *dev,
|
||||||
#endif /* CONFIG_SOC_SERIES_STM32H7X */
|
#endif /* CONFIG_SOC_SERIES_STM32H7X */
|
||||||
default:
|
default:
|
||||||
LOG_ERR("Invalid oversampling");
|
LOG_ERR("Invalid oversampling");
|
||||||
LL_ADC_Enable(adc);
|
adc_stm32_enable(adc);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
/* re-enable ADC after changing the OVS */
|
/* re-enable ADC after changing the OVS */
|
||||||
LL_ADC_Enable(adc);
|
adc_stm32_enable(adc);
|
||||||
#else
|
#else
|
||||||
if (sequence->oversampling) {
|
if (sequence->oversampling) {
|
||||||
LOG_ERR("Oversampling not supported");
|
LOG_ERR("Oversampling not supported");
|
||||||
|
@ -606,7 +643,7 @@ static int start_read(const struct device *dev,
|
||||||
}
|
}
|
||||||
adc_stm32_calib(dev);
|
adc_stm32_calib(dev);
|
||||||
/* re-enable ADC after calibration */
|
/* re-enable ADC after calibration */
|
||||||
LL_ADC_Enable(adc);
|
adc_stm32_enable(adc);
|
||||||
#else
|
#else
|
||||||
LOG_ERR("Calibration not supported");
|
LOG_ERR("Calibration not supported");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
|
@ -628,7 +665,7 @@ static int start_read(const struct device *dev,
|
||||||
#elif defined(CONFIG_SOC_SERIES_STM32F1X)
|
#elif defined(CONFIG_SOC_SERIES_STM32F1X)
|
||||||
LL_ADC_EnableIT_EOS(adc);
|
LL_ADC_EnableIT_EOS(adc);
|
||||||
#elif defined(STM32F3X_ADC_V2_5)
|
#elif defined(STM32F3X_ADC_V2_5)
|
||||||
LL_ADC_Enable(adc);
|
adc_stm32_enable(adc);
|
||||||
LL_ADC_EnableIT_EOS(adc);
|
LL_ADC_EnableIT_EOS(adc);
|
||||||
#else
|
#else
|
||||||
LL_ADC_EnableIT_EOCS(adc);
|
LL_ADC_EnableIT_EOCS(adc);
|
||||||
|
@ -975,32 +1012,10 @@ static int adc_stm32_init(const struct device *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LL_ADC_Enable(adc);
|
err = adc_stm32_enable(adc);
|
||||||
|
if (err < 0) {
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
|
return err;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
config->irq_cfg_func();
|
config->irq_cfg_func();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue