Kevin
4 years ago
143 changed files with 2047 additions and 302 deletions
@ -0,0 +1,16 @@ |
|||||||
|
# Copyright (c) 2020 Pete Johanson, Kurtis Lew |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
if SHIELD_IRIS_LEFT |
||||||
|
|
||||||
|
config ZMK_KEYBOARD_NAME |
||||||
|
default "Iris Left" |
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
if SHIELD_IRIS_RIGHT |
||||||
|
|
||||||
|
config ZMK_KEYBOARD_NAME |
||||||
|
default "Iris Right" |
||||||
|
|
||||||
|
endif |
@ -0,0 +1,8 @@ |
|||||||
|
# Copyright (c) 2020 Pete Johanson, Kurtis Lew |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
config SHIELD_IRIS_LEFT |
||||||
|
def_bool $(shields_list_contains,iris_left) |
||||||
|
|
||||||
|
config SHIELD_IRIS_RIGHT |
||||||
|
def_bool $(shields_list_contains,iris_right) |
@ -0,0 +1,51 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Pete Johanson, Kurtis Lew |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <dt-bindings/zmk/matrix-transform.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
chosen { |
||||||
|
zmk,kscan = &kscan0; |
||||||
|
zmk,matrix_transform = &default_transform; |
||||||
|
}; |
||||||
|
|
||||||
|
default_transform: keymap_transform_0 { |
||||||
|
compatible = "zmk,matrix-transform"; |
||||||
|
columns = <16>; |
||||||
|
rows = <4>; |
||||||
|
// | SW6 | SW5 | SW4 | SW3 | SW2 | SW1 | | SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | |
||||||
|
// | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | |
||||||
|
// | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | |
||||||
|
// | SW24 | SW23 | SW22 | SW21 | SW20 | SW19 | SW25 | | SW25 | SW19 | SW20 | SW21 | SW22 | SW23 | SW24 | |
||||||
|
// | SW29 | SW28 | SW27 | SW26 | | SW26 | SW27 | SW28 | SW29 | |
||||||
|
map = < |
||||||
|
RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11) |
||||||
|
RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11) |
||||||
|
RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11) |
||||||
|
RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,2) RC(4,9) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) |
||||||
|
RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) RC(4,8) |
||||||
|
>; |
||||||
|
}; |
||||||
|
|
||||||
|
kscan0: kscan { |
||||||
|
compatible = "zmk,kscan-gpio-matrix"; |
||||||
|
label = "KSCAN"; |
||||||
|
|
||||||
|
diode-direction = "col2row"; |
||||||
|
row-gpios |
||||||
|
= <&pro_micro_d 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
; |
||||||
|
|
||||||
|
}; |
||||||
|
|
||||||
|
bt_unpair_combo: bt_unpair_combo { |
||||||
|
compatible = "zmk,bt-unpair-combo"; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,59 @@ |
|||||||
|
# Copyright (c) 2020 Pete Johanson, Kurtis Lew |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
#include <behaviors.dtsi> |
||||||
|
#include <dt-bindings/zmk/keys.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
keymap { |
||||||
|
compatible = "zmk,keymap"; |
||||||
|
|
||||||
|
default_layer { |
||||||
|
// ------------------------------------------------------------------------------------------------------------ |
||||||
|
// | ESC | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | ` | |
||||||
|
// | TAB | Q | W | E | R | T | | Y | U | I | O | P | - | |
||||||
|
// | CTRL | A | S | D | F | G | | H | J | K | L | ; | ' | |
||||||
|
// | SHIFT | Z | X | C | V | B | "[" | | "]" | N | M | , | . | / | SHIFT | |
||||||
|
// | GUI | LOWER| SPACE | | ENTER | RAISE| ALT | |
||||||
|
bindings = < |
||||||
|
&kp ESC &kp NUM_1 &kp NUM_2 &kp NUM_3 &kp NUM_4 &kp NUM_5 &kp NUM_6 &kp NUM_7 &kp NUM_8 &kp NUM_9 &kp NUM_0 &kp GRAV |
||||||
|
&kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp MINUS |
||||||
|
&kp LCTL &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SCLN &kp QUOT |
||||||
|
&kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp LBKT &kp RBKT &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RSFT |
||||||
|
&kp LGUI &mo 1 &kp SPC &kp RET &mo 2 &kp RALT |
||||||
|
>; |
||||||
|
}; |
||||||
|
|
||||||
|
lower_layer { |
||||||
|
// ------------------------------------------------------------------------------------------------------------ |
||||||
|
// | | | | | | | | | | | | | | |
||||||
|
// | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 | |
||||||
|
// | ` | ! | @ | # | $ | % | | ^ | & | * | ( | ) | ~ | |
||||||
|
// | | | | | | | | | | | _ | + | { | } | "|" | |
||||||
|
// | | | | | | | | |
||||||
|
bindings = < |
||||||
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans |
||||||
|
&kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 |
||||||
|
&kp GRAV &kp BANG &kp ATSN &kp HASH &kp CURU &kp PRCT &kp CRRT &kp AMPS &kp KMLT &kp LPRN &kp RPRN &kp TILD |
||||||
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &kp MINUS &kp KPLS &kp LCUR &kp RCUR &kp PIPE |
||||||
|
&trans &trans &trans &trans &trans &trans |
||||||
|
>; |
||||||
|
}; |
||||||
|
|
||||||
|
raise_layer { |
||||||
|
// ------------------------------------------------------------------------------------------------------------ |
||||||
|
// | | | | | | | | | | | | | | |
||||||
|
// | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | | |
||||||
|
// | F1 | F2 | F3 | F4 | F5 | F6 | | | <- | ^ | v | -> | | |
||||||
|
// | F7 | F8 | F9 | F10 | F11 | F12 | | | | + | - | = | [ | ] | \ | |
||||||
|
// | | | | | | | | |
||||||
|
bindings = < |
||||||
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans |
||||||
|
&kp GRAV &kp NUM_1 &kp NUM_2 &kp NUM_3 &kp NUM_4 &kp NUM_5 &kp NUM_6 &kp NUM_7 &kp NUM_8 &kp NUM_9 &kp NUM_0 &trans |
||||||
|
&kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &trans &kp LARW &kp DARW &kp UARW &kp RARW &trans |
||||||
|
&kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &trans &kp KPLS &kp MINUS &kp EQL &kp LBKT &kp RBKT &kp BSLH |
||||||
|
&trans &trans &trans &trans &trans &trans |
||||||
|
>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,2 @@ |
|||||||
|
CONFIG_ZMK_SPLIT=y |
||||||
|
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y |
@ -0,0 +1,22 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Pete Johanson, Kurtis Lew |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "iris.dtsi" |
||||||
|
|
||||||
|
&kscan0 { |
||||||
|
col-gpios |
||||||
|
= <&pro_micro_a 1 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 0 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 15 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 14 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 16 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 10 GPIO_ACTIVE_HIGH> |
||||||
|
; |
||||||
|
}; |
||||||
|
|
||||||
|
&bt_unpair_combo { |
||||||
|
key-positions = <0 42>; |
||||||
|
}; |
@ -0,0 +1,2 @@ |
|||||||
|
CONFIG_ZMK_SPLIT=y |
||||||
|
CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y |
@ -0,0 +1,26 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Pete Johanson, Kurtis Lew |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "iris.dtsi" |
||||||
|
|
||||||
|
&default_transform { |
||||||
|
col-offset = <6>; |
||||||
|
}; |
||||||
|
|
||||||
|
&kscan0 { |
||||||
|
col-gpios |
||||||
|
= <&pro_micro_a 1 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 0 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 15 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 14 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 16 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 10 GPIO_ACTIVE_HIGH> |
||||||
|
; |
||||||
|
}; |
||||||
|
|
||||||
|
&bt_unpair_combo { |
||||||
|
key-positions = <11 43>; |
||||||
|
}; |
@ -0,0 +1,54 @@ |
|||||||
|
# Copyright (c) 2020 Ryan Cross |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
if SHIELD_SOFLE_LEFT |
||||||
|
|
||||||
|
config ZMK_KEYBOARD_NAME |
||||||
|
default "Sofle Left" |
||||||
|
endif |
||||||
|
|
||||||
|
if SHIELD_SOFLE_RIGHT |
||||||
|
|
||||||
|
config ZMK_KEYBOARD_NAME |
||||||
|
default "Sofle Right" |
||||||
|
endif |
||||||
|
|
||||||
|
if SHIELD_SOFLE_LEFT || SHIELD_SOFLE_RIGHT |
||||||
|
|
||||||
|
if ZMK_DISPLAY |
||||||
|
|
||||||
|
config I2C |
||||||
|
default y |
||||||
|
|
||||||
|
config SSD1306 |
||||||
|
default y |
||||||
|
|
||||||
|
config SSD1306_REVERSE_MODE |
||||||
|
default y |
||||||
|
|
||||||
|
endif # ZMK_DISPLAY |
||||||
|
|
||||||
|
if LVGL |
||||||
|
|
||||||
|
config LVGL_HOR_RES |
||||||
|
default 128 |
||||||
|
|
||||||
|
config LVGL_VER_RES |
||||||
|
default 32 |
||||||
|
|
||||||
|
config LVGL_VDB_SIZE |
||||||
|
default 64 |
||||||
|
|
||||||
|
config LVGL_DPI |
||||||
|
default 148 |
||||||
|
|
||||||
|
config LVGL_BITS_PER_PIXEL |
||||||
|
default 1 |
||||||
|
|
||||||
|
choice LVGL_COLOR_DEPTH |
||||||
|
default LVGL_COLOR_DEPTH_1 |
||||||
|
endchoice |
||||||
|
|
||||||
|
endif # LVGL |
||||||
|
|
||||||
|
endif |
@ -0,0 +1,8 @@ |
|||||||
|
# Copyright (c) 2020 Ryan Cross |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
config SHIELD_SOFLE_LEFT |
||||||
|
def_bool $(shields_list_contains,sofle_left) |
||||||
|
|
||||||
|
config SHIELD_SOFLE_RIGHT |
||||||
|
def_bool $(shields_list_contains,sofle_right) |
@ -0,0 +1,9 @@ |
|||||||
|
# Copyright (c) 2020 Ryan Cross |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
# Uncomment the following line to enable the Sofle OLED Display |
||||||
|
# CONFIG_ZMK_DISPLAY=y |
||||||
|
|
||||||
|
# Uncomment these two lines to add support for encoders |
||||||
|
# CONFIG_EC11=y |
||||||
|
# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y |
@ -0,0 +1,91 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Pete Johanson, Ryan Cross |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <dt-bindings/zmk/matrix-transform.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
chosen { |
||||||
|
zmk,kscan = &kscan0; |
||||||
|
zmk,matrix_transform = &default_transform; |
||||||
|
}; |
||||||
|
|
||||||
|
default_transform: keymap_transform_0 { |
||||||
|
compatible = "zmk,matrix-transform"; |
||||||
|
columns = <16>; |
||||||
|
rows = <4>; |
||||||
|
// | SW6 | SW5 | SW4 | SW3 | SW2 | SW1 | | SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | |
||||||
|
// | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | |
||||||
|
// | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | |
||||||
|
// | SW24 | SW23 | SW22 | SW21 | SW20 | SW19 | SW25 | | SW25 | SW19 | SW20 | SW21 | SW22 | SW23 | SW24 | |
||||||
|
// | SW30 | SW29 | SW28 | SW27 | SW26 | | SW26 | SW27 | SW28 | SW29 | SW30 | |
||||||
|
map = < |
||||||
|
RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11) |
||||||
|
RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11) |
||||||
|
RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11) |
||||||
|
RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) |
||||||
|
RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,7) RC(4,8) RC(4,9) RC(4,10) RC(4,11) |
||||||
|
>; |
||||||
|
}; |
||||||
|
|
||||||
|
kscan0: kscan { |
||||||
|
compatible = "zmk,kscan-gpio-matrix"; |
||||||
|
label = "KSCAN"; |
||||||
|
|
||||||
|
diode-direction = "col2row"; |
||||||
|
row-gpios |
||||||
|
= <&pro_micro_d 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
, <&pro_micro_d 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> |
||||||
|
; |
||||||
|
}; |
||||||
|
|
||||||
|
left_encoder: encoder_left { |
||||||
|
compatible = "alps,ec11"; |
||||||
|
label = "LEFT_ENCODER"; |
||||||
|
a-gpios = <&pro_micro_a 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; |
||||||
|
b-gpios = <&pro_micro_a 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; |
||||||
|
resolution = <4>; |
||||||
|
}; |
||||||
|
|
||||||
|
right_encoder: encoder_right { |
||||||
|
compatible = "alps,ec11"; |
||||||
|
label = "RIGHT_ENCODER"; |
||||||
|
a-gpios = <&pro_micro_a 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; |
||||||
|
b-gpios = <&pro_micro_a 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; |
||||||
|
resolution = <4>; |
||||||
|
}; |
||||||
|
|
||||||
|
sensors { |
||||||
|
compatible = "zmk,keymap-sensors"; |
||||||
|
sensors = <&left_encoder &right_encoder>; |
||||||
|
}; |
||||||
|
|
||||||
|
bt_unpair_combo: bt_unpair_combo { |
||||||
|
compatible = "zmk,bt-unpair-combo"; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
&pro_micro_i2c { |
||||||
|
status = "okay"; |
||||||
|
|
||||||
|
ssd1306@3c { |
||||||
|
compatible = "solomon,ssd1306fb"; |
||||||
|
reg = <0x3c>; |
||||||
|
label = "DISPLAY"; |
||||||
|
width = <128>; |
||||||
|
height = <32>; |
||||||
|
segment-offset = <0>; |
||||||
|
page-offset = <0>; |
||||||
|
display-offset = <0>; |
||||||
|
multiplex-ratio = <31>; |
||||||
|
segment-remap; |
||||||
|
com-invdir; |
||||||
|
com-sequential; |
||||||
|
prechargep = <0x22>; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,63 @@ |
|||||||
|
#include <behaviors.dtsi> |
||||||
|
#include <dt-bindings/zmk/keys.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
keymap { |
||||||
|
compatible = "zmk,keymap"; |
||||||
|
|
||||||
|
default_layer { |
||||||
|
// ------------------------------------------------------------------------------------------------------------ |
||||||
|
// | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | | |
||||||
|
// | ESC | Q | W | E | R | T | | Y | U | I | O | P | BKSPC | |
||||||
|
// | TAB | A | S | D | F | G | | H | J | K | L | ; | ' | |
||||||
|
// | SHIFT | Z | X | C | V | B | MUTE | | | N | M | , | . | / | SHIFT | |
||||||
|
// | GUI | ALT | CTRL | LOWER| ENTER | | SPACE | RAISE| CTRL | ALT | GUI | |
||||||
|
bindings = < |
||||||
|
&kp GRAV &kp NUM_1 &kp NUM_2 &kp NUM_3 &kp NUM_4 &kp NUM_5 &kp NUM_6 &kp NUM_7 &kp NUM_8 &kp NUM_9 &kp NUM_0 &none |
||||||
|
&kp ESC &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BKSP |
||||||
|
&kp TAB &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SCLN &kp QUOT |
||||||
|
&kp LSFT &kp Z &kp X &kp C &kp V &kp B &cp M_MUTE &none &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RSFT |
||||||
|
&kp LGUI &kp LALT &kp LCTL &mo 1 &kp RET &kp SPC &mo 2 &kp RCTL &kp RALT &kp RGUI |
||||||
|
>; |
||||||
|
|
||||||
|
sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD &inc_dec_kp PGUP PGDN>; |
||||||
|
}; |
||||||
|
|
||||||
|
lower_layer { |
||||||
|
// TODO: Some binds are waiting for shifted keycode support. |
||||||
|
// ------------------------------------------------------------------------------------------------------------ |
||||||
|
// | | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10 | F11 | |
||||||
|
// | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | F12 | |
||||||
|
// | | ! | @ | # | $ | % | | ^ | & | * | ( | ) | | | |
||||||
|
// | | = | - | + | { | } | | | | [ | ] | ; | : | \ | | |
||||||
|
// | | | | | | | | | | | | |
||||||
|
bindings = < |
||||||
|
&trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 |
||||||
|
&kp GRAV &kp NUM_1 &kp NUM_2 &kp NUM_3 &kp NUM_4 &kp NUM_5 &kp NUM_6 &kp NUM_7 &kp NUM_8 &kp NUM_9 &kp NUM_0 &kp F12 |
||||||
|
&trans &kp BANG &kp ATSN &kp HASH &kp CURU &kp PRCT &kp CRRT &kp AMPS &kp KMLT &kp LPRN &kp RPRN &kp PIPE |
||||||
|
&trans &kp EQL &kp MINUS &kp KPLS &kp LCUR &kp RCUR &trans &trans &kp LBKT &kp RBKT &kp SCLN &kp COLN &kp BSLH &trans |
||||||
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans |
||||||
|
>; |
||||||
|
|
||||||
|
sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD &inc_dec_kp PGUP PGDN>; |
||||||
|
}; |
||||||
|
|
||||||
|
raise_layer { |
||||||
|
// ------------------------------------------------------------------------------------------------------------ |
||||||
|
// | | | | | | | | | | | | | | |
||||||
|
// | | INS | PSCR | GUI | | | | PGUP | | ^ | | | | |
||||||
|
// | | ALT | CTRL | SHIFT | | CAPS | | PGDN | <- | v | -> | DEL | BKSPC | |
||||||
|
// | | UNDO | CUT | COPY | PASTE | | | | | | | | | | | |
||||||
|
// | | | | | | | | | | | | |
||||||
|
bindings = < |
||||||
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans |
||||||
|
&trans &kp INS &kp PRSC &kp GUI &trans &trans &kp PGUP &trans &kp UARW &trans &kp NUM_0 &trans |
||||||
|
&trans &kp LALT &kp LCTL &kp LSFT &trans &kp CLCK &kp PGDN &kp LARW &kp DARW &kp RARW &kp DEL &kp BKSP |
||||||
|
&trans &kp UNDO &kp CUT &kp COPY &kp PSTE &trans &trans &trans &trans &trans &trans &trans &trans &trans |
||||||
|
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans |
||||||
|
>; |
||||||
|
|
||||||
|
sensor-bindings = <&inc_dec_cp M_VOLU M_VOLD &inc_dec_kp PGUP PGDN>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,5 @@ |
|||||||
|
# Copyright (c) 2020 Ryan Cross |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
CONFIG_ZMK_SPLIT=y |
||||||
|
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y |
@ -0,0 +1,26 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Ryan Cross |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "sofle.dtsi" |
||||||
|
|
||||||
|
&kscan0 { |
||||||
|
col-gpios |
||||||
|
= <&pro_micro_a 1 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 0 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 15 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 14 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 16 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 10 GPIO_ACTIVE_HIGH> |
||||||
|
; |
||||||
|
}; |
||||||
|
|
||||||
|
&left_encoder { |
||||||
|
status = "okay"; |
||||||
|
}; |
||||||
|
|
||||||
|
&bt_unpair_combo { |
||||||
|
key-positions = <0 54>; |
||||||
|
}; |
@ -0,0 +1,5 @@ |
|||||||
|
# Copyright (c) 2020 Ryan Cross |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
CONFIG_ZMK_SPLIT=y |
||||||
|
CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y |
@ -0,0 +1,30 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2020 Ryan Cross |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "sofle.dtsi" |
||||||
|
|
||||||
|
&default_transform { |
||||||
|
col-offset = <6>; |
||||||
|
}; |
||||||
|
|
||||||
|
&kscan0 { |
||||||
|
col-gpios |
||||||
|
= <&pro_micro_d 10 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 16 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 14 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_d 15 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 0 GPIO_ACTIVE_HIGH> |
||||||
|
, <&pro_micro_a 1 GPIO_ACTIVE_HIGH> |
||||||
|
; |
||||||
|
}; |
||||||
|
|
||||||
|
&right_encoder { |
||||||
|
status = "okay"; |
||||||
|
}; |
||||||
|
|
||||||
|
&bt_unpair_combo { |
||||||
|
key-positions = <11 55>; |
||||||
|
}; |
@ -0,0 +1,12 @@ |
|||||||
|
/ { |
||||||
|
behaviors { |
||||||
|
lt: behavior_layer_tap { |
||||||
|
compatible = "zmk,behavior-hold-tap"; |
||||||
|
label = "LAYER_TAP"; |
||||||
|
#binding-cells = <2>; |
||||||
|
flavor = "tap-preferred"; |
||||||
|
tapping_term_ms = <200>; |
||||||
|
bindings = <&mo>, <&kp>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
@ -1,9 +1,12 @@ |
|||||||
/ { |
/ { |
||||||
behaviors { |
behaviors { |
||||||
mt: behavior_mod_tap { |
mt: behavior_mod_tap { |
||||||
compatible = "zmk,behavior-mod-tap"; |
compatible = "zmk,behavior-hold-tap"; |
||||||
label = "MOD_TAP"; |
label = "MOD_TAP"; |
||||||
#binding-cells = <2>; |
#binding-cells = <2>; |
||||||
|
flavor = "hold-preferred"; |
||||||
|
tapping_term_ms = <200>; |
||||||
|
bindings = <&kp>, <&kp>; |
||||||
}; |
}; |
||||||
}; |
}; |
||||||
}; |
}; |
||||||
|
@ -0,0 +1,23 @@ |
|||||||
|
# Copyright (c) 2020, Cody McGinnis; Okke Formsma |
||||||
|
# SPDX-License-Identifier: MIT |
||||||
|
|
||||||
|
description: Hold or Tap behavior |
||||||
|
|
||||||
|
compatible: "zmk,behavior-hold-tap" |
||||||
|
|
||||||
|
include: two_param.yaml |
||||||
|
|
||||||
|
properties: |
||||||
|
bindings: |
||||||
|
type: phandles |
||||||
|
required: true |
||||||
|
tapping_term_ms: |
||||||
|
type: int |
||||||
|
flavor: |
||||||
|
type: string |
||||||
|
required: false |
||||||
|
default: "hold-preferred" |
||||||
|
enum: |
||||||
|
- "hold-preferred" |
||||||
|
- "balanced" |
||||||
|
- "tap-preferred" |
@ -1,8 +0,0 @@ |
|||||||
# Copyright (c) 2020, Pete Johanson |
|
||||||
# SPDX-License-Identifier: MIT |
|
||||||
|
|
||||||
description: Mod-Tap Beavhior |
|
||||||
|
|
||||||
compatible: "zmk,behavior-mod-tap" |
|
||||||
|
|
||||||
include: two_param.yaml |
|
@ -0,0 +1,502 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020 Cody McGinnis, Okke Formsma |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: MIT |
||||||
|
*/ |
||||||
|
|
||||||
|
#define DT_DRV_COMPAT zmk_behavior_hold_tap |
||||||
|
|
||||||
|
#include <device.h> |
||||||
|
#include <drivers/behavior.h> |
||||||
|
#include <logging/log.h> |
||||||
|
#include <zmk/behavior.h> |
||||||
|
|
||||||
|
#include <zmk/matrix.h> |
||||||
|
#include <zmk/endpoints.h> |
||||||
|
#include <zmk/event-manager.h> |
||||||
|
#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> |
||||||
|
|
||||||
|
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); |
||||||
|
|
||||||
|
#if DT_NODE_EXISTS(DT_DRV_INST(0)) |
||||||
|
|
||||||
|
#define ZMK_BHV_HOLD_TAP_MAX_HELD 10 |
||||||
|
#define ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS 40 |
||||||
|
|
||||||
|
// increase if you have keyboard with more keys.
|
||||||
|
#define ZMK_BHV_HOLD_TAP_POSITION_NOT_USED 9999 |
||||||
|
|
||||||
|
|
||||||
|
enum flavor { |
||||||
|
ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED = 0, |
||||||
|
ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED = 1, |
||||||
|
ZMK_BHV_HOLD_TAP_FLAVOR_TAP_PREFERRED = 2, |
||||||
|
}; |
||||||
|
|
||||||
|
struct behavior_hold_tap_behaviors { |
||||||
|
struct zmk_behavior_binding tap; |
||||||
|
struct zmk_behavior_binding hold; |
||||||
|
}; |
||||||
|
|
||||||
|
typedef k_timeout_t (*timer_func)(); |
||||||
|
|
||||||
|
struct behavior_hold_tap_config { |
||||||
|
timer_func tapping_term_ms; |
||||||
|
struct behavior_hold_tap_behaviors *behaviors; |
||||||
|
enum flavor flavor; |
||||||
|
}; |
||||||
|
|
||||||
|
// this data is specific for each hold-tap
|
||||||
|
struct active_hold_tap { |
||||||
|
s32_t position; |
||||||
|
u32_t param_hold; |
||||||
|
u32_t param_tap; |
||||||
|
bool is_decided; |
||||||
|
bool is_hold; |
||||||
|
const struct behavior_hold_tap_config *config; |
||||||
|
struct k_delayed_work work; |
||||||
|
bool work_is_cancelled; |
||||||
|
}; |
||||||
|
|
||||||
|
// The undecided hold tap is the hold tap that needs to be decided before
|
||||||
|
// other keypress events can be released. While the undecided_hold_tap is
|
||||||
|
// not NULL, most events are captured in captured_events.
|
||||||
|
// After the hold_tap is decided, it will stay in the active_hold_taps until
|
||||||
|
// its key-up has been processed and the delayed work is cleaned up.
|
||||||
|
struct active_hold_tap *undecided_hold_tap = NULL; |
||||||
|
struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {}; |
||||||
|
// We capture most position_state_changed events and some modifiers_state_changed events.
|
||||||
|
const struct zmk_event_header *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {}; |
||||||
|
|
||||||
|
static int capture_event(const struct zmk_event_header *event) |
||||||
|
{ |
||||||
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) { |
||||||
|
if (captured_events[i] == NULL) { |
||||||
|
captured_events[i] = event; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
return -ENOMEM; |
||||||
|
} |
||||||
|
|
||||||
|
static struct position_state_changed *find_captured_keydown_event(u32_t position) |
||||||
|
{ |
||||||
|
struct position_state_changed *last_match = NULL; |
||||||
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) { |
||||||
|
const struct zmk_event_header *eh = captured_events[i]; |
||||||
|
if (eh == NULL) { |
||||||
|
return last_match; |
||||||
|
} |
||||||
|
if (!is_position_state_changed(eh)) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
struct position_state_changed *position_event = cast_position_state_changed(eh); |
||||||
|
if (position_event->position == position && position_event->state) { |
||||||
|
last_match = position_event; |
||||||
|
} |
||||||
|
} |
||||||
|
return last_match; |
||||||
|
} |
||||||
|
|
||||||
|
const struct zmk_listener zmk_listener_behavior_hold_tap; |
||||||
|
|
||||||
|
static void release_captured_events() |
||||||
|
{ |
||||||
|
if (undecided_hold_tap != NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// We use a trick to prevent copying the captured_events array.
|
||||||
|
//
|
||||||
|
// Events for different mod-tap instances are separated by a NULL pointer.
|
||||||
|
//
|
||||||
|
// The first event popped will never be catched by the next active hold-tap
|
||||||
|
// because to start capturing a mod-tap-key-down event must first completely
|
||||||
|
// go through the events queue.
|
||||||
|
//
|
||||||
|
// Example of this release process;
|
||||||
|
// [mt2_down, k1_down, k1_up, mt2_up, null, ...]
|
||||||
|
// ^
|
||||||
|
// mt2_down position event isn't captured because no hold-tap is active.
|
||||||
|
// mt2_down behavior event is handled, now we have an undecided hold-tap
|
||||||
|
// [null, k1_down, k1_up, mt2_up, null, ...]
|
||||||
|
// ^
|
||||||
|
// k1_down is captured by the mt2 mod-tap
|
||||||
|
// !note that searches for find_captured_keydown_event by the mt2 behavior will stop at the first null encountered
|
||||||
|
// [mt1_down, null, k1_up, mt2_up, null, ...]
|
||||||
|
// ^
|
||||||
|
// k1_up event is captured by the new hold-tap:
|
||||||
|
// [k1_down, k1_up, null, mt2_up, null, ...]
|
||||||
|
// ^
|
||||||
|
// mt2_up event is not captured but causes release of mt2 behavior
|
||||||
|
// [k1_down, k1_up, null, null, null, ...]
|
||||||
|
// now mt2 will start releasing it's own captured positions.
|
||||||
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) { |
||||||
|
const struct zmk_event_header *captured_event = captured_events[i]; |
||||||
|
if (captured_event == NULL) { |
||||||
|
return; |
||||||
|
} |
||||||
|
captured_events[i] = NULL; |
||||||
|
if (undecided_hold_tap != NULL) { |
||||||
|
k_msleep(10); |
||||||
|
} |
||||||
|
if (is_position_state_changed(captured_event)) { |
||||||
|
struct position_state_changed *position_event = cast_position_state_changed(captured_event); |
||||||
|
LOG_DBG("Releasing key position event for position %d %s", position_event->position, (position_event->state ? "pressed" : "released")); |
||||||
|
} else { |
||||||
|
struct keycode_state_changed *modifier_event = cast_keycode_state_changed(captured_event); |
||||||
|
LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode, (modifier_event->state ? "pressed" : "released")); |
||||||
|
} |
||||||
|
ZMK_EVENT_RAISE_AT(captured_event, behavior_hold_tap); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static struct active_hold_tap *find_hold_tap(u32_t position) |
||||||
|
{ |
||||||
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) { |
||||||
|
if (active_hold_taps[i].position == position) { |
||||||
|
return &active_hold_taps[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static struct active_hold_tap *store_hold_tap(u32_t position, u32_t param_hold, u32_t param_tap, const struct behavior_hold_tap_config *config) |
||||||
|
{ |
||||||
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) { |
||||||
|
if (active_hold_taps[i].position != ZMK_BHV_HOLD_TAP_POSITION_NOT_USED) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
active_hold_taps[i].position = position; |
||||||
|
active_hold_taps[i].is_decided = false; |
||||||
|
active_hold_taps[i].is_hold = false; |
||||||
|
active_hold_taps[i].config = config; |
||||||
|
active_hold_taps[i].param_hold = param_hold; |
||||||
|
active_hold_taps[i].param_tap = param_tap; |
||||||
|
return &active_hold_taps[i]; |
||||||
|
} |
||||||
|
return NULL; |
||||||
|
} |
||||||
|
|
||||||
|
static void clear_hold_tap(struct active_hold_tap *hold_tap) |
||||||
|
{ |
||||||
|
hold_tap->position = ZMK_BHV_HOLD_TAP_POSITION_NOT_USED; |
||||||
|
hold_tap->is_decided = false; |
||||||
|
hold_tap->is_hold = false; |
||||||
|
hold_tap->work_is_cancelled = false; |
||||||
|
} |
||||||
|
|
||||||
|
enum decision_moment { |
||||||
|
HT_KEY_UP = 0, |
||||||
|
HT_OTHER_KEY_DOWN = 1, |
||||||
|
HT_OTHER_KEY_UP = 2, |
||||||
|
HT_TIMER_EVENT = 3, |
||||||
|
}; |
||||||
|
|
||||||
|
static void decide_balanced(struct active_hold_tap *hold_tap, enum decision_moment event) |
||||||
|
{ |
||||||
|
switch (event) { |
||||||
|
case HT_KEY_UP: |
||||||
|
hold_tap->is_hold = 0; |
||||||
|
hold_tap->is_decided = true; |
||||||
|
break; |
||||||
|
case HT_OTHER_KEY_UP: |
||||||
|
case HT_TIMER_EVENT: |
||||||
|
hold_tap->is_hold = 1; |
||||||
|
hold_tap->is_decided = true; |
||||||
|
break; |
||||||
|
default: return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) |
||||||
|
{ |
||||||
|
switch (event) { |
||||||
|
case HT_KEY_UP: |
||||||
|
hold_tap->is_hold = 0; |
||||||
|
hold_tap->is_decided = true; |
||||||
|
break; |
||||||
|
case HT_TIMER_EVENT: |
||||||
|
hold_tap->is_hold = 1; |
||||||
|
hold_tap->is_decided = true; |
||||||
|
break; |
||||||
|
default: return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) |
||||||
|
{ |
||||||
|
switch (event) { |
||||||
|
case HT_KEY_UP: |
||||||
|
hold_tap->is_hold = 0; |
||||||
|
hold_tap->is_decided = true; |
||||||
|
break; |
||||||
|
case HT_OTHER_KEY_DOWN: |
||||||
|
case HT_TIMER_EVENT: |
||||||
|
hold_tap->is_hold = 1; |
||||||
|
hold_tap->is_decided = true; |
||||||
|
break; |
||||||
|
default: return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static inline char* flavor_str(enum flavor flavor) { |
||||||
|
switch(flavor) { |
||||||
|
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED: |
||||||
|
return "hold-preferred"; |
||||||
|
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED: |
||||||
|
return "balanced"; |
||||||
|
case ZMK_BHV_HOLD_TAP_FLAVOR_TAP_PREFERRED: |
||||||
|
return "tap-preferred"; |
||||||
|
} |
||||||
|
return "UNKNOWN FLAVOR"; |
||||||
|
} |
||||||
|
|
||||||
|
static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment event) |
||||||
|
{ |
||||||
|
if (hold_tap->is_decided) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (hold_tap != undecided_hold_tap) { |
||||||
|
LOG_DBG("ERROR found undecided tap hold that is not the active tap hold"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
switch(hold_tap->config->flavor) { |
||||||
|
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED: |
||||||
|
decide_hold_preferred(hold_tap, event); |
||||||
|
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED: |
||||||
|
decide_balanced(hold_tap, event); |
||||||
|
case ZMK_BHV_HOLD_TAP_FLAVOR_TAP_PREFERRED: |
||||||
|
decide_tap_preferred(hold_tap, event); |
||||||
|
} |
||||||
|
|
||||||
|
if (!hold_tap->is_decided) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
LOG_DBG("%d decided %s (%s event %d)",
|
||||||
|
hold_tap->position,
|
||||||
|
hold_tap->is_hold ? "hold" : "tap",
|
||||||
|
flavor_str(hold_tap->config->flavor), |
||||||
|
event); |
||||||
|
undecided_hold_tap = NULL; |
||||||
|
|
||||||
|
struct zmk_behavior_binding *behavior; |
||||||
|
if (hold_tap->is_hold) { |
||||||
|
behavior = &hold_tap->config->behaviors->hold; |
||||||
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev); |
||||||
|
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_hold, 0); |
||||||
|
} else { |
||||||
|
behavior = &hold_tap->config->behaviors->tap; |
||||||
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev); |
||||||
|
behavior_keymap_binding_pressed(behavior_device, hold_tap->position, hold_tap->param_tap, 0); |
||||||
|
} |
||||||
|
release_captured_events(); |
||||||
|
} |
||||||
|
|
||||||
|
static int on_hold_tap_binding_pressed(struct device *dev, u32_t position, u32_t param_hold, u32_t param_tap) |
||||||
|
{ |
||||||
|
const struct behavior_hold_tap_config *cfg = dev->config_info; |
||||||
|
|
||||||
|
if (undecided_hold_tap != NULL) { |
||||||
|
LOG_DBG("ERROR another hold-tap behavior is undecided."); |
||||||
|
// if this happens, make sure the behavior events occur AFTER other position events.
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
struct active_hold_tap *hold_tap = store_hold_tap(position, param_hold, param_tap, cfg); |
||||||
|
if (hold_tap == NULL) { |
||||||
|
LOG_ERR("unable to store hold-tap info, did you press more than %d hold-taps?", ZMK_BHV_HOLD_TAP_MAX_HELD); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
LOG_DBG("%d new undecided hold_tap", position); |
||||||
|
undecided_hold_tap = hold_tap; |
||||||
|
k_delayed_work_submit(&hold_tap->work, cfg->tapping_term_ms()); |
||||||
|
|
||||||
|
// todo: once we get timing info for keypresses, start the timer relative to the original keypress
|
||||||
|
// don't forget to simulate a timer-event before the event after that time was handled.
|
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static int on_hold_tap_binding_released(struct device *dev, u32_t position, u32_t _, u32_t __) |
||||||
|
{ |
||||||
|
struct active_hold_tap *hold_tap = find_hold_tap(position); |
||||||
|
|
||||||
|
if (hold_tap == NULL) { |
||||||
|
LOG_ERR("ACTIVE_HOLD_TAP_CLEANED_UP_TOO_EARLY"); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int work_cancel_result = k_delayed_work_cancel(&hold_tap->work); |
||||||
|
decide_hold_tap(hold_tap, HT_KEY_UP); |
||||||
|
|
||||||
|
struct zmk_behavior_binding *behavior; |
||||||
|
if (hold_tap->is_hold) { |
||||||
|
behavior = &hold_tap->config->behaviors->hold; |
||||||
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev); |
||||||
|
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_hold, 0); |
||||||
|
} else { |
||||||
|
behavior = &hold_tap->config->behaviors->tap; |
||||||
|
struct device *behavior_device = device_get_binding(behavior->behavior_dev); |
||||||
|
behavior_keymap_binding_released(behavior_device, hold_tap->position, hold_tap->param_tap, 0); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
if (work_cancel_result == -EINPROGRESS) { |
||||||
|
// let the timer handler clean up
|
||||||
|
// if we'd clear now, the timer may call back for an uninitialized active_hold_tap.
|
||||||
|
LOG_DBG("%d hold-tap timer work in event queue", position); |
||||||
|
hold_tap->work_is_cancelled = true; |
||||||
|
} else { |
||||||
|
LOG_DBG("%d cleaning up hold-tap", position); |
||||||
|
clear_hold_tap(hold_tap); |
||||||
|
} |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static const struct behavior_driver_api behavior_hold_tap_driver_api = { |
||||||
|
.binding_pressed = on_hold_tap_binding_pressed, |
||||||
|
.binding_released = on_hold_tap_binding_released, |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
static int position_state_changed_listener(const struct zmk_event_header *eh) |
||||||
|
{ |
||||||
|
struct position_state_changed *ev = cast_position_state_changed(eh); |
||||||
|
|
||||||
|
if (undecided_hold_tap == NULL) { |
||||||
|
LOG_DBG("%d bubble (no undecided hold_tap active)", ev->position); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (undecided_hold_tap->position == ev->position) { |
||||||
|
if (ev->state) { // keydown
|
||||||
|
LOG_ERR("hold-tap listener should be called before before most other listeners!"); |
||||||
|
return 0; |
||||||
|
} else { // keyup
|
||||||
|
LOG_DBG("%d bubble undecided hold-tap keyrelease event", undecided_hold_tap->position); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!ev->state && find_captured_keydown_event(ev->position) == NULL) { |
||||||
|
// no keydown event has been captured, let it bubble.
|
||||||
|
// we'll catch modifiers later in modifier_state_changed_listener
|
||||||
|
LOG_DBG("%d bubbling %d %s event", undecided_hold_tap->position, ev->position, ev->state ? "down" : "up"); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
LOG_DBG("%d capturing %d %s event", undecided_hold_tap->position, ev->position, ev->state ? "down" : "up"); |
||||||
|
capture_event(eh); |
||||||
|
decide_hold_tap(undecided_hold_tap, ev->state ? HT_OTHER_KEY_DOWN : HT_OTHER_KEY_UP); |
||||||
|
return ZMK_EV_EVENT_CAPTURED; |
||||||
|
} |
||||||
|
|
||||||
|
static bool is_mod(struct keycode_state_changed *ev) |
||||||
|
{ |
||||||
|
return ev->usage_page == USAGE_KEYPAD && ev->keycode >= LCTL && ev->keycode <= RGUI; |
||||||
|
} |
||||||
|
|
||||||
|
static int keycode_state_changed_listener(const struct zmk_event_header *eh) |
||||||
|
{ |
||||||
|
// we want to catch layer-up events too... how?
|
||||||
|
struct keycode_state_changed *ev = cast_keycode_state_changed(eh); |
||||||
|
|
||||||
|
if (undecided_hold_tap == NULL) { |
||||||
|
// LOG_DBG("0x%02X bubble (no undecided hold_tap active)", ev->keycode);
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (!is_mod(ev)) { |
||||||
|
// LOG_DBG("0x%02X bubble (not a mod)", ev->keycode);
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
// only key-up events will bubble through position_state_changed_listener
|
||||||
|
// if a undecided_hold_tap is active.
|
||||||
|
LOG_DBG("%d capturing 0x%02X %s event", undecided_hold_tap->position, ev->keycode, ev->state ? "down" : "up"); |
||||||
|
capture_event(eh); |
||||||
|
return ZMK_EV_EVENT_CAPTURED; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
int behavior_hold_tap_listener(const struct zmk_event_header *eh) |
||||||
|
{ |
||||||
|
if (is_position_state_changed(eh)) { |
||||||
|
return position_state_changed_listener(eh); |
||||||
|
} else if (is_keycode_state_changed(eh)) { |
||||||
|
return keycode_state_changed_listener(eh); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
ZMK_LISTENER(behavior_hold_tap, behavior_hold_tap_listener); |
||||||
|
ZMK_SUBSCRIPTION(behavior_hold_tap, position_state_changed); |
||||||
|
// this should be modifiers_state_changed, but unfrotunately that's not implemented yet.
|
||||||
|
ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed); |
||||||
|
|
||||||
|
void behavior_hold_tap_timer_work_handler(struct k_work *item) |
||||||
|
{ |
||||||
|
struct active_hold_tap *hold_tap = CONTAINER_OF(item, struct active_hold_tap, work); |
||||||
|
|
||||||
|
if (hold_tap->work_is_cancelled) { |
||||||
|
clear_hold_tap(hold_tap); |
||||||
|
} else { |
||||||
|
decide_hold_tap(hold_tap, HT_TIMER_EVENT); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static int behavior_hold_tap_init(struct device *dev) |
||||||
|
{ |
||||||
|
static bool init_first_run = true; |
||||||
|
|
||||||
|
if (init_first_run) { |
||||||
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) { |
||||||
|
k_delayed_work_init(&active_hold_taps[i].work, behavior_hold_tap_timer_work_handler); |
||||||
|
active_hold_taps[i].position = ZMK_BHV_HOLD_TAP_POSITION_NOT_USED; |
||||||
|
} |
||||||
|
} |
||||||
|
init_first_run = false; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
struct behavior_hold_tap_data {}; |
||||||
|
static struct behavior_hold_tap_data behavior_hold_tap_data; |
||||||
|
|
||||||
|
#define _TRANSFORM_ENTRY(idx, node) \ |
||||||
|
{ \
|
||||||
|
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \
|
||||||
|
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), (DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
|
||||||
|
.param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), (DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \
|
||||||
|
}, |
||||||
|
|
||||||
|
#define KP_INST(n) \ |
||||||
|
static k_timeout_t behavior_hold_tap_config_##n##_gettime() { return K_MSEC(DT_INST_PROP(n, tapping_term_ms)); } \
|
||||||
|
static struct behavior_hold_tap_behaviors behavior_hold_tap_behaviors_##n = { \
|
||||||
|
.hold = _TRANSFORM_ENTRY(0, n) \
|
||||||
|
.tap = _TRANSFORM_ENTRY(1, n) \
|
||||||
|
}; \
|
||||||
|
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
||||||
|
.behaviors = &behavior_hold_tap_behaviors_##n, \
|
||||||
|
.tapping_term_ms = &behavior_hold_tap_config_##n##_gettime, \
|
||||||
|
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
|
||||||
|
}; \
|
||||||
|
DEVICE_AND_API_INIT( \
|
||||||
|
behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \
|
||||||
|
&behavior_hold_tap_data, \
|
||||||
|
&behavior_hold_tap_config_##n, \
|
||||||
|
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||||
|
&behavior_hold_tap_driver_api); |
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(KP_INST) |
||||||
|
|
||||||
|
|
||||||
|
#endif |
@ -1,252 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (c) 2020 Peter Johanson <peter@peterjohanson.com> |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: MIT |
|
||||||
*/ |
|
||||||
|
|
||||||
#define DT_DRV_COMPAT zmk_behavior_mod_tap |
|
||||||
|
|
||||||
#include <device.h> |
|
||||||
#include <drivers/behavior.h> |
|
||||||
#include <logging/log.h> |
|
||||||
|
|
||||||
#include <zmk/matrix.h> |
|
||||||
#include <zmk/endpoints.h> |
|
||||||
#include <zmk/event-manager.h> |
|
||||||
#include <zmk/events/keycode-state-changed.h> |
|
||||||
#include <zmk/events/modifiers-state-changed.h> |
|
||||||
#include <zmk/hid.h> |
|
||||||
|
|
||||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); |
|
||||||
|
|
||||||
#define ZMK_BHV_MOD_TAP_MAX_HELD 4 |
|
||||||
#define ZMK_BHV_MOD_TAP_MAX_PENDING_KC 4 |
|
||||||
|
|
||||||
struct active_mod_tap_item { |
|
||||||
u32_t keycode; |
|
||||||
u8_t mods; |
|
||||||
bool pending; |
|
||||||
zmk_mod_flags active_mods; |
|
||||||
}; |
|
||||||
|
|
||||||
struct captured_keycode_state_change_item { |
|
||||||
struct keycode_state_changed* event; |
|
||||||
zmk_mod_flags active_mods; |
|
||||||
}; |
|
||||||
|
|
||||||
struct behavior_mod_tap_config { }; |
|
||||||
struct behavior_mod_tap_data { |
|
||||||
struct active_mod_tap_item active_mod_taps[ZMK_BHV_MOD_TAP_MAX_HELD]; |
|
||||||
struct captured_keycode_state_change_item captured_keycode_events[ZMK_BHV_MOD_TAP_MAX_PENDING_KC]; |
|
||||||
}; |
|
||||||
|
|
||||||
bool have_pending_mods(char *label) { |
|
||||||
struct device *dev = device_get_binding(label); |
|
||||||
struct behavior_mod_tap_data *data = dev->driver_data; |
|
||||||
|
|
||||||
for (int i = 0; i < ZMK_BHV_MOD_TAP_MAX_HELD; i++) { |
|
||||||
if (data->active_mod_taps[i].mods) { |
|
||||||
LOG_DBG("Found pending mods for %d and keycode 0x%02X", data->active_mod_taps[i].mods, data->active_mod_taps[i].keycode); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
struct captured_keycode_state_change_item* find_pending_keycode(struct behavior_mod_tap_data *data, u32_t keycode) |
|
||||||
{ |
|
||||||
for (int i = 0; i < ZMK_BHV_MOD_TAP_MAX_PENDING_KC; i++) { |
|
||||||
if (data->captured_keycode_events[i].event == NULL) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if (data->captured_keycode_events[i].event->keycode == keycode) { |
|
||||||
return &data->captured_keycode_events[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
zmk_mod_flags behavior_mod_tap_active_mods(struct behavior_mod_tap_data *data) |
|
||||||
{ |
|
||||||
zmk_mod_flags mods = 0; |
|
||||||
|
|
||||||
for (int i = 0; i < ZMK_BHV_MOD_TAP_MAX_HELD; i++) { |
|
||||||
mods |= data->active_mod_taps[i].mods; |
|
||||||
} |
|
||||||
|
|
||||||
return mods; |
|
||||||
} |
|
||||||
|
|
||||||
int behavior_mod_tap_capture_keycode_event(struct behavior_mod_tap_data *data, struct keycode_state_changed *ev) |
|
||||||
{ |
|
||||||
for (int i = 0; i < ZMK_BHV_MOD_TAP_MAX_PENDING_KC; i++) { |
|
||||||
if (data->captured_keycode_events[i].event != NULL) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
data->captured_keycode_events[i].event = ev; |
|
||||||
data->captured_keycode_events[i].active_mods = behavior_mod_tap_active_mods(data); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
return -ENOMEM; |
|
||||||
} |
|
||||||
|
|
||||||
void behavior_mod_tap_update_active_mods_state(struct behavior_mod_tap_data *data, zmk_mod_flags used_flags) |
|
||||||
{ |
|
||||||
for (int i = 0; i < ZMK_BHV_MOD_TAP_MAX_HELD; i++) { |
|
||||||
if ((data->active_mod_taps[i].mods & used_flags) == data->active_mod_taps[i].mods) { |
|
||||||
data->active_mod_taps[i].pending = false; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// How to pass context to subscription?!
|
|
||||||
int behavior_mod_tap_listener(const struct zmk_event_header *eh) |
|
||||||
{ |
|
||||||
if (is_keycode_state_changed(eh) && have_pending_mods(DT_INST_LABEL(0))) { |
|
||||||
struct device *dev = device_get_binding(DT_INST_LABEL(0)); |
|
||||||
struct keycode_state_changed *ev = cast_keycode_state_changed(eh); |
|
||||||
struct behavior_mod_tap_data *data = dev->driver_data; |
|
||||||
struct captured_keycode_state_change_item* pending_keycode; |
|
||||||
if (ev->state) { |
|
||||||
LOG_DBG("Have pending mods, capturing keycode 0x%02X event to ressend later", ev->keycode); |
|
||||||
behavior_mod_tap_capture_keycode_event(data, ev); |
|
||||||
return ZMK_EV_EVENT_CAPTURED; |
|
||||||
} else if ((pending_keycode = find_pending_keycode(data, ev->keycode)) != NULL) { |
|
||||||
LOG_DBG("Key released, going to activate mods 0x%02X then send pending key press for keycode 0x%02X", |
|
||||||
pending_keycode->active_mods, pending_keycode->event->keycode); |
|
||||||
|
|
||||||
zmk_hid_register_mods(pending_keycode->active_mods); |
|
||||||
behavior_mod_tap_update_active_mods_state(data, pending_keycode->active_mods); |
|
||||||
|
|
||||||
ZMK_EVENT_RELEASE(pending_keycode->event); |
|
||||||
k_msleep(10); |
|
||||||
|
|
||||||
pending_keycode->event = NULL; |
|
||||||
pending_keycode->active_mods = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
ZMK_LISTENER(behavior_mod_tap, behavior_mod_tap_listener); |
|
||||||
ZMK_SUBSCRIPTION(behavior_mod_tap, keycode_state_changed); |
|
||||||
|
|
||||||
static int behavior_mod_tap_init(struct device *dev) |
|
||||||
{ |
|
||||||
return 0; |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t mods, u32_t keycode) |
|
||||||
{ |
|
||||||
struct behavior_mod_tap_data *data = dev->driver_data; |
|
||||||
LOG_DBG("mods: %d, keycode: 0x%02X", mods, keycode); |
|
||||||
for (int i = 0; i < ZMK_BHV_MOD_TAP_MAX_HELD; i++) { |
|
||||||
if (data->active_mod_taps[i].mods != 0) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
zmk_mod_flags active_mods = behavior_mod_tap_active_mods(data); |
|
||||||
|
|
||||||
data->active_mod_taps[i].active_mods = active_mods; |
|
||||||
data->active_mod_taps[i].mods = mods; |
|
||||||
data->active_mod_taps[i].keycode = keycode; |
|
||||||
data->active_mod_taps[i].pending = true; |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
LOG_WRN("Failed to record mod-tap activation, at maximum concurrent mod-tap activations"); |
|
||||||
|
|
||||||
return -ENOMEM; |
|
||||||
} |
|
||||||
|
|
||||||
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t mods, u32_t keycode) |
|
||||||
{ |
|
||||||
struct behavior_mod_tap_data *data = dev->driver_data; |
|
||||||
LOG_DBG("mods: %d, keycode: %d", mods, keycode); |
|
||||||
|
|
||||||
for (int i = 0; i < ZMK_BHV_MOD_TAP_MAX_HELD; i++) { |
|
||||||
struct active_mod_tap_item *item = &data->active_mod_taps[i]; |
|
||||||
if (item->mods == mods && item->keycode == keycode) { |
|
||||||
if (item->pending) { |
|
||||||
LOG_DBG("Sending un-triggered mod-tap for keycode: 0x%02X", keycode); |
|
||||||
|
|
||||||
if (item->active_mods) { |
|
||||||
LOG_DBG("Registering recorded active mods captured when mod-tap initially activated: 0x%02X", item->active_mods); |
|
||||||
behavior_mod_tap_update_active_mods_state(data, item->active_mods); |
|
||||||
zmk_hid_register_mods(item->active_mods); |
|
||||||
} |
|
||||||
|
|
||||||
struct keycode_state_changed *key_press = create_keycode_state_changed(USAGE_KEYPAD, item->keycode, true); |
|
||||||
ZMK_EVENT_RAISE_AFTER(key_press, behavior_mod_tap); |
|
||||||
k_msleep(10); |
|
||||||
|
|
||||||
for (int j = 0; j < ZMK_BHV_MOD_TAP_MAX_PENDING_KC; j++) { |
|
||||||
if (data->captured_keycode_events[j].event == NULL) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
struct keycode_state_changed *ev = data->captured_keycode_events[j].event; |
|
||||||
data->captured_keycode_events[j].event = NULL; |
|
||||||
data->captured_keycode_events[j].active_mods = 0; |
|
||||||
LOG_DBG("Re-sending latched key press for usage page 0x%02X keycode 0x%02X state %s", ev->usage_page, ev->keycode, (ev->state ? "pressed" : "released")); |
|
||||||
ZMK_EVENT_RELEASE(ev); |
|
||||||
k_msleep(10); |
|
||||||
} |
|
||||||
|
|
||||||
struct keycode_state_changed *key_release = create_keycode_state_changed(USAGE_KEYPAD, keycode, false); |
|
||||||
LOG_DBG("Sending un-triggered mod-tap release for keycode: 0x%02X", keycode); |
|
||||||
ZMK_EVENT_RAISE_AFTER(key_release, behavior_mod_tap); |
|
||||||
k_msleep(10); |
|
||||||
|
|
||||||
if (item->active_mods) { |
|
||||||
LOG_DBG("Unregistering recorded active mods captured when mod-tap initially activated: 0x%02X", item->active_mods); |
|
||||||
zmk_hid_unregister_mods(item->active_mods); |
|
||||||
zmk_endpoints_send_report(USAGE_KEYPAD); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} else { |
|
||||||
LOG_DBG("Releasing triggered mods: %d", mods); |
|
||||||
zmk_hid_unregister_mods(mods); |
|
||||||
zmk_endpoints_send_report(USAGE_KEYPAD); |
|
||||||
} |
|
||||||
|
|
||||||
item->mods = 0; |
|
||||||
item->keycode = 0; |
|
||||||
item->active_mods = 0; |
|
||||||
|
|
||||||
LOG_DBG("Removing mods %d from active_mods for other held mod-taps", mods); |
|
||||||
for (int j = 0; j < ZMK_BHV_MOD_TAP_MAX_HELD; j++) { |
|
||||||
if (data->active_mod_taps[j].active_mods & mods) { |
|
||||||
LOG_DBG("Removing 0x%02X from active mod tap mods 0x%02X keycode 0x%02X", mods, data->active_mod_taps[j].mods, data->active_mod_taps[j].keycode); |
|
||||||
data->active_mod_taps[j].active_mods &= ~mods; |
|
||||||
} |
|
||||||
} |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
static const struct behavior_driver_api behavior_mod_tap_driver_api = { |
|
||||||
.binding_pressed = on_keymap_binding_pressed, |
|
||||||
.binding_released = on_keymap_binding_released, |
|
||||||
}; |
|
||||||
|
|
||||||
static const struct behavior_mod_tap_config behavior_mod_tap_config = {}; |
|
||||||
|
|
||||||
static struct behavior_mod_tap_data behavior_mod_tap_data; |
|
||||||
|
|
||||||
DEVICE_AND_API_INIT(behavior_mod_tap, DT_INST_LABEL(0), behavior_mod_tap_init, |
|
||||||
&behavior_mod_tap_data, |
|
||||||
&behavior_mod_tap_config, |
|
||||||
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, |
|
||||||
&behavior_mod_tap_driver_api); |
|
@ -0,0 +1 @@ |
|||||||
|
Refer to the pdf/open document "zmk-modtap-proposal.{pdf,odt}" in this directory for a visual representation of the numbered tests for hold-tap. |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,11 @@ |
|||||||
|
#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,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,11 @@ |
|||||||
|
#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,0,500) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0xe4 |
||||||
|
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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,13 @@ |
|||||||
|
#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(1,1,10) /*ctrl*/ |
||||||
|
ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,1,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0xe4 |
||||||
|
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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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(1,1,10) /*ctrl*/ |
||||||
|
ZMK_MOCK_PRESS(0,0,50) /*mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,1,300) |
||||||
|
/*timer*/ |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0x07 |
||||||
|
ht_binding_pressed: 0 new undecided hold_tap |
||||||
|
kp_released: usage_page 0x07 keycode 0x07 |
||||||
|
ht_decide: 0 decided tap (balanced event 0) |
||||||
|
kp_pressed: usage_page 0x07 keycode 0x09 |
||||||
|
kp_released: usage_page 0x07 keycode 0x09 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,13 @@ |
|||||||
|
#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(1,0,10) /*d*/ |
||||||
|
ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0x07 |
||||||
|
ht_binding_pressed: 0 new undecided hold_tap |
||||||
|
kp_released: usage_page 0x07 keycode 0x07 |
||||||
|
ht_decide: 0 decided hold (balanced event 3) |
||||||
|
kp_pressed: usage_page 0x07 keycode 0xe1 |
||||||
|
kp_released: usage_page 0x07 keycode 0xe1 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,13 @@ |
|||||||
|
#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(1,0,10) /* d */ |
||||||
|
ZMK_MOCK_PRESS(0,0,100) /* mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,400) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
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 |
||||||
|
ht_binding_released: 1 cleaning up hold-tap |
||||||
|
kp_released: usage_page 0x07 keycode 0xe1 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,200) |
||||||
|
ZMK_MOCK_PRESS(0,1,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(0,1,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,200) |
||||||
|
ZMK_MOCK_PRESS(1,0,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,100) |
||||||
|
ZMK_MOCK_PRESS(1,0,100) |
||||||
|
ZMK_MOCK_RELEASE(1,0,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,10) |
||||||
|
ZMK_MOCK_PRESS(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
/* timer */ |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
||||||
|
kp_released: usage_page 0x07 keycode 0x07 |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,100) |
||||||
|
ZMK_MOCK_PRESS(1,0,100) |
||||||
|
ZMK_MOCK_RELEASE(0,0,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,27 @@ |
|||||||
|
#include <dt-bindings/zmk/keys.h> |
||||||
|
#include <behaviors.dtsi> |
||||||
|
#include <dt-bindings/zmk/kscan-mock.h> |
||||||
|
|
||||||
|
/ { |
||||||
|
behaviors { |
||||||
|
ht_bal: behavior_hold_tap_balanced { |
||||||
|
compatible = "zmk,behavior-hold-tap"; |
||||||
|
label = "HOLD_TAP_BALANCED"; |
||||||
|
#binding-cells = <2>; |
||||||
|
flavor = "balanced"; |
||||||
|
tapping_term_ms = <300>; |
||||||
|
bindings = <&kp>, <&kp>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
keymap { |
||||||
|
compatible = "zmk,keymap"; |
||||||
|
label ="Default keymap"; |
||||||
|
|
||||||
|
default_layer { |
||||||
|
bindings = < |
||||||
|
&ht_bal LSFT F &ht_bal LCTL J |
||||||
|
&kp D &kp RCTL>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,11 @@ |
|||||||
|
#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,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,11 @@ |
|||||||
|
#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,0,500) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0xe4 |
||||||
|
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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,13 @@ |
|||||||
|
#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(1,1,10) /*ctrl*/ |
||||||
|
ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,1,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0xe4 |
||||||
|
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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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(1,1,10) /*ctrl*/ |
||||||
|
ZMK_MOCK_PRESS(0,0,50) /*mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,1,300) |
||||||
|
/*timer*/ |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0x07 |
||||||
|
ht_binding_pressed: 0 new undecided hold_tap |
||||||
|
kp_released: usage_page 0x07 keycode 0x07 |
||||||
|
ht_decide: 0 decided tap (hold-preferred event 0) |
||||||
|
kp_pressed: usage_page 0x07 keycode 0x09 |
||||||
|
kp_released: usage_page 0x07 keycode 0x09 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,13 @@ |
|||||||
|
#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(1,0,10) /*d*/ |
||||||
|
ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +1,7 @@ |
|||||||
|
kp_pressed: usage_page 0x07 keycode 0x07 |
||||||
|
ht_binding_pressed: 0 new undecided hold_tap |
||||||
|
kp_released: usage_page 0x07 keycode 0x07 |
||||||
|
ht_decide: 0 decided hold (hold-preferred event 3) |
||||||
|
kp_pressed: usage_page 0x07 keycode 0xe1 |
||||||
|
kp_released: usage_page 0x07 keycode 0xe1 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,13 @@ |
|||||||
|
#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(1,0,10) /* d */ |
||||||
|
ZMK_MOCK_PRESS(0,0,100) /* mt f-shift */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,400) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
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 |
||||||
|
ht_binding_released: 1 cleaning up hold-tap |
||||||
|
kp_released: usage_page 0x07 keycode 0xe1 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,200) |
||||||
|
ZMK_MOCK_PRESS(0,1,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(0,1,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,200) |
||||||
|
ZMK_MOCK_PRESS(1,0,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,100) |
||||||
|
ZMK_MOCK_PRESS(1,0,100) |
||||||
|
ZMK_MOCK_RELEASE(1,0,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,10) |
||||||
|
ZMK_MOCK_PRESS(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
ZMK_MOCK_RELEASE(0,0,10) |
||||||
|
/* timer */ |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,4 @@ |
|||||||
|
s/.*hid_listener_keycode/kp/p |
||||||
|
s/.*mo_keymap_binding/mo/p |
||||||
|
s/.*on_hold_tap_binding/ht_binding/p |
||||||
|
s/.*decide_hold_tap/ht_decide/p |
@ -0,0 +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 |
||||||
|
ht_binding_released: 0 cleaning up hold-tap |
||||||
|
kp_released: usage_page 0x07 keycode 0x07 |
@ -0,0 +1,14 @@ |
|||||||
|
#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,0,100) |
||||||
|
ZMK_MOCK_PRESS(1,0,100) |
||||||
|
ZMK_MOCK_RELEASE(0,0,200) |
||||||
|
/* timer fires */ |
||||||
|
ZMK_MOCK_RELEASE(1,0,10) |
||||||
|
>; |
||||||
|
}; |
@ -0,0 +1,29 @@ |
|||||||
|
#include <dt-bindings/zmk/keys.h> |
||||||
|
#include <behaviors.dtsi> |
||||||
|
#include <dt-bindings/zmk/kscan-mock.h> |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/ { |
||||||
|
behaviors { |
||||||
|
ht_hold: behavior_hold_hold_tap { |
||||||
|
compatible = "zmk,behavior-hold-tap"; |
||||||
|
label = "hold_hold_tap"; |
||||||
|
#binding-cells = <2>; |
||||||
|
flavor = "hold-preferred"; |
||||||
|
tapping_term_ms = <300>; |
||||||
|
bindings = <&kp>, <&kp>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
keymap { |
||||||
|
compatible = "zmk,keymap"; |
||||||
|
label ="Default keymap"; |
||||||
|
|
||||||
|
default_layer { |
||||||
|
bindings = < |
||||||
|
&ht_hold LSFT F &ht_hold LCTL J |
||||||
|
&kp D &kp RCTL>; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue