drivers: adc: stm32: support multiple channels
Support sequencing multiple channels into a single read Signed-off-by: Hein Wessels <heinwessels93@gmail.com>
This commit is contained in:
parent
dce0eb7e8f
commit
cbe52e9027
1 changed files with 156 additions and 106 deletions
|
@ -4,6 +4,7 @@
|
||||||
* Copyright (c) 2019 Endre Karlson
|
* Copyright (c) 2019 Endre Karlson
|
||||||
* Copyright (c) 2020 Teslabs Engineering S.L.
|
* Copyright (c) 2020 Teslabs Engineering S.L.
|
||||||
* Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
* Copyright (c) 2021 Marius Scholtz, RIC Electronics
|
||||||
|
* Copyright (c) 2023 Hein Wessels, Nobleo Technology
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -69,6 +70,7 @@ static const uint32_t table_rank[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SEQ_LEN(n) LL_ADC_REG_SEQ_SCAN_ENABLE_##n##RANKS
|
#define SEQ_LEN(n) LL_ADC_REG_SEQ_SCAN_ENABLE_##n##RANKS
|
||||||
|
/* Length of this array signifies the maximum sequence length */
|
||||||
static const uint32_t table_seq_len[] = {
|
static const uint32_t table_seq_len[] = {
|
||||||
LL_ADC_REG_SEQ_SCAN_DISABLE,
|
LL_ADC_REG_SEQ_SCAN_DISABLE,
|
||||||
SEQ_LEN(2),
|
SEQ_LEN(2),
|
||||||
|
@ -250,7 +252,9 @@ struct adc_stm32_data {
|
||||||
uint16_t *repeat_buffer;
|
uint16_t *repeat_buffer;
|
||||||
|
|
||||||
uint8_t resolution;
|
uint8_t resolution;
|
||||||
|
uint32_t channels;
|
||||||
uint8_t channel_count;
|
uint8_t channel_count;
|
||||||
|
uint8_t samples_count;
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \
|
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \
|
||||||
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
defined(CONFIG_SOC_SERIES_STM32G0X) || \
|
||||||
defined(CONFIG_SOC_SERIES_STM32L0X)
|
defined(CONFIG_SOC_SERIES_STM32L0X)
|
||||||
|
@ -534,7 +538,7 @@ static void adc_stm32_set_common_path(const struct device *dev, uint32_t PathInt
|
||||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), PathInternal);
|
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), PathInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adc_stm32_setup_channels(const struct device *dev, uint8_t channel_id)
|
static void adc_stm32_setup_channel(const struct device *dev, uint8_t channel_id)
|
||||||
{
|
{
|
||||||
const struct adc_stm32_cfg *config = dev->config;
|
const struct adc_stm32_cfg *config = dev->config;
|
||||||
ADC_TypeDef *adc = (ADC_TypeDef *)config->base;
|
ADC_TypeDef *adc = (ADC_TypeDef *)config->base;
|
||||||
|
@ -626,69 +630,79 @@ static void adc_stm32_unset_common_path(const struct device *dev, uint32_t PathI
|
||||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), PathInternal);
|
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc), PathInternal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adc_stm32_teardown_channels(const struct device *dev, uint8_t channel_id)
|
static void adc_stm32_teardown_channels(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct adc_stm32_cfg *config = dev->config;
|
const struct adc_stm32_cfg *config = dev->config;
|
||||||
|
struct adc_stm32_data *data = dev->data;
|
||||||
ADC_TypeDef *adc = (ADC_TypeDef *)config->base;
|
ADC_TypeDef *adc = (ADC_TypeDef *)config->base;
|
||||||
|
uint8_t channel_id;
|
||||||
|
|
||||||
|
for (uint32_t channels = data->channels; channels; channels &= ~BIT(channel_id)) {
|
||||||
|
channel_id = find_lsb_set(channels) - 1;
|
||||||
#ifdef CONFIG_SOC_SERIES_STM32G4X
|
#ifdef CONFIG_SOC_SERIES_STM32G4X
|
||||||
if (config->has_temp_channel) {
|
if (config->has_temp_channel) {
|
||||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
|
||||||
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC1) == channel_id)
|
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC1) ==
|
||||||
&& (config->base == ADC1)) {
|
channel_id) &&
|
||||||
adc_stm32_disable(adc);
|
(config->base == ADC1)) {
|
||||||
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
adc_stm32_disable(adc);
|
||||||
}
|
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc5), okay)
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc5), okay)
|
||||||
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC5) == channel_id)
|
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC5) ==
|
||||||
&& (config->base == ADC5)) {
|
channel_id) &&
|
||||||
adc_stm32_disable(adc);
|
(config->base == ADC5)) {
|
||||||
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
adc_stm32_disable(adc);
|
||||||
}
|
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
#elif CONFIG_SOC_SERIES_STM32U5X
|
|
||||||
if (config->has_temp_channel) {
|
|
||||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
|
|
||||||
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) == channel_id)
|
|
||||||
&& (config->base == ADC1)) {
|
|
||||||
adc_stm32_disable(adc);
|
|
||||||
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
|
||||||
}
|
}
|
||||||
|
#elif CONFIG_SOC_SERIES_STM32U5X
|
||||||
|
if (config->has_temp_channel) {
|
||||||
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay)
|
||||||
|
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) ==
|
||||||
|
channel_id) &&
|
||||||
|
(config->base == ADC1)) {
|
||||||
|
adc_stm32_disable(adc);
|
||||||
|
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc4), okay)
|
#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc4), okay)
|
||||||
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC4) == channel_id)
|
if ((__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR_ADC4) ==
|
||||||
&& (config->base == ADC4)) {
|
channel_id) &&
|
||||||
|
(config->base == ADC4)) {
|
||||||
|
adc_stm32_disable(adc);
|
||||||
|
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (config->has_temp_channel &&
|
||||||
|
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) == channel_id)) {
|
||||||
adc_stm32_disable(adc);
|
adc_stm32_disable(adc);
|
||||||
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (config->has_temp_channel &&
|
|
||||||
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_TEMPSENSOR) == channel_id)) {
|
|
||||||
adc_stm32_disable(adc);
|
|
||||||
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_SOC_SERIES_STM32G4X */
|
#endif /* CONFIG_SOC_SERIES_STM32G4X */
|
||||||
|
|
||||||
if (config->has_vref_channel &&
|
if (config->has_vref_channel &&
|
||||||
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VREFINT) == channel_id)) {
|
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VREFINT) == channel_id)) {
|
||||||
adc_stm32_disable(adc);
|
adc_stm32_disable(adc);
|
||||||
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VREFINT);
|
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VREFINT);
|
||||||
}
|
}
|
||||||
#if defined(LL_ADC_CHANNEL_VBAT)
|
#if defined(LL_ADC_CHANNEL_VBAT)
|
||||||
/* Enable the bridge divider only when needed for ADC conversion. */
|
/* Enable the bridge divider only when needed for ADC conversion. */
|
||||||
if (config->has_vbat_channel && (
|
if (config->has_vbat_channel && (
|
||||||
#if defined(LL_ADC_CHANNEL_VBAT_ADC4)
|
#if defined(LL_ADC_CHANNEL_VBAT_ADC4)
|
||||||
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT_ADC4) == channel_id) ||
|
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT_ADC4) == channel_id) ||
|
||||||
#endif /* LL_ADC_CHANNEL_VBAT_ADC4 */
|
#endif /* LL_ADC_CHANNEL_VBAT_ADC4 */
|
||||||
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT) == channel_id))) {
|
(__LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_VBAT) == channel_id))) {
|
||||||
adc_stm32_disable(adc);
|
adc_stm32_disable(adc);
|
||||||
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VBAT);
|
adc_stm32_unset_common_path(dev, LL_ADC_PATH_INTERNAL_VBAT);
|
||||||
}
|
}
|
||||||
#endif /* LL_ADC_CHANNEL_VBAT */
|
#endif /* LL_ADC_CHANNEL_VBAT */
|
||||||
|
}
|
||||||
|
|
||||||
adc_stm32_enable(adc);
|
adc_stm32_enable(adc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,71 +772,104 @@ static int start_read(const struct device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t channels = sequence->channels;
|
|
||||||
uint8_t index = find_lsb_set(channels) - 1;
|
|
||||||
|
|
||||||
if (channels > BIT(index)) {
|
|
||||||
LOG_ERR("Only single channel supported");
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
adc_stm32_setup_channels(dev, index);
|
|
||||||
|
|
||||||
data->buffer = sequence->buffer;
|
data->buffer = sequence->buffer;
|
||||||
|
data->channels = sequence->channels;
|
||||||
|
data->channel_count = POPCOUNT(data->channels);
|
||||||
|
data->samples_count = 0;
|
||||||
|
|
||||||
uint32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(index);
|
if (data->channel_count == 0) {
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32H7X)
|
LOG_ERR("No channels selected");
|
||||||
/*
|
return -EINVAL;
|
||||||
* Each channel in the sequence must be previously enabled in PCSEL.
|
|
||||||
* This register controls the analog switch integrated in the IO level.
|
|
||||||
*/
|
|
||||||
LL_ADC_SetChannelPreSelection(adc, channel);
|
|
||||||
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
|
|
||||||
/*
|
|
||||||
* Each channel in the sequence must be previously enabled in PCSEL.
|
|
||||||
* This register controls the analog switch integrated in the IO level.
|
|
||||||
* Only for ADC1 instance (ADC4 has no Channel preselection capability).
|
|
||||||
*/
|
|
||||||
if (adc == ADC1) {
|
|
||||||
LL_ADC_SetChannelPreselection(adc, channel);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \
|
if (data->channels > BIT(STM32_CHANNEL_COUNT) - 1) {
|
||||||
defined(CONFIG_SOC_SERIES_STM32L0X)
|
LOG_ERR("Channels bitmask uses out of range channel");
|
||||||
LL_ADC_REG_SetSequencerChannels(adc, channel);
|
return -EINVAL;
|
||||||
#elif defined(CONFIG_SOC_SERIES_STM32WLX)
|
|
||||||
/* Init the the ADC group for REGULAR conversion*/
|
|
||||||
LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_CONFIGURABLE);
|
|
||||||
LL_ADC_REG_SetTriggerSource(adc, LL_ADC_REG_TRIG_SOFTWARE);
|
|
||||||
LL_ADC_REG_SetSequencerLength(adc, LL_ADC_REG_SEQ_SCAN_DISABLE);
|
|
||||||
LL_ADC_REG_SetOverrun(adc, LL_ADC_REG_OVR_DATA_OVERWRITTEN);
|
|
||||||
LL_ADC_REG_SetSequencerRanks(adc, LL_ADC_REG_RANK_1, channel);
|
|
||||||
LL_ADC_REG_SetSequencerChannels(adc, channel);
|
|
||||||
/* Wait for config complete config is ready */
|
|
||||||
while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) {
|
|
||||||
}
|
}
|
||||||
LL_ADC_ClearFlag_CCRDY(adc);
|
|
||||||
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
|
#if !defined(CONFIG_SOC_SERIES_STM32F0X) && \
|
||||||
/* STM32G0 in "not fully configurable" sequencer mode */
|
!defined(CONFIG_SOC_SERIES_STM32G0X) && \
|
||||||
LL_ADC_REG_SetSequencerChannels(adc, channel);
|
!defined(CONFIG_SOC_SERIES_STM32L0X) && \
|
||||||
LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_FIXED);
|
!defined(CONFIG_SOC_SERIES_STM32WLX)
|
||||||
while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) {
|
if (data->channel_count > ARRAY_SIZE(table_seq_len)) {
|
||||||
}
|
LOG_ERR("Too many channels for sequencer. Max: %d", ARRAY_SIZE(table_seq_len));
|
||||||
LL_ADC_ClearFlag_CCRDY(adc);
|
return -EINVAL;
|
||||||
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
|
|
||||||
if (adc != ADC4) {
|
|
||||||
LL_ADC_REG_SetSequencerRanks(adc, table_rank[0], channel);
|
|
||||||
LL_ADC_REG_SetSequencerLength(adc, table_seq_len[0]);
|
|
||||||
} else {
|
|
||||||
LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_FIXED);
|
|
||||||
LL_ADC_REG_SetSequencerLength(adc,
|
|
||||||
BIT(__LL_ADC_CHANNEL_TO_DECIMAL_NB(channel)));
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
LL_ADC_REG_SetSequencerRanks(adc, table_rank[0], channel);
|
if (data->channel_count > 1) {
|
||||||
LL_ADC_REG_SetSequencerLength(adc, table_seq_len[0]);
|
LOG_ERR("This device only supports single channel sampling");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
data->channel_count = 1;
|
|
||||||
|
uint8_t channel_id;
|
||||||
|
uint8_t channel_index = 0;
|
||||||
|
|
||||||
|
/* Iterate over selected channels in bitmask keeping track of:
|
||||||
|
* - channel_index: ranging from 0 -> ( data->channel_count - 1 )
|
||||||
|
* - channel_id: ordinal position of channel in data->channels bitmask
|
||||||
|
*/
|
||||||
|
for (uint32_t channels = data->channels; channels;
|
||||||
|
channels &= ~BIT(channel_id), channel_index++) {
|
||||||
|
channel_id = find_lsb_set(channels) - 1;
|
||||||
|
|
||||||
|
uint32_t channel = __LL_ADC_DECIMAL_NB_TO_CHANNEL(channel_id);
|
||||||
|
|
||||||
|
adc_stm32_setup_channel(dev, channel_id);
|
||||||
|
|
||||||
|
#if defined(CONFIG_SOC_SERIES_STM32H7X)
|
||||||
|
/*
|
||||||
|
* Each channel in the sequence must be previously enabled in PCSEL.
|
||||||
|
* This register controls the analog switch integrated in the IO level.
|
||||||
|
*/
|
||||||
|
LL_ADC_SetChannelPreSelection(adc, channel);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
|
||||||
|
/*
|
||||||
|
* Each channel in the sequence must be previously enabled in PCSEL.
|
||||||
|
* This register controls the analog switch integrated in the IO level.
|
||||||
|
* Only for ADC1 instance (ADC4 has no Channel preselection capability).
|
||||||
|
*/
|
||||||
|
if (adc == ADC1) {
|
||||||
|
LL_ADC_SetChannelPreselection(adc, channel);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_SOC_SERIES_STM32F0X) || \
|
||||||
|
defined(CONFIG_SOC_SERIES_STM32L0X)
|
||||||
|
LL_ADC_REG_SetSequencerChannels(adc, channel);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_STM32WLX)
|
||||||
|
/* Init the the ADC group for REGULAR conversion*/
|
||||||
|
LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_CONFIGURABLE);
|
||||||
|
LL_ADC_REG_SetTriggerSource(adc, LL_ADC_REG_TRIG_SOFTWARE);
|
||||||
|
LL_ADC_REG_SetSequencerLength(adc, LL_ADC_REG_SEQ_SCAN_DISABLE);
|
||||||
|
LL_ADC_REG_SetOverrun(adc, LL_ADC_REG_OVR_DATA_OVERWRITTEN);
|
||||||
|
LL_ADC_REG_SetSequencerRanks(adc, LL_ADC_REG_RANK_1, channel);
|
||||||
|
LL_ADC_REG_SetSequencerChannels(adc, channel);
|
||||||
|
/* Wait for config complete config is ready */
|
||||||
|
while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) {
|
||||||
|
}
|
||||||
|
LL_ADC_ClearFlag_CCRDY(adc);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
|
||||||
|
/* STM32G0 in "not fully configurable" sequencer mode */
|
||||||
|
LL_ADC_REG_SetSequencerChannels(adc, channel);
|
||||||
|
LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_FIXED);
|
||||||
|
while (LL_ADC_IsActiveFlag_CCRDY(adc) == 0) {
|
||||||
|
}
|
||||||
|
LL_ADC_ClearFlag_CCRDY(adc);
|
||||||
|
#elif defined(CONFIG_SOC_SERIES_STM32U5X)
|
||||||
|
if (adc != ADC4) {
|
||||||
|
LL_ADC_REG_SetSequencerRanks(adc, table_rank[channel_index], channel);
|
||||||
|
LL_ADC_REG_SetSequencerLength(adc, table_seq_len[channel_index]);
|
||||||
|
} else {
|
||||||
|
LL_ADC_REG_SetSequencerConfigurable(adc, LL_ADC_REG_SEQ_FIXED);
|
||||||
|
LL_ADC_REG_SetSequencerLength(adc,
|
||||||
|
BIT(__LL_ADC_CHANNEL_TO_DECIMAL_NB(channel)));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
LL_ADC_REG_SetSequencerRanks(adc, table_rank[channel_index], channel);
|
||||||
|
LL_ADC_REG_SetSequencerLength(adc, table_seq_len[channel_index]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
err = check_buffer_size(sequence, data->channel_count);
|
err = check_buffer_size(sequence, data->channel_count);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -948,11 +995,9 @@ static int start_read(const struct device *dev,
|
||||||
|
|
||||||
adc_context_start_read(&data->ctx, sequence);
|
adc_context_start_read(&data->ctx, sequence);
|
||||||
|
|
||||||
err = adc_context_wait_for_completion(&data->ctx);
|
int result = adc_context_wait_for_completion(&data->ctx);
|
||||||
|
|
||||||
adc_stm32_teardown_channels(dev, index);
|
return result;
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adc_context_start_sampling(struct adc_context *ctx)
|
static void adc_context_start_sampling(struct adc_context *ctx)
|
||||||
|
@ -985,7 +1030,12 @@ static void adc_stm32_isr(const struct device *dev)
|
||||||
|
|
||||||
*data->buffer++ = LL_ADC_REG_ReadConversionData32(adc);
|
*data->buffer++ = LL_ADC_REG_ReadConversionData32(adc);
|
||||||
|
|
||||||
adc_context_on_sampling_done(&data->ctx, dev);
|
/* ISR is triggered after each conversion, and at the end-of-sequence. */
|
||||||
|
if (++data->samples_count == data->channel_count) {
|
||||||
|
data->samples_count = 0;
|
||||||
|
adc_context_on_sampling_done(&data->ctx, dev);
|
||||||
|
adc_stm32_teardown_channels(dev);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_DBG("%s ISR triggered.", dev->name);
|
LOG_DBG("%s ISR triggered.", dev->name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue