aboutsummaryrefslogtreecommitdiffhomepage
path: root/app/src
diff options
context:
space:
mode:
authorNick Conway <[email protected]>2022-05-23 16:33:08 -0400
committerPete Johanson <[email protected]>2023-04-21 21:13:31 -0700
commit3db163aa2cf7db2bd710ba93b57f3eb804b086c7 (patch)
tree3154e3d3cbb63235af8f37a9ccab76af0c78d78f /app/src
parent9a73650041da7008fa2df7bd8bbb02ecc8efd9b4 (diff)
downloadzmk-3db163aa2cf7db2bd710ba93b57f3eb804b086c7.tar.gz
zmk-3db163aa2cf7db2bd710ba93b57f3eb804b086c7.zip
feat(behaviors): Add reusable sensor behaviors.
* Add new sensor behaviors that either take full bindings add definition, or accept parameters when bound in the keymap. * Remove existing hard-coded key press sensor behavior and instead leverage new generic sensor behaviors to achieve the same functionality. Co-authored-by: [email protected]
Diffstat (limited to 'app/src')
-rw-r--r--app/src/behaviors/behavior_sensor_rotate.c40
-rw-r--r--app/src/behaviors/behavior_sensor_rotate_common.c52
-rw-r--r--app/src/behaviors/behavior_sensor_rotate_common.h13
-rw-r--r--app/src/behaviors/behavior_sensor_rotate_key_press.c69
-rw-r--r--app/src/behaviors/behavior_sensor_rotate_var.c31
-rw-r--r--app/src/keymap.c5
6 files changed, 139 insertions, 71 deletions
diff --git a/app/src/behaviors/behavior_sensor_rotate.c b/app/src/behaviors/behavior_sensor_rotate.c
new file mode 100644
index 0000000000..e12278bba1
--- /dev/null
+++ b/app/src/behaviors/behavior_sensor_rotate.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 The ZMK Contributors
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#define DT_DRV_COMPAT zmk_behavior_sensor_rotate
+
+#include <zephyr/device.h>
+
+#include <drivers/behavior.h>
+
+#include "behavior_sensor_rotate_common.h"
+
+static const struct behavior_driver_api behavior_sensor_rotate_driver_api = {
+ .sensor_binding_triggered = zmk_behavior_sensor_rotate_common_trigger};
+
+static int behavior_sensor_rotate_init(const struct device *dev) { return 0; };
+
+#define _TRANSFORM_ENTRY(idx, node) \
+ { \
+ .behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(node, bindings, idx), label), \
+ .param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \
+ (DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
+ .param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \
+ (DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \
+ }
+
+#define SENSOR_ROTATE_INST(n) \
+ static struct behavior_sensor_rotate_config behavior_sensor_rotate_config_##n = { \
+ .cw_binding = _TRANSFORM_ENTRY(0, n), \
+ .ccw_binding = _TRANSFORM_ENTRY(1, n), \
+ .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);
+
+DT_INST_FOREACH_STATUS_OKAY(SENSOR_ROTATE_INST)
diff --git a/app/src/behaviors/behavior_sensor_rotate_common.c b/app/src/behaviors/behavior_sensor_rotate_common.c
new file mode 100644
index 0000000000..bd31170eda
--- /dev/null
+++ b/app/src/behaviors/behavior_sensor_rotate_common.c
@@ -0,0 +1,52 @@
+
+#include <zephyr/device.h>
+#include <zephyr/drivers/sensor.h>
+#include <zephyr/logging/log.h>
+#include <zephyr/kernel.h>
+
+#include <zmk/behavior_queue.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) {
+ const struct device *dev = device_get_binding(binding->behavior_dev);
+ const struct behavior_sensor_rotate_config *cfg = dev->config;
+
+ struct sensor_value value;
+
+ const int err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value);
+
+ if (err < 0) {
+ LOG_WRN("Failed to get sensor rotation value: %d", err);
+ return err;
+ }
+
+ struct zmk_behavior_binding triggered_binding;
+ switch (value.val1) {
+ case 1:
+ triggered_binding = cfg->cw_binding;
+ if (cfg->override_params) {
+ triggered_binding.param1 = binding->param1;
+ }
+ break;
+ case -1:
+ triggered_binding = cfg->ccw_binding;
+ if (cfg->override_params) {
+ triggered_binding.param1 = binding->param2;
+ }
+ break;
+ default:
+ return -ENOTSUP;
+ }
+
+ 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);
+
+ return ZMK_BEHAVIOR_OPAQUE;
+}
diff --git a/app/src/behaviors/behavior_sensor_rotate_common.h b/app/src/behaviors/behavior_sensor_rotate_common.h
new file mode 100644
index 0000000000..2d58218d8a
--- /dev/null
+++ b/app/src/behaviors/behavior_sensor_rotate_common.h
@@ -0,0 +1,13 @@
+
+#include <zmk/behavior.h>
+
+struct behavior_sensor_rotate_config {
+ struct zmk_behavior_binding cw_binding;
+ struct zmk_behavior_binding ccw_binding;
+ int tap_ms;
+ bool override_params;
+};
+
+int zmk_behavior_sensor_rotate_common_trigger(struct zmk_behavior_binding *binding,
+ const struct device *sensor,
+ struct zmk_behavior_binding_event event); \ No newline at end of file
diff --git a/app/src/behaviors/behavior_sensor_rotate_key_press.c b/app/src/behaviors/behavior_sensor_rotate_key_press.c
deleted file mode 100644
index 72e33ea46b..0000000000
--- a/app/src/behaviors/behavior_sensor_rotate_key_press.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2020 The ZMK Contributors
- *
- * SPDX-License-Identifier: MIT
- */
-
-#define DT_DRV_COMPAT zmk_behavior_sensor_rotate_key_press
-
-#include <zephyr/device.h>
-#include <zephyr/drivers/sensor.h>
-#include <zephyr/logging/log.h>
-
-#include <drivers/behavior.h>
-#include <zmk/event_manager.h>
-#include <zmk/events/keycode_state_changed.h>
-
-LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
-
-#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
-
-static int behavior_sensor_rotate_key_press_init(const struct device *dev) { return 0; };
-
-static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding,
- const struct device *sensor, uint32_t virtual_key_position,
- int64_t timestamp) {
- struct sensor_value value;
- int err;
- uint32_t keycode;
- LOG_DBG("inc keycode 0x%02X dec keycode 0x%02X", binding->param1, binding->param2);
-
- err = sensor_channel_get(sensor, SENSOR_CHAN_ROTATION, &value);
-
- if (err) {
- LOG_WRN("Failed to ge sensor rotation value: %d", err);
- return err;
- }
-
- switch (value.val1) {
- case 1:
- keycode = binding->param1;
- break;
- case -1:
- keycode = binding->param2;
- break;
- default:
- return -ENOTSUP;
- }
-
- LOG_DBG("SEND %d", keycode);
-
- ZMK_EVENT_RAISE(zmk_keycode_state_changed_from_encoded(keycode, true, timestamp));
-
- // TODO: Better way to do this?
- k_msleep(5);
-
- return ZMK_EVENT_RAISE(zmk_keycode_state_changed_from_encoded(keycode, false, timestamp));
-}
-
-static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_api = {
- .sensor_binding_triggered = on_sensor_binding_triggered};
-
-#define KP_INST(n) \
- DEVICE_DT_INST_DEFINE(n, behavior_sensor_rotate_key_press_init, NULL, NULL, NULL, APPLICATION, \
- CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
- &behavior_sensor_rotate_key_press_driver_api);
-
-DT_INST_FOREACH_STATUS_OKAY(KP_INST)
-
-#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
diff --git a/app/src/behaviors/behavior_sensor_rotate_var.c b/app/src/behaviors/behavior_sensor_rotate_var.c
new file mode 100644
index 0000000000..a82267a55e
--- /dev/null
+++ b/app/src/behaviors/behavior_sensor_rotate_var.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2022 The ZMK Contributors
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#define DT_DRV_COMPAT zmk_behavior_sensor_rotate_var
+
+#include <zephyr/device.h>
+
+#include <drivers/behavior.h>
+
+#include "behavior_sensor_rotate_common.h"
+
+static const struct behavior_driver_api behavior_sensor_rotate_var_driver_api = {
+ .sensor_binding_triggered = zmk_behavior_sensor_rotate_common_trigger};
+
+static int behavior_sensor_rotate_var_init(const struct device *dev) { return 0; };
+
+#define SENSOR_ROTATE_VAR_INST(n) \
+ static struct behavior_sensor_rotate_config behavior_sensor_rotate_var_config_##n = { \
+ .cw_binding = {.behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 0), label)}, \
+ .ccw_binding = {.behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 1), label)}, \
+ .tap_ms = DT_INST_PROP(n, tap_ms), \
+ .override_params = true, \
+ }; \
+ 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);
+
+DT_INST_FOREACH_STATUS_OKAY(SENSOR_ROTATE_VAR_INST)
diff --git a/app/src/keymap.c b/app/src/keymap.c
index 1f55ad03d3..909fd20de8 100644
--- a/app/src/keymap.c
+++ b/app/src/keymap.c
@@ -270,8 +270,9 @@ int zmk_keymap_sensor_triggered(uint8_t sensor_number, const struct device *sens
continue;
}
- const uint32_t position = ZMK_VIRTUAL_KEY_POSITION_SENSOR(sensor_number);
- ret = behavior_sensor_keymap_binding_triggered(binding, sensor, position, timestamp);
+ struct zmk_behavior_binding_event event = {
+ .position = ZMK_VIRTUAL_KEY_POSITION_SENSOR(sensor_number), .timestamp = timestamp};
+ ret = behavior_sensor_keymap_binding_triggered(binding, sensor, event);
if (ret > 0) {
LOG_DBG("behavior processing to continue to next layer");