drivers: adc: stm32h7 adc driver has a different oversampling ratio

The adc_stm32_oversampling function is used to configure
the ratio and shift for each sequence->oversampling
depending on the soc serie and ADC instance in the serie
In the stm32H7 serie, only ADC3 of ADC_VER_V5_V90 version
have a LL_ADC_OVS_RATIO_x contant (other a 9bit value).

Signed-off-by: Francois Ramu <francois.ramu@st.com>
This commit is contained in:
Francois Ramu 2021-09-17 11:39:52 +02:00 committed by Christopher Friedt
commit 0af4a393ee

View file

@ -319,6 +319,60 @@ static void adc_stm32_calib(const struct device *dev)
}
#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_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32WLX)
#ifdef LL_ADC_OVS_RATIO_2
/* table for shifting oversampling mostly for ADC3 != ADC_VER_V5_V90 */
static const uint32_t stm32_adc_ratio_table[] = {
0,
LL_ADC_OVS_RATIO_2,
LL_ADC_OVS_RATIO_4,
LL_ADC_OVS_RATIO_8,
LL_ADC_OVS_RATIO_16,
LL_ADC_OVS_RATIO_32,
LL_ADC_OVS_RATIO_64,
LL_ADC_OVS_RATIO_128,
LL_ADC_OVS_RATIO_256,
};
#endif /* ! ADC_VER_V5_V90 */
/*
* Function to configure the oversampling ratio and shit using stm32 LL
* ratio is directly the sequence->oversampling (a 2^n value)
* shift is the corresponding LL_ADC_OVS_SHIFT_RIGHT_x constant
*/
static void adc_stm32_oversampling(ADC_TypeDef *adc, uint8_t ratio, uint32_t shift)
{
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
/*
* Set bits manually to circumvent bug in LL Libraries
* https://github.com/STMicroelectronics/STM32CubeH7/issues/177
*/
#if defined(ADC_VER_V5_V90)
if (adc == ADC3) {
MODIFY_REG(adc->CFGR2, (ADC_CFGR2_OVSS | ADC3_CFGR2_OVSR),
(shift | stm32_adc_ratio_table[ratio]));
} else {
MODIFY_REG(adc->CFGR2, (ADC_CFGR2_OVSS | ADC_CFGR2_OVSR),
(shift | (((1UL << ratio) - 1) << ADC_CFGR2_OVSR_Pos)));
}
#endif /* ADC_VER_V5_V90*/
MODIFY_REG(adc->CFGR2, (ADC_CFGR2_OVSS | ADC_CFGR2_OVSR),
(shift | (((1UL << ratio) - 1) << ADC_CFGR2_OVSR_Pos)));
#else /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_ConfigOverSamplingRatioShift(adc, stm32_adc_ratio_table[ratio], shift);
#endif /* CONFIG_SOC_SERIES_STM32H7X */
}
#endif /* CONFIG_SOC_SERIES_STM32xxx */
static int start_read(const struct device *dev,
const struct adc_sequence *sequence)
{
@ -450,76 +504,28 @@ static int start_read(const struct device *dev,
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_DISABLE);
break;
case 1:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_2,
#endif /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_OVS_SHIFT_RIGHT_1);
adc_stm32_oversampling(adc, 1, LL_ADC_OVS_SHIFT_RIGHT_1);
break;
case 2:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_4,
#endif /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_OVS_SHIFT_RIGHT_2);
adc_stm32_oversampling(adc, 2, LL_ADC_OVS_SHIFT_RIGHT_2);
break;
case 3:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_8,
#endif /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_OVS_SHIFT_RIGHT_3);
adc_stm32_oversampling(adc, 3, LL_ADC_OVS_SHIFT_RIGHT_3);
break;
case 4:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_16,
#endif /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_OVS_SHIFT_RIGHT_4);
adc_stm32_oversampling(adc, 4, LL_ADC_OVS_SHIFT_RIGHT_4);
break;
case 5:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_32,
#endif /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_OVS_SHIFT_RIGHT_5);
adc_stm32_oversampling(adc, 5, LL_ADC_OVS_SHIFT_RIGHT_5);
break;
case 6:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_64,
#endif /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_OVS_SHIFT_RIGHT_6);
adc_stm32_oversampling(adc, 6, LL_ADC_OVS_SHIFT_RIGHT_6);
break;
case 7:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_128,
#endif /* CONFIG_SOC_SERIES_STM32H7X */
LL_ADC_OVS_SHIFT_RIGHT_7);
adc_stm32_oversampling(adc, 7, LL_ADC_OVS_SHIFT_RIGHT_7);
break;
case 8:
LL_ADC_SetOverSamplingScope(adc, LL_ADC_OVS_GRP_REGULAR_CONTINUED);
#if defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_ConfigOverSamplingRatioShift(adc, sequence->oversampling,
#else
LL_ADC_ConfigOverSamplingRatioShift(adc, LL_ADC_OVS_RATIO_256,
#endif
LL_ADC_OVS_SHIFT_RIGHT_8);
adc_stm32_oversampling(adc, 8, LL_ADC_OVS_SHIFT_RIGHT_8);
break;
default:
LOG_ERR("Invalid oversampling");