drivers: adc: STM32: add support for oversampling

The STM32 G0, G4, H7, L0, L4, WB and WL series have hardware support for
oversampling. This patch adds support for it, using the oversampling
value provided in the adc sequence. The result is shifted right
accordingly to not change the resolution of the measured value, like it
is done on other ADC drivers.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Aurelien Jarno 2021-07-04 14:09:42 +02:00 committed by Christopher Friedt
parent 0d42e75666
commit 58b8c4006e

View file

@ -428,6 +428,68 @@ static int start_read(const struct device *dev,
LL_ADC_SetResolution(adc, resolution);
#endif
#if defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32G4X) || \
defined(CONFIG_SOC_SERIES_STM32H7X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32WLX)
switch (sequence->oversampling) {
case 0:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_DISABLE);
break;
case 1:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_2,
LL_ADC_OVS_SHIFT_RIGHT_1);
break;
case 2:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_4,
LL_ADC_OVS_SHIFT_RIGHT_2);
break;
case 3:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_8,
LL_ADC_OVS_SHIFT_RIGHT_3);
break;
case 4:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_16,
LL_ADC_OVS_SHIFT_RIGHT_4);
break;
case 5:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_32,
LL_ADC_OVS_SHIFT_RIGHT_5);
break;
case 6:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_64,
LL_ADC_OVS_SHIFT_RIGHT_6);
break;
case 7:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_128,
LL_ADC_OVS_SHIFT_RIGHT_7);
break;
case 8:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_256,
LL_ADC_OVS_SHIFT_RIGHT_8);
break;
default:
LOG_ERR("Invalid oversampling");
return -EINVAL;
}
#else
if (sequence->oversampling) {
LOG_ERR("Oversampling not supported");
return -ENOTSUP;
}
#endif
if (sequence->calibrate) {
#if !defined(CONFIG_SOC_SERIES_STM32F2X) && \
!defined(CONFIG_SOC_SERIES_STM32F4X) && \