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 <benedikt.schmidt@embedded-solutions.at>
This commit is contained in:
Benedikt Schmidt 2023-05-04 17:20:37 +02:00 committed by Fabio Baltieri
parent feef931fbb
commit 0d33ecd56a
3 changed files with 20 additions and 2 deletions

View file

@ -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.

View file

@ -16,6 +16,8 @@
#include <zephyr/sys/util.h>
#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)

View file

@ -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;
}