From b1b5ab8d1a614b6f33c4d39bd2fbcdc49180b027 Mon Sep 17 00:00:00 2001 From: Yasushi SHOJI Date: Mon, 15 Jan 2024 16:11:57 +0900 Subject: [PATCH] drivers: sensor: ams_as5600: Fix calculation of fractional part commit 98903d48c3fcd5cd8789c51ac27953e455a7062d upstream. The original calculation has two bugs. One is the calculated value, and the other is that the value is not in one-millionth parts. What the original calculation does is compute a scaled position value by multiplying the raw sensor value (`dev_data->position`) by `AS5600_FULL_ANGLE`, which represents a full rotation in degrees. It then subtracts the product of the whole number of pulses (`val->val1`) and `AS5600_PULSES_PER_REV` from this scaled position value. ((int32_t)dev_data->position * AS5600_FULL_ANGLE) - (val->val1 * AS5600_PULSES_PER_REV); What you actually need is to extract the fractional part of the value by taking the modulo of AS5600_PULSES_PER_REV from the scaled value of the position. (((int32_t)dev_data->position * AS5600_FULL_ANGLE) % AS5600_PULSES_PER_REV) Then convert the value to one-millionth part. * (AS5600_MILLION_UNIT / AS5600_PULSES_PER_REV); Signed-off-by: Yasushi SHOJI --- drivers/sensor/ams_as5600/ams_as5600.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/sensor/ams_as5600/ams_as5600.c b/drivers/sensor/ams_as5600/ams_as5600.c index c5775e74701b..68c9e2e90a77 100644 --- a/drivers/sensor/ams_as5600/ams_as5600.c +++ b/drivers/sensor/ams_as5600/ams_as5600.c @@ -19,6 +19,7 @@ LOG_MODULE_REGISTER(ams_as5600, CONFIG_SENSOR_LOG_LEVEL); #define AS5600_ANGLE_REGISTER_H 0x0E #define AS5600_FULL_ANGLE 360 #define AS5600_PULSES_PER_REV 4096 +#define AS5600_MILLION_UNIT 1000000 struct as5600_dev_cfg { struct i2c_dt_spec i2c_port; @@ -60,8 +61,8 @@ static int as5600_get(const struct device *dev, enum sensor_channel chan, val->val1 = ((int32_t)dev_data->position * AS5600_FULL_ANGLE) / AS5600_PULSES_PER_REV; - val->val2 = ((int32_t)dev_data->position * AS5600_FULL_ANGLE) - - (val->val1 * AS5600_PULSES_PER_REV); + val->val2 = (((int32_t)dev_data->position * AS5600_FULL_ANGLE) % + AS5600_PULSES_PER_REV) * (AS5600_MILLION_UNIT / AS5600_PULSES_PER_REV); } else { return -ENOTSUP; }