From 46e3b96dd800d2d4f2e6cf4118eb40b5ab65cfab Mon Sep 17 00:00:00 2001 From: Johan Lafon Date: Thu, 14 Nov 2024 12:23:13 +0100 Subject: [PATCH] drivers: adc: fix mV conversion error with high resolution ADC data Fix the overflow encountered with too high resolution ADC output data when using adc_raw_to_millivolts. This is done by using int64_t instead of a int32_t for the internal computations. Signed-off-by: Johan Lafon --- drivers/adc/adc_common.c | 2 +- drivers/adc/adc_emul.c | 2 +- include/zephyr/drivers/adc.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/adc/adc_common.c b/drivers/adc/adc_common.c index cf6472718dec0..aa25ed7a4643e 100644 --- a/drivers/adc/adc_common.c +++ b/drivers/adc/adc_common.c @@ -7,7 +7,7 @@ #include int adc_gain_invert(enum adc_gain gain, - int32_t *value) + int64_t *value) { struct gain_desc { uint8_t mul; diff --git a/drivers/adc/adc_emul.c b/drivers/adc/adc_emul.c index 20b9764fd5fbb..759af792b0efb 100644 --- a/drivers/adc/adc_emul.c +++ b/drivers/adc/adc_emul.c @@ -406,7 +406,7 @@ static int adc_emul_get_chan_value(struct adc_emul_data *data, { struct adc_emul_chan_cfg *chan_cfg = &data->chan_cfg[chan]; uint32_t input_mV; - uint32_t ref_v; + uint64_t ref_v; uint64_t temp; /* Temporary 64 bit value prevent overflows */ int err = 0; diff --git a/include/zephyr/drivers/adc.h b/include/zephyr/drivers/adc.h index 583c04cd0e71e..0689929cc8e8e 100644 --- a/include/zephyr/drivers/adc.h +++ b/include/zephyr/drivers/adc.h @@ -71,7 +71,7 @@ enum adc_gain { * @retval -EINVAL if the gain could not be interpreted */ int adc_gain_invert(enum adc_gain gain, - int32_t *value); + int64_t *value); /** @brief ADC references. */ enum adc_reference { @@ -880,11 +880,11 @@ static inline int adc_raw_to_millivolts(int32_t ref_mv, uint8_t resolution, int32_t *valp) { - int32_t adc_mv = *valp * ref_mv; + int64_t adc_mv = ((uint64_t) *valp) * ref_mv; int ret = adc_gain_invert(gain, &adc_mv); if (ret == 0) { - *valp = (adc_mv >> resolution); + *valp = (uint32_t) (adc_mv >> resolution); } return ret;