diff options
114 files changed, 1562 insertions, 397 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e22dc65..e6be31a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,10 @@ -on: [push, pull_request] +on: + push: + paths: + - "app/**" + pull_request: + paths: + - "app/**" name: Build diff --git a/.github/workflows/doc-checks.yml b/.github/workflows/doc-checks.yml new file mode 100644 index 0000000..a31a88e --- /dev/null +++ b/.github/workflows/doc-checks.yml @@ -0,0 +1,35 @@ +name: doc-checks + +on: + push: + paths: + - "docs/**" + pull_request: + paths: + - "docs/**" + +jobs: + lint: + runs-on: ubuntu-latest + name: ESLint + + steps: + - uses: actions/checkout@v2 + - uses: bahmutov/npm-install@v1 + with: + working-directory: docs + - name: ESLint + run: npm run lint + working-directory: docs + prettier: + runs-on: ubuntu-latest + name: Prettier + + steps: + - uses: actions/checkout@v2 + - uses: bahmutov/npm-install@v1 + with: + working-directory: docs + - name: Prettier Check + run: npm run prettier:check + working-directory: docs diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 8a3971e..7a12a81 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -37,11 +37,13 @@ target_sources(app PRIVATE src/events/keycode_state_changed.c) target_sources(app PRIVATE src/events/modifiers_state_changed.c) target_sources(app PRIVATE src/events/sensor_event.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/ble_active_profile_changed.c) +target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c) if (NOT CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL) target_sources(app PRIVATE src/behaviors/behavior_key_press.c) target_sources(app PRIVATE src/behaviors/behavior_reset.c) target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c) target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c) + target_sources(app PRIVATE src/behaviors/behavior_outputs.c) target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c) target_sources(app PRIVATE src/behaviors/behavior_transparent.c) target_sources(app PRIVATE src/behaviors/behavior_none.c) @@ -52,6 +54,7 @@ endif() target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/behaviors/behavior_rgb_underglow.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/behaviors/behavior_bt.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c) +target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/battery.c) target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL app PRIVATE src/split_listener.c) target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL app PRIVATE src/split/bluetooth/service.c) target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL app PRIVATE src/split/bluetooth/central.c) diff --git a/app/boards/arm/bluemicro840/bluemicro840_v1.dts b/app/boards/arm/bluemicro840/bluemicro840_v1.dts index 32aa2e6..141dbe1 100644 --- a/app/boards/arm/bluemicro840/bluemicro840_v1.dts +++ b/app/boards/arm/bluemicro840/bluemicro840_v1.dts @@ -31,7 +31,7 @@ vbatt { compatible = "zmk,battery-voltage-divider"; - label = "VOLTAGE_DIVIDER"; + label = "BATTERY"; io-channels = <&adc 7>; output-ohms = <2000000>; full-ohms = <(2000000 + 806000)>; @@ -82,27 +82,32 @@ #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "adafruit_boot"; - reg = <0x000000000 0x0000C000>; + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; }; code_partition: partition@26000 { label = "code_partition"; - reg = <0x00026000 0x000d2000>; + reg = <0x00026000 0x000c6000>; }; /* - * The flash starting at 0x000f8000 and ending at - * 0x000fffff is reserved for use by the application. + * The flash starting at 0x000ec000 and ending at + * 0x000f3fff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ - storage_partition: partition@f8000 { + storage_partition: partition@ec000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; }; }; }; diff --git a/app/boards/arm/nice_nano/nice_nano.dts b/app/boards/arm/nice_nano/nice_nano.dts index 1819541..a9bdeb3 100644 --- a/app/boards/arm/nice_nano/nice_nano.dts +++ b/app/boards/arm/nice_nano/nice_nano.dts @@ -37,7 +37,7 @@ vbatt { compatible = "zmk,battery-voltage-divider"; - label = "VOLTAGE_DIVIDER"; + label = "BATTERY"; io-channels = <&adc 2>; output-ohms = <2000000>; full-ohms = <(2000000 + 806000)>; @@ -91,27 +91,32 @@ #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "adafruit_boot"; - reg = <0x000000000 0x0000C000>; + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; }; code_partition: partition@26000 { label = "code_partition"; - reg = <0x00026000 0x000d2000>; + reg = <0x00026000 0x000c6000>; }; /* - * The flash starting at 0x000f8000 and ending at - * 0x000fffff is reserved for use by the application. + * The flash starting at 0x000ec000 and ending at + * 0x000f3fff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ - storage_partition: partition@f8000 { + storage_partition: partition@ec000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; }; }; }; diff --git a/app/boards/arm/nrf52840_m2/nrf52840_m2.dts b/app/boards/arm/nrf52840_m2/nrf52840_m2.dts index fb5b0ff..e998b39 100644 --- a/app/boards/arm/nrf52840_m2/nrf52840_m2.dts +++ b/app/boards/arm/nrf52840_m2/nrf52840_m2.dts @@ -71,27 +71,32 @@ #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "adafruit_boot"; - reg = <0x000000000 0x0000C000>; + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; }; code_partition: partition@26000 { label = "code_partition"; - reg = <0x00026000 0x000d2000>; + reg = <0x00026000 0x000c6000>; }; /* - * The flash starting at 0x000f8000 and ending at - * 0x000fffff is reserved for use by the application. + * The flash starting at 0x000ec000 and ending at + * 0x000f3fff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ - storage_partition: partition@f8000 { + storage_partition: partition@ec000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; }; }; }; diff --git a/app/boards/arm/nrfmicro/nrfmicro_11.dts b/app/boards/arm/nrfmicro/nrfmicro_11.dts index 87c650e..0cec662 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_11.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_11.dts @@ -72,27 +72,32 @@ #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "adafruit_boot"; - reg = <0x000000000 0x0000C000>; + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; }; code_partition: partition@26000 { label = "code_partition"; - reg = <0x00026000 0x000d2000>; + reg = <0x00026000 0x000c6000>; }; /* - * The flash starting at 0x000f8000 and ending at - * 0x000fffff is reserved for use by the application. + * The flash starting at 0x000ec000 and ending at + * 0x000f3fff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ - storage_partition: partition@f8000 { + storage_partition: partition@ec000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; }; }; }; diff --git a/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts b/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts index ea15b81..6c1bb6a 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_11_flipped.dts @@ -72,27 +72,32 @@ #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "adafruit_boot"; - reg = <0x000000000 0x0000C000>; + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; }; code_partition: partition@26000 { label = "code_partition"; - reg = <0x00026000 0x000d2000>; + reg = <0x00026000 0x000c6000>; }; /* - * The flash starting at 0x000f8000 and ending at - * 0x000fffff is reserved for use by the application. + * The flash starting at 0x000ec000 and ending at + * 0x000f3fff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ - storage_partition: partition@f8000 { + storage_partition: partition@ec000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; }; }; -}; +};
\ No newline at end of file diff --git a/app/boards/arm/nrfmicro/nrfmicro_13.dts b/app/boards/arm/nrfmicro/nrfmicro_13.dts index 5ae11ba..2910980 100644 --- a/app/boards/arm/nrfmicro/nrfmicro_13.dts +++ b/app/boards/arm/nrfmicro/nrfmicro_13.dts @@ -34,7 +34,7 @@ vbatt { compatible = "zmk,battery-voltage-divider"; - label = "VOLTAGE_DIVIDER"; + label = "BATTERY"; io-channels = <&adc 2>; output-ohms = <2000000>; full-ohms = <(2000000 + 820000)>; @@ -84,27 +84,32 @@ #address-cells = <1>; #size-cells = <1>; - boot_partition: partition@0 { - label = "adafruit_boot"; - reg = <0x000000000 0x0000C000>; + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; }; code_partition: partition@26000 { label = "code_partition"; - reg = <0x00026000 0x000d2000>; + reg = <0x00026000 0x000c6000>; }; /* - * The flash starting at 0x000f8000 and ending at - * 0x000fffff is reserved for use by the application. + * The flash starting at 0x000ec000 and ending at + * 0x000f3fff is reserved for use by the application. */ /* * Storage partition will be used by FCB/LittleFS/NVS * if enabled. */ - storage_partition: partition@f8000 { + storage_partition: partition@ec000 { label = "storage"; - reg = <0x000f8000 0x00008000>; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; }; }; }; diff --git a/app/drivers/zephyr/battery_voltage_divider.c b/app/drivers/zephyr/battery_voltage_divider.c index 37ac024..b94e2a2 100644 --- a/app/drivers/zephyr/battery_voltage_divider.c +++ b/app/drivers/zephyr/battery_voltage_divider.c @@ -61,7 +61,9 @@ static int bvd_sample_fetch(struct device *dev, enum sensor_channel chan) { struct adc_sequence *as = &drv_data->as; // Make sure selected channel is supported - if (chan != SENSOR_CHAN_GAUGE_VOLTAGE && chan != SENSOR_CHAN_GAUGE_STATE_OF_CHARGE) { + if (chan != SENSOR_CHAN_GAUGE_VOLTAGE && chan != SENSOR_CHAN_GAUGE_STATE_OF_CHARGE && + chan != SENSOR_CHAN_ALL) { + LOG_DBG("Selected channel is not supported: %d.", chan); return -ENOTSUP; } diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index 36c918c..a120b84 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -10,3 +10,4 @@ #include <behaviors/rgb_underglow.dtsi> #include <behaviors/bluetooth.dtsi> #include <behaviors/ext_power.dtsi> +#include <behaviors/outputs.dtsi> diff --git a/app/dts/behaviors/outputs.dtsi b/app/dts/behaviors/outputs.dtsi new file mode 100644 index 0000000..a534cbf --- /dev/null +++ b/app/dts/behaviors/outputs.dtsi @@ -0,0 +1,9 @@ +/ { + behaviors { + out: behavior_outputs { + compatible = "zmk,behavior-outputs"; + label = "OUTPUTS"; + #binding-cells = <1>; + }; + }; +}; diff --git a/app/dts/bindings/behaviors/zmk,behavior-outputs.yaml b/app/dts/bindings/behaviors/zmk,behavior-outputs.yaml new file mode 100644 index 0000000..8bcefd9 --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-outputs.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2020, The ZMK Contributors +# SPDX-License-Identifier: MIT +# + +description: Output Selection Behavior + +compatible: "zmk,behavior-outputs" + +include: one_param.yaml diff --git a/app/include/dt-bindings/zmk/keys.h b/app/include/dt-bindings/zmk/keys.h index a3b2229..5a52753 100644 --- a/app/include/dt-bindings/zmk/keys.h +++ b/app/include/dt-bindings/zmk/keys.h @@ -3,9 +3,10 @@ * * SPDX-License-Identifier: MIT */ - #pragma once +#include <dt-bindings/zmk/modifiers.h> + #define USAGE_KEYPAD 0x07 #define USAGE_CONSUMER 0x0C @@ -143,12 +144,3 @@ #define M_MUTE 0xE2 #define M_VOLU 0xE9 #define M_VOLD 0xEA - -#define MOD_LCTL (1 << 0x00) -#define MOD_LSFT (1 << 0x01) -#define MOD_LALT (1 << 0x02) -#define MOD_LGUI (1 << 0x03) -#define MOD_RCTL (1 << 0x04) -#define MOD_RSFT (1 << 0x05) -#define MOD_RALT (1 << 0x06) -#define MOD_RGUI (1 << 0x07)
\ No newline at end of file diff --git a/app/include/dt-bindings/zmk/modifiers.h b/app/include/dt-bindings/zmk/modifiers.h new file mode 100644 index 0000000..b49849d --- /dev/null +++ b/app/include/dt-bindings/zmk/modifiers.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ +#pragma once + +#define MOD_LCTL 0x01 +#define MOD_LSFT 0x02 +#define MOD_LALT 0x04 +#define MOD_LGUI 0x08 +#define MOD_RCTL 0x10 +#define MOD_RSFT 0x20 +#define MOD_RALT 0x40 +#define MOD_RGUI 0x80 + +#define SELECT_MODS(keycode) (keycode >> 24) +#define STRIP_MODS(keycode) (keycode & ~(0xFF << 24)) +#define APPLY_MODS(mods, keycode) (mods << 24 | keycode) + +#define LC(keycode) APPLY_MODS(MOD_LCTL, keycode) +#define LS(keycode) APPLY_MODS(MOD_LSFT, keycode) +#define LA(keycode) APPLY_MODS(MOD_LALT, keycode) +#define LG(keycode) APPLY_MODS(MOD_LGUI, keycode) +#define RC(keycode) APPLY_MODS(MOD_RCTL, keycode) +#define RS(keycode) APPLY_MODS(MOD_RSFT, keycode) +#define RA(keycode) APPLY_MODS(MOD_RALT, keycode) +#define RG(keycode) APPLY_MODS(MOD_RGUI, keycode)
\ No newline at end of file diff --git a/app/include/dt-bindings/zmk/outputs.h b/app/include/dt-bindings/zmk/outputs.h new file mode 100644 index 0000000..f24380f --- /dev/null +++ b/app/include/dt-bindings/zmk/outputs.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define OUT_TOG 0 +#define OUT_USB 1 +#define OUT_BLE 2
\ No newline at end of file diff --git a/app/include/zmk/ble.h b/app/include/zmk/ble.h index 1cf71a7..56980c6 100644 --- a/app/include/zmk/ble.h +++ b/app/include/zmk/ble.h @@ -15,6 +15,7 @@ int zmk_ble_prof_prev(); int zmk_ble_prof_select(u8_t index); bt_addr_le_t *zmk_ble_active_profile_addr(); +bool zmk_ble_active_profile_is_connected(); char *zmk_ble_active_profile_name(); int zmk_ble_unpair_all(); diff --git a/app/include/zmk/endpoints.h b/app/include/zmk/endpoints.h index aad6265..aad688e 100644 --- a/app/include/zmk/endpoints.h +++ b/app/include/zmk/endpoints.h @@ -9,4 +9,12 @@ #include <zmk/keys.h> #include <zmk/hid.h> +enum zmk_endpoint { + ZMK_ENDPOINT_USB, + ZMK_ENDPOINT_BLE, +}; + +int zmk_endpoints_select(enum zmk_endpoint endpoint); +int zmk_endpoints_toggle(); + int zmk_endpoints_send_report(u8_t usage_report); diff --git a/app/include/zmk/events/keycode-state-changed.h b/app/include/zmk/events/keycode-state-changed.h index 1e2c24e..26d07ec 100644 --- a/app/include/zmk/events/keycode-state-changed.h +++ b/app/include/zmk/events/keycode-state-changed.h @@ -7,22 +7,25 @@ #pragma once #include <zephyr.h> +#include <dt-bindings/zmk/modifiers.h> #include <zmk/event-manager.h> struct keycode_state_changed { struct zmk_event_header header; u8_t usage_page; u32_t keycode; + u8_t implicit_modifiers; bool state; }; ZMK_EVENT_DECLARE(keycode_state_changed); -inline struct keycode_state_changed *create_keycode_state_changed(u8_t usage_page, u32_t keycode, - bool state) { +static inline struct keycode_state_changed * +create_keycode_state_changed(u8_t usage_page, u32_t keycode, bool state) { struct keycode_state_changed *ev = new_keycode_state_changed(); ev->usage_page = usage_page; - ev->keycode = keycode; + ev->keycode = STRIP_MODS(keycode); + ev->implicit_modifiers = SELECT_MODS(keycode); ev->state = state; return ev; -}
\ No newline at end of file +} diff --git a/app/include/zmk/events/usb-conn-state-changed.h b/app/include/zmk/events/usb-conn-state-changed.h new file mode 100644 index 0000000..d6cc698 --- /dev/null +++ b/app/include/zmk/events/usb-conn-state-changed.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include <zephyr.h> +#include <usb/usb_device.h> + +#include <zmk/event-manager.h> +#include <zmk/usb.h> + +struct usb_conn_state_changed { + struct zmk_event_header header; + enum zmk_usb_conn_state conn_state; +}; + +ZMK_EVENT_DECLARE(usb_conn_state_changed);
\ No newline at end of file diff --git a/app/include/zmk/handlers.h b/app/include/zmk/handlers.h index 7ce1d27..92bd7e0 100644 --- a/app/include/zmk/handlers.h +++ b/app/include/zmk/handlers.h @@ -6,8 +6,6 @@ #pragma once -#include <dt-bindings/zmk/keys.h> - #include <zmk/keymap.h> #include <zmk/keys.h> diff --git a/app/include/zmk/hid.h b/app/include/zmk/hid.h index 744de98..2426c2d 100644 --- a/app/include/zmk/hid.h +++ b/app/include/zmk/hid.h @@ -9,13 +9,13 @@ #include <usb/usb_device.h> #include <usb/class/usb_hid.h> -#include <dt-bindings/zmk/keys.h> - #include <zmk/keys.h> #define COLLECTION_REPORT 0x03 -#define ZMK_HID_MAX_KEYCODE GUI +#define ZMK_HID_KEYPAD_NKRO_SIZE 6 + +#define ZMK_HID_CONSUMER_NKRO_SIZE 6 static const u8_t zmk_hid_report_desc[] = { /* USAGE_PAGE (Generic Desktop) */ @@ -59,39 +59,41 @@ static const u8_t zmk_hid_report_desc[] = { /* USAGE_PAGE (Keypad) */ HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP_KEYPAD, + /* REPORT_SIZE (8) */ + HID_GI_REPORT_SIZE, + 0x08, + /* REPORT_COUNT (1) */ + HID_GI_REPORT_COUNT, + 0x01, + /* INPUT (Cnst,Var,Abs) */ + HID_MI_INPUT, + 0x03, + + /* USAGE_PAGE (Keypad) */ + HID_GI_USAGE_PAGE, + USAGE_GEN_DESKTOP_KEYPAD, /* LOGICAL_MINIMUM (0) */ HID_GI_LOGICAL_MIN(1), 0x00, - /* LOGICAL_MAXIMUM (1) */ + /* LOGICAL_MAXIMUM (0xFF) */ HID_GI_LOGICAL_MAX(1), - 0x01, + 0xFF, /* USAGE_MINIMUM (Reserved) */ HID_LI_USAGE_MIN(1), 0x00, /* USAGE_MAXIMUM (Keyboard Application) */ HID_LI_USAGE_MAX(1), - ZMK_HID_MAX_KEYCODE, - /* REPORT_SIZE (8) */ + 0xFF, + /* REPORT_SIZE (1) */ HID_GI_REPORT_SIZE, - 0x01, - /* REPORT_COUNT (6) */ + 0x08, + /* REPORT_COUNT (ZMK_HID_KEYPAD_NKRO_SIZE) */ HID_GI_REPORT_COUNT, - ZMK_HID_MAX_KEYCODE + 1, + ZMK_HID_KEYPAD_NKRO_SIZE, /* INPUT (Data,Ary,Abs) */ HID_MI_INPUT, - 0x02, - /* USAGE_PAGE (Keypad) */ - HID_GI_USAGE_PAGE, - USAGE_GEN_DESKTOP_KEYPAD, - /* REPORT_SIZE (8) */ - HID_GI_REPORT_SIZE, - 0x02, - /* REPORT_COUNT (6) */ - HID_GI_REPORT_COUNT, - 0x01, - /* INPUT (Cnst,Var,Abs) */ - HID_MI_INPUT, - 0x03, + 0x00, + /* END_COLLECTION */ HID_MI_COLLECTION_END, /* USAGE_PAGE (Consumer) */ @@ -124,9 +126,9 @@ static const u8_t zmk_hid_report_desc[] = { /* REPORT_SIZE (8) */ HID_GI_REPORT_SIZE, 0x08, - /* REPORT_COUNT (8) */ + /* REPORT_COUNT (ZMK_HID_CONSUMER_NKRO_SIZE) */ HID_GI_REPORT_COUNT, - 0x06, + ZMK_HID_CONSUMER_NKRO_SIZE, HID_MI_INPUT, 0x00, /* END COLLECTION */ @@ -142,7 +144,8 @@ static const u8_t zmk_hid_report_desc[] = { struct zmk_hid_keypad_report_body { zmk_mod_flags modifiers; - u8_t keys[13]; + u8_t _reserved; + u8_t keys[ZMK_HID_KEYPAD_NKRO_SIZE]; } __packed; struct zmk_hid_keypad_report { @@ -151,7 +154,7 @@ struct zmk_hid_keypad_report { } __packed; struct zmk_hid_consumer_report_body { - u8_t keys[6]; + u8_t keys[ZMK_HID_CONSUMER_NKRO_SIZE]; } __packed; struct zmk_hid_consumer_report { @@ -161,13 +164,15 @@ struct zmk_hid_consumer_report { int zmk_hid_register_mod(zmk_mod modifier); int zmk_hid_unregister_mod(zmk_mod modifier); -int zmk_hid_register_mods(zmk_mod_flags modifiers); -int zmk_hid_unregister_mods(zmk_mod_flags modifiers); +int zmk_hid_implicit_modifiers_press(zmk_mod_flags implicit_modifiers); +int zmk_hid_implicit_modifiers_release(); int zmk_hid_keypad_press(zmk_key key); int zmk_hid_keypad_release(zmk_key key); +void zmk_hid_keypad_clear(); int zmk_hid_consumer_press(zmk_key key); int zmk_hid_consumer_release(zmk_key key); +void zmk_hid_consumer_clear(); struct zmk_hid_keypad_report *zmk_hid_get_keypad_report(); struct zmk_hid_consumer_report *zmk_hid_get_consumer_report(); diff --git a/app/include/zmk/usb.h b/app/include/zmk/usb.h index 452fd54..30461de 100644 --- a/app/include/zmk/usb.h +++ b/app/include/zmk/usb.h @@ -12,8 +12,18 @@ #include <zmk/keys.h> #include <zmk/hid.h> +enum zmk_usb_conn_state { + ZMK_USB_CONN_NONE, + ZMK_USB_CONN_POWERED, + ZMK_USB_CONN_HID, +}; + enum usb_dc_status_code zmk_usb_get_status(); +enum zmk_usb_conn_state zmk_usb_get_conn_state(); + +static inline bool zmk_usb_is_powered() { return zmk_usb_get_conn_state() != ZMK_USB_CONN_NONE; } +static inline bool zmk_usb_is_hid_ready() { return zmk_usb_get_conn_state() == ZMK_USB_CONN_HID; } #ifdef CONFIG_ZMK_USB -int zmk_usb_hid_send_report(u8_t *report, size_t len); +int zmk_usb_hid_send_report(const u8_t *report, size_t len); #endif /* CONFIG_ZMK_USB */
\ No newline at end of file diff --git a/app/src/battery.c b/app/src/battery.c new file mode 100644 index 0000000..9496570 --- /dev/null +++ b/app/src/battery.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include <device.h> +#include <init.h> +#include <kernel.h> +#include <drivers/sensor.h> +#include <bluetooth/services/bas.h> + +#include <logging/log.h> + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +struct device *battery; + +static int zmk_battery_update(struct device *battery) { + struct sensor_value state_of_charge; + + int rc = sensor_sample_fetch_chan(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE); + + if (rc != 0) { + LOG_DBG("Failed to fetch battery values: %d", rc); + return rc; + } + + rc = sensor_channel_get(battery, SENSOR_CHAN_GAUGE_STATE_OF_CHARGE, &state_of_charge); + + if (rc != 0) { + LOG_DBG("Failed to get battery state of charge: %d", rc); + return rc; + } + + LOG_DBG("Setting BAS GATT battery level to %d.", state_of_charge.val1); + + return bt_gatt_bas_set_battery_level(state_of_charge.val1); +} + +static void zmk_battery_work(struct k_work *work) { + int rc = zmk_battery_update(battery); + + if (rc != 0) { + LOG_DBG("Failed to update battery value: %d.", rc); + } +} + +K_WORK_DEFINE(battery_work, zmk_battery_work); + +static void zmk_battery_timer(struct k_timer *timer) { k_work_submit(&battery_work); } + +K_TIMER_DEFINE(battery_timer, zmk_battery_timer, NULL); + +static int zmk_battery_init(struct device *_arg) { + battery = device_get_binding("BATTERY"); + + if (battery == NULL) { + LOG_DBG("No battery device labelled BATTERY found."); + return -ENODEV; + } + + int rc = zmk_battery_update(battery); + + if (rc != 0) { + LOG_DBG("Failed to update battery value: %d.", rc); + return rc; + } + + k_timer_start(&battery_timer, K_MINUTES(1), K_MINUTES(1)); + + return 0; +} + +SYS_INIT(zmk_battery_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 8b3620e..ac91e7d 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -8,6 +8,7 @@ #include <device.h> #include <drivers/behavior.h> +#include <dt-bindings/zmk/keys.h> #include <logging/log.h> #include <zmk/behavior.h> #include <zmk/matrix.h> @@ -16,7 +17,6 @@ #include <zmk/events/position-state-changed.h> #include <zmk/events/keycode-state-changed.h> #include <zmk/events/modifiers-state-changed.h> -#include <zmk/hid.h> #include <zmk/behavior.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -427,7 +427,7 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) { return ZMK_EV_EVENT_CAPTURED; } -static bool is_mod(struct keycode_state_changed *ev) { +static inline bool only_mods(struct keycode_state_changed *ev) { return ev->usage_page == USAGE_KEYPAD && ev->keycode >= LCTL && ev->keycode <= RGUI; } @@ -440,7 +440,7 @@ static int keycode_state_changed_listener(const struct zmk_event_header *eh) { return 0; } - if (!is_mod(ev)) { + if (!only_mods(ev)) { // LOG_DBG("0x%02X bubble (not a mod)", ev->keycode); return 0; } diff --git a/app/src/behaviors/behavior_outputs.c b/app/src/behaviors/behavior_outputs.c new file mode 100644 index 0000000..e5182bd --- /dev/null +++ b/app/src/behaviors/behavior_outputs.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_outputs + +#include <device.h> +#include <devicetree.h> +#include <drivers/behavior.h> + +#include <dt-bindings/zmk/outputs.h> + +#include <zmk/behavior.h> +#include <zmk/endpoints.h> + +#include <logging/log.h> +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + switch (binding->param1) { + case OUT_TOG: + return zmk_endpoints_toggle(); + case OUT_USB: + return zmk_endpoints_select(ZMK_ENDPOINT_USB); + case OUT_BLE: + return zmk_endpoints_select(ZMK_ENDPOINT_BLE); + default: + LOG_ERR("Unknown output command: %d", binding->param1); + } + + return -ENOTSUP; +} + +static int behavior_out_init(struct device *dev) { return 0; } + +static const struct behavior_driver_api behavior_outputs_driver_api = { + .binding_pressed = on_keymap_binding_pressed, +}; + +DEVICE_AND_API_INIT(behavior_out, DT_INST_LABEL(0), behavior_out_init, NULL, NULL, APPLICATION, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_outputs_driver_api); diff --git a/app/src/ble.c b/app/src/ble.c index 9090582..f3962ae 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -94,6 +94,12 @@ static void raise_profile_changed_event() { ZMK_EVENT_RAISE(ev); } +static void raise_profile_changed_event_callback(struct k_work *work) { + raise_profile_changed_event(); +} + +K_WORK_DEFINE(raise_profile_changed_event_work, raise_profile_changed_event_callback); + static bool active_profile_is_open() { return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY); } @@ -111,7 +117,7 @@ void set_profile_address(u8_t index, const bt_addr_le_t *addr) { raise_profile_changed_event(); } -bool active_profile_is_connected() { +bool zmk_ble_active_profile_is_connected() { struct bt_conn *conn; bt_addr_le_t *addr = zmk_ble_active_profile_addr(); if (!bt_addr_le_cmp(addr, BT_ADDR_LE_ANY)) { @@ -163,9 +169,9 @@ int update_advertising() { struct bt_conn *conn; enum advertising_type desired_adv = ZMK_ADV_NONE; - if (active_profile_is_open() || !active_profile_is_connected()) { + if (active_profile_is_open()) { desired_adv = ZMK_ADV_CONN; - } else if (!active_profile_is_connected()) { + } else if (!zmk_ble_active_profile_is_connected()) { desired_adv = ZMK_ADV_CONN; // Need to fix directed advertising for privacy centrals. See // https://github.com/zephyrproject-rtos/zephyr/pull/14984 char @@ -327,6 +333,10 @@ static int ble_profiles_handle_set(const char *name, size_t len, settings_read_c struct settings_handler profiles_handler = {.name = "ble", .h_set = ble_profiles_handle_set}; #endif /* IS_ENABLED(CONFIG_SETTINGS) */ +static bool is_conn_active_profile(const struct bt_conn *conn) { + return bt_addr_le_cmp(bt_conn_get_dst(conn), &profiles[active_profile].peer) == 0; +} + static void connected(struct bt_conn *conn, u8_t err) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); @@ -352,6 +362,11 @@ static void connected(struct bt_conn *conn, u8_t err) { } update_advertising(); + + if (is_conn_active_profile(conn)) { + LOG_DBG("Active profile connected"); + raise_profile_changed_event(); + } } static void disconnected(struct bt_conn *conn, u8_t reason) { @@ -364,6 +379,11 @@ static void disconnected(struct bt_conn *conn, u8_t reason) { // We need to do this in a work callback, otherwise the advertising update will still see the // connection for a profile as active, and not start advertising yet. k_work_submit(&update_advertising_work); + + if (is_conn_active_profile(conn)) { + LOG_DBG("Active profile disconnected"); + k_work_submit(&raise_profile_changed_event_work); + } } static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { diff --git a/app/src/endpoints.c b/app/src/endpoints.c index 79d294e..0c79589 100644 --- a/app/src/endpoints.c +++ b/app/src/endpoints.c @@ -4,58 +4,238 @@ * SPDX-License-Identifier: MIT */ +#include <init.h> +#include <settings/settings.h> + +#include <zmk/ble.h> #include <zmk/endpoints.h> #include <zmk/hid.h> #include <zmk/usb.h> #include <zmk/hog.h> +#include <zmk/event-manager.h> +#include <zmk/events/ble-active-profile-changed.h> +#include <zmk/events/usb-conn-state-changed.h> #include <logging/log.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); -int zmk_endpoints_send_report(u8_t usage_page) { - int err; - struct zmk_hid_keypad_report *keypad_report; - struct zmk_hid_consumer_report *consumer_report; - LOG_DBG("usage page 0x%02X", usage_page); - switch (usage_page) { - case USAGE_KEYPAD: - keypad_report = zmk_hid_get_keypad_report(); -#ifdef CONFIG_ZMK_USB - if (zmk_usb_hid_send_report((u8_t *)keypad_report, sizeof(struct zmk_hid_keypad_report)) != - 0) { - LOG_DBG("USB Send Failed"); +#define DEFAULT_ENDPOINT \ + COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ZMK_ENDPOINT_BLE), (ZMK_ENDPOINT_USB)) + +static enum zmk_endpoint current_endpoint = DEFAULT_ENDPOINT; +static enum zmk_endpoint preferred_endpoint = + ZMK_ENDPOINT_USB; /* Used if multiple endpoints are ready */ + +static void update_current_endpoint(); + +int zmk_endpoints_select(enum zmk_endpoint endpoint) { + LOG_DBG("Selected endpoint %d", endpoint); + + if (preferred_endpoint == endpoint) { + return 0; + } + + preferred_endpoint = endpoint; + +#if IS_ENABLED(CONFIG_SETTINGS) + settings_save_one("endpoints/preferred", &preferred_endpoint, sizeof(preferred_endpoint)); +#endif + + update_current_endpoint(); + + return 0; +} + +int zmk_endpoints_toggle() { + enum zmk_endpoint new_endpoint = + (preferred_endpoint == ZMK_ENDPOINT_USB) ? ZMK_ENDPOINT_BLE : ZMK_ENDPOINT_USB; + return zmk_endpoints_select(new_endpoint); +} + +static int send_keypad_report() { + struct zmk_hid_keypad_report *keypad_report = zmk_hid_get_keypad_report(); + + switch (current_endpoint) { +#if IS_ENABLED(CONFIG_ZMK_USB) + case ZMK_ENDPOINT_USB: { + int err = zmk_usb_hid_send_report((u8_t *)keypad_report, sizeof(*keypad_report)); + if (err) { + LOG_ERR("FAILED TO SEND OVER USB: %d", err); } -#endif /* CONFIG_ZMK_USB */ + return err; + } +#endif /* IS_ENABLED(CONFIG_ZMK_USB) */ -#ifdef CONFIG_ZMK_BLE - err = zmk_hog_send_keypad_report(&keypad_report->body); +#if IS_ENABLED(CONFIG_ZMK_BLE) + case ZMK_ENDPOINT_BLE: { + int err = zmk_hog_send_keypad_report(&keypad_report->body); if (err) { LOG_ERR("FAILED TO SEND OVER HOG: %d", err); } -#endif /* CONFIG_ZMK_BLE */ + return err; + } +#endif /* IS_ENABLED(CONFIG_ZMK_BLE) */ - break; - case USAGE_CONSUMER: - consumer_report = zmk_hid_get_consumer_report(); -#ifdef CONFIG_ZMK_USB - if (zmk_usb_hid_send_report((u8_t *)consumer_report, - sizeof(struct zmk_hid_consumer_report)) != 0) { - LOG_DBG("USB Send Failed"); + default: + LOG_ERR("Unsupported endpoint %d", current_endpoint); + return -ENOTSUP; + } +} + +static int send_consumer_report() { + struct zmk_hid_consumer_report *consumer_report = zmk_hid_get_consumer_report(); + + switch (current_endpoint) { +#if IS_ENABLED(CONFIG_ZMK_USB) + case ZMK_ENDPOINT_USB: { + int err = zmk_usb_hid_send_report((u8_t *)consumer_report, sizeof(*consumer_report)); + if (err) { + LOG_ERR("FAILED TO SEND OVER USB: %d", err); } -#endif /* CONFIG_ZMK_USB */ + return err; + } +#endif /* IS_ENABLED(CONFIG_ZMK_USB) */ -#ifdef CONFIG_ZMK_BLE - err = zmk_hog_send_consumer_report(&consumer_report->body); +#if IS_ENABLED(CONFIG_ZMK_BLE) + case ZMK_ENDPOINT_BLE: { + int err = zmk_hog_send_consumer_report(&consumer_report->body); if (err) { LOG_ERR("FAILED TO SEND OVER HOG: %d", err); } -#endif /* CONFIG_ZMK_BLE */ + return err; + } +#endif /* IS_ENABLED(CONFIG_ZMK_BLE) */ - break; + default: + LOG_ERR("Unsupported endpoint %d", current_endpoint); + return -ENOTSUP; + } +} + +int zmk_endpoints_send_report(u8_t usage_page) { + + LOG_DBG("usage page 0x%02X", usage_page); + switch (usage_page) { + case USAGE_KEYPAD: + return send_keypad_report(); + case USAGE_CONSUMER: + return send_consumer_report(); default: LOG_ERR("Unsupported usage page %d", usage_page); return -ENOTSUP; } +} + +#if IS_ENABLED(CONFIG_SETTINGS) + +static int endpoints_handle_set(const char *name, size_t len, settings_read_cb read_cb, + void *cb_arg) { + LOG_DBG("Setting endpoint value %s", log_strdup(name)); + + if (settings_name_steq(name, "preferred", NULL)) { + if (len != sizeof(enum zmk_endpoint)) { + LOG_ERR("Invalid endpoint size (got %d expected %d)", len, sizeof(enum zmk_endpoint)); + return -EINVAL; + } + + int err = read_cb(cb_arg, &preferred_endpoint, sizeof(enum zmk_endpoint)); + if (err <= 0) { + LOG_ERR("Failed to read preferred endpoint from settings (err %d)", err); + return err; + } + + update_current_endpoint(); + } + + return 0; +} + +struct settings_handler endpoints_handler = {.name = "endpoints", .h_set = endpoints_handle_set}; +#endif /* IS_ENABLED(CONFIG_SETTINGS) */ + +static int zmk_endpoints_init(struct device *_arg) { +#if IS_ENABLED(CONFIG_SETTINGS) + settings_subsys_init(); + + int err = settings_register(&endpoints_handler); + if (err) { + LOG_ERR("Failed to register the endpoints settings handler (err %d)", err); + return err; + } + + settings_load(); +#endif return 0; } + +static bool is_usb_ready() { +#if IS_ENABLED(CONFIG_ZMK_USB) + return zmk_usb_is_hid_ready(); +#else + return false; +#endif +} + +static bool is_ble_ready() { +#if IS_ENABLED(CONFIG_ZMK_BLE) + return zmk_ble_active_profile_is_connected(); +#else + return false; +#endif +} + +static enum zmk_endpoint get_selected_endpoint() { + if (is_ble_ready()) { + if (is_usb_ready()) { + LOG_DBG("Both endpoints are ready. Using %d", preferred_endpoint); + return preferred_endpoint; + } + + LOG_DBG("Only BLE is ready."); + return ZMK_ENDPOINT_BLE; + } + + if (is_usb_ready()) { + LOG_DBG("Only USB is ready."); + return ZMK_ENDPOINT_USB; + } + + LOG_DBG("No endpoints are ready."); + return DEFAULT_ENDPOINT; +} + +static void disconnect_current_endpoint() { + zmk_hid_keypad_clear(); + zmk_hid_consumer_clear(); + + zmk_endpoints_send_report(USAGE_KEYPAD); + zmk_endpoints_send_report(USAGE_CONSUMER); +} + +static void update_current_endpoint() { + enum zmk_endpoint new_endpoint = get_selected_endpoint(); + + if (new_endpoint != current_endpoint) { + /* Cancel all current keypresses so keys don't stay held on the old endpoint. */ + disconnect_current_endpoint(); + + current_endpoint = new_endpoint; + LOG_INF("Endpoint changed: %d", current_endpoint); + } +} + +static int endpoint_listener(const struct zmk_event_header *eh) { + update_current_endpoint(); + return 0; +} + +ZMK_LISTENER(endpoint_listener, endpoint_listener); +#if IS_ENABLED(CONFIG_ZMK_USB) +ZMK_SUBSCRIPTION(endpoint_listener, usb_conn_state_changed); +#endif +#if IS_ENABLED(CONFIG_ZMK_BLE) +ZMK_SUBSCRIPTION(endpoint_listener, ble_active_profile_changed); +#endif + +SYS_INIT(zmk_endpoints_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/app/src/events/usb_conn_state_changed.c b/app/src/events/usb_conn_state_changed.c new file mode 100644 index 0000000..d845f6d --- /dev/null +++ b/app/src/events/usb_conn_state_changed.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include <kernel.h> +#include <zmk/events/usb-conn-state-changed.h> + +ZMK_EVENT_IMPL(usb_conn_state_changed);
\ No newline at end of file diff --git a/app/src/hid.c b/app/src/hid.c index f80906c..1925765 100644 --- a/app/src/hid.c +++ b/app/src/hid.c @@ -8,53 +8,58 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include <zmk/hid.h> +#include <dt-bindings/zmk/modifiers.h> static struct zmk_hid_keypad_report kp_report = { - .report_id = 1, .body = {.modifiers = 0, .keys = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}; + .report_id = 1, .body = {.modifiers = 0, ._reserved = 0, .keys = {0}}}; -static struct zmk_hid_consumer_report consumer_report = {.report_id = 2, - .body = {.keys = {0, 0, 0, 0, 0, 0}}}; +static struct zmk_hid_consumer_report consumer_report = {.report_id = 2, .body = {.keys = {0}}}; -#define _TOGGLE_MOD(mod, state) \ - if (modifier > MOD_RGUI) { \ - return -EINVAL; \ - } \ - WRITE_BIT(kp_report.body.modifiers, mod, state); \ - return 0; +// Keep track of how often a modifier was pressed. +// Only release the modifier if the count is 0. +static int explicit_modifier_counts[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +static zmk_mod_flags explicit_modifiers = 0; -int zmk_hid_register_mod(zmk_mod modifier) { _TOGGLE_MOD(modifier, true); } -int zmk_hid_unregister_mod(zmk_mod modifier) { _TOGGLE_MOD(modifier, false); } +#define SET_MODIFIERS(mods) \ + { \ + kp_report.body.modifiers = mods; \ + LOG_DBG("Modifiers set to 0x%02X", kp_report.body.modifiers); \ + } -int zmk_hid_register_mods(zmk_mod_flags modifiers) { - kp_report.body.modifiers |= modifiers; +int zmk_hid_register_mod(zmk_mod modifier) { + explicit_modifier_counts[modifier]++; + LOG_DBG("Modifier %d count %d", modifier, explicit_modifier_counts[modifier]); + WRITE_BIT(explicit_modifiers, modifier, true); + SET_MODIFIERS(explicit_modifiers); return 0; } -int zmk_hid_unregister_mods(zmk_mod_flags modifiers) { - kp_report.body.modifiers &= ~modifiers; +int zmk_hid_unregister_mod(zmk_mod modifier) { + if (explicit_modifier_counts[modifier] <= 0) { + LOG_ERR("Tried to unregister modifier %d too often", modifier); + return -EINVAL; + } + explicit_modifier_counts[modifier]--; + LOG_DBG("Modifier %d count: %d", modifier, explicit_modifier_counts[modifier]); + if (explicit_modifier_counts[modifier] == 0) { + LOG_DBG("Modifier %d released", modifier); + WRITE_BIT(explicit_modifiers, modifier, false); + } + SET_MODIFIERS(explicit_modifiers); return 0; } -#define KEY_OFFSET 0x02 -#define MAX_KEYS 6 - -/* -#define TOGGLE_BOOT_KEY(match, val) \ - for (int idx = 0; idx < MAX_KEYS; idx++) \ - { \ - if (kp_report.boot.keys[idx + KEY_OFFSET] != match) \ - { \ - continue; \ - } \ - kp_report.boot.keys[idx + KEY_OFFSET] = val; \ - break; \ +#define TOGGLE_KEYPAD(match, val) \ + for (int idx = 0; idx < ZMK_HID_KEYPAD_NKRO_SIZE; idx++) { \ + if (kp_report.body.keys[idx] != match) { \ + continue; \ + } \ + kp_report.body.keys[idx] = val; \ + break; \ } -*/ - -#define TOGGLE_KEY(code, val) WRITE_BIT(kp_report.body.keys[code / 8], code % 8, val) #define TOGGLE_CONSUMER(match, val) \ - for (int idx = 0; idx < MAX_KEYS; idx++) { \ + for (int idx = 0; idx < ZMK_HID_CONSUMER_NKRO_SIZE; idx++) { \ if (consumer_report.body.keys[idx] != match) { \ continue; \ } \ @@ -62,19 +67,21 @@ int zmk_hid_unregister_mods(zmk_mod_flags modifiers) { break; \ } +int zmk_hid_implicit_modifiers_press(zmk_mod_flags implicit_modifiers) { + SET_MODIFIERS(explicit_modifiers | implicit_modifiers); + return 0; +} + +int zmk_hid_implicit_modifiers_release() { + SET_MODIFIERS(explicit_modifiers); + return 0; +} + int zmk_hid_keypad_press(zmk_key code) { if (code >= LCTL && code <= RGUI) { return zmk_hid_register_mod(code - LCTL); } - - if (code > ZMK_HID_MAX_KEYCODE) { - return -EINVAL; - } - - // TOGGLE_BOOT_KEY(0U, code); - - TOGGLE_KEY(code, true); - + TOGGLE_KEYPAD(0U, code); return 0; }; @@ -82,18 +89,12 @@ int zmk_hid_keypad_release(zmk_key code) { if (code >= LCTL && code <= RGUI) { return zmk_hid_unregister_mod(code - LCTL); } - - if (code > ZMK_HID_MAX_KEYCODE) { - return -EINVAL; - } - - // TOGGLE_BOOT_KEY(0U, code); - - TOGGLE_KEY(code, false); - + TOGGLE_KEYPAD(code, 0U); return 0; }; +void zmk_hid_keypad_clear() { memset(&kp_report.body, 0, sizeof(kp_report.body)); } + int zmk_hid_consumer_press(zmk_key code) { TOGGLE_CONSUMER(0U, code); return 0; @@ -104,6 +105,8 @@ int zmk_hid_consumer_release(zmk_key code) { return 0; }; +void zmk_hid_consumer_clear() { memset(&consumer_report.body, 0, sizeof(consumer_report.body)); } + struct zmk_hid_keypad_report *zmk_hid_get_keypad_report() { return &kp_report; } diff --git a/app/src/hid_listener.c b/app/src/hid_listener.c index 4467e6d..32e9d97 100644 --- a/app/src/hid_listener.c +++ b/app/src/hid_listener.c @@ -15,10 +15,11 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include <zmk/hid.h> #include <zmk/endpoints.h> -static int hid_listener_keycode_pressed(u8_t usage_page, u32_t keycode) { +static int hid_listener_keycode_pressed(u8_t usage_page, u32_t keycode, + zmk_mod_flags implicit_modifiers) { int err; - LOG_DBG("usage_page 0x%02X keycode 0x%02X", usage_page, keycode); - + LOG_DBG("usage_page 0x%02X keycode 0x%02X mods 0x%02X", usage_page, keycode, + implicit_modifiers); switch (usage_page) { case USAGE_KEYPAD: err = zmk_hid_keypad_press(keycode); @@ -35,14 +36,15 @@ static int hid_listener_keycode_pressed(u8_t usage_page, u32_t keycode) { } break; } - + zmk_hid_implicit_modifiers_press(implicit_modifiers); return zmk_endpoints_send_report(usage_page); } -static int hid_listener_keycode_released(u8_t usage_page, u32_t keycode) { +static int hid_listener_keycode_released(u8_t usage_page, u32_t keycode, + zmk_mod_flags implicit_modifiers) { int err; - LOG_DBG("usage_page 0x%02X keycode 0x%02X", usage_page, keycode); - + LOG_DBG("usage_page 0x%02X keycode 0x%02X mods 0x%02X", usage_page, keycode, + implicit_modifiers); switch (usage_page) { case USAGE_KEYPAD: err = zmk_hid_keypad_release(keycode); @@ -57,44 +59,27 @@ static int hid_listener_keycode_released(u8_t usage_page, u32_t keycode) { LOG_ERR("Unable to release keycode"); return err; } - break; } + // There is a minor issue with this code. + // If LC(A) is pressed, then LS(B), then LC(A) is released, the shift for B will be released + // prematurely. This causes if LS(B) to repeat like Bbbbbbbb when pressed for a long time. + // Solving this would require keeping track of which key's implicit modifiers are currently + // active and only releasing modifiers at that time. + zmk_hid_implicit_modifiers_release(); return zmk_endpoints_send_report(usage_page); } -static int hid_listener_modifiers_pressed(zmk_mod_flags modifiers) { - LOG_DBG("modifiers %d", modifiers); - - zmk_hid_register_mods(modifiers); - return zmk_endpoints_send_report(USAGE_KEYPAD); -} - -static int hid_listener_modifiers_released(zmk_mod_flags modifiers) { - LOG_DBG("modifiers %d", modifiers); - - zmk_hid_unregister_mods(modifiers); - return zmk_endpoints_send_report(USAGE_KEYPAD); -} - int hid_listener(const struct zmk_event_header *eh) { if (is_keycode_state_changed(eh)) { const struct keycode_state_changed *ev = cast_keycode_state_changed(eh); if (ev->state) { - hid_listener_keycode_pressed(ev->usage_page, ev->keycode); - } else { - hid_listener_keycode_released(ev->usage_page, ev->keycode); - } - } else if (is_modifiers_state_changed(eh)) { - const struct modifiers_state_changed *ev = cast_modifiers_state_changed(eh); - if (ev->state) { - hid_listener_modifiers_pressed(ev->modifiers); + hid_listener_keycode_pressed(ev->usage_page, ev->keycode, ev->implicit_modifiers); } else { - hid_listener_modifiers_released(ev->modifiers); + hid_listener_keycode_released(ev->usage_page, ev->keycode, ev->implicit_modifiers); } } return 0; } ZMK_LISTENER(hid_listener, hid_listener); -ZMK_SUBSCRIPTION(hid_listener, keycode_state_changed); -ZMK_SUBSCRIPTION(hid_listener, modifiers_state_changed);
\ No newline at end of file +ZMK_SUBSCRIPTION(hid_listener, keycode_state_changed);
\ No newline at end of file diff --git a/app/src/keymap.c b/app/src/keymap.c index 74fe60d..1d289e5 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -11,7 +11,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include <zmk/matrix.h> #include <zmk/sensors.h> #include <zmk/keymap.h> -#include <dt-bindings/zmk/matrix-transform.h> #include <drivers/behavior.h> #include <zmk/behavior.h> diff --git a/app/src/power.c b/app/src/power.c index 73b3f12..bad54d2 100644 --- a/app/src/power.c +++ b/app/src/power.c @@ -23,14 +23,7 @@ static u32_t power_last_uptime; bool is_usb_power_present() { #ifdef CONFIG_USB - enum usb_dc_status_code usb_status = zmk_usb_get_status(); - switch (usb_status) { - case USB_DC_DISCONNECTED: - case USB_DC_UNKNOWN: - return false; - default: - return true; - } + return zmk_usb_is_powered(); #else return false; #endif /* CONFIG_USB */ diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index b371c94..084482e 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -227,6 +227,14 @@ static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) { K_TIMER_DEFINE(underglow_tick, zmk_rgb_underglow_tick_handler, NULL); +#if IS_ENABLED(CONFIG_SETTINGS) +static void zmk_rgb_underglow_save_state_work() { + settings_save_one("rgb/underglow/state", &state, sizeof(state)); +} + +static struct k_delayed_work underglow_save_work; +#endif + static int zmk_rgb_underglow_init(struct device *_arg) { led_strip = device_get_binding(STRIP_LABEL); if (led_strip) { @@ -248,6 +256,7 @@ static int zmk_rgb_underglow_init(struct device *_arg) { #if IS_ENABLED(CONFIG_SETTINGS) settings_register(&rgb_conf); + k_delayed_work_init(&underglow_save_work, zmk_rgb_underglow_save_state_work); #endif k_timer_start(&underglow_tick, K_NO_WAIT, K_MSEC(50)); @@ -257,7 +266,8 @@ static int zmk_rgb_underglow_init(struct device *_arg) { int zmk_rgb_underglow_save_state() { #if IS_ENABLED(CONFIG_SETTINGS) - return settings_save_one("rgb/underglow/state", &state, sizeof(state)); + k_delayed_work_cancel(&underglow_save_work); + return k_delayed_work_submit(&underglow_save_work, K_MINUTES(1)); #else return 0; #endif diff --git a/app/src/usb.c b/app/src/usb.c index 434b3d4..79d03c7 100644 --- a/app/src/usb.c +++ b/app/src/usb.c @@ -9,10 +9,11 @@ #include <usb/usb_device.h> #include <usb/class/usb_hid.h> -#include <dt-bindings/zmk/keys.h> #include <zmk/hid.h> #include <zmk/keymap.h> +#include <zmk/event-manager.h> +#include <zmk/events/usb-conn-state-changed.h> LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -53,9 +54,34 @@ int zmk_usb_hid_send_report(const u8_t *report, size_t len) { #endif /* CONFIG_ZMK_USB */ +static void raise_usb_status_changed_event() { + struct usb_conn_state_changed *ev = new_usb_conn_state_changed(); + ev->conn_state = zmk_usb_get_conn_state(); + + ZMK_EVENT_RAISE(ev); +} + enum usb_dc_status_code zmk_usb_get_status() { return usb_status; } -void usb_status_cb(enum usb_dc_status_code status, const u8_t *params) { usb_status = status; }; +enum zmk_usb_conn_state zmk_usb_get_conn_state() { + switch (usb_status) { + case USB_DC_DISCONNECTED: + case USB_DC_UNKNOWN: + return ZMK_USB_CONN_NONE; + + case USB_DC_ERROR: + case USB_DC_RESET: + return ZMK_USB_CONN_POWERED; + + default: + return ZMK_USB_CONN_HID; + } +} + +void usb_status_cb(enum usb_dc_status_code status, const u8_t *params) { + usb_status = status; + raise_usb_status_changed_event(); +}; static int zmk_usb_init(struct device *_arg) { int usb_enable_ret; diff --git a/app/tests/hold-tap/balanced/1-dn-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/1-dn-up/keycode_events.snapshot index 5f6a266..c088e5e 100644 --- a/app/tests/hold-tap/balanced/1-dn-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/1-dn-up/keycode_events.snapshot @@ -1,5 +1,5 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (balanced event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/2-dn-timer-up/keycode_events.snapshot index ddda1ae..a8b5d1f 100644 --- a/app/tests/hold-tap/balanced/2-dn-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/2-dn-timer-up/keycode_events.snapshot @@ -1,5 +1,5 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/3a-moddn-dn-modup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/3a-moddn-dn-modup-up/keycode_events.snapshot index a435103..ca458c7 100644 --- a/app/tests/hold-tap/balanced/3a-moddn-dn-modup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/3a-moddn-dn-modup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0xe4 +kp_pressed: usage_page 0x07 keycode 0xe4 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (balanced event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0xe4 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/3b-moddn-dn-modup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/3b-moddn-dn-modup-timer-up/keycode_events.snapshot index c0da94f..ef4dfa5 100644 --- a/app/tests/hold-tap/balanced/3b-moddn-dn-modup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/3b-moddn-dn-modup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0xe4 +kp_pressed: usage_page 0x07 keycode 0xe4 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe4 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/3c-kcdn-dn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/3c-kcdn-dn-kcup-up/keycode_events.snapshot index ce6e7b7..70a3353 100644 --- a/app/tests/hold-tap/balanced/3c-kcdn-dn-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/3c-kcdn-dn-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0x07 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 ht_decide: 0 decided tap (balanced event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot index 1ec384a..121f007 100644 --- a/app/tests/hold-tap/balanced/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0x07 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 ht_decide: 0 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/4a-dn-htdn-timer-htup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/4a-dn-htdn-timer-htup-up/keycode_events.snapshot index 8a1980b..ae9dcc9 100644 --- a/app/tests/hold-tap/balanced/4a-dn-htdn-timer-htup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/4a-dn-htdn-timer-htup-up/keycode_events.snapshot @@ -1,10 +1,10 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_pressed: 1 new undecided hold_tap ht_decide: 1 decided tap (balanced event 0) -kp_pressed: usage_page 0x07 keycode 0x0d -kp_released: usage_page 0x07 keycode 0x0d +kp_pressed: usage_page 0x07 keycode 0x0d mods 0x00 +kp_released: usage_page 0x07 keycode 0x0d mods 0x00 ht_binding_released: 1 cleaning up hold-tap -kp_released: usage_page 0x07 keycode 0xe1 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot index b89b21d..c1e03ad 100644 --- a/app/tests/hold-tap/balanced/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot index 798e2ee..95330e6 100644 --- a/app/tests/hold-tap/balanced/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (balanced event 2) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/4c-dn-kcdn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/4c-dn-kcdn-kcup-up/keycode_events.snapshot index 798e2ee..95330e6 100644 --- a/app/tests/hold-tap/balanced/4c-dn-kcdn-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/4c-dn-kcdn-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (balanced event 2) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot b/app/tests/hold-tap/balanced/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot index 5c9f4e3..63219ee 100644 --- a/app/tests/hold-tap/balanced/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (balanced event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 diff --git a/app/tests/hold-tap/balanced/many-nested/keycode_events.snapshot b/app/tests/hold-tap/balanced/many-nested/keycode_events.snapshot index 806896f..dda02dd 100644 --- a/app/tests/hold-tap/balanced/many-nested/keycode_events.snapshot +++ b/app/tests/hold-tap/balanced/many-nested/keycode_events.snapshot @@ -1,20 +1,20 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_pressed: 1 new undecided hold_tap ht_decide: 1 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe0 +kp_pressed: usage_page 0x07 keycode 0xe0 mods 0x00 ht_binding_pressed: 2 new undecided hold_tap ht_binding_released: 0 cleaning up hold-tap ht_decide: 2 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe3 +kp_pressed: usage_page 0x07 keycode 0xe3 mods 0x00 ht_binding_pressed: 3 new undecided hold_tap ht_binding_released: 1 cleaning up hold-tap ht_decide: 3 decided hold (balanced event 3) -kp_pressed: usage_page 0x07 keycode 0xe2 -kp_released: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe0 -kp_released: usage_page 0x07 keycode 0xe3 +kp_pressed: usage_page 0x07 keycode 0xe2 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe0 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe3 mods 0x00 ht_binding_released: 2 cleaning up hold-tap -kp_released: usage_page 0x07 keycode 0xe2 +kp_released: usage_page 0x07 keycode 0xe2 mods 0x00 ht_binding_released: 3 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/1-dn-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/1-dn-up/keycode_events.snapshot index cf787d8..2eb6475 100644 --- a/app/tests/hold-tap/hold-preferred/1-dn-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/1-dn-up/keycode_events.snapshot @@ -1,5 +1,5 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (hold-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/2-dn-timer-up/keycode_events.snapshot index 03329d5..86517aa 100644 --- a/app/tests/hold-tap/hold-preferred/2-dn-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/2-dn-timer-up/keycode_events.snapshot @@ -1,5 +1,5 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (hold-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot index adf4fe2..b7434c6 100644 --- a/app/tests/hold-tap/hold-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0xe4 +kp_pressed: usage_page 0x07 keycode 0xe4 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (hold-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0xe4 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot index 69b64a9..ffb6aad 100644 --- a/app/tests/hold-tap/hold-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0xe4 +kp_pressed: usage_page 0x07 keycode 0xe4 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (hold-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe4 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot index b06a1d7..1254fed 100644 --- a/app/tests/hold-tap/hold-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0x07 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 ht_decide: 0 decided tap (hold-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot index bf31955..ba7b48b 100644 --- a/app/tests/hold-tap/hold-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0x07 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 ht_decide: 0 decided hold (hold-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot index 3ed7de0..c8acfc1 100644 --- a/app/tests/hold-tap/hold-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot @@ -1,10 +1,10 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (hold-preferred event 1) -kp_pressed: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_pressed: 1 new undecided hold_tap ht_decide: 1 decided tap (hold-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x0d -kp_released: usage_page 0x07 keycode 0x0d +kp_pressed: usage_page 0x07 keycode 0x0d mods 0x00 +kp_released: usage_page 0x07 keycode 0x0d mods 0x00 ht_binding_released: 1 cleaning up hold-tap -kp_released: usage_page 0x07 keycode 0xe1 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot index e0b57fd..97cd07b 100644 --- a/app/tests/hold-tap/hold-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (hold-preferred event 1) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot index e0b57fd..97cd07b 100644 --- a/app/tests/hold-tap/hold-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (hold-preferred event 1) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot index e0b57fd..97cd07b 100644 --- a/app/tests/hold-tap/hold-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (hold-preferred event 1) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot index cac579d..2a21d92 100644 --- a/app/tests/hold-tap/hold-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot +++ b/app/tests/hold-tap/hold-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (hold-preferred event 1) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 diff --git a/app/tests/hold-tap/tap-preferred/1-dn-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/1-dn-up/keycode_events.snapshot index 2a250fb..57e4fcd 100644 --- a/app/tests/hold-tap/tap-preferred/1-dn-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/1-dn-up/keycode_events.snapshot @@ -1,5 +1,5 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (tap-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/2-dn-timer-up/keycode_events.snapshot index 4f1ee63..71ba8da 100644 --- a/app/tests/hold-tap/tap-preferred/2-dn-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/2-dn-timer-up/keycode_events.snapshot @@ -1,5 +1,5 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (tap-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot index 87d1406..0bc731f 100644 --- a/app/tests/hold-tap/tap-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/3a-moddn-dn-modup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0xe4 +kp_pressed: usage_page 0x07 keycode 0xe4 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (tap-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0xe4 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot index 7455d2a..6a3398f 100644 --- a/app/tests/hold-tap/tap-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/3b-moddn-dn-modup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0xe4 +kp_pressed: usage_page 0x07 keycode 0xe4 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (tap-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe4 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot index 3d7eaf1..e518582 100644 --- a/app/tests/hold-tap/tap-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/3c-kcdn-dn-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0x07 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 ht_decide: 0 decided tap (tap-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot index 059d99c..b3b0673 100644 --- a/app/tests/hold-tap/tap-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ -kp_pressed: usage_page 0x07 keycode 0x07 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 ht_binding_pressed: 0 new undecided hold_tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 ht_decide: 0 decided hold (tap-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot index a8cf490..7f45421 100644 --- a/app/tests/hold-tap/tap-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/4a-dn-htdn-timer-htup-up/keycode_events.snapshot @@ -1,10 +1,10 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (tap-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_pressed: 1 new undecided hold_tap ht_decide: 1 decided tap (tap-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x0d -kp_released: usage_page 0x07 keycode 0x0d +kp_pressed: usage_page 0x07 keycode 0x0d mods 0x00 +kp_released: usage_page 0x07 keycode 0x0d mods 0x00 ht_binding_released: 1 cleaning up hold-tap -kp_released: usage_page 0x07 keycode 0xe1 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot index 92a3569..ade0d3e 100644 --- a/app/tests/hold-tap/tap-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (tap-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot index 92a3569..ade0d3e 100644 --- a/app/tests/hold-tap/tap-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided hold (tap-preferred event 3) -kp_pressed: usage_page 0x07 keycode 0xe1 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0xe1 +kp_pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot index bc8aa8e..418312c 100644 --- a/app/tests/hold-tap/tap-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/4c-dn-kcdn-kcup-up/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (tap-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot index b106f13..c0b4c0b 100644 --- a/app/tests/hold-tap/tap-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot +++ b/app/tests/hold-tap/tap-preferred/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot @@ -1,7 +1,7 @@ ht_binding_pressed: 0 new undecided hold_tap ht_decide: 0 decided tap (tap-preferred event 0) -kp_pressed: usage_page 0x07 keycode 0x09 -kp_pressed: usage_page 0x07 keycode 0x07 -kp_released: usage_page 0x07 keycode 0x09 +kp_pressed: usage_page 0x07 keycode 0x09 mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 mods 0x00 ht_binding_released: 0 cleaning up hold-tap -kp_released: usage_page 0x07 keycode 0x07 +kp_released: usage_page 0x07 keycode 0x07 mods 0x00 diff --git a/app/tests/keypress/behavior_keymap.dtsi b/app/tests/keypress/behavior_keymap.dtsi index 34c445c..3a45809 100644 --- a/app/tests/keypress/behavior_keymap.dtsi +++ b/app/tests/keypress/behavior_keymap.dtsi @@ -9,20 +9,8 @@ default_layer { bindings = < - &kp B &mo 1 - &kp D &kp G>; - }; - - lower_layer { - bindings = < - &cp M_NEXT &trans - &kp L &kp J>; - }; - - raise_layer { - bindings = < - &kp W &kp U - &kp X &kp M>; + &kp B &none + &cp M_NEXT &none>; }; }; }; diff --git a/app/tests/keypress/cp-press-release/keycode_events.snapshot b/app/tests/keypress/cp-press-release/keycode_events.snapshot index f1ef0ed..95d24a4 100644 --- a/app/tests/keypress/cp-press-release/keycode_events.snapshot +++ b/app/tests/keypress/cp-press-release/keycode_events.snapshot @@ -1,2 +1,2 @@ -pressed: usage_page 0x0c keycode 0xb5 -released: usage_page 0x0c keycode 0xb5 +pressed: usage_page 0x0c keycode 0xb5 mods 0x00 +pressed: usage_page 0x0c keycode 0xb5 mods 0x00 diff --git a/app/tests/keypress/cp-press-release/native_posix.keymap b/app/tests/keypress/cp-press-release/native_posix.keymap index 0e86f93..bf93af7 100644 --- a/app/tests/keypress/cp-press-release/native_posix.keymap +++ b/app/tests/keypress/cp-press-release/native_posix.keymap @@ -1,5 +1,5 @@ #include "../behavior_keymap.dtsi" &kscan { - events = <ZMK_MOCK_PRESS(0,1,10) ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_RELEASE(0,0,10) ZMK_MOCK_RELEASE(0,1,10)>; + events = <ZMK_MOCK_PRESS(1,0,10) ZMK_MOCK_PRESS(1,0,10)>; };
\ No newline at end of file diff --git a/app/tests/keypress/kp-press-release/keycode_events.snapshot b/app/tests/keypress/kp-press-release/keycode_events.snapshot index f1ef0ed..80cac20 100644 --- a/app/tests/keypress/kp-press-release/keycode_events.snapshot +++ b/app/tests/keypress/kp-press-release/keycode_events.snapshot @@ -1,2 +1,2 @@ -pressed: usage_page 0x0c keycode 0xb5 -released: usage_page 0x0c keycode 0xb5 +pressed: usage_page 0x07 keycode 0x05 mods 0x00 +released: usage_page 0x07 keycode 0x05 mods 0x00 diff --git a/app/tests/keypress/kp-press-release/native_posix.keymap b/app/tests/keypress/kp-press-release/native_posix.keymap index 7f73690..279b084 100644 --- a/app/tests/keypress/kp-press-release/native_posix.keymap +++ b/app/tests/keypress/kp-press-release/native_posix.keymap @@ -1,8 +1,5 @@ -#include <dt-bindings/zmk/keys.h> -#include <behaviors.dtsi> -#include <dt-bindings/zmk/kscan-mock.h> #include "../behavior_keymap.dtsi" &kscan { - events = <ZMK_MOCK_PRESS(0,1,10) ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_RELEASE(0,0,10) ZMK_MOCK_RELEASE(0,1,10)>; + events = <ZMK_MOCK_PRESS(0,0,10) ZMK_MOCK_RELEASE(0,0,10)>; };
\ No newline at end of file diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/events.patterns b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/keycode_events.snapshot b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/keycode_events.snapshot new file mode 100644 index 0000000..6218e65 --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/keycode_events.snapshot @@ -0,0 +1,17 @@ +pressed: usage_page 0x07 keycode 0xe0 mods 0x00 +reg: Modifier 0 count 1 +reg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +pressed: usage_page 0x07 keycode 0xe0 mods 0x00 +reg: Modifier 0 count 2 +reg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +released: usage_page 0x07 keycode 0xe0 mods 0x00 +unreg: Modifier 0 count: 1 +unreg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +released: usage_page 0x07 keycode 0xe0 mods 0x00 +unreg: Modifier 0 count: 0 +unreg: Modifier 0 released +unreg: Modifiers set to 0x00 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/native_posix.keymap b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/native_posix.keymap new file mode 100644 index 0000000..6150094 --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-dn-lctl-up-lctl-up/native_posix.keymap @@ -0,0 +1,27 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LCTL &kp LCTL + &kp LSFT &none + >; + }; + }; +}; diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/events.patterns b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/keycode_events.snapshot b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/keycode_events.snapshot new file mode 100644 index 0000000..4232428 --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/keycode_events.snapshot @@ -0,0 +1,9 @@ +pressed: usage_page 0x07 keycode 0xe0 mods 0x00 +reg: Modifier 0 count 1 +reg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +released: usage_page 0x07 keycode 0xe0 mods 0x00 +unreg: Modifier 0 count: 0 +unreg: Modifier 0 released +unreg: Modifiers set to 0x00 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/native_posix.keymap b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/native_posix.keymap new file mode 100644 index 0000000..3324584 --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lctl-up/native_posix.keymap @@ -0,0 +1,25 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LCTL &kp LCTL + &kp LSFT &none + >; + }; + }; +}; diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/events.patterns b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/keycode_events.snapshot b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/keycode_events.snapshot new file mode 100644 index 0000000..60d829a --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/keycode_events.snapshot @@ -0,0 +1,18 @@ +pressed: usage_page 0x07 keycode 0xe0 mods 0x00 +reg: Modifier 0 count 1 +reg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +reg: Modifier 1 count 1 +reg: Modifiers set to 0x03 +mods: Modifiers set to 0x03 +released: usage_page 0x07 keycode 0xe0 mods 0x00 +unreg: Modifier 0 count: 0 +unreg: Modifier 0 released +unreg: Modifiers set to 0x02 +mods: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0xe1 mods 0x00 +unreg: Modifier 1 count: 0 +unreg: Modifier 1 released +unreg: Modifiers set to 0x00 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/native_posix.keymap b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/native_posix.keymap new file mode 100644 index 0000000..b6f9631 --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lctl-up-lsft-up/native_posix.keymap @@ -0,0 +1,27 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LCTL &kp LCTL + &kp LSFT &none + >; + }; + }; +}; diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/events.patterns b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/keycode_events.snapshot b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/keycode_events.snapshot new file mode 100644 index 0000000..b4755e5 --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/keycode_events.snapshot @@ -0,0 +1,18 @@ +pressed: usage_page 0x07 keycode 0xe0 mods 0x00 +reg: Modifier 0 count 1 +reg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +pressed: usage_page 0x07 keycode 0xe1 mods 0x00 +reg: Modifier 1 count 1 +reg: Modifiers set to 0x03 +mods: Modifiers set to 0x03 +released: usage_page 0x07 keycode 0xe1 mods 0x00 +unreg: Modifier 1 count: 0 +unreg: Modifier 1 released +unreg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +released: usage_page 0x07 keycode 0xe0 mods 0x00 +unreg: Modifier 0 count: 0 +unreg: Modifier 0 released +unreg: Modifiers set to 0x00 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/native_posix.keymap b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/native_posix.keymap new file mode 100644 index 0000000..3fedad2 --- /dev/null +++ b/app/tests/modifiers/explicit/kp-lctl-dn-lsft-dn-lsft-up-lctl-up/native_posix.keymap @@ -0,0 +1,28 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LCTL &kp LCTL + &kp LSFT &none + >; + }; + }; +}; diff --git a/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/events.patterns b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/keycode_events.snapshot b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/keycode_events.snapshot new file mode 100644 index 0000000..61dd271 --- /dev/null +++ b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/keycode_events.snapshot @@ -0,0 +1,8 @@ +pressed: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x02 +pressed: usage_page 0x07 keycode 0x04 mods 0x01 +mods: Modifiers set to 0x01 +released: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x01 +released: usage_page 0x07 keycode 0x04 mods 0x01 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/native_posix.keymap b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/native_posix.keymap new file mode 100644 index 0000000..c603c00 --- /dev/null +++ b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/native_posix.keymap @@ -0,0 +1,27 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LC(A) &kp LS(B) + &kp LCTL &none + >; + }; + }; +}; diff --git a/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/pending b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/pending new file mode 100644 index 0000000..3f49005 --- /dev/null +++ b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod1-up-mod2-up/pending @@ -0,0 +1,9 @@ +This test fails because the hid_listener_keycode_released function +releases implicit modifiers always, even if they were not set by the +key that's going up. Also see the comment in that function: + + If LC(A) is pressed, then LS(B), then LC(A) is released, the shift for B will be released + prematurely. This causes if LS(B) to repeat like Bbbbbbbb when pressed for a long time. + Solving this would require keeping track of which key's implicit modifiers are currently + active and only releasing modifiers at that time. + diff --git a/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/events.patterns b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/keycode_events.snapshot b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/keycode_events.snapshot new file mode 100644 index 0000000..e8a231f --- /dev/null +++ b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/keycode_events.snapshot @@ -0,0 +1,8 @@ +pressed: usage_page 0x07 keycode 0x04 mods 0x01 +mods: Modifiers set to 0x01 +pressed: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x04 mods 0x01 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/native_posix.keymap b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/native_posix.keymap new file mode 100644 index 0000000..109d60e --- /dev/null +++ b/app/tests/modifiers/implicit/kp-mod1-dn-mod2-dn-mod2-up-mod1-up/native_posix.keymap @@ -0,0 +1,27 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LC(A) &kp LS(B) + &none &none + >; + }; + }; +}; diff --git a/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/events.patterns b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/keycode_events.snapshot b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/keycode_events.snapshot new file mode 100644 index 0000000..40c5841 --- /dev/null +++ b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/keycode_events.snapshot @@ -0,0 +1,13 @@ +pressed: usage_page 0x07 keycode 0xe0 mods 0x00 +reg: Modifier 0 count 1 +reg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +pressed: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x03 +released: usage_page 0x07 keycode 0xe0 mods 0x00 +unreg: Modifier 0 count: 0 +unreg: Modifier 0 released +unreg: Modifiers set to 0x00 +mods: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/native_posix.keymap b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/native_posix.keymap new file mode 100644 index 0000000..d381e4b --- /dev/null +++ b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-lctl-up-mod-up/native_posix.keymap @@ -0,0 +1,27 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LC(A) &kp LS(B) + &kp LCTL &none + >; + }; + }; +}; diff --git a/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/events.patterns b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/events.patterns new file mode 100644 index 0000000..cbf21af --- /dev/null +++ b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_register_mod/reg/p +s/.*hid_unregister_mod/unreg/p +s/.*zmk_hid_.*Modifiers set to /mods: Modifiers set to /p
\ No newline at end of file diff --git a/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/keycode_events.snapshot b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/keycode_events.snapshot new file mode 100644 index 0000000..5df571b --- /dev/null +++ b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/keycode_events.snapshot @@ -0,0 +1,13 @@ +pressed: usage_page 0x07 keycode 0xe0 mods 0x00 +reg: Modifier 0 count 1 +reg: Modifiers set to 0x01 +mods: Modifiers set to 0x01 +pressed: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x03 +released: usage_page 0x07 keycode 0x05 mods 0x02 +mods: Modifiers set to 0x01 +released: usage_page 0x07 keycode 0xe0 mods 0x00 +unreg: Modifier 0 count: 0 +unreg: Modifier 0 released +unreg: Modifiers set to 0x00 +mods: Modifiers set to 0x00 diff --git a/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/native_posix.keymap b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/native_posix.keymap new file mode 100644 index 0000000..b47b5f7 --- /dev/null +++ b/app/tests/modifiers/mixed/kp-lctl-dn-mod-dn-mod-up-lctl-up/native_posix.keymap @@ -0,0 +1,27 @@ +#include <dt-bindings/zmk/keys.h> +#include <behaviors.dtsi> +#include <dt-bindings/zmk/kscan-mock.h> + + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; + +/ { + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &kp LC(A) &kp LS(B) + &kp LCTL &none + >; + }; + }; +}; diff --git a/app/tests/momentary-layer/early-key-release/keycode_events.snapshot b/app/tests/momentary-layer/early-key-release/keycode_events.snapshot index 474eef7..82ebc67 100644 --- a/app/tests/momentary-layer/early-key-release/keycode_events.snapshot +++ b/app/tests/momentary-layer/early-key-release/keycode_events.snapshot @@ -1,4 +1,4 @@ -kp_pressed: usage_page 0x07 keycode 0x05 +kp_pressed: usage_page 0x07 keycode 0x05 mods 0x00 mo_pressed: position 1 layer 1 -kp_released: usage_page 0x07 keycode 0x05 +kp_released: usage_page 0x07 keycode 0x05 mods 0x00 mo_released: position 1 layer 1 diff --git a/app/tests/momentary-layer/normal/keycode_events.snapshot b/app/tests/momentary-layer/normal/keycode_events.snapshot index 9dc6101..247128f 100644 --- a/app/tests/momentary-layer/normal/keycode_events.snapshot +++ b/app/tests/momentary-layer/normal/keycode_events.snapshot @@ -1,4 +1,4 @@ mo_pressed: position 1 layer 1 -kp_pressed: usage_page 0x0c keycode 0xb5 -kp_released: usage_page 0x0c keycode 0xb5 +kp_pressed: usage_page 0x0c keycode 0xb5 mods 0x00 +kp_released: usage_page 0x0c keycode 0xb5 mods 0x00 mo_released: position 1 layer 1 diff --git a/app/tests/toggle-layer/early-key-release/keycode_events.snapshot b/app/tests/toggle-layer/early-key-release/keycode_events.snapshot index 3ac017c..6b4d50b 100644 --- a/app/tests/toggle-layer/early-key-release/keycode_events.snapshot +++ b/app/tests/toggle-layer/early-key-release/keycode_events.snapshot @@ -1,6 +1,6 @@ -kp_pressed: usage_page 0x07 keycode 0x05 +kp_pressed: usage_page 0x07 keycode 0x05 mods 0x00 tog_pressed: position 1 layer 1 -kp_released: usage_page 0x07 keycode 0x05 +kp_released: usage_page 0x07 keycode 0x05 mods 0x00 tog_released: position 1 layer 1 -kp_pressed: usage_page 0x0c keycode 0xb5 -kp_released: usage_page 0x0c keycode 0xb5 +kp_pressed: usage_page 0x0c keycode 0xb5 mods 0x00 +kp_released: usage_page 0x0c keycode 0xb5 mods 0x00 diff --git a/app/tests/toggle-layer/normal/keycode_events.snapshot b/app/tests/toggle-layer/normal/keycode_events.snapshot index 42174cc..d03295e 100644 --- a/app/tests/toggle-layer/normal/keycode_events.snapshot +++ b/app/tests/toggle-layer/normal/keycode_events.snapshot @@ -1,4 +1,4 @@ tog_pressed: position 1 layer 1 tog_released: position 1 layer 1 -kp_pressed: usage_page 0x0c keycode 0xb5 -kp_released: usage_page 0x0c keycode 0xb5 +kp_pressed: usage_page 0x0c keycode 0xb5 mods 0x00 +kp_released: usage_page 0x0c keycode 0xb5 mods 0x00 diff --git a/app/tests/transparent/layered/keycode_events.snapshot b/app/tests/transparent/layered/keycode_events.snapshot index d0bd245..5e707b8 100644 --- a/app/tests/transparent/layered/keycode_events.snapshot +++ b/app/tests/transparent/layered/keycode_events.snapshot @@ -1,2 +1,2 @@ -kp_pressed: usage_page 0x07 keycode 0x04 -kp_released: usage_page 0x07 keycode 0x04 +kp_pressed: usage_page 0x07 keycode 0x04 mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 mods 0x00 diff --git a/docs/.nvmrc b/docs/.nvmrc new file mode 100644 index 0000000..1a2f5bd --- /dev/null +++ b/docs/.nvmrc @@ -0,0 +1 @@ +lts/*
\ No newline at end of file diff --git a/docs/blog/2020-10-03-bootloader-fix.md b/docs/blog/2020-10-03-bootloader-fix.md new file mode 100644 index 0000000..8a9fd7f --- /dev/null +++ b/docs/blog/2020-10-03-bootloader-fix.md @@ -0,0 +1,195 @@ +--- +title: Fixing the Mysterious Broken Bootloader +author: Nick Winans +author_title: Contributor +author_url: https://github.com/Nicell +author_image_url: https://avatars1.githubusercontent.com/u/9439650 +tags: [bootloader, keyboards, firmware, oss, ble] +--- + +Recently I was able to fix the "stuck in the bootloader" issue in +[#322](https://github.com/zmkfirmware/zmk/pull/322) that had been plaguing us +for quite some time. I want to go over what the issue was, how the issue was +diagnosed, and how it was fixed. + +## Background + +What exactly is the "stuck in the bootloader" issue? Seemingly randomly, users' +keyboards would suddenly stop working and when they would reset their keyboard +they would get put into the bootloader instead of back into the firmware. This +would require the user to re-flash the firmware again to get into the firmware. +That wouldn't be so bad except for the fact that once this occurs, every reset +would require the user to re-flash the firmware again. The only way to really +fix this issue was to re-flash the bootloader itself, which is a huge pain. + +Going into this, all we knew was that this issue was most likely introduced +somewhere in the [#133](https://github.com/zmkfirmware/zmk/pull/133), which +added Bluetooth profile management. We've had quite a few attempts at trying to +recreate the issue, but we never were able to get it to happen consistently. + +## Diagnosing the issue + +This issue had been happening sporadically for the past month, and I finally +decided to dig in to see what was going on. We started in the Discord and +discussed what was common between all of the people who have experienced this +issue. Everyone who had this issue reported that they did quite a bit of profile +switching. This lined up with the possible connection to the Bluetooth profile +management pull request. + +### Pinpointing the cause + +I had a hunch that this was related to the settings system. The settings system +is used by profile Bluetooth switching, and the settings system works directly +with the system flash. Based on this hunch, I tried spamming the RGB underglow +cycle behavior on my main keyboard. Sure enough after a couple minutes, I got +stuck in the bootloader. I was even able to reproduce it again. + +This was an important discovery for two reasons. First, I was able to recreate +the issue consistently, which meant I could set up logging and more closely +monitor what the board was doing. Second, this more or less proved that it was +specifically the settings system at fault. Both Bluetooth profile switching and +RGB underglow cycling trigger it, and the one common piece is they save their +state to settings. + +### Settings system overview + +To understand what's going wrong, we first need to understand how the settings +system works. Here's a diagram to explain the flash space that the settings +system holds for our nRF52840 based boards (nice!nano, nRFMicro, BlueMicro). + + + +The settings flash space lives at the end of the flash of the chip. In this case +it starts at `0xF8000` and is `0x8000` bytes long, which is 32KB in more +comprehensible units. Then due to the chip's architecture, this flash space is +broken into pages, which are `0x1000` bytes in size (4KB). + +The backend that carries out the settings save and read operation in ZMK is +called NVS. NVS calls these pages sectors. Due to how flash works, you can't +write to the same bytes multiple times without erasing them first, and to erase +bytes, you need to erase the entire sector of flash. This means when NVS writes +to the settings flash if there's no erased space available for the new value, it +will need to erase a sector. + +### Logging discoveries + +So first I enabled logging of the NVS module by adding +`CONFIG_NVS_LOG_LEVEL_DBG=y` to my `.conf` file. I repeated the same test of +spamming RGB underglow effect cycle and the resulting logs I got were this: + +``` +[00:00:00.000,671] <inf> fs_nvs: 8 Sectors of 4096 bytes +[00:00:00.000,671] <inf> fs_nvs: alloc wra: 3, f70 +[00:00:00.000,671] <inf> fs_nvs: data wra: 3, f40 +// A bunch of effect cycle spam +[00:02:34.781,188] <dbg> fs_nvs: Erasing flash at fd000, len 4096 +// A bunch more effect cycle spam +[00:06:42.219,970] <dbg> fs_nvs: Erasing flash at ff000, len 4096 +// A bunch more effect cycle spam +// KABOOM - bootloader issue +``` + +So at start up, we can see that the 8 sectors of 4KB are found by NVS properly, +however, I wasn't sure what the second and third lines meant, but we'll get back +to that. Nonetheless the next two logs from NVS showed erasing the sector at +`0xFD000` and then erasing the `0xFF000` sector. + + + +It's really odd that the third to last sector and the last sector are erased, +and then shortly after the bootloader issue is hit. I really had no explanation +for this behavior. + +### Reaching out to Zephyr + +At this point, I nor anyone else working on the ZMK project knew enough about +NVS to explain what was going on here. [Pete +Johanson](https://github.com/petejohanson), project founder, reached out on the +Zephyr Project's Slack (ZMK is built on top of Zephyr if you weren't aware). +Justin B and Laczen assisted by first explaining that those `alloc wra` and +`data wra` logs from earlier are showing what data NVS found at startup. + +More specifically, `data wra` should be `0` when it first starts up on a clean +flash. As we can see from my earlier logging on a clean flash I was instead +getting `f40`. NVS is finding data in our settings sectors when they should be +blank! We were then given the advice to double check our bootloader. + +### The Adafruit nRF52 Bootloader + +Most of the boards the contributors of ZMK use have the [Adafruit nRF52 +Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader), which allows +for extremely easy flashing by dragging and dropping `.uf2` files onto the board +as a USB drive. Every bootloader takes up a portion of the flash, and in the +README explains that the first `0x26000` is reserved for the bootloader with the +nRF52840, and we've properly allocated that. + +However, there isn't a full explanation of the flash allocation of the +bootloader in the README. There's a possibility that the bootloader is using +part of the same flash area we're using. I reached out on the Adafruit Discord, +and [Dan Halbert](https://github.com/dhalbert) pointed me towards the [linker +map](https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/master/linker/nrf52840.ld) +of the nRF52840. Let's take a look. + +``` +FLASH (rx) : ORIGIN = 0xF4000, LENGTH = 0xFE000-0xF4000-2048 /* 38 KB */ + +BOOTLOADER_CONFIG (r): ORIGIN = 0xFE000 - 2048, LENGTH = 2048 + +/** Location of mbr params page in flash. */ +MBR_PARAMS_PAGE (rw) : ORIGIN = 0xFE000, LENGTH = 0x1000 + +/** Location of bootloader setting in flash. */ +BOOTLOADER_SETTINGS (rw) : ORIGIN = 0xFF000, LENGTH = 0x1000 +``` + +Here's a diagram to show this a bit better. + + + +We've found the issue! As you can see from the red bar (representing our +settings flash area), we've put the settings flash area _right on top_ of the +Adafruit bootloader's flash space. Oops! + +This also shines some light on why NVS erased `0xFD000` and `0xFF000` sectors. +It's possible there was no flash written to `0xFD000` because the bootloader +didn't use up all of that space it has, and then there possibly weren't any +bootloader settings set yet, so `0xFF000` could be used and erased by NVS too. + +After erasing `0xFF000`, NVS probably next erased a rather important part of the +bootloader that resulted in this issue at hand. In my opinion, we're pretty +lucky that it didn't delete an even more vital part of the bootloader. At least +we could still get to it, so that we could re-flash the bootloader easily! + +## The solution + +Now that we've found the issue, we can pretty easily fix this. We'll need to +move the settings flash area back so that it doesn't overlap with the +bootloader. First we calculate the size of the of flash area the bootloader is using. + +``` +0x100000 (end of flash) - 0x0F4000 (start of bootloader) = 0xC000 (48KB) +``` + +So the bootloader is using the last 48KB of the flash, this means all we need to +do is shift back the settings area and code space `0xC000` bytes. We'll apply +this to all of the `.dts` files for the boards that were affected by this issue. + +```diff + code_partition: partition@26000 { + label = "code_partition"; +- reg = <0x00026000 0x000d2000>; ++ reg = <0x00026000 0x000c6000>; + }; + + +- storage_partition: partition@f8000 { ++ storage_partition: partition@ec000 { + label = "storage"; +- reg = <0x000f8000 0x00008000>; ++ reg = <0x000ec000 0x00008000>; + }; +``` + +And with those changes, we should no longer run into this issue! In the process +of these changes, we lost 48KB of space for application code, but we're only +using around 20% of it anyways. 🎉 diff --git a/docs/docs/behavior/outputs.md b/docs/docs/behavior/outputs.md new file mode 100644 index 0000000..ae81249 --- /dev/null +++ b/docs/docs/behavior/outputs.md @@ -0,0 +1,59 @@ +--- +title: Output Selection Behavior +sidebar_label: Output Selection +--- + +## Summary + +The output behavior allows selecting whether keyboard output is sent to the +USB or bluetooth connection when both are connected. This allows connecting a +keyboard to USB for power but outputting to a different device over bluetooth. + +By default, output is sent to USB when both USB and BLE are connected. +Once you select a different output, it will be remembered until you change it again. + +## Output Command Defines + +Output command defines are provided through the [`dt-bindings/zmk/outputs.h`](https://github.com/zmkfirmware/zmk/blob/main/app/include/dt-bindings/zmk/outputs.h) +header, which is added at the top of the keymap file: + +``` +#include <dt-bindings/zmk/outputs.h> +``` + +This allows you to reference the actions defined in this header: + +| Define | Action | +| --------- | ----------------------------------------------- | +| `OUT_USB` | Prefer sending to USB | +| `OUT_BLE` | Prefer sending to the current bluetooth profile | +| `OUT_TOG` | Toggle between USB and BLE | + +## Output Selection Behavior + +The output selection behavior changes the preferred output on press. + +### Behavior Binding + +- Reference: `&out` +- Parameter #1: Command, e.g. `OUT_BLE` + +### Examples + +1. Behavior binding to prefer sending keyboard output to USB + + ``` + &out OUT_USB + ``` + +1. Behavior binding to prefer sending keyboard output to the current bluetooth profile + + ``` + &out OUT_BLE + ``` + +1. Behavior binding to toggle between preferring USB and BLE + + ``` + &out OUT_TOG + ``` diff --git a/docs/docs/dev-guide-new-shield.md b/docs/docs/dev-guide-new-shield.md index 94f7d1d..e1d6f25 100644 --- a/docs/docs/dev-guide-new-shield.md +++ b/docs/docs/dev-guide-new-shield.md @@ -27,6 +27,15 @@ ZMK support for split keyboards requires a few more files than single boards to ## New Shield Directory +:::note +This guide describes how to add shield to the ZMK main repository. If you are building firmware for your +own prototype or handwired keyboard, it is recommended to use your own user config repository. Follow the +[user setup guide](./user-setup.md) to create your user config repository first. When following the rest +of this guide, replace the `app/` directory in the ZMK main repository with the `config/` directory in your +user config repository. For example, `app/boards/shields/<keyboard_name>` should now be +`config/boards/shields/<keyboard_name>`. +::: + Shields for Zephyr applications go into the `boards/shields/` directory; since ZMK's Zephyr application lives in the `app/` subdirectory of the repository, that means the new shield directory should be: ```bash @@ -66,7 +75,11 @@ that make sense to have different defaults when this shield is used. One main it that usually has a new default value set here is the `ZMK_KEYBOARD_NAME` value, which controls the display name of the device over USB and BLE. -The updated new default values should always be wrapped inside a conditional on the shield config name defined in the `Kconfig.shield` file. Here's the simplest example file: +The updated new default values should always be wrapped inside a conditional on the shield config name defined in the `Kconfig.shield` file. Here's the simplest example file. + +:::warning +Do not make the keyboard name too long, otherwise the bluetooth advertising might fail and you will not be able to find your keyboard from your laptop / tablet. +::: ``` if SHIELD_MY_BOARD diff --git a/docs/docs/dev-guide-usb-logging.md b/docs/docs/dev-guide-usb-logging.md index d0274d1..50884be 100644 --- a/docs/docs/dev-guide-usb-logging.md +++ b/docs/docs/dev-guide-usb-logging.md @@ -12,11 +12,25 @@ If you are developing ZMK on a device that does not have a built in UART for deb Zephyr can be configured to create a USB CDC ACM device and the direct all `printk`, console output, and log messages to that device instead. +:::warning Battery Life Impact + +Enabling logging increases the power usage of your keyboard, and can have a non-trivial impact to your time on battery. +It is recommended to only enable logging when needed, and not leaving it on by default. + +::: + ## Kconfig The following KConfig values need to be set, either by copy and pasting into the `app/prj.conf` file, or by running `west build -t menuconfig` and manually enabling the various settings in that UI. +:::note +If you are debugging your own keyboard in your [user config repository](./user-setup.md), use +`config/boards/shields/<your_keyboard>/<your_keyboard>.conf` instead of `app/prj.conf`. In Github +Actions, you can search the `Kconfig file` build log to verify the options above have been enabled +for you successfully. +::: + ``` # Turn on logging, and set ZMK logging to debug output CONFIG_LOG=y @@ -52,6 +66,7 @@ defaultValue="linux" values={[ {label: 'Linux', value: 'linux'}, {label: 'Windows', value: 'win'}, +{label: 'MacOS', value: 'macos'} ]}> <TabItem value="linux"> @@ -73,6 +88,17 @@ On Windows, you can use [PuTTY](https://www.putty.org/). Once installed, use Dev If you already have the Ardunio IDE installed you can also use its built-in Serial Monitor. </TabItem> +<TabItem value="macos"> + +On MacOS, the device name is something like `/dev/tty.usbmodemXXXXX` where `XXXXX` is some numerical ID. +You can connect to the device with [tio](https://tio.github.io/) (can be installed via [Homebrew](https://formulae.brew.sh/formula/tio)): + +``` +sudo tio /dev/tty.usbmodem14401 +``` + +You should see tio printing `Disconnected` or `Connected` when you disconnect or reconnect the USB cable. +</TabItem> </Tabs> From there, you should see the various log messages from ZMK and Zephyr, depending on which systems you have set to what log levels. diff --git a/docs/docs/feature/keymaps.md b/docs/docs/feature/keymaps.md index 56fc2cc..a322336 100644 --- a/docs/docs/feature/keymaps.md +++ b/docs/docs/feature/keymaps.md @@ -68,7 +68,7 @@ In this case, the `A` is actually a define for the raw HID keycode, to make keym For example of a binding that uses two parameters, you can see how "mod-tap" (`mt`) is bound: ``` -&mt MOD_LSFT D +&mt LSFT D ``` Here, the first parameter is the set of modifiers that should be used for the "hold" behavior, and the second @@ -92,7 +92,7 @@ The top two lines of most keymaps should include: The first defines the nodes for all the available behaviors in ZMK, which will be referenced in the behavior bindings. This is how bindings like `&kp` can reference the key press behavior defined with an anchor name of `kp`. -The second include brings in the defines for all the keycodes (e.g. `A`, `NUM_1`, `M_PLAY`) and the modifiers (e.g. `MOD_LSFT`) used for various behavior bindings. +The second include brings in the defines for all the keycodes (e.g. `A`, `NUM_1`, `M_PLAY`) and the modifiers (e.g. `LSFT`) used for various behavior bindings. ### Root devicetree Node diff --git a/docs/docs/intro.md b/docs/docs/intro.md index 547265a..cb227a2 100644 --- a/docs/docs/intro.md +++ b/docs/docs/intro.md @@ -16,7 +16,7 @@ ZMK is currently missing some features found in other popular firmware. This tab | ---------------------------------------------------------------------------------------------------------------------- | :-: | :-------: | :-: | | Low Latency BLE Support | ✅ | ✅ | | | Multi-Device BLE Support | ✅ | | | -| USB Connectivity | ✅ | | ✅ | +| [USB Connectivity](behavior/outputs) | ✅ | | ✅ | | User Configuration Repositories | ✅ | | | | Split Keyboard Support | ✅ | ✅ | ✅ | | [Keymaps and Layers](behavior/layers) | ✅ | ✅ | ✅ | diff --git a/docs/docs/user-setup.md b/docs/docs/user-setup.md index 5a4921e..990a8f6 100644 --- a/docs/docs/user-setup.md +++ b/docs/docs/user-setup.md @@ -39,6 +39,7 @@ The remainder of this guide assumes the following prerequisites: 1. You have an active, working [GitHub](https://github.com/) account. 1. You have installed and configured the [`git`](https://git-scm.com/) version control tool. +1. You have locally configured git to access your github account. If using [personal access tokens](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token), please be sure it was created with the "workflow" scope option selected. :::note If you need to, a quick read of [Learn The Basics Of Git In Under 10 Minutes](https://www.freecodecamp.org/news/learn-the-basics-of-git-in-under-10-minutes-da548267cc91/) will help you get started. @@ -102,6 +103,12 @@ Pick an MCU board: ### Keyboard Shield Selection +:::note +If you are building firmware for a new keyboard shield that is not included in the built-in +list of shields, you can choose any shield from the list that is similar to yours to generate the repository, +and edit / add necessary files according to the [guide for adding new keyboard shield](./dev-guide-new-shield.md). +::: + When prompted, enter the number for the corresponding keyboard shield you would like to target: ``` diff --git a/docs/package.json b/docs/package.json index f1e911e..cb42506 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,7 +8,10 @@ "serve": "docusaurus serve", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", - "clear": "docusaurus clear" + "clear": "docusaurus clear", + "lint": "eslint . --ext js,jsx,md,mdx", + "prettier:check": "prettier --check .", + "prettier:format": "prettier --write ." }, "dependencies": { "@docusaurus/core": "^2.0.0-alpha.66", diff --git a/docs/sidebars.js b/docs/sidebars.js index 54f6576..c8dc79f 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -22,6 +22,7 @@ module.exports = { "behavior/mod-tap", "behavior/reset", "behavior/bluetooth", + "behavior/outputs", "behavior/lighting", "behavior/power", ], |