diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index ed2c28c8..89f4055b 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,6 +1,7 @@ # Find Zephyr. This also loads Zephyr's build system. cmake_minimum_required(VERSION 3.13.1) +set(CONFIG_APPLICATION_DEFINED_SYSCALL true) list(APPEND BOARD_ROOT ${CMAKE_SOURCE_DIR}) list(APPEND DTS_ROOT ${CMAKE_SOURCE_DIR}) @@ -29,6 +30,8 @@ target_include_directories(app PRIVATE include) target_sources(app PRIVATE src/kscan.c) target_sources(app PRIVATE src/keymap.c) target_sources(app PRIVATE src/hid.c) +target_sources(app PRIVATE src/behaviors/behavior_key_press.c) +target_sources(app PRIVATE src/behaviors/behavior_reset.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c) target_sources_ifdef(CONFIG_ZMK_KSCAN_MOCK_DRIVER app PRIVATE src/kscan_mock.c) target_sources_ifdef(CONFIG_ZMK_KSCAN_COMPOSITE_DRIVER app PRIVATE src/kscan_composite.c) diff --git a/app/boards/arm/nice_nano/nice_nano.dts b/app/boards/arm/nice_nano/nice_nano.dts index 21b60d38..4604e9a6 100644 --- a/app/boards/arm/nice_nano/nice_nano.dts +++ b/app/boards/arm/nice_nano/nice_nano.dts @@ -6,6 +6,8 @@ /dts-v1/; #include +#include +#include #include "arduino_pro_micro_pins.dtsi" / { diff --git a/app/boards/shields/petejohanson_handwire/keymap/keymap.overlay b/app/boards/shields/petejohanson_handwire/keymap/keymap.overlay index d87363f9..8cb76541 100644 --- a/app/boards/shields/petejohanson_handwire/keymap/keymap.overlay +++ b/app/boards/shields/petejohanson_handwire/keymap/keymap.overlay @@ -1,4 +1,6 @@ #include +#include +#include #include / { @@ -21,6 +23,9 @@ KC_A MT(MOD_LSFT, KC_B) ZC_NO ZC_NO CC_RAIS CC_LOWR ZC_NO ZC_NO >; + bindings = < + &reset &kp 0 + &kp 1 &kp 2>; }; lower: layer_1 { @@ -29,6 +34,10 @@ KC_MPLY KC_MNXT ZC_NO ZC_NO ZC_TRNS ZC_TRNS ZC_NO ZC_NO >; + + bindings = < + &reset &kp 0 + &kp 1 &kp 2>; }; raise: layer_2 { @@ -36,6 +45,10 @@ keys = < KC_C KC_D ZC_NO ZC_NO ZC_TRNS ZC_TRNS ZC_NO ZC_NO>; + + bindings = < + &reset &kp 0 + &kp 1 &kp 2>; }; }; }; diff --git a/app/boards/shields/petejohanson_proton_handwire/keymap/keymap.overlay b/app/boards/shields/petejohanson_proton_handwire/keymap/keymap.overlay index c1bd5425..f4d746ed 100644 --- a/app/boards/shields/petejohanson_proton_handwire/keymap/keymap.overlay +++ b/app/boards/shields/petejohanson_proton_handwire/keymap/keymap.overlay @@ -21,6 +21,9 @@ KC_A MT(MOD_LSFT, KC_B) CC_RAIS CC_LOWR >; + bindings = < + &reset &kp 0 + &kp 1 &kp 2>; }; lower: layer_1 { @@ -29,6 +32,9 @@ KC_MPLY KC_MNXT ZC_TRNS ZC_TRNS >; + bindings = < + &reset &kp 0 + &kp 1 &kp 2>; }; raise: layer_2 { @@ -37,6 +43,9 @@ KC_C KC_D ZC_TRNS ZC_TRNS >; + bindings = < + &reset &kp 0 + &kp 1 &kp 2>; }; }; }; diff --git a/app/dts/behaviors/key_press.dtsi b/app/dts/behaviors/key_press.dtsi new file mode 100644 index 00000000..7c7ac5b3 --- /dev/null +++ b/app/dts/behaviors/key_press.dtsi @@ -0,0 +1,9 @@ +/ { + behaviors { + kp: behavior_key_press { + compatible = "zmk,behavior-key-press"; + label = "KEY_PRESS"; + #binding-cells = <1>; + }; + }; +}; diff --git a/app/dts/behaviors/reset.dtsi b/app/dts/behaviors/reset.dtsi new file mode 100644 index 00000000..4e3b4446 --- /dev/null +++ b/app/dts/behaviors/reset.dtsi @@ -0,0 +1,9 @@ +/ { + behaviors { + reset: behavior_reset { + compatible = "zmk,behavior-reset"; + label = "RESET"; + #binding-cells = <0>; + }; + }; +}; diff --git a/app/dts/bindings/behaviors/one_param.yaml b/app/dts/bindings/behaviors/one_param.yaml new file mode 100644 index 00000000..1f33aee2 --- /dev/null +++ b/app/dts/bindings/behaviors/one_param.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2020, Pete Johanson +# SPDX-License-Identifier: MIT + +properties: + label: + type: string + required: true + "#binding-cells": + type: int + required: true + const: 1 + +binding-cells: + - param1 diff --git a/app/dts/bindings/behaviors/two_param.yaml b/app/dts/bindings/behaviors/two_param.yaml new file mode 100644 index 00000000..f8b3af93 --- /dev/null +++ b/app/dts/bindings/behaviors/two_param.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2020, Pete Johanson +# SPDX-License-Identifier: MIT + +properties: + label: + type: string + required: true + "#binding-cells": + type: int + required: true + const: 2 + +binding-cells: + - param1 + - param2 diff --git a/app/dts/bindings/behaviors/zero_param.yaml b/app/dts/bindings/behaviors/zero_param.yaml new file mode 100644 index 00000000..20f15288 --- /dev/null +++ b/app/dts/bindings/behaviors/zero_param.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2020, Pete Johanson +# SPDX-License-Identifier: MIT + +properties: + label: + type: string + required: true + "#binding-cells": + type: int + required: true + const: 0 diff --git a/app/dts/bindings/behaviors/zmk,behavior-key-press.yaml b/app/dts/bindings/behaviors/zmk,behavior-key-press.yaml new file mode 100644 index 00000000..0169d7d5 --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-key-press.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2020, Pete Johanson +# SPDX-License-Identifier: MIT + +description: Key press/release behavior + +compatible: "zmk,behavior-key-press" + +include: one_param.yaml diff --git a/app/dts/bindings/behaviors/zmk,behavior-reset.yaml b/app/dts/bindings/behaviors/zmk,behavior-reset.yaml new file mode 100644 index 00000000..c8e5e6fb --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-reset.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2020, Pete Johanson +# SPDX-License-Identifier: MIT + +description: Keyboard Reset Behavior + +compatible: "zmk,behavior-reset" + +include: zero_param.yaml diff --git a/app/dts/bindings/zmk,layers.yaml b/app/dts/bindings/zmk,layers.yaml index c9b462a1..2bbb0231 100644 --- a/app/dts/bindings/zmk,layers.yaml +++ b/app/dts/bindings/zmk,layers.yaml @@ -11,4 +11,5 @@ child-binding: type: string keys: type: array - + bindings: + type: phandle-array diff --git a/app/include/drivers/behavior.h b/app/include/drivers/behavior.h new file mode 100644 index 00000000..84b11ce2 --- /dev/null +++ b/app/include/drivers/behavior.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020 Peter Johanson + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @cond INTERNAL_HIDDEN + * + * Behavior driver API definition and system call entry points. + * + * (Internal use only.) + */ + +typedef int (*behavior_position_pressed_t)(struct device *dev, u32_t param1, u32_t param2); +typedef int (*behavior_position_released_t)(struct device *dev, u32_t param1, u32_t param2); + +__subsystem struct behavior_driver_api { + behavior_position_pressed_t position_pressed; + behavior_position_released_t position_released; +}; +/** + * @endcond + */ + +/** + * @brief Handle the assigned position being pressed + * @param dev Pointer to the device structure for the driver instance. + * @param param1 User parameter specified at time of behavior assignment. + * + * @retval 0 If successful. + * @retval Negative errno code if failure. + */ +__syscall int behavior_position_pressed(struct device *dev, u32_t param1, u32_t param2); + +static inline int z_impl_behavior_position_pressed(struct device *dev, u32_t param1, u32_t param2) +{ + const struct behavior_driver_api *api = + (const struct behavior_driver_api *)dev->driver_api; + + if (api->position_pressed == NULL) { + return -ENOTSUP; + } + + return api->position_pressed(dev, param1, param2); +} + +/** + * @brief Handle the assigned position being pressed + * @param dev Pointer to the device structure for the driver instance. + * @param param1 User parameter specified at time of behavior assignment. + * + * @retval 0 If successful. + * @retval Negative errno code if failure. + */ +__syscall int behavior_position_released(struct device *dev, u32_t param1, u32_t param2); + +static inline int z_impl_behavior_position_released(struct device *dev, u32_t param1, u32_t param2) +{ + const struct behavior_driver_api *api = + (const struct behavior_driver_api *)dev->driver_api; + + if (api->position_released == NULL) { + return -ENOTSUP; + } + + return api->position_released(dev, param1, param2); +} + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#include diff --git a/app/include/zmk/keymap.h b/app/include/zmk/keymap.h index 285b0718..7866cd57 100644 --- a/app/include/zmk/keymap.h +++ b/app/include/zmk/keymap.h @@ -6,23 +6,9 @@ #include #include -#include - -#define ZMK_KEYMAP_NODE DT_CHOSEN(zmk_keymap) -#define ZMK_KEYMAP_LAYERS_LEN DT_PROP_LEN(ZMK_KEYMAP_NODE, layers) - -/* TODO: Need to actually be able to get a NODELABEL from a node id -#define _ZMK_KEYMAP_GENERATE_LAYER_CONST(node_id) \ - DT_NODELABEL_FOR_NODE(node_id)_layer, - -enum zmk_keymap_layer -{ - DT_FOREACH_CHILD(DT_INST(0, zmk_layers), _ZMK_KEYMAP_GENERATE_LAYER_CONST) -}; -*/ +// #include bool zmk_keymap_layer_activate(u8_t layer); bool zmk_keymap_layer_deactivate(u8_t layer); -zmk_key -zmk_keymap_keycode_from_position(u32_t row, u32_t column); +int zmk_keymap_position_state_changed(u32_t row, u32_t column, bool pressed); diff --git a/app/prj.conf b/app/prj.conf index f5b2d4a9..cba93112 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -1,3 +1,4 @@ -# CONFIG_LOG=y -# CONFIG_ZMK_LOG_LEVEL_DBG=y +CONFIG_LOG=y +CONFIG_ZMK_LOG_LEVEL_DBG=y CONFIG_KERNEL_BIN_NAME="zmk" +CONFIG_REBOOT=y \ No newline at end of file diff --git a/app/src/behaviors/behavior_key_press.c b/app/src/behaviors/behavior_key_press.c new file mode 100644 index 00000000..b9d0ff04 --- /dev/null +++ b/app/src/behaviors/behavior_key_press.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 Peter Johanson + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_key_press + +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct behavior_key_press_config { }; +struct behavior_key_press_data { }; + +static int behavior_key_press_init(struct device *dev) +{ + return 0; +}; + + +// They keycode is passed by the "keymap" based on the parameter created as part of the assignment. +// Other drivers instead might activate a layer, update the consumer page state, or update the RGB state, etc. +// Returns: +// * > 0 - indicate successful processing, and halt further handling, +// * 0 - Indicate successful processing, and continue propagation. +// * < 0 - Indicate error processing, report and halt further propagation. +static int on_position_pressed(struct device *dev, u32_t keycode, u32_t _) +{ + // Invoking this triggers a *new* event, that can be linked to other behaviours. + //return zmk_key_state_press(u32_t keycode); + return 0; +} + + +// They keycode is passed by the "keymap" based on the parameter created as part of the assignment. +static int on_position_released(struct device *dev, u32_t keycode, u32_t _) +{ + // Invoking this triggers a *new* event, that can will be handled by other behaviors + // This is the "command" piece. Which could be better/richer, but captures essence here. + // return zmk_key_state_release(u32_t keycode); + return 0; +} + +static const struct behavior_driver_api behavior_key_press_driver_api = { + // These callbacks are all optional, and define which kinds of events the behavior can handle. + // They can reference local functions defined here, or shared event handlers. + .position_pressed = on_position_pressed, + .position_released = on_position_released + // Other optional callbacks a behavior can implement + // .on_mouse_moved + // .on_sensor_data - Any behaviour that wants to be linked to a censor can implement this behavior +}; + + +static const struct behavior_key_press_config behavior_key_press_config = {}; + +static struct behavior_key_press_data behavior_key_press_data; + +DEVICE_AND_API_INIT(behavior_key_press, DT_INST_LABEL(0), behavior_key_press_init, + &behavior_key_press_data, + &behavior_key_press_config, + APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &behavior_key_press_driver_api); diff --git a/app/src/behaviors/behavior_reset.c b/app/src/behaviors/behavior_reset.c new file mode 100644 index 00000000..1609fad6 --- /dev/null +++ b/app/src/behaviors/behavior_reset.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 Peter Johanson + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_reset + +#include +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct behavior_reset_config { }; +struct behavior_reset_data { }; + +static int behavior_reset_init(struct device *dev) +{ + return 0; +}; + +static int on_position_pressed(struct device *dev, u32_t _param1, u32_t _param2) +{ + // TODO: Correct magic code for going into DFU? + // See https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/d6b28e66053eea467166f44875e3c7ec741cb471/src/main.c#L107 + sys_reboot(0); + return 0; +} + +static int on_position_released(struct device *dev, u32_t _param1, u32_t _param2) +{ + return 0; +} + +static const struct behavior_driver_api behavior_reset_driver_api = { + .position_pressed = on_position_pressed, + .position_released = on_position_released +}; + + +static const struct behavior_reset_config behavior_reset_config = {}; + +static struct behavior_reset_data behavior_reset_data; + +DEVICE_AND_API_INIT(behavior_reset, DT_INST_LABEL(0), behavior_reset_init, + &behavior_reset_data, + &behavior_reset_config, + APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &behavior_reset_driver_api); \ No newline at end of file diff --git a/app/src/keymap.c b/app/src/keymap.c index 1cb705e2..386de81f 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -3,22 +3,48 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include +#include #include static u32_t zmk_keymap_layer_state = 0; static u8_t zmk_keymap_layer_default = 0; +struct zmk_behavior_binding { + char *behavior_dev; + u32_t param1; + u32_t param2; +}; + +#define ZMK_KEYMAP_NODE DT_CHOSEN(zmk_keymap) +#define ZMK_KEYMAP_LAYERS_LEN DT_PROP_LEN(ZMK_KEYMAP_NODE, layers) + +#define LAYER_NODE(l) DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, l) + +#define BINDING_FOR_IDX(layer,idx) \ + { .behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, layer), bindings, idx)), \ + .param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(LAYER_NODE(layer), bindings, idx, param1), (0), (DT_PHA_BY_IDX(LAYER_NODE(layer), bindings, idx, param1))), \ + .param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(LAYER_NODE(layer), bindings, idx, param2), (0), (DT_PHA_BY_IDX(LAYER_NODE(layer), bindings, idx, param2))), \ + } + #if DT_NODE_HAS_PROP(ZMK_KEYMAP_NODE, transform) #define ZMK_KEYMAP_TRANSFORM_NODE DT_PHANDLE(ZMK_KEYMAP_NODE, transform) #define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_TRANSFORM_NODE, map) #define _TRANSFORM_ENTRY(i, l) \ - [(KT_ROW(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i)) * ZMK_MATRIX_COLS) + KT_COL(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i))] = DT_PROP_BY_IDX(DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, l), keys, i), + [(KT_ROW(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i)) * ZMK_MATRIX_COLS) + KT_COL(DT_PROP_BY_IDX(ZMK_KEYMAP_TRANSFORM_NODE, map, i))] = BINDING_FOR_IDX(l,i), + +#else + +#define ZMK_KEYMAP_LEN DT_PROP_LEN(ZMK_KEYMAP_NODE, bindings) +#define _TRANSFORM_ENTRY(i, l) \ + BINDING_FOR_IDX(l,i), + +#endif #define TRANSFORMED_LAYER(idx) \ - { UTIL_LISTIFY(ZMK_KEYMAP_LEN, _TRANSFORM_ENTRY, idx) } + { UTIL_LISTIFY(DT_PROP_LEN(DT_PHANDLE_BY_IDX(ZMK_KEYMAP_NODE, layers, idx), bindings), _TRANSFORM_ENTRY, idx) } -static zmk_key zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = { +static struct zmk_behavior_binding zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = { #if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 0) TRANSFORMED_LAYER(0), #endif @@ -51,36 +77,7 @@ static zmk_key zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_CO #endif }; -#else - -static zmk_key zmk_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_MATRIX_ROWS * ZMK_MATRIX_COLS] = { -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 0) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 0, keys), -#endif -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 1) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 1, keys), -#endif -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 2) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 2, keys), -#endif -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 3) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 3, keys), -#endif -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 4) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 4, keys), -#endif -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 5) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 5, keys), -#endif -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 6) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 6, keys), -#endif -#if DT_PROP_HAS_IDX(ZMK_KEYMAP_NODE, layers, 7) - DT_PROP_BY_PHANDLE_IDX(ZMK_KEYMAP_NODE, layers, 7, keys), -#endif -}; - -#endif +// #else #define SET_LAYER_STATE(layer, state) \ if (layer >= 32) \ @@ -100,24 +97,38 @@ bool zmk_keymap_layer_deactivate(u8_t layer) SET_LAYER_STATE(layer, false); }; -zmk_key zmk_keymap_keycode_from_position(u32_t row, u32_t column) +int zmk_keymap_position_state_changed(u32_t row, u32_t column, bool pressed) { for (int layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer >= zmk_keymap_layer_default; layer--) { if ((zmk_keymap_layer_state & BIT(layer)) == BIT(layer) || layer == zmk_keymap_layer_default) { u8_t key_index = (row * ZMK_MATRIX_COLS) + column; - LOG_DBG("Getting key at index %d", key_index); + struct zmk_behavior_binding *binding = &zmk_keymap[layer][key_index]; + struct device *behavior; + int ret; - zmk_key key = zmk_keymap[layer][key_index]; - if (key == ZC_TRNS) - { - continue; + LOG_DBG("key index: %d, binding name: %s", key_index, binding->behavior_dev); + + behavior = device_get_binding(binding->behavior_dev); + if (pressed) { + ret = behavior_position_pressed(behavior, binding->param1, binding->param2); + } else { + ret = behavior_position_released(behavior, binding->param1, binding->param2); } + - return key; + if (ret > 0) { + LOG_DBG("behavior processing to continue to next layer"); + continue; + } else if (ret < 0) { + LOG_DBG("Behavior returned error: %d", ret); + return ret; + } else { + return ret; + } } } - return ZC_NO; + return -ENOTSUP; } diff --git a/app/src/kscan.c b/app/src/kscan.c index 1f54a147..d1ed6210 100644 --- a/app/src/kscan.c +++ b/app/src/kscan.c @@ -49,11 +49,12 @@ void zmk_kscan_process_msgq(struct k_work *item) while (k_msgq_get(&zmk_kscan_msgq, &ev, K_NO_WAIT) == 0) { bool pressed = (ev.state == ZMK_KSCAN_EVENT_STATE_PRESSED); - zmk_key key = zmk_keymap_keycode_from_position(ev.row, ev.column); - struct zmk_key_event kev = (struct zmk_key_event){.row = ev.row, .column = ev.column, .key = key, .pressed = pressed}; + zmk_keymap_position_state_changed(ev.row, ev.column, pressed); + // zmk_key key = zmk_keymap_keycode_from_position(ev.row, ev.column); + // struct zmk_key_event kev = (struct zmk_key_event){.row = ev.row, .column = ev.column, .key = key, .pressed = pressed}; - LOG_DBG("Row: %d, col: %d, key: %d, pressed: %s\n", ev.row, ev.column, key, (pressed ? "true" : "false")); - zmk_handle_key(kev); + // LOG_DBG("Row: %d, col: %d, key: %d, pressed: %s\n", ev.row, ev.column, key, (pressed ? "true" : "false")); + // zmk_handle_key(kev); } }