drivers: adc: stm32: add support for stm32g0 series

Adds support for ADC on G0 series.
Simple implementation: sequencer not fully configurable,
and only one common sampling time.

Signed-off-by: Thomas Stranger <thomas.stranger@outlook.com>
This commit is contained in:
Thomas Stranger 2020-12-21 03:00:00 +01:00 committed by Maureen Helm
commit 4ed375040e
2 changed files with 64 additions and 12 deletions

View file

@ -29,6 +29,7 @@ LOG_MODULE_REGISTER(adc_stm32);
#include <pinmux/stm32/pinmux_stm32.h> #include <pinmux/stm32/pinmux_stm32.h>
#if !defined(CONFIG_SOC_SERIES_STM32F0X) && \ #if !defined(CONFIG_SOC_SERIES_STM32F0X) && \
!defined(CONFIG_SOC_SERIES_STM32G0X) && \
!defined(CONFIG_SOC_SERIES_STM32L0X) !defined(CONFIG_SOC_SERIES_STM32L0X)
#define RANK(n) LL_ADC_REG_RANK_##n #define RANK(n) LL_ADC_REG_RANK_##n
static const uint32_t table_rank[] = { static const uint32_t table_rank[] = {
@ -148,7 +149,8 @@ static const uint32_t table_samp_time[] = {
SMP_TIME(239, S_5), SMP_TIME(239, S_5),
}; };
#endif /* ADC5_V1_1 */ #endif /* ADC5_V1_1 */
#elif defined(CONFIG_SOC_SERIES_STM32L0X) #elif defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X)
static const uint16_t acq_time_tbl[8] = {2, 4, 8, 13, 20, 40, 80, 161}; static const uint16_t acq_time_tbl[8] = {2, 4, 8, 13, 20, 40, 80, 161};
static const uint32_t table_samp_time[] = { static const uint32_t table_samp_time[] = {
SMP_TIME(1, _5), SMP_TIME(1, _5),
@ -211,7 +213,9 @@ struct adc_stm32_data {
uint8_t resolution; uint8_t resolution;
uint8_t channel_count; uint8_t channel_count;
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X) #if defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X)
int8_t acq_time_index; int8_t acq_time_index;
#endif #endif
}; };
@ -256,6 +260,7 @@ static void adc_stm32_start_conversion(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_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
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)
LL_ADC_REG_StartConversion(adc); LL_ADC_REG_StartConversion(adc);
@ -332,6 +337,11 @@ static int start_read(const struct device *dev,
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \ #if defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) defined(CONFIG_SOC_SERIES_STM32L0X)
LL_ADC_REG_SetSequencerChannels(adc, channel); LL_ADC_REG_SetSequencerChannels(adc, channel);
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
/* STM32G0 in "not fully configurable" sequencer mode */
LL_ADC_REG_SetSequencerChannels(adc, channel);
while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) {
}
#else #else
LL_ADC_REG_SetSequencerRanks(adc, table_rank[0], channel); LL_ADC_REG_SetSequencerRanks(adc, table_rank[0], channel);
LL_ADC_REG_SetSequencerLength(adc, table_seq_len[0]); LL_ADC_REG_SetSequencerLength(adc, table_seq_len[0]);
@ -343,7 +353,21 @@ static int start_read(const struct device *dev,
return err; return err;
} }
#if !defined(CONFIG_SOC_SERIES_STM32F1X) #if defined(CONFIG_SOC_SERIES_STM32G0X)
/*
* Errata: Writing ADC_CFGR1 register while ADEN bit is set
* resets RES[1:0] bitfield. We need to disable and enable adc.
*/
if (LL_ADC_IsEnabled(adc) == 1UL) {
LL_ADC_Disable(adc);
}
while (LL_ADC_IsEnabled(adc) == 1UL) {
}
LL_ADC_SetResolution(adc, resolution);
LL_ADC_Enable(adc);
while (LL_ADC_IsActiveFlag_ADRDY(adc) != 1UL) {
}
#elif !defined(CONFIG_SOC_SERIES_STM32F1X)
LL_ADC_SetResolution(adc, resolution); LL_ADC_SetResolution(adc, resolution);
#endif #endif
@ -352,6 +376,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_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
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)
LL_ADC_EnableIT_EOC(adc); LL_ADC_EnableIT_EOC(adc);
@ -457,6 +482,9 @@ static void adc_stm32_setup_speed(const struct device *dev, uint8_t id,
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X) #if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X)
LL_ADC_SetSamplingTimeCommonChannels(adc, LL_ADC_SetSamplingTimeCommonChannels(adc,
table_samp_time[acq_time_index]); table_samp_time[acq_time_index]);
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
LL_ADC_SetSamplingTimeCommonChannels(adc, LL_ADC_SAMPLINGTIME_COMMON_1,
table_samp_time[acq_time_index]);
#else #else
LL_ADC_SetChannelSamplingTime(adc, LL_ADC_SetChannelSamplingTime(adc,
__LL_ADC_DECIMAL_NB_TO_CHANNEL(id), __LL_ADC_DECIMAL_NB_TO_CHANNEL(id),
@ -467,7 +495,9 @@ static void adc_stm32_setup_speed(const struct device *dev, uint8_t id,
static int adc_stm32_channel_setup(const struct device *dev, static int adc_stm32_channel_setup(const struct device *dev,
const struct adc_channel_cfg *channel_cfg) const struct adc_channel_cfg *channel_cfg)
{ {
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X) #if defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X)
struct adc_stm32_data *data = dev->data; struct adc_stm32_data *data = dev->data;
#endif #endif
int acq_time_index; int acq_time_index;
@ -482,7 +512,9 @@ static int adc_stm32_channel_setup(const struct device *dev,
if (acq_time_index < 0) { if (acq_time_index < 0) {
return acq_time_index; return acq_time_index;
} }
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X) #if defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X)
if (data->acq_time_index == -1) { if (data->acq_time_index == -1) {
data->acq_time_index = acq_time_index; data->acq_time_index = acq_time_index;
} else { } else {
@ -533,6 +565,7 @@ static void adc_stm32_calib(const struct device *dev)
defined(CONFIG_SOC_SERIES_STM32G4X) defined(CONFIG_SOC_SERIES_STM32G4X)
LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED); LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED);
#elif defined(CONFIG_SOC_SERIES_STM32F0X) || \ #elif defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) defined(CONFIG_SOC_SERIES_STM32L0X)
LL_ADC_StartCalibration(adc); LL_ADC_StartCalibration(adc);
#elif defined(CONFIG_SOC_SERIES_STM32H7X) #elif defined(CONFIG_SOC_SERIES_STM32H7X)
@ -555,12 +588,15 @@ static int adc_stm32_init(const struct device *dev)
LOG_DBG("Initializing...."); LOG_DBG("Initializing....");
data->dev = dev; data->dev = dev;
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X) #if defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X)
/* /*
* All conversion time for all channels on one ADC instance for F0 and * All conversion time for all channels on one ADC instance for F0 and
* L0 series chips has to be the same. This additional variable is for * L0 series chips has to be the same. For STM32G0 currently only one
* checking if the conversion time selection of all channels on one ADC * of the two available common channel conversion times is used.
* instance is the same. * This additional variable is for checking if the conversion time
* selection of all channels on one ADC instance is the same.
*/ */
data->acq_time_index = -1; data->acq_time_index = -1;
#endif #endif
@ -591,12 +627,13 @@ static int adc_stm32_init(const struct device *dev)
LL_ADC_DisableDeepPowerDown(adc); LL_ADC_DisableDeepPowerDown(adc);
#endif #endif
/* /*
* F3, L4, WB and G4 ADC modules need some time to be stabilized before * F3, L4, WB, G0 and G4 ADC modules need some time
* performing any enable or calibration actions. * to be stabilized before performing any enable or calibration actions.
*/ */
#if defined(CONFIG_SOC_SERIES_STM32F3X) || \ #if defined(CONFIG_SOC_SERIES_STM32F3X) || \
defined(CONFIG_SOC_SERIES_STM32L4X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
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)
LL_ADC_EnableInternalRegulator(adc); LL_ADC_EnableInternalRegulator(adc);
@ -609,6 +646,7 @@ static int adc_stm32_init(const struct device *dev)
#elif defined(CONFIG_SOC_SERIES_STM32F3X) || \ #elif defined(CONFIG_SOC_SERIES_STM32F3X) || \
defined(CONFIG_SOC_SERIES_STM32L4X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
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)
LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc), LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(adc),
@ -634,6 +672,7 @@ static int adc_stm32_init(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_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
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)
if (LL_ADC_IsActiveFlag_ADRDY(adc)) { if (LL_ADC_IsActiveFlag_ADRDY(adc)) {
@ -653,6 +692,7 @@ static int adc_stm32_init(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_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
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)
/* /*
@ -677,10 +717,11 @@ static int adc_stm32_init(const struct device *dev)
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \ #if defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \ defined(CONFIG_SOC_SERIES_STM32WBX) || \
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)
/* /*
* Enabling ADC modules in L4, WB and G4 series may fail if they are * 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 * still not stabilized, this will wait for a short time to ensure ADC
* modules are properly enabled. * modules are properly enabled.
*/ */

View file

@ -230,6 +230,17 @@
status = "disabled"; status = "disabled";
label = "SPI_2"; label = "SPI_2";
}; };
adc1: adc@40012400 {
compatible = "st,stm32-adc";
reg = <0x40012400 0x400>;
clocks = <&rcc STM32_CLOCK_BUS_APB2 0x00100000>;
interrupts = <12 0>;
interrupt-names = "combined";
status = "disabled";
label = "ADC_1";
#io-channel-cells = <1>;
};
}; };
}; };