From 4461167d82e55ef391a6c7716c4ebe7945b237bb Mon Sep 17 00:00:00 2001 From: kurtis-lew Date: Mon, 24 May 2021 11:03:52 -0700 Subject: [PATCH] First version of full tap dance functionality --- app/src/behaviors/behavior_tap_dance.c | 96 +++++++++++--------------- 1 file changed, 39 insertions(+), 57 deletions(-) diff --git a/app/src/behaviors/behavior_tap_dance.c b/app/src/behaviors/behavior_tap_dance.c index c3447d04..b26a6ec4 100644 --- a/app/src/behaviors/behavior_tap_dance.c +++ b/app/src/behaviors/behavior_tap_dance.c @@ -24,7 +24,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); struct behavior_tap_dance_config { uint32_t tapping_term_ms; - struct zmk_behavior_binding behavior; + int behavior_count; + struct zmk_behavior_binding *behaviors; }; struct active_tap_dance { @@ -37,6 +38,7 @@ struct active_tap_dance { bool timer_cancelled; int64_t release_at; struct k_delayed_work release_timer; + struct zmk_behavior_binding_event event; }; struct active_tap_dance the_tap_dance; @@ -46,51 +48,6 @@ static void clear_tap_dance(struct active_tap_dance *tap_dance) { tap_dance-> position = ZMK_BHV_TAP_DANCE_POSITION_FREE; } - - -static inline int press_tap_dance_behavior(struct active_tap_dance *tap_dance, - int64_t timestamp) { - LOG_DBG("Press Tap Dance Behavior"); - struct zmk_behavior_binding binding = { - .behavior_dev = tap_dance->config->behavior.behavior_dev, - }; - struct zmk_behavior_binding_event event = { - .position = tap_dance->position, - .timestamp = timestamp, - }; - return 0; - //return behavior_keymap_binding_pressed(&binding, event); -} - -static inline int release_tap_dance_behavior(struct active_tap_dance *tap_dance, - int64_t timestamp) { - LOG_DBG("Release Tap Dance Behavior"); - struct zmk_behavior_binding binding = { - .behavior_dev = tap_dance->config->behavior.behavior_dev, - }; - struct zmk_behavior_binding_event event = { - .position = tap_dance->position, - .timestamp = timestamp, - }; - - clear_tap_dance(tap_dance); - return 0; - //return behavior_keymap_binding_released(&binding, event); -} - -/*static int stop_timer(struct active_tap_dance *tap_dance) { - LOG_DBG("Stop Timer"); - int timer_cancel_result = k_delayed_work_cancel(&tap_dance->release_timer); - if (timer_cancel_result == -EINPROGRESS) { - tap_dance->timer_cancelled = true; - } - return timer_cancel_result; - - static struct active_tap_dance *tap_dance -}*/ - - - static int on_tap_dance_binding_pressed(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) { LOG_DBG("On Binding Pressed"); @@ -100,17 +57,19 @@ static int on_tap_dance_binding_pressed(struct zmk_behavior_binding *binding, if (!the_tap_dance.timer_started){ LOG_DBG("Initializing Tap Dance"); the_tap_dance.timer_started = true; - the_tap_dance.counter = 1; + the_tap_dance.counter = 0; the_tap_dance.position = event.position; the_tap_dance.config = cfg; the_tap_dance.release_at = 0; the_tap_dance.timer_cancelled = false; the_tap_dance.timer_started = false; + } else { LOG_DBG("Incrementing Tap Dance"); - the_tap_dance.counter ++; } + the_tap_dance.counter ++; + the_tap_dance.event = event; LOG_DBG("Counter is now at value: %d", the_tap_dance.counter); return ZMK_BEHAVIOR_OPAQUE; } @@ -131,14 +90,9 @@ static int on_tap_dance_binding_released(struct zmk_behavior_binding *binding, return ZMK_BEHAVIOR_OPAQUE; } -static const struct behavior_driver_api behavior_tap_dance_driver_api = { - .binding_pressed = on_tap_dance_binding_pressed, - .binding_released = on_tap_dance_binding_released, -}; - void behavior_tap_dance_timer_handler(struct k_work *item) { LOG_DBG("Timer Handler Called"); - struct active_tap_dance *tap_dance = + struct active_tap_dance *tap_dance = CONTAINER_OF(item, struct active_tap_dance, release_timer); if (tap_dance->position == ZMK_BHV_TAP_DANCE_POSITION_FREE) { return; @@ -146,18 +100,41 @@ void behavior_tap_dance_timer_handler(struct k_work *item) { if (tap_dance->timer_cancelled) { tap_dance->timer_cancelled = false; } else { - release_tap_dance_behavior(tap_dance, tap_dance->release_at); + if (the_tap_dance.counter <= the_tap_dance.config->behavior_count) { + behavior_keymap_binding_pressed(&the_tap_dance.config->behaviors[the_tap_dance.counter-1], the_tap_dance.event); + behavior_keymap_binding_released(&the_tap_dance.config->behaviors[the_tap_dance.counter-1], the_tap_dance.event); + } + else{ + LOG_DBG("Counter exceeded number of keybinds"); + } + clear_tap_dance(tap_dance); } the_tap_dance.counter = 0; the_tap_dance.timer_started = false; } +static const struct behavior_driver_api behavior_tap_dance_driver_api = { + .binding_pressed = on_tap_dance_binding_pressed, + .binding_released = on_tap_dance_binding_released, +}; + +#define _TRANSFORM_ENTRY(idx, node) \ + { \ + .behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \ + .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 TRANSFORMED_BINDINGS(node) \ + { UTIL_LISTIFY(DT_INST_PROP_LEN(node, bindings), _TRANSFORM_ENTRY, node) } + static int behavior_tap_dance_init(const struct device *dev) { static bool init_first_run = true; if (init_first_run) { k_delayed_work_init(&the_tap_dance.release_timer, behavior_tap_dance_timer_handler); - LOG_DBG("Hello World"); the_tap_dance.position = ZMK_BHV_TAP_DANCE_POSITION_FREE; } init_first_run = false; @@ -168,8 +145,13 @@ struct behavior_tap_dance_data {}; static struct behavior_tap_dance_data behavior_tap_dance_data; #define KP_INST(n) \ + static struct zmk_behavior_binding \ + behavior_tap_dance_config_##n##_bindings[DT_INST_PROP_LEN(n, bindings)] = \ + TRANSFORMED_BINDINGS(n); \ static struct behavior_tap_dance_config behavior_tap_dance_config_##n = { \ - .tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \ + .tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \ + .behaviors = behavior_tap_dance_config_##n##_bindings, \ + .behavior_count = DT_INST_PROP_LEN(n, bindings) \ }; \ DEVICE_AND_API_INIT(behavior_tap_dance_##n, DT_INST_LABEL(n), behavior_tap_dance_init, &behavior_tap_dance_data, \ &behavior_tap_dance_config_##n, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \