From 36a4ae0f2abeceb234f7cb6bf06da8f74d2319f5 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Thu, 2 Dec 2021 15:07:29 +0000 Subject: [PATCH] refactor(sensors): ec11 rotation sensor value in degrees. * Add new `steps` property to the `aips,ec11` binding, to make the driver properly report degrees in the rotation delta channel. * Handle old sensor values in sensor rotate behavior. --- app/drivers/sensor/ec11/ec11.c | 30 +++++++++++++++---- app/drivers/sensor/ec11/ec11.h | 1 + .../zephyr/dts/bindings/sensor/alps,ec11.yaml | 4 +++ .../behavior_sensor_rotate_key_press.c | 6 ++-- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/app/drivers/sensor/ec11/ec11.c b/app/drivers/sensor/ec11/ec11.c index 2fe641fa7c3d..c711454d2931 100644 --- a/app/drivers/sensor/ec11/ec11.c +++ b/app/drivers/sensor/ec11/ec11.c @@ -16,6 +16,8 @@ #include "ec11.h" +#define FULL_ROTATION 360 + LOG_MODULE_REGISTER(EC11, CONFIG_SENSOR_LOG_LEVEL); static int ec11_get_ab_state(const struct device *dev) { @@ -61,9 +63,11 @@ static int ec11_sample_fetch(const struct device *dev, enum sensor_channel chan) drv_data->pulses += delta; drv_data->ab_state = val; - drv_data->ticks = drv_data->pulses / drv_cfg->resolution; - drv_data->delta = delta; - drv_data->pulses %= drv_cfg->resolution; + if (drv_cfg->steps == 0) { + drv_data->ticks = drv_data->pulses / drv_cfg->resolution; + drv_data->delta = delta; + drv_data->pulses %= drv_cfg->resolution; + } return 0; } @@ -71,13 +75,26 @@ static int ec11_sample_fetch(const struct device *dev, enum sensor_channel chan) static int ec11_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) { struct ec11_data *drv_data = dev->data; + const struct ec11_config *drv_cfg = dev->config; + int32_t pulses = drv_data->pulses; if (chan != SENSOR_CHAN_ROTATION) { return -ENOTSUP; } - val->val1 = drv_data->ticks; - val->val2 = drv_data->delta; + drv_data->pulses = 0; + + if (drv_cfg->steps > 0) { + val->val1 = (pulses * FULL_ROTATION) / drv_cfg->steps; + val->val2 = (pulses * FULL_ROTATION) - (val->val1 * drv_cfg->steps); + if (val->val2 != 0) { + val->val2 *= 1000000; + val->val2 /= drv_cfg->steps; + } + } else { + val->val1 = drv_data->ticks; + val->val2 = drv_data->delta; + } return 0; } @@ -140,7 +157,8 @@ int ec11_init(const struct device *dev) { .b_label = DT_INST_GPIO_LABEL(n, b_gpios), \ .b_pin = DT_INST_GPIO_PIN(n, b_gpios), \ .b_flags = DT_INST_GPIO_FLAGS(n, b_gpios), \ - COND_CODE_0(DT_INST_NODE_HAS_PROP(n, resolution), (1), (DT_INST_PROP(n, resolution))), \ + .resolution = DT_INST_PROP_OR(n, resolution, 1), \ + .steps = DT_INST_PROP_OR(n, steps, 0), \ }; \ DEVICE_DT_INST_DEFINE(n, ec11_init, NULL, &ec11_data_##n, &ec11_cfg_##n, POST_KERNEL, \ CONFIG_SENSOR_INIT_PRIORITY, &ec11_driver_api); diff --git a/app/drivers/sensor/ec11/ec11.h b/app/drivers/sensor/ec11/ec11.h index 1cb9c5f77ec0..e43541d0d0c4 100644 --- a/app/drivers/sensor/ec11/ec11.h +++ b/app/drivers/sensor/ec11/ec11.h @@ -20,6 +20,7 @@ struct ec11_config { const uint8_t b_flags; const uint8_t resolution; + const uint8_t steps; }; struct ec11_data { diff --git a/app/drivers/zephyr/dts/bindings/sensor/alps,ec11.yaml b/app/drivers/zephyr/dts/bindings/sensor/alps,ec11.yaml index 5cbe77a2ad0c..8231b8652f70 100644 --- a/app/drivers/zephyr/dts/bindings/sensor/alps,ec11.yaml +++ b/app/drivers/zephyr/dts/bindings/sensor/alps,ec11.yaml @@ -19,3 +19,7 @@ properties: type: int description: Number of pulses per tick required: false + steps: + type: int + description: Number of pulses in one full rotation + required: false diff --git a/app/src/behaviors/behavior_sensor_rotate_key_press.c b/app/src/behaviors/behavior_sensor_rotate_key_press.c index ab8c26763dcf..5bf777d63a7a 100644 --- a/app/src/behaviors/behavior_sensor_rotate_key_press.c +++ b/app/src/behaviors/behavior_sensor_rotate_key_press.c @@ -39,8 +39,10 @@ static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding, struct behavior_sensor_rotate_key_press_sensor_data *data = behavior_dev->data; uint32_t keycode; - - data->remainder[event.position] += value->val1; + + // Some funky special casing for "old encoder behavior" where ticks where reported in val2 only, + // instead of rotational degrees in val1. + data->remainder[event.position] += (value->val1 == 0 ? (value->val2 * cfg->activation_resolution) : value->val1); int8_t triggers = data->remainder[event.position] / cfg->activation_resolution; data->remainder[event.position] %= cfg->activation_resolution;