drivers: adc: stm32: Fix race condition with internal channels
When using one of the internal channels (die_temp, vbat, vref) the channels are enabled in the individual drivers and disabled again whenever an adc conversion is complete. This creates a race condition if the ADC is used from multiple threads. This commit moves the disabling of the channels to the individual drivers. Signed-off-by: Brian Juel Folkmann <bju@trackunit.com>
This commit is contained in:
parent
768ed26010
commit
06b57926a2
|
@ -1087,10 +1087,6 @@ static void adc_context_on_complete(struct adc_context *ctx, int status)
|
|||
/* Reset acquisition time used for the sequence */
|
||||
data->acq_time_index = -1;
|
||||
|
||||
/* Reset internal channels */
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(adc),
|
||||
LL_ADC_PATH_INTERNAL_NONE);
|
||||
|
||||
#if defined(CONFIG_SOC_SERIES_STM32H7X) || defined(CONFIG_SOC_SERIES_STM32U5X)
|
||||
/* Reset channel preselection register */
|
||||
LL_ADC_SetChannelPreselection(adc, 0);
|
||||
|
|
|
@ -67,6 +67,7 @@ static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
struct stm32_temp_data *data = dev->data;
|
||||
struct adc_sequence *sp = &data->adc_seq;
|
||||
int rc;
|
||||
uint32_t path;
|
||||
|
||||
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP) {
|
||||
return -ENOTSUP;
|
||||
|
@ -80,8 +81,10 @@ static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
path = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base));
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base),
|
||||
LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||
LL_ADC_PATH_INTERNAL_TEMPSENSOR | path);
|
||||
|
||||
k_usleep(LL_ADC_DELAY_TEMPSENSOR_STAB_US);
|
||||
|
||||
rc = adc_read(data->adc, sp);
|
||||
|
@ -89,6 +92,10 @@ static int stm32_temp_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
data->raw = data->sample_buffer;
|
||||
}
|
||||
|
||||
path = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base));
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base),
|
||||
path &= ~LL_ADC_PATH_INTERNAL_TEMPSENSOR);
|
||||
|
||||
unlock:
|
||||
k_mutex_unlock(&data->mutex);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ static int stm32_vbat_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
struct stm32_vbat_data *data = dev->data;
|
||||
struct adc_sequence *sp = &data->adc_seq;
|
||||
int rc;
|
||||
uint32_t path;
|
||||
|
||||
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_VOLTAGE) {
|
||||
return -ENOTSUP;
|
||||
|
@ -52,14 +53,19 @@ static int stm32_vbat_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
path = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base));
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base),
|
||||
LL_ADC_PATH_INTERNAL_VBAT);
|
||||
LL_ADC_PATH_INTERNAL_VBAT | path);
|
||||
|
||||
rc = adc_read(data->adc, sp);
|
||||
if (rc == 0) {
|
||||
data->raw = data->sample_buffer;
|
||||
}
|
||||
|
||||
path = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base));
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base),
|
||||
path &= ~LL_ADC_PATH_INTERNAL_VBAT);
|
||||
|
||||
unlock:
|
||||
k_mutex_unlock(&data->mutex);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ static int stm32_vref_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
struct stm32_vref_data *data = dev->data;
|
||||
struct adc_sequence *sp = &data->adc_seq;
|
||||
int rc;
|
||||
uint32_t path;
|
||||
|
||||
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_VOLTAGE) {
|
||||
return -ENOTSUP;
|
||||
|
@ -51,8 +52,10 @@ static int stm32_vref_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
goto unlock;
|
||||
}
|
||||
|
||||
path = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base));
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base),
|
||||
LL_ADC_PATH_INTERNAL_VREFINT);
|
||||
LL_ADC_PATH_INTERNAL_VREFINT | path);
|
||||
|
||||
#ifdef LL_ADC_DELAY_VREFINT_STAB_US
|
||||
k_usleep(LL_ADC_DELAY_VREFINT_STAB_US);
|
||||
#endif
|
||||
|
@ -62,6 +65,11 @@ static int stm32_vref_sample_fetch(const struct device *dev, enum sensor_channel
|
|||
data->raw = data->sample_buffer;
|
||||
}
|
||||
|
||||
path = LL_ADC_GetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base));
|
||||
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(data->adc_base),
|
||||
path &= ~LL_ADC_PATH_INTERNAL_VREFINT);
|
||||
|
||||
|
||||
unlock:
|
||||
k_mutex_unlock(&data->mutex);
|
||||
|
||||
|
|
Loading…
Reference in a new issue