drivers: adc: use dts properties for stm32 adc sampling time

Use the new dts properties for sampling time in the STM32 ADC driver:
- Get the sampling time from dts
- Remove all sampling time macro concatenation.
- Simplify/refactor setting of sampling time
- Check that sampling time is the same for all series using common channel

This also fixes a few cases where wrong sampling times were used for an
ADC instance (like ADC4 on U5, or ADC3 on STM32H723).

Signed-off-by: Guillaume Gautier <guillaume.gautier-ext@st.com>
This commit is contained in:
Guillaume Gautier 2023-04-20 17:12:06 +02:00 committed by Fabio Baltieri
parent aa2933b42f
commit a7b8a5d61f

View file

@ -51,6 +51,14 @@ LOG_MODULE_REGISTER(adc_stm32);
#endif
#endif
#define ANY_NUM_COMMON_SAMPLING_TIME_CHANNELS_IS(value) \
(DT_INST_FOREACH_STATUS_OKAY_VARGS(IS_EQ_PROP_OR, \
num_sampling_time_common_channels,\
0, value) 0)
#define IS_EQ_PROP_OR(inst, prop, default_value, compare_value) \
IS_EQ(DT_INST_PROP_OR(inst, prop, default_value), compare_value) ||
/* reference voltage for the ADC */
#define STM32_ADC_VREF_MV DT_INST_PROP(0, vref_mv)
@ -101,137 +109,12 @@ static const uint32_t table_seq_len[] = {
};
#endif
#define SMP_TIME(x, y) LL_ADC_SAMPLINGTIME_##x##CYCLE##y
/*
* Conversion time in ADC cycles. Many values should have been 0.5 less,
* but the adc api system currently does not support describing 'half cycles'.
* So all half cycles are counted as one.
*/
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32F1X)
static const uint16_t acq_time_tbl[8] = {2, 8, 14, 29, 42, 56, 72, 240};
static const uint32_t table_samp_time[] = {
SMP_TIME(1, _5),
SMP_TIME(7, S_5),
SMP_TIME(13, S_5),
SMP_TIME(28, S_5),
SMP_TIME(41, S_5),
SMP_TIME(55, S_5),
SMP_TIME(71, S_5),
SMP_TIME(239, S_5),
};
#elif defined(CONFIG_SOC_SERIES_STM32F2X) || \
defined(CONFIG_SOC_SERIES_STM32F4X) || \
defined(CONFIG_SOC_SERIES_STM32F7X)
static const uint16_t acq_time_tbl[8] = {3, 15, 28, 56, 84, 112, 144, 480};
static const uint32_t table_samp_time[] = {
SMP_TIME(3, S),
SMP_TIME(15, S),
SMP_TIME(28, S),
SMP_TIME(56, S),
SMP_TIME(84, S),
SMP_TIME(112, S),
SMP_TIME(144, S),
SMP_TIME(480, S),
};
#elif defined(CONFIG_SOC_SERIES_STM32F3X)
#ifdef ADC5_V1_1
static const uint16_t acq_time_tbl[8] = {2, 3, 5, 8, 20, 62, 182, 602};
static const uint32_t table_samp_time[] = {
SMP_TIME(1, _5),
SMP_TIME(2, S_5),
SMP_TIME(4, S_5),
SMP_TIME(7, S_5),
SMP_TIME(19, S_5),
SMP_TIME(61, S_5),
SMP_TIME(181, S_5),
SMP_TIME(601, S_5),
};
#else
static const uint16_t acq_time_tbl[8] = {2, 8, 14, 29, 42, 56, 72, 240};
static const uint32_t table_samp_time[] = {
SMP_TIME(1, _5),
SMP_TIME(7, S_5),
SMP_TIME(13, S_5),
SMP_TIME(28, S_5),
SMP_TIME(41, S_5),
SMP_TIME(55, S_5),
SMP_TIME(71, S_5),
SMP_TIME(239, S_5),
};
#endif /* ADC5_V1_1 */
#elif defined(CONFIG_SOC_SERIES_STM32C0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32WLX)
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),
SMP_TIME(3, S_5),
SMP_TIME(7, S_5),
SMP_TIME(12, S_5),
SMP_TIME(19, S_5),
SMP_TIME(39, S_5),
SMP_TIME(79, S_5),
SMP_TIME(160, S_5),
};
#elif defined(CONFIG_SOC_SERIES_STM32L4X) || \
defined(CONFIG_SOC_SERIES_STM32L5X) || \
defined(CONFIG_SOC_SERIES_STM32H5X) || \
defined(CONFIG_SOC_SERIES_STM32WBX) || \
defined(CONFIG_SOC_SERIES_STM32G4X)
static const uint16_t acq_time_tbl[8] = {3, 7, 13, 25, 48, 93, 248, 641};
static const uint32_t table_samp_time[] = {
SMP_TIME(2, S_5),
SMP_TIME(6, S_5),
SMP_TIME(12, S_5),
SMP_TIME(24, S_5),
SMP_TIME(47, S_5),
SMP_TIME(92, S_5),
SMP_TIME(247, S_5),
SMP_TIME(640, S_5),
};
#elif defined(CONFIG_SOC_SERIES_STM32L1X)
static const uint16_t acq_time_tbl[8] = {5, 10, 17, 25, 49, 97, 193, 385};
static const uint32_t table_samp_time[] = {
SMP_TIME(4, S),
SMP_TIME(9, S),
SMP_TIME(16, S),
SMP_TIME(24, S),
SMP_TIME(48, S),
SMP_TIME(96, S),
SMP_TIME(192, S),
SMP_TIME(384, S),
};
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
static const uint16_t acq_time_tbl[8] = {2, 3, 9, 17, 33, 65, 388, 811};
static const uint32_t table_samp_time[] = {
SMP_TIME(1, _5),
SMP_TIME(2, S_5),
SMP_TIME(8, S_5),
SMP_TIME(16, S_5),
SMP_TIME(32, S_5),
SMP_TIME(64, S_5),
SMP_TIME(387, 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
/* External channels (maximum). */
#define STM32_CHANNEL_COUNT 20
/* Number of different sampling time values */
#define STM32_NB_SAMPLING_TIME 8
#ifdef CONFIG_ADC_STM32_DMA
struct stream {
const struct device *dma_dev;
@ -254,12 +137,7 @@ struct adc_stm32_data {
uint32_t channels;
uint8_t channel_count;
uint8_t samples_count;
#if defined(CONFIG_SOC_SERIES_STM32C0X) || \
defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X)
int8_t acq_time_index;
#endif
#ifdef CONFIG_ADC_STM32_DMA
volatile int dma_error;
@ -272,6 +150,8 @@ struct adc_stm32_cfg {
void (*irq_cfg_func)(void);
struct stm32_pclken pclken;
const struct pinctrl_dev_config *pcfg;
const uint16_t sampling_time_table[STM32_NB_SAMPLING_TIME];
int8_t num_sampling_time_common_channels;
int8_t temp_channel;
int8_t vref_channel;
int8_t vbat_channel;
@ -1212,80 +1092,81 @@ static int adc_stm32_read_async(const struct device *dev,
}
#endif
static int adc_stm32_check_acq_time(uint16_t acq_time)
static int adc_stm32_check_acq_time(const struct device *dev, uint16_t acq_time)
{
if (acq_time == ADC_ACQ_TIME_MAX) {
return ARRAY_SIZE(acq_time_tbl) - 1;
}
for (int i = 0; i < 8; i++) {
if (acq_time == ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS,
acq_time_tbl[i])) {
return i;
}
}
const struct adc_stm32_cfg *config =
(const struct adc_stm32_cfg *)dev->config;
if (acq_time == ADC_ACQ_TIME_DEFAULT) {
return 0;
}
if (acq_time == ADC_ACQ_TIME_MAX) {
return STM32_NB_SAMPLING_TIME - 1;
}
for (int i = 0; i < STM32_NB_SAMPLING_TIME; i++) {
if (acq_time == ADC_ACQ_TIME(ADC_ACQ_TIME_TICKS,
config->sampling_time_table[i])) {
return i;
}
}
LOG_ERR("Conversion time not supported.");
return -EINVAL;
}
static void adc_stm32_setup_speed(const struct device *dev, uint8_t id,
static int adc_stm32_setup_speed(const struct device *dev, uint8_t id,
uint8_t acq_time_index)
{
const struct adc_stm32_cfg *config =
(const struct adc_stm32_cfg *)dev->config;
ADC_TypeDef *adc = config->base;
#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_STM32C0X)
LL_ADC_SetSamplingTimeCommonChannels(adc, LL_ADC_SAMPLINGTIME_COMMON_1,
table_samp_time[acq_time_index]);
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
/* Errata ES0418 and more: ADC sampling time might be one cycle longer */
if (acq_time_index < 2) {
acq_time_index = 2;
}
LL_ADC_SetSamplingTimeCommonChannels(adc, LL_ADC_SAMPLINGTIME_COMMON_1,
table_samp_time[acq_time_index]);
#elif defined(CONFIG_SOC_SERIES_STM32WLX)
LL_ADC_SetChannelSamplingTime(adc,
__LL_ADC_DECIMAL_NB_TO_CHANNEL(id),
LL_ADC_SAMPLINGTIME_COMMON_1);
LL_ADC_SetSamplingTimeCommonChannels(adc,
__LL_ADC_DECIMAL_NB_TO_CHANNEL(id),
table_samp_time[acq_time_index]);
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
if (adc != ADC4) {
/*
* For all series we use the fact that the macros LL_ADC_SAMPLINGTIME_*
* that should be passed to the set functions are all coded on 3 bits
* with 0 shift (ie 0 to 7). So acq_time_index is equivalent to the
* macro we would use for the desired sampling time.
*/
switch (config->num_sampling_time_common_channels) {
case 0:
#if ANY_NUM_COMMON_SAMPLING_TIME_CHANNELS_IS(0)
LL_ADC_SetChannelSamplingTime(adc,
__LL_ADC_DECIMAL_NB_TO_CHANNEL(id),
table_samp_time[acq_time_index]);
} else {
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),
table_samp_time[acq_time_index]);
__LL_ADC_DECIMAL_NB_TO_CHANNEL(id),
acq_time_index);
#endif
break;
case 1:
#if ANY_NUM_COMMON_SAMPLING_TIME_CHANNELS_IS(1)
LL_ADC_SetSamplingTimeCommonChannels(adc,
acq_time_index);
#endif
break;
case 2:
#if ANY_NUM_COMMON_SAMPLING_TIME_CHANNELS_IS(2)
LL_ADC_SetChannelSamplingTime(adc,
__LL_ADC_DECIMAL_NB_TO_CHANNEL(id),
LL_ADC_SAMPLINGTIME_COMMON_1);
LL_ADC_SetSamplingTimeCommonChannels(adc,
LL_ADC_SAMPLINGTIME_COMMON_1,
acq_time_index);
#endif
break;
default:
LOG_ERR("Number of common sampling time channels not supported");
return -EINVAL;
}
return 0;
}
static int adc_stm32_channel_setup(const struct device *dev,
const struct adc_channel_cfg *channel_cfg)
{
#if defined(CONFIG_SOC_SERIES_STM32C0X) || \
defined(CONFIG_SOC_SERIES_STM32F0X) || \
defined(CONFIG_SOC_SERIES_STM32G0X) || \
defined(CONFIG_SOC_SERIES_STM32L0X)
const struct adc_stm32_cfg *config =
(const struct adc_stm32_cfg *)dev->config;
struct adc_stm32_data *data = dev->data;
#endif
int acq_time_index;
if (channel_cfg->channel_id >= STM32_CHANNEL_COUNT) {
@ -1293,24 +1174,24 @@ static int adc_stm32_channel_setup(const struct device *dev,
return -EINVAL;
}
acq_time_index = adc_stm32_check_acq_time(
acq_time_index = adc_stm32_check_acq_time(dev,
channel_cfg->acquisition_time);
if (acq_time_index < 0) {
return acq_time_index;
}
#if defined(CONFIG_SOC_SERIES_STM32C0X) || \
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 {
/* All channels of F0/L0 must have identical acquisition time.*/
if (acq_time_index != data->acq_time_index) {
return -EINVAL;
if (config->num_sampling_time_common_channels) {
if (data->acq_time_index == -1) {
data->acq_time_index = acq_time_index;
} else {
/*
* All families that use common channel must have
* identical acquisition time.
*/
if (acq_time_index != data->acq_time_index) {
return -EINVAL;
}
}
}
#endif
if (channel_cfg->differential) {
LOG_ERR("Differential channels are not supported");
@ -1327,8 +1208,11 @@ static int adc_stm32_channel_setup(const struct device *dev,
return -EINVAL;
}
adc_stm32_setup_speed(dev, channel_cfg->channel_id,
acq_time_index);
if (adc_stm32_setup_speed(dev, channel_cfg->channel_id,
acq_time_index) != 0) {
LOG_ERR("Invalid sampling time");
return -EINVAL;
}
LOG_DBG("Channel setup succeeded!");
@ -1351,19 +1235,17 @@ static int adc_stm32_init(const struct device *dev)
}
data->dev = dev;
#if defined(CONFIG_SOC_SERIES_STM32C0X) || \
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. For C0 and G0 currently only one
* For series that use common channels for sampling time, all
* conversion time for all channels on one ADC instance has to
* be the same.
* For series that use two common channels, 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
if (clock_control_on(clk,
(clock_control_subsys_t) &config->pclken) != 0) {
@ -1692,6 +1574,9 @@ static const struct adc_stm32_cfg adc_stm32_cfg_##index = { \
.temp_channel = DT_INST_PROP_OR(index, temp_channel, 0xFF), \
.vref_channel = DT_INST_PROP_OR(index, vref_channel, 0xFF), \
.vbat_channel = DT_INST_PROP_OR(index, vbat_channel, 0xFF), \
.sampling_time_table = DT_INST_PROP(index, sampling_times), \
.num_sampling_time_common_channels = \
DT_INST_PROP_OR(index, num_sampling_time_common_channels, 0),\
.res_table_size = DT_INST_PROP_LEN(index, resolutions), \
.res_table = DT_INST_PROP(index, resolutions), \
}; \