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>
|
#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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue