From 0d33ecd56aec5456017933bb22c88a7eabbbb27b Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 4 May 2023 17:20:37 +0200 Subject: [PATCH] drivers: adc: configurable wait for completion timeout Depending on the ADC implementation it might happen that the driver is waiting on an external interrupt. If this interrupt gets lost, for instance due to a race condition with an external port expander, the system will get stuck. Making this configurable allows the user to recover from such an error. Signed-off-by: Benedikt Schmidt --- drivers/adc/Kconfig.ads114s0x | 7 +++++++ drivers/adc/adc_ads114s0x.c | 4 +++- drivers/adc/adc_context.h | 11 ++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/adc/Kconfig.ads114s0x b/drivers/adc/Kconfig.ads114s0x index 31f193906b1..4507ad30217 100644 --- a/drivers/adc/Kconfig.ads114s0x +++ b/drivers/adc/Kconfig.ads114s0x @@ -34,3 +34,10 @@ config ADC_ADS114S0X_GPIO The GPIO functionality is handled by the ADS114S0x GPIO driver. + +config ADC_ADS114S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS + int "Timeout for wait for completion of a read in ms" + default 1000 + depends on ADC_ADS114S0X + help + This is the wait time in ms until a read is completed. diff --git a/drivers/adc/adc_ads114s0x.c b/drivers/adc/adc_ads114s0x.c index eeafd0d3aef..5c7edd90965 100644 --- a/drivers/adc/adc_ads114s0x.c +++ b/drivers/adc/adc_ads114s0x.c @@ -16,6 +16,8 @@ #include #define ADC_CONTEXT_USES_KERNEL_TIMER 1 +#define ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT \ + K_MSEC(CONFIG_ADC_ADS114S0X_WAIT_FOR_COMPLETION_TIMEOUT_MS) #include "adc_context.h" LOG_MODULE_REGISTER(ads114s0x, CONFIG_ADC_LOG_LEVEL); @@ -922,7 +924,7 @@ static int ads114s0x_wait_data_ready(const struct device *dev) { struct ads114s0x_data *data = dev->data; - return k_sem_take(&data->data_ready_signal, K_FOREVER); + return k_sem_take(&data->data_ready_signal, ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT); } static int ads114s0x_read_sample(const struct device *dev, uint16_t *buffer) diff --git a/drivers/adc/adc_context.h b/drivers/adc/adc_context.h index f5dd2549edb..859b1f97f44 100644 --- a/drivers/adc/adc_context.h +++ b/drivers/adc/adc_context.h @@ -48,6 +48,10 @@ static void adc_context_disable_timer(struct adc_context *ctx); static void adc_context_on_complete(struct adc_context *ctx, int status); #endif /* ADC_CONTEXT_ENABLE_ON_COMPLETE */ +#ifndef ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT +#define ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT K_FOREVER +#endif + struct adc_context { atomic_t sampling_requested; #ifdef ADC_CONTEXT_USES_KERNEL_TIMER @@ -168,7 +172,12 @@ static inline int adc_context_wait_for_completion(struct adc_context *ctx) } #endif /* CONFIG_ADC_ASYNC */ - k_sem_take(&ctx->sync, K_FOREVER); + int status = k_sem_take(&ctx->sync, ADC_CONTEXT_WAIT_FOR_COMPLETION_TIMEOUT); + + if (status != 0) { + ctx->status = status; + } + return ctx->status; }