drivers: adc: add the stm32U5 devices to the adc driver

The STM32U5x device has ADC instance of different versions
similar to the stm32H7 about the oversampling.
ADC1 of 14bit resolution has a ratio from 1..1024 on OSR[9:0]
ADC4 of 12bit resolution has a ratio on OVSR[2:0]

Signed-off-by: Francois Ramu <francois.ramu@st.com>
This commit is contained in:
Francois Ramu 2021-10-05 18:21:29 +02:00 committed by Maureen Helm
commit 2185863d3b

View file

@ -17,6 +17,9 @@
#include <init.h> #include <init.h>
#include <soc.h> #include <soc.h>
#include <stm32_ll_adc.h> #include <stm32_ll_adc.h>
#if defined(CONFIG_SOC_SERIES_STM32U5X)
#include <stm32_ll_pwr.h>
#endif /* CONFIG_SOC_SERIES_STM32U5X */
#define ADC_CONTEXT_USES_KERNEL_TIMER #define ADC_CONTEXT_USES_KERNEL_TIMER
#include "adc_context.h" #include "adc_context.h"
@ -91,6 +94,9 @@ static const uint32_t table_resolution[] = {
RES(8), RES(8),
RES(10), RES(10),
RES(12), RES(12),
#if defined(CONFIG_SOC_SERIES_STM32U5X)
RES(14),
#endif /* CONFIG_SOC_SERIES_STM32U5X */
#else #else
RES(8), RES(8),
RES(10), RES(10),
@ -212,6 +218,18 @@ static const uint32_t table_samp_time[] = {
SMP_TIME(387, S_5), SMP_TIME(387, S_5),
SMP_TIME(810, S_5), SMP_TIME(810, S_5),
}; };
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
static const uint16_t acq_time_tbl[8] = {5, 6, 12, 20, 36, 68, 391, 814};
static const uint32_t table_samp_time[] = {
SMP_TIME(5,),
SMP_TIME(6, S),
SMP_TIME(12, S),
SMP_TIME(20, S),
SMP_TIME(36, S),
SMP_TIME(68, S),
SMP_TIME(391, S_5),
SMP_TIME(814, S),
};
#endif #endif
/* Bugfix for STM32G4 HAL */ /* Bugfix for STM32G4 HAL */
@ -281,6 +299,7 @@ static void adc_stm32_start_conversion(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32G0X) || \ 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) || \
defined(CONFIG_SOC_SERIES_STM32U5X) || \
defined(CONFIG_SOC_SERIES_STM32WLX) defined(CONFIG_SOC_SERIES_STM32WLX)
LL_ADC_REG_StartConversion(adc); LL_ADC_REG_StartConversion(adc);
#else #else
@ -311,6 +330,8 @@ static void adc_stm32_calib(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32L0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32WLX) defined(CONFIG_SOC_SERIES_STM32WLX)
LL_ADC_StartCalibration(adc); LL_ADC_StartCalibration(adc);
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET);
#elif defined(CONFIG_SOC_SERIES_STM32H7X) #elif defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET, LL_ADC_SINGLE_ENDED); LL_ADC_StartCalibration(adc, LL_ADC_CALIB_OFFSET, LL_ADC_SINGLE_ENDED);
#endif #endif
@ -410,6 +431,11 @@ static int start_read(const struct device *dev,
case 12: case 12:
resolution = table_resolution[3]; resolution = table_resolution[3];
break; break;
#if defined(CONFIG_SOC_SERIES_STM32U5X)
case 14:
resolution = table_resolution[4];
break;
#endif /* CONFIG_SOC_SERIES_STM32U5X */
#else #else
case 8: case 8:
resolution = table_resolution[0]; resolution = table_resolution[0];
@ -505,6 +531,7 @@ static int start_read(const struct device *dev,
defined(CONFIG_SOC_SERIES_STM32L0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32L4X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32L5X) || \ defined(CONFIG_SOC_SERIES_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32U5X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32WLX) defined(CONFIG_SOC_SERIES_STM32WLX)
@ -536,8 +563,8 @@ static int start_read(const struct device *dev,
case 8: case 8:
adc_stm32_oversampling(adc, 8, LL_ADC_OVS_SHIFT_RIGHT_8); adc_stm32_oversampling(adc, 8, LL_ADC_OVS_SHIFT_RIGHT_8);
break; break;
#if defined(CONFIG_SOC_SERIES_STM32H7X) #if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32U5X)
/* stm32 H7 ADC1 & 2 have oversampling ratio from 1..1024 */ /* stm32 U5, H7 ADC1 & 2 have oversampling ratio from 1..1024 */
case 9: case 9:
adc_stm32_oversampling(adc, 9, LL_ADC_OVS_SHIFT_RIGHT_9); adc_stm32_oversampling(adc, 9, LL_ADC_OVS_SHIFT_RIGHT_9);
break; break;
@ -582,6 +609,7 @@ static int start_read(const struct device *dev,
defined(CONFIG_SOC_SERIES_STM32G0X) || \ 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) || \
defined(CONFIG_SOC_SERIES_STM32U5X) || \
defined(CONFIG_SOC_SERIES_STM32WLX) defined(CONFIG_SOC_SERIES_STM32WLX)
LL_ADC_EnableIT_EOC(adc); LL_ADC_EnableIT_EOC(adc);
#elif defined(CONFIG_SOC_SERIES_STM32F1X) #elif defined(CONFIG_SOC_SERIES_STM32F1X)
@ -817,14 +845,19 @@ static int adc_stm32_init(const struct device *dev)
LOG_ERR("ADC pinctrl setup failed (%d)", err); LOG_ERR("ADC pinctrl setup failed (%d)", err);
return err; return err;
} }
#if defined(CONFIG_SOC_SERIES_STM32U5X)
/* Enable the independent analog supply */
LL_PWR_EnableVDDA();
#endif /* CONFIG_SOC_SERIES_STM32U5X */
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \ #if defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32L5X) || \ defined(CONFIG_SOC_SERIES_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32G4X) || \ defined(CONFIG_SOC_SERIES_STM32G4X) || \
defined(CONFIG_SOC_SERIES_STM32H7X) defined(CONFIG_SOC_SERIES_STM32H7X) || \
defined(CONFIG_SOC_SERIES_STM32U5X)
/* /*
* L4, WB, G4 and H7 series STM32 needs to be awaken from deep sleep * L4, WB, G4, H7 and U5 series STM32 needs to be awaken from deep sleep
* mode, and restore its calibration parameters if there are some * mode, and restore its calibration parameters if there are some
* previously stored calibration parameters. * previously stored calibration parameters.
*/ */
@ -842,6 +875,7 @@ static int adc_stm32_init(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32G0X) || \ 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) || \
defined(CONFIG_SOC_SERIES_STM32U5X) || \
defined(CONFIG_SOC_SERIES_STM32WLX) defined(CONFIG_SOC_SERIES_STM32WLX)
LL_ADC_EnableInternalRegulator(adc); LL_ADC_EnableInternalRegulator(adc);
k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US);
@ -860,7 +894,8 @@ static int adc_stm32_init(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32H7X) defined(CONFIG_SOC_SERIES_STM32H7X)
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc), LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
LL_ADC_CLOCK_SYNC_PCLK_DIV4); LL_ADC_CLOCK_SYNC_PCLK_DIV4);
#elif defined(CONFIG_SOC_SERIES_STM32L1X) #elif defined(CONFIG_SOC_SERIES_STM32L1X) || \
defined(CONFIG_SOC_SERIES_STM32U5X)
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc), LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
LL_ADC_CLOCK_ASYNC_DIV4); LL_ADC_CLOCK_ASYNC_DIV4);
#endif #endif
@ -886,6 +921,7 @@ static int adc_stm32_init(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32G0X) || \ 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) || \
defined(CONFIG_SOC_SERIES_STM32U5X) || \
defined(CONFIG_SOC_SERIES_STM32WLX) defined(CONFIG_SOC_SERIES_STM32WLX)
if (LL_ADC_IsActiveFlag_ADRDY(adc)) { if (LL_ADC_IsActiveFlag_ADRDY(adc)) {
LL_ADC_ClearFlag_ADRDY(adc); LL_ADC_ClearFlag_ADRDY(adc);
@ -908,6 +944,7 @@ static int adc_stm32_init(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32G0X) || \ 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) || \
defined(CONFIG_SOC_SERIES_STM32U5X) || \
defined(CONFIG_SOC_SERIES_STM32WLX) defined(CONFIG_SOC_SERIES_STM32WLX)
/* /*
* ADC modules on these series have to wait for some cycles to be * ADC modules on these series have to wait for some cycles to be