diff --git a/firmware/zmk-config/boards/shields/goose/Kconfig.defconfig b/firmware/zmk-config/boards/shields/goose/Kconfig.defconfig new file mode 100644 index 0000000..21d8d4d --- /dev/null +++ b/firmware/zmk-config/boards/shields/goose/Kconfig.defconfig @@ -0,0 +1,16 @@ +if SHIELD_GOOSE_LEFT + +config ZMK_KEYBOARD_NAME + default "Cherry Goose" +config USB_DEVICE_MANUFACTURER + default "Pipshag" +config ZMK_SPLIT_ROLE_CENTRAL + default y + +endif + +if SHIELD_GOOSE_LEFT || SHIELD_GOOSE_RIGHT + +config ZMK_SPLIT + default y +endif diff --git a/firmware/zmk-config/boards/shields/goose/Kconfig.shield b/firmware/zmk-config/boards/shields/goose/Kconfig.shield new file mode 100644 index 0000000..727ed1d --- /dev/null +++ b/firmware/zmk-config/boards/shields/goose/Kconfig.shield @@ -0,0 +1,5 @@ +config SHIELD_GOOSE_LEFT + def_bool $(shields_list_contains,goose_left) + +config SHIELD_GOOSE_RIGHT + def_bool $(shields_list_contains,goose_right) diff --git a/firmware/zmk-config/boards/shields/goose/goose.dtsi b/firmware/zmk-config/boards/shields/goose/goose.dtsi new file mode 100644 index 0000000..3785e1c --- /dev/null +++ b/firmware/zmk-config/boards/shields/goose/goose.dtsi @@ -0,0 +1,47 @@ +#include + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <10>; + rows = <4>; + 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(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(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(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) + >; + }; + + left_encoder: left_encoder { + compatible = "alps,ec11"; + label = "LEFT_ENCODER"; + steps = <80>; + status = "disabled"; + + a-gpios = <&xiao_d 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + b-gpios = <&xiao_d 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + }; + + right_encoder: right_encoder { + compatible = "alps,ec11"; + label = "RIGHT_ENCODER"; + steps = <80>; + status = "disabled"; + + a-gpios = <&xiao_d 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + b-gpios = <&xiao_d 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + }; + + sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&left_encoder &right_encoder>; + triggers-per-rotation = <24>; + }; + +}; diff --git a/firmware/zmk-config/boards/shields/goose/goose.zmk.yml b/firmware/zmk-config/boards/shields/goose/goose.zmk.yml new file mode 100644 index 0000000..4e1b2bb --- /dev/null +++ b/firmware/zmk-config/boards/shields/goose/goose.zmk.yml @@ -0,0 +1,13 @@ +file_format: "1" +id: goose +name: Cherry Goose +type: shield +url: https://github.com/Pipshag/goosekb +requires: + - seeeduino_xiao_ble +features: + - keys + - encoder +siblings: + - goose_left + - goose_right diff --git a/firmware/zmk-config/boards/shields/goose/goose_left.overlay b/firmware/zmk-config/boards/shields/goose/goose_left.overlay new file mode 100644 index 0000000..50004ac --- /dev/null +++ b/firmware/zmk-config/boards/shields/goose/goose_left.overlay @@ -0,0 +1,33 @@ +#include "goose.dtsi" +/ { + chosen { + zmk,kscan = &kscan0; + }; + + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + + + col-gpios + = <&xiao_d 0 GPIO_ACTIVE_HIGH> + , <&xiao_d 1 GPIO_ACTIVE_HIGH> + , <&xiao_d 2 GPIO_ACTIVE_HIGH> + , <&xiao_d 3 GPIO_ACTIVE_HIGH> + , <&xiao_d 4 GPIO_ACTIVE_HIGH> + ; + + row-gpios + = <&xiao_d 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + , <&xiao_d 6 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + , <&xiao_d 10 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + , <&xiao_d 9 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + ; + }; + +}; + +&left_encoder { + status = "okay"; +}; diff --git a/firmware/zmk-config/boards/shields/goose/goose_right.overlay b/firmware/zmk-config/boards/shields/goose/goose_right.overlay new file mode 100644 index 0000000..2d5535b --- /dev/null +++ b/firmware/zmk-config/boards/shields/goose/goose_right.overlay @@ -0,0 +1,39 @@ +#include "goose.dtsi" + +/ { + chosen { + zmk,kscan = &kscan0; + }; + + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + + + col-gpios + = <&xiao_d 4 GPIO_ACTIVE_HIGH> + , <&xiao_d 3 GPIO_ACTIVE_HIGH> + , <&xiao_d 2 GPIO_ACTIVE_HIGH> + , <&xiao_d 1 GPIO_ACTIVE_HIGH> + , <&xiao_d 0 GPIO_ACTIVE_HIGH> + ; + + row-gpios + = <&xiao_d 5 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + , <&xiao_d 6 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + , <&xiao_d 10 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + , <&xiao_d 9 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)> + ; + }; + +}; + +&right_encoder { + status = "okay"; +}; + +&default_transform { + col-offset = <5>; +}; + diff --git a/firmware/zmk-config/goose.conf b/firmware/zmk-config/goose.conf new file mode 100644 index 0000000..1084f8d --- /dev/null +++ b/firmware/zmk-config/goose.conf @@ -0,0 +1,12 @@ +# Enable deep sleep and timeouts +CONFIG_ZMK_SLEEP=y +CONFIG_ZMK_IDLE_TIMEOUT=30000 +CONFIG_ZMK_IDLE_SLEEP_TIMEOUT=900000 + +# Enable encoder +CONFIG_EC11=y +CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y + +# Debounce ? +CONFIG_ZMK_KSCAN_DEBOUNCE_PRESS_MS=10 +CONFIG_ZMK_KSCAN_DEBOUNCE_RELEASE_MS=10 diff --git a/firmware/zmk-config/goose.json b/firmware/zmk-config/goose.json new file mode 100644 index 0000000..98d85d5 --- /dev/null +++ b/firmware/zmk-config/goose.json @@ -0,0 +1,70 @@ +{ + "id": "goose", + "name": "goose", + "layouts": { + "default_layout": { + "name": "default_layout", + "layout": [ + { "row": 0, "col": 0, "x": 0, "y": 0 }, + { "row": 0, "col": 1, "x": 1, "y": 0 }, + { "row": 0, "col": 2, "x": 2, "y": 0 }, + { "row": 0, "col": 3, "x": 3, "y": 0 }, + { "row": 0, "col": 4, "x": 4, "y": 0 }, + { "row": 0, "col": 5, "x": 5, "y": 0 }, + { "row": 0, "col": 6, "x": 6, "y": 0 }, + { "row": 0, "col": 7, "x": 7, "y": 0 }, + { "row": 0, "col": 8, "x": 8, "y": 0 }, + { "row": 0, "col": 9, "x": 9, "y": 0 }, + + { "row": 1, "col": 0, "x": 0, "y": 1 }, + { "row": 1, "col": 1, "x": 1, "y": 1 }, + { "row": 1, "col": 2, "x": 2, "y": 1 }, + { "row": 1, "col": 3, "x": 3, "y": 1 }, + { "row": 1, "col": 4, "x": 4, "y": 1 }, + { "row": 1, "col": 5, "x": 5, "y": 1 }, + { "row": 1, "col": 6, "x": 6, "y": 1 }, + { "row": 1, "col": 7, "x": 7, "y": 1 }, + { "row": 1, "col": 8, "x": 8, "y": 1 }, + { "row": 1, "col": 9, "x": 9, "y": 1 }, + + { "row": 2, "col": 0, "x": 0, "y": 2 }, + { "row": 2, "col": 1, "x": 1, "y": 2 }, + { "row": 2, "col": 2, "x": 2, "y": 2 }, + { "row": 2, "col": 3, "x": 3, "y": 2 }, + { "row": 2, "col": 4, "x": 4, "y": 2 }, + { "row": 2, "col": 5, "x": 5, "y": 2 }, + { "row": 2, "col": 6, "x": 6, "y": 2 }, + { "row": 2, "col": 7, "x": 7, "y": 2 }, + { "row": 2, "col": 8, "x": 8, "y": 2 }, + { "row": 2, "col": 9, "x": 9, "y": 2 }, + + { "row": 3, "col": 1, "x": 1, "y": 3 }, + { "row": 3, "col": 2, "x": 2, "y": 3 }, + { "row": 3, "col": 3, "x": 3, "y": 3 }, + { "row": 3, "col": 4, "x": 4, "y": 3 }, + { "row": 3, "col": 5, "x": 5, "y": 3 }, + { "row": 3, "col": 6, "x": 6, "y": 3 }, + { "row": 3, "col": 7, "x": 7, "y": 3 }, + { "row": 3, "col": 8, "x": 8, "y": 3 } + ] + } + }, + "sensors": [ + { + "ref": "left_encoder", + "name": "left_encoder", + "identifier": "left_encoder", + "compatible": "alps,ec11", + "label": "LEFT_ENCODER", + "enabled": false + }, + { + "ref": "right_encoder", + "name": "right_encoder", + "identifier": "right_encoder", + "compatible": "alps,ec11", + "label": "RIGHT_ENCODER", + "enabled": false + } + ] +} diff --git a/firmware/zmk-config/goose.keymap b/firmware/zmk-config/goose.keymap new file mode 100644 index 0000000..c830d42 --- /dev/null +++ b/firmware/zmk-config/goose.keymap @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#define QUICK_TAP_MS 125 +#define TAPPING_TERM_MS 150 +#define SLOW_TAPPING_TERM_MS 350 +#define IDLE_TIMEOUT_MS 5000 +#define REQ_IDLE_MS 150 + +< { + // Layer toggle + + flavor = "tap-preferred"; + tapping-term-ms = ; + quick-tap-ms = ; +}; + +&sk { + // Sticky keys settings, One Shot Keys [QMK] + + release-after-ms = ; + quick-release; +}; + +&caps_word { + // Allow caps word to continue even when minus or underscore are pressed. + // Also prevent mod presses from cancelling caps word. + + continue-list = < + UNDERSCORE MINUS + LCTRL LALT LGUI LSHFT + RCTRL RALT RGUI RSHFT + BACKSPACE + >; + + /delete-property/ ignore-modifiers; +}; + +/ { + behaviors { + hml: homerow_mods_left { + compatible = "zmk,behavior-hold-tap"; + label = "HOMEROW_MODS_LEFT_HAND"; + bindings = <&kp>, <&kp>; + + #binding-cells = <2>; + tapping-term-ms = ; + quick-tap-ms = ; + flavor = "balanced"; + require-prior-idle-ms = ; + hold-trigger-key-positions = <5 6 7 8 9 19 18 17 16 15 34 25 26 35 27 28 29 37 36>; + hold-trigger-on-release; + }; + hmr: homerow_mods_right { + compatible = "zmk,behavior-hold-tap"; + label = "HOMEROW_MODS_RIGHT_HAND"; + bindings = <&kp>, <&kp>; + + #binding-cells = <2>; + tapping-term-ms = ; + quick-tap-ms = ; + require-prior-idle-ms = ; + hold-trigger-key-positions = <0 1 2 3 4 14 13 12 11 10 11 12 13 14 20 21 22 23 24 30 31 32 33>; + flavor = "balanced"; + hold-trigger-on-release; + }; + ss_cw: shift_capsword { + compatible = "zmk,behavior-tap-dance"; + label = "SHIFT_CAPSWORD"; + #binding-cells = <0>; + bindings = <&sk LEFT_SHIFT>, <&caps_word>; + + tapping-term-ms = ; + }; + cln_scln_td: cln_scln_td { + compatible = "zmk,behavior-tap-dance"; + label = "CLN_SCLN_TD"; + #binding-cells = <0>; + bindings = <&kp COLON>, <&kp SEMICOLON>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + + base { + bindings = < +&kp Q &kp W &kp F &kp P &kp G &kp J &kp L &kp U &kp Y &kp APOSTROPHE +&hml LEFT_GUI A &hml LEFT_ALT R &hml LEFT_CONTROL S &hml LEFT_SHIFT T &kp D &kp H &hmr RIGHT_SHIFT N &hmr RIGHT_CONTROL E &hmr RIGHT_ALT I &hmr RIGHT_GUI O +&kp Z &kp X &kp C &kp V &kp B &kp K &kp M &kp COMMA &kp PERIOD &kp SLASH + &trans &kp ESCAPE < 3 SPACE &ss_cw &kp ENTER < 1 BACKSPACE < 2 DELETE &kp RIGHT_ALT + >; + + sensor-bindings = + <&inc_dec_kp C_VOL_UP C_VOLUME_DOWN>, + <&inc_dec_kp PAGE_UP PAGE_DOWN>; + }; + + num_fun { + bindings = < +&none &kp N7 &kp N8 &kp N9 &none &kp C_PREV &kp F7 &kp F8 &kp F9 &kp F12 +&none &kp N4 &kp N5 &kp N6 &none &kp C_PP &kp F4 &kp F5 &kp F6 &none +&none &kp N1 &kp N2 &kp N3 &kp DOT &kp C_NEXT &kp F1 &kp F2 &kp F3 &none + &kp PLUS &kp EQUAL &kp N0 &kp MINUS &trans &trans &trans &trans + >; + + sensor-bindings = <&inc_dec_kp K_REDO K_UNDO>; + }; + + sym_uti { + bindings = < +&kp PERCENT &kp CARET &kp DOLLAR &kp RA(N5) &cln_scln_td &none &kp LEFT_BRACE &kp RIGHT_BRACE &kp AT_SIGN &kp HASH +&kp FSLH &kp ASTERISK &kp MINUS &kp PLUS &kp PIPE &none &kp LEFT_PARENTHESIS &kp RIGHT_PARENTHESIS &kp LESS_THAN &kp GREATER_THAN +&kp BSLH &kp AMPERSAND &kp EXCLAMATION &kp EQUAL &kp UNDERSCORE &none &kp LBKT &kp RBKT &kp TILDE &kp GRAVE + &trans &trans &trans &trans &trans &trans &trans &trans + >; + + sensor-bindings = <&inc_dec_kp LC(RIGHT) LC(LEFT)>; + }; + + nav_sys { + bindings = < +&none &kp LS(TAB) &kp TAB &kp LC(LS(TAB)) &kp LC(TAB) &kp PG_UP &kp H &kp J &kp K &kp L +&kp LC(A) &none &none &none &none &kp PG_DN &kp LEFT &kp DOWN &kp UP &kp RIGHT +&kp LC(Z) &kp LC(X) &kp LC(C) &kp LC(V) &kp LS(LC(V)) &none &none &none &none &none + &bootloader &sys_reset &trans &tog 4 &trans &trans &sys_reset &bootloader + >; + }; + + flat { + bindings = < +&kp Q &kp W &kp F &kp P &kp G &kp J &kp L &kp U &kp Y &kp APOSTROPHE +&kp A &kp R &kp S &kp T &kp D &kp H &kp N &kp E &kp I &kp O +&kp Z &kp X &kp C &kp V &kp B &kp K &kp M &kp COMMA &kp DOT &kp FSLH + &kp TAB &kp ESC &kp SPACE &kp LSHFT &kp ENTER &kp BSPC &kp TAB &tog 4 + >; + }; + + sensor-bindings = <&inc_dec_kp C_VOLUME_UP C_VOLUME_DOWN>; + }; +}; diff --git a/firmware/zmk-config/west.yml b/firmware/zmk-config/west.yml new file mode 100644 index 0000000..379d291 --- /dev/null +++ b/firmware/zmk-config/west.yml @@ -0,0 +1,11 @@ +manifest: + remotes: + - name: zmkfirmware + url-base: https://github.com/zmkfirmware + projects: + - name: zmk + remote: zmkfirmware + revision: main + import: app/west.yml + self: + path: config