From 16bfb1886afbf393403185d83cfe8da8bc10d04a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Stasiak?= Date: Thu, 11 Jul 2024 07:54:12 +0200 Subject: [PATCH] [nrf fromtree] drivers: sensor: qdec: fix QDEC overflow handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QDEC sensor driver fails to inform user of the overflow in the ACC register, which makes the most recently fetched data invalid. An error code return has been added to nrfx_qdec_sample_fetch(), that indicates that an overflow has occured, based on oveflow flag. Also, raw_acc field was added in the qdec_nrfx_data structure, to adjust QDEC to sensor API rules - two subsequent sensor_channel_get() calls should will yield the same values. Signed-off-by: MichaƂ Stasiak (cherry picked from commit 2e6c83dd4cc23df0b17624d17ec8898db34e3370) --- drivers/sensor/nordic/qdec_nrfx/qdec_nrfx.c | 23 +++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/nordic/qdec_nrfx/qdec_nrfx.c b/drivers/sensor/nordic/qdec_nrfx/qdec_nrfx.c index 10035e0a103..dc70c27d417 100644 --- a/drivers/sensor/nordic/qdec_nrfx/qdec_nrfx.c +++ b/drivers/sensor/nordic/qdec_nrfx/qdec_nrfx.c @@ -26,7 +26,9 @@ LOG_MODULE_REGISTER(qdec_nrfx, CONFIG_SENSOR_LOG_LEVEL); struct qdec_nrfx_data { + int32_t fetched_acc; int32_t acc; + bool overflow; sensor_trigger_handler_t data_ready_handler; const struct sensor_trigger *data_ready_trigger; }; @@ -49,6 +51,8 @@ static void accumulate(struct qdec_nrfx_data *data, int32_t acc) if (!overflow) { data->acc += acc; + } else { + data->overflow = true; } irq_unlock(key); @@ -70,6 +74,18 @@ static int qdec_nrfx_sample_fetch(const struct device *dev, accumulate(data, acc); + unsigned int key = irq_lock(); + + data->fetched_acc = data->acc; + data->acc = 0; + + irq_unlock(key); + + if (data->overflow) { + data->overflow = false; + return -EOVERFLOW; + } + return 0; } @@ -87,8 +103,7 @@ static int qdec_nrfx_channel_get(const struct device *dev, } key = irq_lock(); - acc = data->acc; - data->acc = 0; + acc = data->fetched_acc; irq_unlock(key); val->val1 = (acc * FULL_ANGLE) / config->steps; @@ -148,6 +163,10 @@ static void qdec_nrfx_event_handler(nrfx_qdec_event_t event, void *p_context) } break; + case NRF_QDEC_EVENT_ACCOF: + dev_data->overflow = true; + break; + default: LOG_ERR("unhandled event (0x%x)", event.type); break;