forked from kofal.net/zmk
refactor(sensors): Sensor event channel data, resolution tweaks.
* Refactor sensor events to include channel data, necessary for prop split encoders, and avoiding duplicate calls, to fetch channel data twice, etc. * More consistent behavior driver API. * Allow setting triggers per resolution at the behavior level optionally.
This commit is contained in:
committed by
Pete Johanson
parent
dcf5e75fa6
commit
2244bd3d81
@@ -33,8 +33,10 @@ static int behavior_sensor_rotate_init(const struct device *dev) { return 0; };
|
||||
.tap_ms = DT_INST_PROP_OR(n, tap_ms, 5), \
|
||||
.override_params = false, \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE( \
|
||||
n, behavior_sensor_rotate_init, NULL, NULL, &behavior_sensor_rotate_config_##n, \
|
||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_sensor_rotate_driver_api);
|
||||
static struct behavior_sensor_rotate_data behavior_sensor_rotate_data_##n = {}; \
|
||||
DEVICE_DT_INST_DEFINE(n, behavior_sensor_rotate_init, NULL, &behavior_sensor_rotate_data_##n, \
|
||||
&behavior_sensor_rotate_config_##n, APPLICATION, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||
&behavior_sensor_rotate_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(SENSOR_ROTATE_INST)
|
||||
|
||||
@@ -5,48 +5,75 @@
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#include <zmk/behavior_queue.h>
|
||||
#include <zmk/virtual_key_position.h>
|
||||
|
||||
#include "behavior_sensor_rotate_common.h"
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
int zmk_behavior_sensor_rotate_common_trigger(struct zmk_behavior_binding *binding,
|
||||
const struct device *sensor,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
struct zmk_behavior_binding_event event,
|
||||
const struct zmk_sensor_config *sensor_config,
|
||||
size_t channel_data_size,
|
||||
const struct zmk_sensor_channel_data *channel_data) {
|
||||
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||
const struct behavior_sensor_rotate_config *cfg = dev->config;
|
||||
struct behavior_sensor_rotate_data *data = dev->data;
|
||||
|
||||
struct sensor_value value;
|
||||
const struct sensor_value value = channel_data[0].value;
|
||||
int triggers;
|
||||
int sensor_position = ZMK_SENSOR_POSITION_FROM_VIRTUAL_KEY_POSITION(event.position);
|
||||
|
||||
const int err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value);
|
||||
// Some funky special casing for "old encoder behavior" where ticks where reported in val2 only,
|
||||
// instead of rotational degrees in val1.
|
||||
// REMOVE ME: Remove after a grace period of old ec11 sensor behavior
|
||||
if (value.val1 == 0) {
|
||||
triggers = value.val2;
|
||||
} else {
|
||||
struct sensor_value remainder = data->remainder[sensor_position];
|
||||
|
||||
if (err < 0) {
|
||||
LOG_WRN("Failed to get sensor rotation value: %d", err);
|
||||
return err;
|
||||
remainder.val1 += value.val1;
|
||||
remainder.val2 += value.val2;
|
||||
|
||||
if (remainder.val2 >= 1000000 || remainder.val2 <= 1000000) {
|
||||
remainder.val1 += remainder.val2 / 1000000;
|
||||
remainder.val2 %= 1000000;
|
||||
}
|
||||
|
||||
int trigger_degrees = 360 / sensor_config->triggers_per_rotation;
|
||||
triggers = remainder.val1 / trigger_degrees;
|
||||
remainder.val1 %= trigger_degrees;
|
||||
|
||||
data->remainder[sensor_position] = remainder;
|
||||
}
|
||||
|
||||
LOG_DBG(
|
||||
"val1: %d, val2: %d, remainder: %d/%d triggers: %d inc keycode 0x%02X dec keycode 0x%02X",
|
||||
value.val1, value.val2, data->remainder[sensor_position].val1,
|
||||
data->remainder[sensor_position].val2, triggers, binding->param1, binding->param2);
|
||||
|
||||
struct zmk_behavior_binding triggered_binding;
|
||||
switch (value.val1) {
|
||||
case 1:
|
||||
if (triggers > 0) {
|
||||
triggered_binding = cfg->cw_binding;
|
||||
if (cfg->override_params) {
|
||||
triggered_binding.param1 = binding->param1;
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
} else if (triggers < 0) {
|
||||
triggers = -triggers;
|
||||
triggered_binding = cfg->ccw_binding;
|
||||
if (cfg->override_params) {
|
||||
triggered_binding.param1 = binding->param2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_DBG("Sensor binding: %s", binding->behavior_dev);
|
||||
|
||||
zmk_behavior_queue_add(event.position, triggered_binding, true, cfg->tap_ms);
|
||||
zmk_behavior_queue_add(event.position, triggered_binding, false, 0);
|
||||
for (int i = 0; i < triggers; i++) {
|
||||
zmk_behavior_queue_add(event.position, triggered_binding, true, cfg->tap_ms);
|
||||
zmk_behavior_queue_add(event.position, triggered_binding, false, 0);
|
||||
}
|
||||
|
||||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2023 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/sensors.h>
|
||||
|
||||
struct behavior_sensor_rotate_config {
|
||||
struct zmk_behavior_binding cw_binding;
|
||||
@@ -8,6 +14,12 @@ struct behavior_sensor_rotate_config {
|
||||
bool override_params;
|
||||
};
|
||||
|
||||
struct behavior_sensor_rotate_data {
|
||||
struct sensor_value remainder[ZMK_KEYMAP_SENSORS_LEN];
|
||||
};
|
||||
|
||||
int zmk_behavior_sensor_rotate_common_trigger(struct zmk_behavior_binding *binding,
|
||||
const struct device *sensor,
|
||||
struct zmk_behavior_binding_event event);
|
||||
struct zmk_behavior_binding_event event,
|
||||
const struct zmk_sensor_config *sensor_config,
|
||||
size_t channel_data_size,
|
||||
const struct zmk_sensor_channel_data *channel_data);
|
||||
@@ -24,8 +24,10 @@ static int behavior_sensor_rotate_var_init(const struct device *dev) { return 0;
|
||||
.tap_ms = DT_INST_PROP(n, tap_ms), \
|
||||
.override_params = true, \
|
||||
}; \
|
||||
static struct behavior_sensor_rotate_data behavior_sensor_rotate_var_data_##n = {}; \
|
||||
DEVICE_DT_INST_DEFINE( \
|
||||
n, behavior_sensor_rotate_var_init, NULL, NULL, &behavior_sensor_rotate_var_config_##n, \
|
||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_sensor_rotate_var_driver_api);
|
||||
n, behavior_sensor_rotate_var_init, NULL, &behavior_sensor_rotate_var_data_##n, \
|
||||
&behavior_sensor_rotate_var_config_##n, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||
&behavior_sensor_rotate_var_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(SENSOR_ROTATE_VAR_INST)
|
||||
|
||||
Reference in New Issue
Block a user