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:
parent
56c3c8b2e3
commit
4ed375040e
2 changed files with 64 additions and 12 deletions
|
@ -29,6 +29,7 @@ LOG_MODULE_REGISTER(adc_stm32);
|
|||
#include <pinmux/stm32/pinmux_stm32.h>
|
||||
|
||||
#if !defined(CONFIG_SOC_SERIES_STM32F0X) && \
|
||||
!defined(CONFIG_SOC_SERIES_STM32G0X) && \
|
||||
!defined(CONFIG_SOC_SERIES_STM32L0X)
|
||||
#define RANK(n) LL_ADC_REG_RANK_##n
|
||||
static const uint32_t table_rank[] = {
|
||||
|
@ -148,7 +149,8 @@ static const uint32_t table_samp_time[] = {
|
|||
SMP_TIME(239, S_5),
|
||||
};
|
||||
#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 uint32_t table_samp_time[] = {
|
||||
SMP_TIME(1, _5),
|
||||
|
@ -211,7 +213,9 @@ struct adc_stm32_data {
|
|||
|
||||
uint8_t resolution;
|
||||
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;
|
||||
#endif
|
||||
};
|
||||
|
@ -256,6 +260,7 @@ static void adc_stm32_start_conversion(const struct device *dev)
|
|||
defined(CONFIG_SOC_SERIES_STM32L0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32L4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||
LL_ADC_REG_StartConversion(adc);
|
||||
|
@ -332,6 +337,11 @@ static int start_read(const struct device *dev,
|
|||
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32L0X)
|
||||
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
|
||||
LL_ADC_REG_SetSequencerRanks(adc, table_rank[0], channel);
|
||||
LL_ADC_REG_SetSequencerLength(adc, table_seq_len[0]);
|
||||
|
@ -343,7 +353,21 @@ static int start_read(const struct device *dev,
|
|||
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);
|
||||
#endif
|
||||
|
||||
|
@ -352,6 +376,7 @@ static int start_read(const struct device *dev,
|
|||
defined(CONFIG_SOC_SERIES_STM32L0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32L4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||
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)
|
||||
LL_ADC_SetSamplingTimeCommonChannels(adc,
|
||||
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
|
||||
LL_ADC_SetChannelSamplingTime(adc,
|
||||
__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,
|
||||
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;
|
||||
#endif
|
||||
int acq_time_index;
|
||||
|
@ -482,7 +512,9 @@ static int adc_stm32_channel_setup(const struct device *dev,
|
|||
if (acq_time_index < 0) {
|
||||
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) {
|
||||
data->acq_time_index = acq_time_index;
|
||||
} else {
|
||||
|
@ -533,6 +565,7 @@ static void adc_stm32_calib(const struct device *dev)
|
|||
defined(CONFIG_SOC_SERIES_STM32G4X)
|
||||
LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED);
|
||||
#elif defined(CONFIG_SOC_SERIES_STM32F0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32L0X)
|
||||
LL_ADC_StartCalibration(adc);
|
||||
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||
|
@ -555,12 +588,15 @@ static int adc_stm32_init(const struct device *dev)
|
|||
LOG_DBG("Initializing....");
|
||||
|
||||
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
|
||||
* L0 series chips has to be the same. This additional variable is for
|
||||
* checking if the conversion time selection of all channels on one ADC
|
||||
* instance is the same.
|
||||
* L0 series chips has to be the same. For STM32G0 currently only one
|
||||
* of the two available common channel conversion times is used.
|
||||
* 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;
|
||||
#endif
|
||||
|
@ -591,12 +627,13 @@ static int adc_stm32_init(const struct device *dev)
|
|||
LL_ADC_DisableDeepPowerDown(adc);
|
||||
#endif
|
||||
/*
|
||||
* F3, L4, WB and G4 ADC modules need some time to be stabilized before
|
||||
* performing any enable or calibration actions.
|
||||
* F3, L4, WB, G0 and G4 ADC modules need some time
|
||||
* to be stabilized before performing any enable or calibration actions.
|
||||
*/
|
||||
#if defined(CONFIG_SOC_SERIES_STM32F3X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32L4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||
LL_ADC_EnableInternalRegulator(adc);
|
||||
|
@ -609,6 +646,7 @@ static int adc_stm32_init(const struct device *dev)
|
|||
#elif defined(CONFIG_SOC_SERIES_STM32F3X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32L4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||
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_STM32L4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||
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_STM32L4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||
/*
|
||||
|
@ -677,10 +717,11 @@ static int adc_stm32_init(const struct device *dev)
|
|||
|
||||
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32WBX) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||
defined(CONFIG_SOC_SERIES_STM32G4X) || \
|
||||
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
|
||||
* modules are properly enabled.
|
||||
*/
|
||||
|
|
|
@ -230,6 +230,17 @@
|
|||
status = "disabled";
|
||||
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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue