drivers/adc: stm32: do not disable the ADC if resolution is unchanged
In case the resolution is already correct (probably the common use case), do nothing instead of disabling the ADC. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
897554bd39
commit
c57a41c5d2
1 changed files with 69 additions and 34 deletions
|
|
@ -344,6 +344,20 @@ static void adc_stm32_calib(const struct device *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable ADC peripheral, and wait until it is disabled
|
||||||
|
*/
|
||||||
|
static inline void adc_stm32_disable(ADC_TypeDef *adc)
|
||||||
|
{
|
||||||
|
if (LL_ADC_IsEnabled(adc) != 1UL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LL_ADC_Disable(adc);
|
||||||
|
while (LL_ADC_IsEnabled(adc) == 1UL) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#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) || \
|
||||||
|
|
@ -369,6 +383,48 @@ static void adc_stm32_calib(const struct device *dev)
|
||||||
};
|
};
|
||||||
#endif /* ! ADC_VER_V5_V90 */
|
#endif /* ! ADC_VER_V5_V90 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to configure the oversampling scope. It is basically a wrapper over
|
||||||
|
* LL_ADC_SetOverSamplingScope() which in addition stops the ADC if needed.
|
||||||
|
*/
|
||||||
|
static void adc_stm32_oversampling_scope(ADC_TypeDef *adc, uint32_t ovs_scope)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_SOC_SERIES_STM32L0X) || \
|
||||||
|
defined(CONFIG_SOC_SERIES_STM32WLX)
|
||||||
|
/*
|
||||||
|
* setting OVS bits is conditioned to ADC state: ADC must be disabled
|
||||||
|
* or enabled without conversion on going : disable it, it will stop
|
||||||
|
*/
|
||||||
|
if (LL_ADC_GetOverSamplingScope(adc) == ovs_scope) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adc_stm32_disable(adc);
|
||||||
|
#endif
|
||||||
|
LL_ADC_SetOverSamplingScope(adc, ovs_scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function to configure the oversampling ratio and shift. It is basically a
|
||||||
|
* wrapper over LL_ADC_SetOverSamplingRatioShift() which in addition stops the
|
||||||
|
* ADC if needed.
|
||||||
|
*/
|
||||||
|
static void adc_stm32_oversampling_ratioshift(ADC_TypeDef *adc, uint32_t ratio, uint32_t shift)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_SOC_SERIES_STM32L0X) || \
|
||||||
|
defined(CONFIG_SOC_SERIES_STM32WLX)
|
||||||
|
/*
|
||||||
|
* setting OVS bits is conditioned to ADC state: ADC must be disabled
|
||||||
|
* or enabled without conversion on going : disable it, it will stop
|
||||||
|
*/
|
||||||
|
if ((LL_ADC_GetOverSamplingRatio(adc) == ratio)
|
||||||
|
&& (LL_ADC_GetOverSamplingShift(adc) == shift)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
adc_stm32_disable(adc);
|
||||||
|
#endif
|
||||||
|
LL_ADC_ConfigOverSamplingRatioShift(adc, ratio, shift);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function to configure the oversampling ratio and shit using stm32 LL
|
* Function to configure the oversampling ratio and shit using stm32 LL
|
||||||
* ratio is directly the sequence->oversampling (a 2^n value)
|
* ratio is directly the sequence->oversampling (a 2^n value)
|
||||||
|
|
@ -376,7 +432,7 @@ static void adc_stm32_calib(const struct device *dev)
|
||||||
*/
|
*/
|
||||||
static void adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio, uint32_t shift)
|
static void adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio, uint32_t shift)
|
||||||
{
|
{
|
||||||
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
|
adc_stm32_oversampling_scope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32H7X)
|
#if defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||||
/*
|
/*
|
||||||
* Set bits manually to circumvent bug in LL Libraries
|
* Set bits manually to circumvent bug in LL Libraries
|
||||||
|
|
@ -396,13 +452,13 @@ static void adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio, uint32_t shi
|
||||||
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
|
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
|
||||||
if (adc == ADC1) {
|
if (adc == ADC1) {
|
||||||
/* the LL function expects a value from 1 to 1024 */
|
/* the LL function expects a value from 1 to 1024 */
|
||||||
LL_ADC_ConfigOverSamplingRatioShift(adc, (1 << ratio), shift);
|
adc_stm32_oversampling_ratioshift(adc, (1 << ratio), shift);
|
||||||
} else {
|
} else {
|
||||||
/* the LL function expects a value LL_ADC_OVS_RATIO_x */
|
/* the LL function expects a value LL_ADC_OVS_RATIO_x */
|
||||||
LL_ADC_ConfigOverSamplingRatioShift(adc, stm32_adc_ratio_table[ratio], shift);
|
adc_stm32_oversampling_ratioshift(adc, stm32_adc_ratio_table[ratio], shift);
|
||||||
}
|
}
|
||||||
#else /* CONFIG_SOC_SERIES_STM32H7X */
|
#else /* CONFIG_SOC_SERIES_STM32H7X */
|
||||||
LL_ADC_ConfigOverSamplingRatioShift(adc, stm32_adc_ratio_table[ratio], shift);
|
adc_stm32_oversampling_ratioshift(adc, stm32_adc_ratio_table[ratio], shift);
|
||||||
#endif /* CONFIG_SOC_SERIES_STM32H7X */
|
#endif /* CONFIG_SOC_SERIES_STM32H7X */
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SOC_SERIES_STM32xxx */
|
#endif /* CONFIG_SOC_SERIES_STM32xxx */
|
||||||
|
|
@ -450,20 +506,6 @@ static int adc_stm32_enable(ADC_TypeDef *adc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Disable ADC peripheral, and wait until it is disabled
|
|
||||||
*/
|
|
||||||
static inline void adc_stm32_disable(ADC_TypeDef *adc)
|
|
||||||
{
|
|
||||||
if (LL_ADC_IsEnabled(adc) != 1UL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LL_ADC_Disable(adc);
|
|
||||||
while (LL_ADC_IsEnabled(adc) == 1UL) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
@ -560,26 +602,19 @@ static int start_read(const struct device *dev,
|
||||||
|
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
#if defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||||
defined(CONFIG_SOC_SERIES_STM32WLX)
|
defined(CONFIG_SOC_SERIES_STM32WLX)
|
||||||
/*
|
if (LL_ADC_GetResolution(adc) != resolution) {
|
||||||
* Writing ADC_CFGR1 register while ADEN bit is set
|
/*
|
||||||
* resets RES[1:0] bitfield. We need to disable and enable adc.
|
* Writing ADC_CFGR1 register while ADEN bit is set
|
||||||
*/
|
* resets RES[1:0] bitfield. We need to disable and enable adc.
|
||||||
adc_stm32_disable(adc);
|
*/
|
||||||
LL_ADC_SetResolution(adc, resolution);
|
adc_stm32_disable(adc);
|
||||||
|
LL_ADC_SetResolution(adc, resolution);
|
||||||
|
}
|
||||||
#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);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32L0X) || \
|
|
||||||
defined(CONFIG_SOC_SERIES_STM32WLX)
|
|
||||||
/*
|
|
||||||
* setting OVS bits is conditioned to ADC state: ADC must be disabled
|
|
||||||
* or enabled without conversion on going : disable it, it will stop
|
|
||||||
*/
|
|
||||||
adc_stm32_disable(adc);
|
|
||||||
#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) || \
|
||||||
|
|
@ -592,7 +627,7 @@ static int start_read(const struct device *dev,
|
||||||
|
|
||||||
switch (sequence->oversampling) {
|
switch (sequence->oversampling) {
|
||||||
case 0:
|
case 0:
|
||||||
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_DISABLE);
|
adc_stm32_oversampling_scope(adc, LL_ADC_OVS_DISABLE);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
adc_stm32_oversampling(adc, 1, LL_ADC_OVS_SHIFT_RIGHT_1);
|
adc_stm32_oversampling(adc, 1, LL_ADC_OVS_SHIFT_RIGHT_1);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue