From 19ee7849f80e18d8f29ac47ffeee3bb223c35a80 Mon Sep 17 00:00:00 2001 From: jmding8 <44815547+jmding8@users.noreply.github.com> Date: Mon, 1 Nov 2021 09:37:20 -0700 Subject: [PATCH 01/46] feat(behaviors) Required keys for tap-hold behaviors * Add optional `hold-trigger-key-positions` hold-tap configuration * Leverage configuration for decision making around when to trigger hold decision in hold-taps. * Add docs for new configuration. * Tests for the new config/decision logic. --- .../behaviors/zmk,behavior-hold-tap.yaml | 4 ++ app/src/behaviors/behavior_hold_tap.c | 54 +++++++++++++++++++ .../2-dn-timer-up/events.patterns | 4 ++ .../2-dn-timer-up/keycode_events.snapshot | 5 ++ .../2-dn-timer-up/native_posix.keymap | 11 ++++ .../events.patterns | 4 ++ .../keycode_events.snapshot | 7 +++ .../native_posix.keymap | 14 +++++ .../4a-dn-tgdn-timer-tgup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 +++ .../native_posix.keymap | 14 +++++ .../7-positional/behavior_keymap.dtsi | 29 ++++++++++ .../events.patterns | 4 ++ .../keycode_events.snapshot | 9 ++++ .../native_posix.keymap | 16 ++++++ .../2-dn-timer-up/events.patterns | 4 ++ .../2-dn-timer-up/keycode_events.snapshot | 5 ++ .../2-dn-timer-up/native_posix.keymap | 11 ++++ .../events.patterns | 4 ++ .../keycode_events.snapshot | 7 +++ .../native_posix.keymap | 14 +++++ .../4a-dn-tgdn-timer-tgup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 +++ .../native_posix.keymap | 14 +++++ .../7-positional/behavior_keymap.dtsi | 29 ++++++++++ .../events.patterns | 4 ++ .../keycode_events.snapshot | 9 ++++ .../native_posix.keymap | 16 ++++++ .../2-dn-timer-up/events.patterns | 4 ++ .../2-dn-timer-up/keycode_events.snapshot | 5 ++ .../2-dn-timer-up/native_posix.keymap | 11 ++++ .../events.patterns | 4 ++ .../keycode_events.snapshot | 7 +++ .../native_posix.keymap | 14 +++++ .../4a-dn-tgdn-timer-tgup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 +++ .../native_posix.keymap | 14 +++++ .../7-positional/behavior_keymap.dtsi | 29 ++++++++++ .../events.patterns | 4 ++ .../keycode_events.snapshot | 9 ++++ .../native_posix.keymap | 16 ++++++ docs/docs/behaviors/hold-tap.md | 42 +++++++++++++++ docs/docs/development/tests.md | 8 +-- 43 files changed, 488 insertions(+), 4 deletions(-) create mode 100644 app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/events.patterns create mode 100644 app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/native_posix.keymap create mode 100644 app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns create mode 100644 app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns create mode 100644 app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/balanced/7-positional/behavior_keymap.dtsi create mode 100644 app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns create mode 100644 app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/events.patterns create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/native_posix.keymap create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/behavior_keymap.dtsi create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/events.patterns create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/behavior_keymap.dtsi create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml index f46b36a4..9d489e80 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml @@ -30,3 +30,7 @@ properties: - "tap-preferred" retro-tap: type: boolean + hold-trigger-key-positions: + type: array + required: false + default: [] diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 02ca5e3a..a5c4e90d 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -58,6 +58,8 @@ struct behavior_hold_tap_config { int quick_tap_ms; enum flavor flavor; bool retro_tap; + int32_t hold_trigger_key_positions_len; + int32_t hold_trigger_key_positions[]; }; // this data is specific for each hold-tap @@ -70,6 +72,9 @@ struct active_hold_tap { const struct behavior_hold_tap_config *config; struct k_delayed_work work; bool work_is_cancelled; + + // initialized to -1, which is to be interpreted as "no other key has been pressed yet" + int32_t position_of_first_other_key_pressed; }; // The undecided hold tap is the hold tap that needs to be decided before @@ -206,6 +211,7 @@ static struct active_hold_tap *store_hold_tap(uint32_t position, uint32_t param_ active_hold_taps[i].param_hold = param_hold; active_hold_taps[i].param_tap = param_tap; active_hold_taps[i].timestamp = timestamp; + active_hold_taps[i].position_of_first_other_key_pressed = -1; return &active_hold_taps[i]; } return NULL; @@ -359,6 +365,39 @@ static int release_binding(struct active_hold_tap *hold_tap) { return behavior_keymap_binding_released(&binding, event); } +static bool is_first_other_key_pressed_trigger_key(struct active_hold_tap *hold_tap) { + for (int i = 0; i < hold_tap->config->hold_trigger_key_positions_len; i++) { + if (hold_tap->config->hold_trigger_key_positions[i] == + hold_tap->position_of_first_other_key_pressed) { + return true; + } + } + return false; +} + +// Force a tap decision if the positional conditions for a hold decision are not met. +static void decide_positional_hold(struct active_hold_tap *hold_tap) { + // Only force a tap decision if the positional hold/tap feature is enabled. + if (!(hold_tap->config->hold_trigger_key_positions_len > 0)) { + return; + } + + // Only force a tap decision if another key was pressed after + // the hold/tap key. + if (hold_tap->position_of_first_other_key_pressed == -1) { + return; + } + + // Only force a tap decision if the first other key to be pressed + // (after the hold/tap key) is not one of the trigger keys. + if (is_first_other_key_pressed_trigger_key(hold_tap)) { + return; + } + + // Since the positional key conditions have failed, force a TAP decision. + hold_tap->status = STATUS_TAP; +} + static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment decision_moment) { if (hold_tap->status != STATUS_UNDECIDED) { @@ -370,6 +409,7 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, return; } + // If the hold-tap behavior is still undecided, attempt to decide it. switch (hold_tap->config->flavor) { case FLAVOR_HOLD_PREFERRED: decide_hold_preferred(hold_tap, decision_moment); @@ -383,6 +423,10 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, return; } + decide_positional_hold(hold_tap); + + // Since the hold-tap has been decided, clean up undecided_hold_tap and + // execute the decided behavior. LOG_DBG("%d decided %s (%s decision moment %s)", hold_tap->position, status_str(hold_tap->status), flavor_str(hold_tap->config->flavor), decision_moment_str(decision_moment)); @@ -501,6 +545,14 @@ static int position_state_changed_listener(const zmk_event_t *eh) { return ZMK_EV_EVENT_BUBBLE; } + // Store the position of pressed key for positional hold-tap purposes. + if ((ev->state) // i.e. key pressed (not released) + && (undecided_hold_tap->position_of_first_other_key_pressed == + -1) // i.e. no other key has been pressed yet + ) { + undecided_hold_tap->position_of_first_other_key_pressed = ev->position; + } + if (undecided_hold_tap->position == ev->position) { if (ev->state) { // keydown LOG_ERR("hold-tap listener should be called before before most other listeners!"); @@ -604,6 +656,8 @@ static struct behavior_hold_tap_data behavior_hold_tap_data; .quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \ .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ .retro_tap = DT_INST_PROP(n, retro_tap), \ + .hold_trigger_key_positions = DT_INST_PROP(n, hold_trigger_key_positions), \ + .hold_trigger_key_positions_len = DT_INST_PROP_LEN(n, hold_trigger_key_positions), \ }; \ DEVICE_DT_INST_DEFINE(n, behavior_hold_tap_init, device_pm_control_nop, \ &behavior_hold_tap_data, &behavior_hold_tap_config_##n, APPLICATION, \ diff --git a/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..926174b4 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot new file mode 100644 index 00000000..1b5cc8f2 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap new file mode 100644 index 00000000..d1d2b756 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,1,200) // non trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..242b31f2 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap new file mode 100644 index 00000000..94d9a923 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,0,200) // trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/behavior_keymap.dtsi b/app/tests/hold-tap/balanced/7-positional/behavior_keymap.dtsi new file mode 100644 index 00000000..5657644d --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + 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>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <2>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_bal LEFT_SHIFT F &ht_bal LEFT_CONTROL J + &kp D &kp E>; + }; + }; +}; diff --git a/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..1e1ea6b9 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot @@ -0,0 +1,9 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap new file mode 100644 index 00000000..6ddf87f8 --- /dev/null +++ b/app/tests/hold-tap/balanced/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap @@ -0,0 +1,16 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) // trigger key + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,1,400) // not trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..827ac986 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (hold-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot new file mode 100644 index 00000000..964cbafe --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (hold-preferred decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap new file mode 100644 index 00000000..d1d2b756 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,1,200) // non trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..1d2b827e --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (hold-preferred decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap new file mode 100644 index 00000000..94d9a923 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,0,200) // trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/behavior_keymap.dtsi b/app/tests/hold-tap/hold-preferred/7-positional/behavior_keymap.dtsi new file mode 100644 index 00000000..bf681004 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + 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>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <2>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_hold LEFT_SHIFT F &ht_hold LEFT_CONTROL J + &kp D &kp E>; + }; + }; +}; diff --git a/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..2838194d --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot @@ -0,0 +1,9 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (hold-preferred decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap new file mode 100644 index 00000000..6ddf87f8 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap @@ -0,0 +1,16 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) // trigger key + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,1,400) // not trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..4bf3e7ca --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot new file mode 100644 index 00000000..337af3e9 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap new file mode 100644 index 00000000..d1d2b756 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-ntgdn-timer-ntgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,1,200) // non trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..2d985568 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap new file mode 100644 index 00000000..94d9a923 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/4a-dn-tgdn-timer-tgup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,200) + ZMK_MOCK_PRESS(1,0,200) // trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/behavior_keymap.dtsi b/app/tests/hold-tap/tap-preferred/7-positional/behavior_keymap.dtsi new file mode 100644 index 00000000..e4be8d15 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + tp: behavior_tap_preferred { + compatible = "zmk,behavior-hold-tap"; + label = "MOD_TAP"; + #binding-cells = <2>; + flavor = "tap-preferred"; + tapping-term-ms = <300>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <2>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &tp LEFT_SHIFT F &tp LEFT_CONTROL J + &kp D &kp E>; + }; + }; +}; diff --git a/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot new file mode 100644 index 00000000..4ecb1b8e --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/keycode_events.snapshot @@ -0,0 +1,9 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap new file mode 100644 index 00000000..6ddf87f8 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/7-positional/tgdn-dn-ntgdn-timer-ntgup-tgup-up/native_posix.keymap @@ -0,0 +1,16 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) // trigger key + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,1,400) // not trigger key + /* timer fires */ + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 6817c602..360a9e3d 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -59,6 +59,48 @@ For example, if you press `&mt LEFT_SHIFT A` and then release it without pressin }; ``` +#### Positional hold-tap and `hold-trigger-key-positions` + +- Including `hold-trigger-key-postions` in your hold-tap definition turns on the positional hold-tap feature. +- With positional hold-tap enabled, if you press any key **NOT** listed in `hold-trigger-key-positions` before `tapping-term-ms` expires, it will produce a tap. +- In all other situations, positional hold-tap will not modify the behavior of your hold-tap. +- Positional hold-tap is useful with home-row modifiers. If you have a home-row modifier key in the left hand for example, by including only keys positions from the right hand in `hold-trigger-key-positions`, you will only get hold behaviors during cross-hand key combinations. +- Note that `hold-trigger-key-postions` is an array of key position indexes. Key positions are numbered according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera. +- See the following example, which uses a hold-tap behavior definition, configured with the `hold-preferrred` flavor, and with positional hold-tap enabled: + +``` +#include +#include +/ { + behaviors { + pht: positional_hold_tap { + compatible = "zmk,behavior-hold-tap"; + label = "POSITIONAL_HOLD_TAP"; + #binding-cells = <2>; + flavor = "hold-preferred"; + tapping-term-ms = <400>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <1>; // <---[[the W key]] + }; + }; + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + default_layer { + bindings = < + // position 0 position 1 position 2 + &pht LEFT_SHIFT Q &kp W &kp E + >; + }; + }; +}; +``` + +- The sequence `(pht_down, E_down, E_up, pht_up)` produces `qe`. The normal hold behavior (LEFT_SHIFT) **IS** modified into a tap behavior (Q) by positional hold-tap because the first key pressed after the hold-tap key is the `E key`, which is in position 2, which **is NOT** included in `hold-trigger-key-positions`. +- The sequence `(pht_down, W_down, W_up, pht_up)` produces `W`. The normal hold behavior (LEFT_SHIFT) **is NOT** modified into a tap behavior (Q) by positional hold-tap because the first key pressed after the hold-tap key is the `W key`, which is in position 1, which **IS** included in `hold-trigger-key-positions`. +- If the `LEFT_SHIFT / Q key` is held by itself for longer than `tapping-term-ms`, a hold behavior is produced. This is because positional hold-tap only modifies the behavior of a hold-tap if another key is pressed before the `tapping-term-ms` period expires. + #### Home row mods This example configures a hold-tap that works well for homerow mods: diff --git a/docs/docs/development/tests.md b/docs/docs/development/tests.md index 5ebf14f2..e84acf8d 100644 --- a/docs/docs/development/tests.md +++ b/docs/docs/development/tests.md @@ -3,10 +3,10 @@ title: Tests sidebar_label: Tests --- -Running tests requires [native posix support](posix-board.md). Any folder under `/app/tests` -containing `native_posix.keymap` will be selected when running `west test`. - -Run a single test with `west test `, like `west test tests/toggle-layer/normal`. +- Running tests requires [native posix support](posix-board.md). +- Any folder under `/app/tests` containing `native_posix.keymap` will be selected when running `west test`. +- Run tests from within the `/zmk/app` directory. +- Run a single test with `west test `, like `west test tests/toggle-layer/normal`. ## Creating a New Test Set From 73fd4b9230bec4333fc3ecc74e455af78016f0e2 Mon Sep 17 00:00:00 2001 From: jmding8 <44815547+jmding8@users.noreply.github.com> Date: Mon, 1 Nov 2021 10:51:12 -0700 Subject: [PATCH 02/46] fix(behavior): Properly break in decision switch statement. Co-authored-by: jding --- app/src/behaviors/behavior_hold_tap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index a5c4e90d..1871df70 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -413,10 +413,13 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, switch (hold_tap->config->flavor) { case FLAVOR_HOLD_PREFERRED: decide_hold_preferred(hold_tap, decision_moment); + break; case FLAVOR_BALANCED: decide_balanced(hold_tap, decision_moment); + break; case FLAVOR_TAP_PREFERRED: decide_tap_preferred(hold_tap, decision_moment); + break; } if (hold_tap->status == STATUS_UNDECIDED) { From 0b0b49d62666cfec2157900fd0dbf62460aa33f9 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Sun, 17 Oct 2021 02:27:10 +0000 Subject: [PATCH 03/46] fix(split): Properly rediscover peripherals. * Handle disconnects of peripherals, and properly clean up and resume discovering for when the peripheral re-appears. --- app/Kconfig | 1 + app/src/split/bluetooth/central.c | 100 +++++++++++++++++------------- 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 8817d506..3502c652 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -167,6 +167,7 @@ menuconfig ZMK_SPLIT_BLE_ROLE_CENTRAL bool "Central" select BT_CENTRAL select BT_GATT_CLIENT + select BT_GATT_AUTO_DISCOVER_CCC if ZMK_SPLIT_BLE_ROLE_CENTRAL diff --git a/app/src/split/bluetooth/central.c b/app/src/split/bluetooth/central.c index a56b0b81..9a7f01b2 100644 --- a/app/src/split/bluetooth/central.c +++ b/app/src/split/bluetooth/central.c @@ -29,9 +29,10 @@ static int start_scan(void); static struct bt_conn *default_conn; -static struct bt_uuid_128 uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID); +static const struct bt_uuid_128 split_service_uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID); static struct bt_gatt_discover_params discover_params; static struct bt_gatt_subscribe_params subscribe_params; +static struct bt_gatt_discover_params sub_discover_params; K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed), CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4); @@ -83,15 +84,12 @@ static uint8_t split_central_notify_func(struct bt_conn *conn, return BT_GATT_ITER_CONTINUE; } -static int split_central_subscribe(struct bt_conn *conn) { +static void split_central_subscribe(struct bt_conn *conn) { int err = bt_gatt_subscribe(conn, &subscribe_params); switch (err) { case -EALREADY: LOG_DBG("[ALREADY SUBSCRIBED]"); break; - // break; - // bt_gatt_unsubscribe(conn, &subscribe_params); - // return split_central_subscribe(conn); case 0: LOG_DBG("[SUBSCRIBED]"); break; @@ -99,14 +97,44 @@ static int split_central_subscribe(struct bt_conn *conn) { LOG_ERR("Subscribe failed (err %d)", err); break; } - - return 0; } -static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct bt_gatt_attr *attr, - struct bt_gatt_discover_params *params) { - int err; +static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + if (!attr) { + LOG_DBG("Discover complete"); + return BT_GATT_ITER_STOP; + } + if (!attr->user_data) { + LOG_ERR("Required user data not passed to discovery"); + return BT_GATT_ITER_STOP; + } + + LOG_DBG("[ATTRIBUTE] handle %u", attr->handle); + + if (!bt_uuid_cmp(((struct bt_gatt_chrc *)attr->user_data)->uuid, + BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID))) { + LOG_DBG("Found position state characteristic"); + discover_params.uuid = NULL; + discover_params.start_handle = attr->handle + 2; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + + subscribe_params.disc_params = &sub_discover_params; + subscribe_params.end_handle = discover_params.end_handle; + subscribe_params.value_handle = bt_gatt_attr_value_handle(attr); + subscribe_params.notify = split_central_notify_func; + subscribe_params.value = BT_GATT_CCC_NOTIFY; + split_central_subscribe(conn); + } + + return subscribe_params.value_handle ? BT_GATT_ITER_STOP : BT_GATT_ITER_CONTINUE; +} + +static uint8_t split_central_service_discovery_func(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { if (!attr) { LOG_DBG("Discover complete"); (void)memset(params, 0, sizeof(*params)); @@ -115,38 +143,21 @@ static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct b LOG_DBG("[ATTRIBUTE] handle %u", attr->handle); - if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID))) { - memcpy(&uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID), sizeof(uuid)); - discover_params.uuid = &uuid.uuid; - discover_params.start_handle = attr->handle + 1; - discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; - - err = bt_gatt_discover(conn, &discover_params); - if (err) { - LOG_ERR("Discover failed (err %d)", err); - } - } else if (!bt_uuid_cmp(discover_params.uuid, - BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID))) { - memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid)); - discover_params.uuid = &uuid.uuid; - discover_params.start_handle = attr->handle + 2; - discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR; - subscribe_params.value_handle = bt_gatt_attr_value_handle(attr); - - err = bt_gatt_discover(conn, &discover_params); - if (err) { - LOG_ERR("Discover failed (err %d)", err); - } - } else { - subscribe_params.notify = split_central_notify_func; - subscribe_params.value = BT_GATT_CCC_NOTIFY; - subscribe_params.ccc_handle = attr->handle; - - split_central_subscribe(conn); - - return BT_GATT_ITER_STOP; + if (bt_uuid_cmp(discover_params.uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID))) { + LOG_DBG("Found other service"); + return BT_GATT_ITER_CONTINUE; } + LOG_DBG("Found split service"); + discover_params.uuid = NULL; + discover_params.func = split_central_chrc_discovery_func; + discover_params.start_handle = attr->handle + 1; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + + int err = bt_gatt_discover(conn, &discover_params); + if (err) { + LOG_ERR("Failed to start discovering split service characteristics (err %d)", err); + } return BT_GATT_ITER_STOP; } @@ -161,9 +172,9 @@ static void split_central_process_connection(struct bt_conn *conn) { return; } - if (conn == default_conn && !subscribe_params.value) { - discover_params.uuid = &uuid.uuid; - discover_params.func = split_central_discovery_func; + if (conn == default_conn && !subscribe_params.value_handle) { + discover_params.uuid = &split_service_uuid.uuid; + discover_params.func = split_central_service_discovery_func; discover_params.start_handle = 0x0001; discover_params.end_handle = 0xffff; discover_params.type = BT_GATT_DISCOVER_PRIMARY; @@ -318,6 +329,9 @@ static void split_central_disconnected(struct bt_conn *conn, uint8_t reason) { bt_conn_unref(default_conn); default_conn = NULL; + // Clean up previously discovered handles; + subscribe_params.value_handle = 0; + start_scan(); } From 944f93170454008759200a27a11225da40935edf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Oct 2021 05:06:35 +0000 Subject: [PATCH 04/46] chore(deps): bump DoozyX/clang-format-lint-action from 0.12 to 0.13 Bumps [DoozyX/clang-format-lint-action](https://github.com/DoozyX/clang-format-lint-action) from 0.12 to 0.13. - [Release notes](https://github.com/DoozyX/clang-format-lint-action/releases) - [Commits](https://github.com/DoozyX/clang-format-lint-action/compare/v0.12...v0.13) --- updated-dependencies: - dependency-name: DoozyX/clang-format-lint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/clang-format-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml index e9b3e077..375bcd4e 100644 --- a/.github/workflows/clang-format-lint.yml +++ b/.github/workflows/clang-format-lint.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: DoozyX/clang-format-lint-action@v0.12 + - uses: DoozyX/clang-format-lint-action@v0.13 with: source: "./app" extensions: "h,c" From f2e0642291621611f3abce69f73a22c33b1ce801 Mon Sep 17 00:00:00 2001 From: Hai-Ninh Dang <30751439+mrninhvn@users.noreply.github.com> Date: Tue, 9 Nov 2021 12:57:24 +0700 Subject: [PATCH 05/46] feat(boards): Add Mikoto board * Supports selecting from several possible charge currents Co-authored-by: Pete Johanson --- app/boards/arm/mikoto/CMakeLists.txt | 14 +++ app/boards/arm/mikoto/Kconfig | 29 +++++ app/boards/arm/mikoto/Kconfig.board | 8 ++ app/boards/arm/mikoto/Kconfig.defconfig | 40 ++++++ .../arm/mikoto/arduino_pro_micro_pins.dtsi | 59 +++++++++ app/boards/arm/mikoto/board.cmake | 5 + app/boards/arm/mikoto/mikoto_520.dts | 115 ++++++++++++++++++ app/boards/arm/mikoto/mikoto_520.yaml | 15 +++ app/boards/arm/mikoto/mikoto_520.zmk.yml | 10 ++ app/boards/arm/mikoto/mikoto_520_defconfig | 20 +++ app/boards/arm/mikoto/pinmux.c | 48 ++++++++ 11 files changed, 363 insertions(+) create mode 100644 app/boards/arm/mikoto/CMakeLists.txt create mode 100644 app/boards/arm/mikoto/Kconfig create mode 100644 app/boards/arm/mikoto/Kconfig.board create mode 100644 app/boards/arm/mikoto/Kconfig.defconfig create mode 100644 app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi create mode 100644 app/boards/arm/mikoto/board.cmake create mode 100644 app/boards/arm/mikoto/mikoto_520.dts create mode 100644 app/boards/arm/mikoto/mikoto_520.yaml create mode 100644 app/boards/arm/mikoto/mikoto_520.zmk.yml create mode 100644 app/boards/arm/mikoto/mikoto_520_defconfig create mode 100644 app/boards/arm/mikoto/pinmux.c diff --git a/app/boards/arm/mikoto/CMakeLists.txt b/app/boards/arm/mikoto/CMakeLists.txt new file mode 100644 index 00000000..cd4843af --- /dev/null +++ b/app/boards/arm/mikoto/CMakeLists.txt @@ -0,0 +1,14 @@ +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/../tools/uf2/utils/uf2conv.py + -c + -b 0x26000 + -f 0xADA52840 + -o ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.uf2 + ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin +) + +if(CONFIG_PINMUX) +zephyr_library() +zephyr_library_sources(pinmux.c) +zephyr_library_include_directories(${ZEPHYR_BASE}/drivers) +endif() \ No newline at end of file diff --git a/app/boards/arm/mikoto/Kconfig b/app/boards/arm/mikoto/Kconfig new file mode 100644 index 00000000..646d119c --- /dev/null +++ b/app/boards/arm/mikoto/Kconfig @@ -0,0 +1,29 @@ +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on (BOARD_MIKOTO_520) + +choice BOARD_MIKOTO_CHARGER_CURRENT + prompt "Charge current to supply to attached batteries" + depends on (BOARD_MIKOTO_520) + +config BOARD_MIKOTO_CHARGER_CURRENT_40MA + bool "40mA charge current, for battery capacity 40mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_100MA + bool "100mA charge current, for battery capacity 100mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_150MA + bool "150mA charge current, for battery capacity 150mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_250MA + bool "250mA charge current, for battery capacity 250mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_350MA + bool "350mA charge current, for battery capacity 350mAh or higher" + +config BOARD_MIKOTO_CHARGER_CURRENT_NONE + bool "Disable charge current" + +endchoice \ No newline at end of file diff --git a/app/boards/arm/mikoto/Kconfig.board b/app/boards/arm/mikoto/Kconfig.board new file mode 100644 index 00000000..067c2fbe --- /dev/null +++ b/app/boards/arm/mikoto/Kconfig.board @@ -0,0 +1,8 @@ +# mikoto board configuration + +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config BOARD_MIKOTO_520 + bool "mikoto_520" + depends on SOC_NRF52840_QIAA diff --git a/app/boards/arm/mikoto/Kconfig.defconfig b/app/boards/arm/mikoto/Kconfig.defconfig new file mode 100644 index 00000000..2ca77b9e --- /dev/null +++ b/app/boards/arm/mikoto/Kconfig.defconfig @@ -0,0 +1,40 @@ +# Electronut Labs Papyr board configuration + +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if BOARD_MIKOTO_520 + +config BOARD + default "mikoto" + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config BT_CTLR + default BT + +config ZMK_BLE + default y + +config ZMK_USB + default y + +config PINMUX + default y + +choice BOARD_MIKOTO_CHARGER_CURRENT + default BOARD_MIKOTO_CHARGER_CURRENT_100MA +endchoice + +config ZMK_BATTERY_VOLTAGE_DIVIDER + default y + +endif # BOARD_MIKOTO_520 diff --git a/app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi b/app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi new file mode 100644 index 00000000..7c5cd12f --- /dev/null +++ b/app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + + +/ { + pro_micro: connector { + compatible = "arduino-pro-micro"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map + = <0 0 &gpio0 4 0> /* D0 */ + , <1 0 &gpio0 8 0> /* D1 */ + , <2 0 &gpio0 17 0> /* D2 */ + , <3 0 &gpio0 20 0> /* D3 */ + , <4 0 &gpio0 22 0> /* D4/A6 */ + , <5 0 &gpio0 24 0> /* D5 */ + , <6 0 &gpio1 0 0> /* D6/A7 */ + , <7 0 &gpio1 2 0> /* D7 */ + , <8 0 &gpio1 4 0> /* D8/A8 */ + , <9 0 &gpio1 6 0> /* D9/A9 */ + , <10 0 &gpio0 9 0> /* D10/A10 */ + , <16 0 &gpio0 10 0> /* D16 */ + , <14 0 &gpio1 13 0> /* D14 */ + , <15 0 &gpio0 2 0> /* D15 */ + , <18 0 &gpio0 29 0> /* D18/A0 */ + , <19 0 &gpio0 31 0> /* D19/A1 */ + , <20 0 &gpio0 25 0> /* D20/A2 */ + , <21 0 &gpio0 11 0> /* D21/A3 */ + ; + }; + + pro_micro_a: connector_a { + compatible = "arduino-pro-micro"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map + = <0 0 &gpio0 29 0> /* D18/A0 */ + , <1 0 &gpio0 31 0> /* D19/A1 */ + , <2 0 &gpio0 25 0> /* D20/A2 */ + , <3 0 &gpio0 11 0> /* D21/A3 */ + , <6 0 &gpio0 22 0> /* D4/A6 */ + , <7 0 &gpio1 0 0> /* D6/A7 */ + , <8 0 &gpio1 4 0> /* D8/A8 */ + , <9 0 &gpio1 6 0> /* D9/A9 */ + , <10 0 &gpio0 9 0> /* D10/A10 */ + ; + }; +}; + + +pro_micro_d: &pro_micro {}; +pro_micro_i2c: &i2c0 {}; +pro_micro_spi: &spi0 {}; +pro_micro_serial: &uart0 {}; diff --git a/app/boards/arm/mikoto/board.cmake b/app/boards/arm/mikoto/board.cmake new file mode 100644 index 00000000..fa847d50 --- /dev/null +++ b/app/boards/arm/mikoto/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: MIT + +board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/mikoto/mikoto_520.dts b/app/boards/arm/mikoto/mikoto_520.dts new file mode 100644 index 00000000..20703e85 --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520.dts @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/dts-v1/; +#include +#include "arduino_pro_micro_pins.dtsi" + +/ { + model = "mikoto"; + compatible = "zhiayang,mikoto"; + + chosen { + zephyr,code-partition = &code_partition; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + leds { + compatible = "gpio-leds"; + blue_led: led_0 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; + + ext-power { + compatible = "zmk,ext-power-generic"; + label = "EXT_POWER"; + control-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; + }; + + vbatt { + compatible = "zmk,battery-voltage-divider"; + label = "BATTERY"; + io-channels = <&adc 2>; + output-ohms = <10000000>; + full-ohms = <(10000000 + 4000000)>; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + sda-pin = <17>; + scl-pin = <20>; +}; + +&uart0 { + compatible = "nordic,nrf-uarte"; + tx-pin = <8>; + rx-pin = <4>; +}; + +&usbd { + status = "okay"; +}; + + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; + }; + code_partition: partition@26000 { + label = "code_partition"; + reg = <0x00026000 0x000c6000>; + }; + + /* + * 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@ec000 { + label = "storage"; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; + }; + }; +}; diff --git a/app/boards/arm/mikoto/mikoto_520.yaml b/app/boards/arm/mikoto/mikoto_520.yaml new file mode 100644 index 00000000..8d9f49ae --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520.yaml @@ -0,0 +1,15 @@ +identifier: mikoto_520 +name: mikoto_520 +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - usb_device + - ble + - ieee802154 + - pwm + - watchdog diff --git a/app/boards/arm/mikoto/mikoto_520.zmk.yml b/app/boards/arm/mikoto/mikoto_520.zmk.yml new file mode 100644 index 00000000..91dcc9e0 --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520.zmk.yml @@ -0,0 +1,10 @@ +file_format: "1" +id: mikoto_520 +name: Mikoto 5.20 +type: board +arch: arm +outputs: + - usb + - ble +url: https://github.com/zhiayang/mikoto +exposes: [pro_micro] diff --git a/app/boards/arm/mikoto/mikoto_520_defconfig b/app/boards/arm/mikoto/mikoto_520_defconfig new file mode 100644 index 00000000..925711c0 --- /dev/null +++ b/app/boards/arm/mikoto/mikoto_520_defconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: MIT + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_MIKOTO_520=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# enable GPIO +CONFIG_GPIO=y + +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_MPU_ALLOW_FLASH_WRITE=y +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y diff --git a/app/boards/arm/mikoto/pinmux.c b/app/boards/arm/mikoto/pinmux.c new file mode 100644 index 00000000..59a38fbf --- /dev/null +++ b/app/boards/arm/mikoto/pinmux.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +#include + +static int pinmux_mikoto_init(const struct device *port) { + ARG_UNUSED(port); + +#if CONFIG_BOARD_MIKOTO_520 + const struct device *p0 = device_get_binding("GPIO_0"); + const struct device *p1 = device_get_binding("GPIO_1"); +#if CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_40MA + gpio_pin_configure(p0, 26, GPIO_INPUT | GPIO_PULL_DOWN); + gpio_pin_configure(p1, 15, GPIO_INPUT); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_100MA + gpio_pin_configure(p0, 26, GPIO_OUTPUT); + gpio_pin_set(p0, 26, 0); + gpio_pin_configure(p1, 15, GPIO_INPUT); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_150MA + gpio_pin_configure(p0, 26, GPIO_OUTPUT); + gpio_pin_set(p0, 26, 0); + gpio_pin_configure(p1, 15, GPIO_INPUT | GPIO_PULL_DOWN); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_250MA + gpio_pin_configure(p0, 26, GPIO_INPUT); + gpio_pin_configure(p1, 15, GPIO_OUTPUT); + gpio_pin_set(p1, 15, 0); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_350MA + gpio_pin_configure(p0, 26, GPIO_OUTPUT); + gpio_pin_set(p0, 26, 0); + gpio_pin_configure(p1, 15, GPIO_OUTPUT); + gpio_pin_set(p1, 15, 0); +#elif CONFIG_BOARD_MIKOTO_CHARGER_CURRENT_NONE + gpio_pin_configure(p0, 26, GPIO_INPUT); + gpio_pin_configure(p1, 15, GPIO_INPUT); +#endif +#endif + return 0; +} + +SYS_INIT(pinmux_mikoto_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); From 4e62319982ea258741eca2b79cf952fe7b8d6b3b Mon Sep 17 00:00:00 2001 From: jding Date: Sat, 6 Nov 2021 21:31:23 +0000 Subject: [PATCH 06/46] feat: hold/tap flavor tap-unless-interrupted Implements new hold/tap flavor, tap-unless-interrupted Adds tests Adds docs --- .../behaviors/zmk,behavior-hold-tap.yaml | 1 + app/src/behaviors/behavior_hold_tap.c | 26 +++++++ .../1-dn-up/events.patterns | 4 ++ .../1-dn-up/keycode_events.snapshot | 5 ++ .../1-dn-up/native_posix.keymap | 11 +++ .../2-dn-timer-up/events.patterns | 4 ++ .../2-dn-timer-up/keycode_events.snapshot | 5 ++ .../2-dn-timer-up/native_posix.keymap | 11 +++ .../3a-moddn-dn-modup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../3a-moddn-dn-modup-up/native_posix.keymap | 13 ++++ .../events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../native_posix.keymap | 14 ++++ .../3c-kcdn-dn-kcup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../3c-kcdn-dn-kcup-up/native_posix.keymap | 13 ++++ .../3d-kcdn-dn-kcup-timer-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../native_posix.keymap | 13 ++++ .../4a-dn-htdn-timer-htup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 10 +++ .../native_posix.keymap | 14 ++++ .../4a-dn-kcdn-timer-kcup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../native_posix.keymap | 14 ++++ .../4b-dn-kcdn-kcup-timer-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../native_posix.keymap | 14 ++++ .../4c-dn-kcdn-kcup-up/events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../4c-dn-kcdn-kcup-up/native_posix.keymap | 14 ++++ .../4d-dn-kcdn-timer-up-kcup/events.patterns | 4 ++ .../keycode_events.snapshot | 7 ++ .../native_posix.keymap | 14 ++++ .../5-quick-tap/events.patterns | 4 ++ .../5-quick-tap/keycode_events.snapshot | 10 +++ .../5-quick-tap/native_posix.keymap | 14 ++++ .../behavior_keymap.dtsi | 30 ++++++++ docs/docs/behaviors/hold-tap.md | 68 ++++++++++++++++++- 40 files changed, 415 insertions(+), 3 deletions(-) create mode 100644 app/tests/hold-tap/tap-unless-interrupted/1-dn-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/1-dn-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/1-dn-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/behavior_keymap.dtsi diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml index 9d489e80..09691159 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml @@ -28,6 +28,7 @@ properties: - "hold-preferred" - "balanced" - "tap-preferred" + - "tap-unless-interrupted" retro-tap: type: boolean hold-trigger-key-positions: diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 1871df70..548d6ef8 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -34,6 +34,7 @@ enum flavor { FLAVOR_HOLD_PREFERRED, FLAVOR_BALANCED, FLAVOR_TAP_PREFERRED, + FLAVOR_TAP_UNLESS_INTERRUPTED, }; enum status { @@ -258,6 +259,26 @@ static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision } } +static void decide_tap_unless_interrupted(struct active_hold_tap *hold_tap, + enum decision_moment event) { + switch (event) { + case HT_KEY_UP: + hold_tap->status = STATUS_TAP; + return; + case HT_OTHER_KEY_DOWN: + hold_tap->status = STATUS_HOLD_INTERRUPT; + return; + case HT_TIMER_EVENT: + hold_tap->status = STATUS_TAP; + return; + case HT_QUICK_TAP: + hold_tap->status = STATUS_TAP; + return; + default: + return; + } +} + static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) { switch (event) { case HT_KEY_UP: @@ -285,6 +306,8 @@ static inline const char *flavor_str(enum flavor flavor) { return "balanced"; case FLAVOR_TAP_PREFERRED: return "tap-preferred"; + case FLAVOR_TAP_UNLESS_INTERRUPTED: + return "tap-unless-interrupted"; default: return "UNKNOWN FLAVOR"; } @@ -420,6 +443,9 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, case FLAVOR_TAP_PREFERRED: decide_tap_preferred(hold_tap, decision_moment); break; + case FLAVOR_TAP_UNLESS_INTERRUPTED: + decide_tap_unless_interrupted(hold_tap, decision_moment); + break; } if (hold_tap->status == STATUS_UNDECIDED) { diff --git a/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/keycode_events.snapshot new file mode 100644 index 00000000..1eb2d1e3 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/native_posix.keymap new file mode 100644 index 00000000..040cdd3e --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/1-dn-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..e036acb9 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/keycode_events.snapshot @@ -0,0 +1,5 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/native_posix.keymap new file mode 100644 index 00000000..11d033f4 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/2-dn-timer-up/native_posix.keymap @@ -0,0 +1,11 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,500) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/keycode_events.snapshot new file mode 100644 index 00000000..a733739d --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/native_posix.keymap new file mode 100644 index 00000000..abb31b4b --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3a-moddn-dn-modup-up/native_posix.keymap @@ -0,0 +1,13 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..d2928131 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe4 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/native_posix.keymap new file mode 100644 index 00000000..38575e9a --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3b-moddn-dn-modup-timer-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/keycode_events.snapshot new file mode 100644 index 00000000..3a9b3dcb --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/native_posix.keymap new file mode 100644 index 00000000..21baa447 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3c-kcdn-dn-kcup-up/native_posix.keymap @@ -0,0 +1,13 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..0a72c83a --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_decide: 0 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/native_posix.keymap new file mode 100644 index 00000000..cd7ff384 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/3d-kcdn-dn-kcup-timer-up/native_posix.keymap @@ -0,0 +1,13 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/keycode_events.snapshot new file mode 100644 index 00000000..b138d6cf --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/keycode_events.snapshot @@ -0,0 +1,10 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 1 new undecided hold_tap +ht_decide: 1 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x0d implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x0d implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 1 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/native_posix.keymap new file mode 100644 index 00000000..b84aa626 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-htdn-timer-htup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot new file mode 100644 index 00000000..6fa61725 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/native_posix.keymap new file mode 100644 index 00000000..bdfaf9d3 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4a-dn-kcdn-timer-kcup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot new file mode 100644 index 00000000..6fa61725 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/native_posix.keymap new file mode 100644 index 00000000..c0fd1bd1 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4b-dn-kcdn-kcup-timer-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/keycode_events.snapshot new file mode 100644 index 00000000..6fa61725 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/native_posix.keymap new file mode 100644 index 00000000..69c19676 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4c-dn-kcdn-kcup-up/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#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 */ + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot new file mode 100644 index 00000000..fc685a37 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/keycode_events.snapshot @@ -0,0 +1,7 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-interrupt (tap-unless-interrupted decision moment other-key-down) +kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/native_posix.keymap new file mode 100644 index 00000000..301ef0ac --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/4d-dn-kcdn-timer-up-kcup/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#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) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/events.patterns new file mode 100644 index 00000000..fdf2b15c --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/events.patterns @@ -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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/keycode_events.snapshot new file mode 100644 index 00000000..070b9938 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/keycode_events.snapshot @@ -0,0 +1,10 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment key-up) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment quick-tap) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/native_posix.keymap new file mode 100644 index 00000000..8f90ffad --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/5-quick-tap/native_posix.keymap @@ -0,0 +1,14 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/behavior_keymap.dtsi b/app/tests/hold-tap/tap-unless-interrupted/behavior_keymap.dtsi new file mode 100644 index 00000000..18f68d63 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/behavior_keymap.dtsi @@ -0,0 +1,30 @@ +#include +#include +#include + + + +/ { + behaviors { + ht_tui: behavior_hold_tap_tap_unless_interrupted { + compatible = "zmk,behavior-hold-tap"; + label = "hold_tap_tap_unless_interrupted"; + #binding-cells = <2>; + flavor = "tap-unless-interrupted"; + tapping-term-ms = <300>; + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_tui LEFT_SHIFT F &ht_tui LEFT_CONTROL J + &kp D &kp RIGHT_CONTROL>; + }; + }; +}; diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 360a9e3d..972df0be 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -26,6 +26,7 @@ We call this the 'hold-preferred' flavor of hold-taps. While this flavor may wor - The 'hold-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired or another key is pressed. - The 'balanced' flavor will trigger the hold behavior when the `tapping-term-ms` has expired or another key is pressed and released. - The 'tap-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired. It triggers the tap behavior when another key is pressed. +- The 'tap-unless-interrupted' flavor triggers a hold behavior only when another key is pressed before `tapping-term-ms` has expired. It triggers the tap behavior in all other situations. When the hold-tap key is released and the hold behavior has not been triggered, the tap behavior will trigger. @@ -103,7 +104,40 @@ For example, if you press `&mt LEFT_SHIFT A` and then release it without pressin #### Home row mods -This example configures a hold-tap that works well for homerow mods: +The following are suggested hold-tap configurations that work well with home row mods: + +##### Option 1: cross-hand only modifiers, using `tap-unless-interrupted` and positional hold-tap (`hold-trigger-key-positions`) + +``` +#include +#include +/ { + behaviors { + lh_pht: left_hand_positional_hold_tap { + compatible = "zmk,behavior-hold-tap"; + label = "POSITIONAL_HOLD_TAP"; + #binding-cells = <2>; + flavor = "tap-unless-interrupted"; + tapping-term-ms = <100>; // <---[[produces tap if held longer than tapping-term-ms]] + quick-tap-ms = <200>; + bindings = <&kp>, <&kp>; + hold-trigger-key-positions = <5 6 7 8 9 10>; // <---[[right-hand keys]] + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + // position 0 pos 1 pos 2 pos 3 pos 4 pos 5 pos 6 pos 7 pos 8 pos 9 pos 10 + &lh_pht LSFT A &lh_pht LGUI S &lh_pht LALT D &lh_pht LCTL F &kp G &kp H &kp I &kp J &kp K &kp L &kp SCLN + >; + }; + }; +}; +``` + +##### Option 2: `tap-preferred` ``` #include @@ -124,7 +158,6 @@ This example configures a hold-tap that works well for homerow mods: keymap { compatible = "zmk,keymap"; - default_layer { bindings = < &hm LCTRL A &hm LGUI S &hm LALT D &hm LSHIFT F @@ -135,7 +168,36 @@ This example configures a hold-tap that works well for homerow mods: ``` -If this config does not work for you, try the flavor "balanced" with a medium `tapping-term-ms` such as 200ms. +##### Option 3: `balanced` + +``` +#include +#include + +/ { + behaviors { + bhm: balanced_homerow_mods { + compatible = "zmk,behavior-hold-tap"; + label = "HOMEROW_MODS"; + #binding-cells = <2>; + tapping-term-ms = <200>; // <---[[moderate duration]] + quick_tap_ms = <0>; + flavor = "balanced"; + bindings = <&kp>, <&kp>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &bhm LCTRL A &bhm LGUI S &bhm LALT D &bhm LSHIFT F + >; + }; + }; +}; + +``` #### Comparison to QMK From c412fad40da718b5df518c92b08b4913d26621c6 Mon Sep 17 00:00:00 2001 From: "Viet (Drake) Tran" Date: Tue, 9 Nov 2021 22:26:21 +0700 Subject: [PATCH 07/46] fix(shields): Fix some keycodes in reviung41 keymap Notice some keycodes are not matched with the expected keys. --- app/boards/shields/reviung41/reviung41.keymap | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/boards/shields/reviung41/reviung41.keymap b/app/boards/shields/reviung41/reviung41.keymap index 9c189759..f0450b19 100644 --- a/app/boards/shields/reviung41/reviung41.keymap +++ b/app/boards/shields/reviung41/reviung41.keymap @@ -35,8 +35,8 @@ // | | | RET | ADJ | | bindings = < &trans &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp N8 &kp LPAR &kp RPAR &kp DEL - &trans &kp MINUS &kp KP_PLUS &kp LBRC &kp RBRC &kp PIPE &kp LEFT &kp DOWN &kp UP &kp RIGHT &kp GRAVE &kp GRAVE - &trans &kp ESC &kp LGUI &kp LALT &kp CLCK &kp SQT &kp HOME &kp END &kp PG_UP &kp PG_DN &kp PSCRN &mt RSHFT RET + &trans &kp MINUS &kp KP_PLUS &kp LBRC &kp RBRC &kp PIPE &kp LEFT &kp DOWN &kp UP &kp RIGHT &kp GRAVE &kp TILDE + &trans &kp ESC &kp LGUI &kp LALT &kp CLCK &kp DQT &kp HOME &kp END &kp PG_UP &kp PG_DN &kp PSCRN &mt RSHFT RET &trans &trans &kp RET &mo 3 &trans >; }; @@ -50,7 +50,7 @@ bindings = < &trans &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp DEL &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 - &trans &kp ESC &kp LGUI &kp RALT &kp CLCK &kp SQT &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &trans &kp ESC &kp LGUI &kp RALT &kp CLCK &kp DQT &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &mo 3 &kp BSPC &trans &trans >; }; @@ -58,7 +58,7 @@ adjust_layer { // ----------------------------------------------------------------------------------------- // | RGB BRI+ | RGB SAT+ | RGB HUE+ | RGB ANI+ | | RGB TOG | | BT1 | BT2 | BT3 | BT4 | BT5 | BT CLR | -// | RGB BRI- | RGB SAT- | RGB HUE- | RGB ANI+ | | | | | | | | | | +// | RGB BRI- | RGB SAT- | RGB HUE- | RGB ANI- | | | | | | | | | | // | | | | | | | | RESET | | | | | | // | | | | | | bindings = < From f8018b22d0bcba97e54652a01e8bdefb15f83c4c Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 8 Nov 2021 21:21:01 +0000 Subject: [PATCH 08/46] fix(hid): Basic consumer code fixes for signed logical max. * Logical max values are signed, so for the report descriptor, use a two byte logical max descriptor item to impart proper 0xFF max logical value. --- app/include/zmk/hid.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/include/zmk/hid.h b/app/include/zmk/hid.h index 95b82d46..e23caff9 100644 --- a/app/include/zmk/hid.h +++ b/app/include/zmk/hid.h @@ -143,12 +143,14 @@ static const uint8_t zmk_hid_report_desc[] = { /* LOGICAL_MINIMUM (0) */ HID_GI_LOGICAL_MIN(1), 0x00, - /* LOGICAL_MAXIMUM (0xFFFF) */ - HID_GI_LOGICAL_MAX(1), + /* LOGICAL_MAXIMUM (0x00FF) - little endian, and requires two bytes because logical max is + signed */ + HID_GI_LOGICAL_MAX(2), 0xFF, + 0x00, HID_LI_USAGE_MIN(1), 0x00, - /* USAGE_MAXIMUM (0xFFFF) */ + /* USAGE_MAXIMUM (0xFF) */ HID_LI_USAGE_MAX(1), 0xFF, /* INPUT (Data,Ary,Abs) */ From e9140b2da914ee121e7f40eaeb8c6cf827d03622 Mon Sep 17 00:00:00 2001 From: Jonathan Rascher Date: Wed, 9 Jun 2021 18:51:28 -0500 Subject: [PATCH 09/46] feat(conditional-layers): Implement feature This is a generalization of the existing concept of tri-layer support that's already well known. Essentially, a conditional-layer configuration activates a particular layer (the then-layer) when one or more other layers (the if-layers) are activated. This is commonly used on ortho keyboards to activate a third "adjust" layer while the primary two layers ("lower" and "raise") are active. --- app/CMakeLists.txt | 1 + app/dts/bindings/zmk,conditional-layers.yaml | 17 ++++ app/src/conditional_layer.c | 91 ++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 app/dts/bindings/zmk,conditional-layers.yaml create mode 100644 app/src/conditional_layer.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 5092deff..9c7befec 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -57,6 +57,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) target_sources(app PRIVATE src/behaviors/behavior_sensor_rotate_key_press.c) target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/behaviors/behavior_ext_power.c) target_sources(app PRIVATE src/combo.c) + target_sources(app PRIVATE src/conditional_layer.c) target_sources(app PRIVATE src/keymap.c) endif() target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/behaviors/behavior_rgb_underglow.c) diff --git a/app/dts/bindings/zmk,conditional-layers.yaml b/app/dts/bindings/zmk,conditional-layers.yaml new file mode 100644 index 00000000..7e79038e --- /dev/null +++ b/app/dts/bindings/zmk,conditional-layers.yaml @@ -0,0 +1,17 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Conditional layers allow layer combinations to trigger additional layers + +compatible: "zmk,conditional-layers" + +child-binding: + description: "Single conditional layer that activates then-layer when if-layers are active" + + properties: + if-layers: + type: array + required: true + then-layer: + type: int + required: true diff --git a/app/src/conditional_layer.c b/app/src/conditional_layer.c new file mode 100644 index 00000000..4beb87e3 --- /dev/null +++ b/app/src/conditional_layer.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_conditional_layers + +#include + +#include +#include + +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +// Conditional layer configuration that activates the specified then-layer when all if-layers are +// active. With two if-layers, this is referred to as "tri-layer", and is commonly used to activate +// a third "adjust" layer if and only if the "lower" and "raise" layers are both active. +struct conditional_layer_cfg { + // A bitmask of each layer that must be pressed for this conditional layer config to activate. + zmk_keymap_layers_state_t if_layers_state_mask; + + // The layer number that should be active while all layers in the if-layers mask are active. + int8_t then_layer; +}; + +#define IF_LAYER_BIT(i, n) BIT(DT_PROP_BY_IDX(n, if_layers, i)) | + +// Evaluates to conditional_layer_cfg struct initializer. +#define CONDITIONAL_LAYER_DECL(n) \ + { \ + /* TODO: Replace UTIL_LISTIFY with DT_FOREACH_PROP_ELEM after Zepyhr 2.6.0 upgrade. */ \ + .if_layers_state_mask = UTIL_LISTIFY(DT_PROP_LEN(n, if_layers), IF_LAYER_BIT, n) 0, \ + .then_layer = DT_PROP(n, then_layer), \ + }, + +// All conditional layer configurations in the keymap. +static const struct conditional_layer_cfg CONDITIONAL_LAYER_CFGS[] = { + DT_INST_FOREACH_CHILD(0, CONDITIONAL_LAYER_DECL)}; + +static const int32_t NUM_CONDITIONAL_LAYER_CFGS = + sizeof(CONDITIONAL_LAYER_CFGS) / sizeof(*CONDITIONAL_LAYER_CFGS); + +static void conditional_layer_activate(int8_t layer) { + // This may trigger another event that could, in turn, activate additional then-layers. However, + // the process will eventually terminate (at worst, when every layer is active). + if (!zmk_keymap_layer_active(layer)) { + LOG_DBG("layer %d", layer); + zmk_keymap_layer_activate(layer); + } +} + +static void conditional_layer_deactivate(int8_t layer) { + // This may deactivate a then-layer that's already active via another mechanism (e.g., a + // momentary layer behavior). However, the same problem arises when multiple keys with the same + // &mo binding are held and then one is released, so it's probably not an issue in practice. + if (zmk_keymap_layer_active(layer)) { + LOG_DBG("layer %d", layer); + zmk_keymap_layer_deactivate(layer); + } +} + +// On layer state changes, examines each conditional layer config to determine if then-layer in the +// config should activate based on the currently active set of if-layers. +static int layer_state_changed_listener(const zmk_event_t *ev) { + for (int i = 0; i < NUM_CONDITIONAL_LAYER_CFGS; i++) { + const struct conditional_layer_cfg *cfg = CONDITIONAL_LAYER_CFGS + i; + zmk_keymap_layers_state_t mask = cfg->if_layers_state_mask; + + // Activate then-layer if and only if all if-layers are already active. Note that we + // reevaluate the current layer state for each config since activation of one layer can also + // trigger activation of another. + if ((zmk_keymap_layer_state() & mask) == mask) { + conditional_layer_activate(cfg->then_layer); + } else { + conditional_layer_deactivate(cfg->then_layer); + } + } + return 0; +} + +ZMK_LISTENER(conditional_layer, layer_state_changed_listener); +ZMK_SUBSCRIPTION(conditional_layer, zmk_layer_state_changed); + +#endif From cbf6e28e34444b584b9dbaf97d7d40f587d22e82 Mon Sep 17 00:00:00 2001 From: Jonathan Rascher Date: Fri, 1 Oct 2021 22:05:37 -0400 Subject: [PATCH 10/46] docs(conditional-layers): Document feature --- docs/docs/features/conditional-layers.md | 56 ++++++++++++++++++++++++ docs/sidebars.js | 1 + 2 files changed, 57 insertions(+) create mode 100644 docs/docs/features/conditional-layers.md diff --git a/docs/docs/features/conditional-layers.md b/docs/docs/features/conditional-layers.md new file mode 100644 index 00000000..a685bcab --- /dev/null +++ b/docs/docs/features/conditional-layers.md @@ -0,0 +1,56 @@ +--- +title: Conditional Layers +--- + +Conditional layers support activating a particular layer (called the `then-layer`) when all layers +in a specified set (called the `if-layers`) are active. This feature generalizes what's commonly +known as tri-layer support, allowing activation of two layers (usually called "lower" and "raise") +to trigger a third (usually called "adjust"). + +Another way to think of this feature is as a simple combo system for layers, just like the usual +[combos for behaviors](combos.md). + +## Configuration + +Conditional layers are configured via a `conditional_layers` node in your `.keymap` file as follows: + +``` +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; +}; +``` + +Each conditional layer configuration may have whatever name you like, but it's helpful to choose +something self explanatory like `tri_layer`. The following properties are supported: + +- `if-layers` specifies a set of layer numbers, all of which must be active for the conditional + layer to trigger. +- `then-layer` specifies a layer number that should be activated if and only if all the layers + specified in the `if-layers` property are active. + +Therefore, in this example, layer 3 ("adjust") will be activated if and only if both layers 1 +("lower") and 2 ("raise") are active. + +:::tip +Since higher-numbered layers are processed first, a `then-layer` should generally have a higher +number than its associated `if-layers` so the `then-layer` can be accessed when active. +::: + +:::info +Activating a `then-layer` in one conditional layer configuration can trigger the `if-layers` +condition in another configuration, possibly repeatedly. +::: + +:::caution +When configured as a `then-layer`, a layer's activation status is entirely controlled by the +conditional layers feature. Even if the layer is activated for another reason (such as a [momentary +layer](../behaviors/layers.md#momentary-layer) behavior), it will be immediately deactivated if the +associated `then-layers` configuration is not met. As such, we recommend avoiding using regular +layer behaviors for `then-layer` targets. +::: diff --git a/docs/sidebars.js b/docs/sidebars.js index 2a406589..04389695 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -11,6 +11,7 @@ module.exports = { Features: [ "features/keymaps", "features/combos", + "features/conditional-layers", "features/debouncing", "features/displays", "features/encoders", From df110beac4c028ac658eb58925dc79176e0b334c Mon Sep 17 00:00:00 2001 From: Jonathan Rascher Date: Wed, 9 Jun 2021 18:55:57 -0500 Subject: [PATCH 11/46] test(conditional-layers): Add basic unit tests --- .../quad-layer/events.patterns | 3 + .../quad-layer/keycode_events.snapshot | 10 ++++ .../quad-layer/native_posix.keymap | 60 +++++++++++++++++++ .../tri-layer/events.patterns | 3 + .../tri-layer/keycode_events.snapshot | 8 +++ .../tri-layer/native_posix.keymap | 52 ++++++++++++++++ 6 files changed, 136 insertions(+) create mode 100644 app/tests/conditional-layer/quad-layer/events.patterns create mode 100644 app/tests/conditional-layer/quad-layer/keycode_events.snapshot create mode 100644 app/tests/conditional-layer/quad-layer/native_posix.keymap create mode 100644 app/tests/conditional-layer/tri-layer/events.patterns create mode 100644 app/tests/conditional-layer/tri-layer/keycode_events.snapshot create mode 100644 app/tests/conditional-layer/tri-layer/native_posix.keymap diff --git a/app/tests/conditional-layer/quad-layer/events.patterns b/app/tests/conditional-layer/quad-layer/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/quad-layer/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/quad-layer/keycode_events.snapshot b/app/tests/conditional-layer/quad-layer/keycode_events.snapshot new file mode 100644 index 00000000..fb54a6ca --- /dev/null +++ b/app/tests/conditional-layer/quad-layer/keycode_events.snapshot @@ -0,0 +1,10 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +mo_pressed: position 1 layer 3 +cl_activate: layer 4 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 1 layer 3 +cl_deactivate: layer 4 +mo_released: position 3 layer 2 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/quad-layer/native_posix.keymap b/app/tests/conditional-layer/quad-layer/native_posix.keymap new file mode 100644 index 00000000..300b1f75 --- /dev/null +++ b/app/tests/conditional-layer/quad-layer/native_posix.keymap @@ -0,0 +1,60 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + quad_layer { + if-layers = <1 2 3>; + then-layer = <4>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &mo 3 + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp B &trans + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp C &trans + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp D &trans + &trans &trans + >; + }; + layer_4 { + bindings = < + &kp E &trans + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; diff --git a/app/tests/conditional-layer/tri-layer/events.patterns b/app/tests/conditional-layer/tri-layer/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/tri-layer/keycode_events.snapshot b/app/tests/conditional-layer/tri-layer/keycode_events.snapshot new file mode 100644 index 00000000..b23e61b2 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer/keycode_events.snapshot @@ -0,0 +1,8 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/tri-layer/native_posix.keymap b/app/tests/conditional-layer/tri-layer/native_posix.keymap new file mode 100644 index 00000000..150d6dd1 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer/native_posix.keymap @@ -0,0 +1,52 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &kp B + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp C &kp D + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp E &kp F + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp G &kp H + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; From a908396013f4af15dd906cc882e23baa121bf89c Mon Sep 17 00:00:00 2001 From: Jonathan Rascher Date: Sat, 2 Oct 2021 00:02:51 -0400 Subject: [PATCH 12/46] test(conditional-layers): Add multi-config tests --- .../multiple-configs/events.patterns | 3 + .../multiple-configs/keycode_events.snapshot | 16 ++++ .../multiple-configs/native_posix.keymap | 74 +++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 app/tests/conditional-layer/multiple-configs/events.patterns create mode 100644 app/tests/conditional-layer/multiple-configs/keycode_events.snapshot create mode 100644 app/tests/conditional-layer/multiple-configs/native_posix.keymap diff --git a/app/tests/conditional-layer/multiple-configs/events.patterns b/app/tests/conditional-layer/multiple-configs/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/multiple-configs/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/multiple-configs/keycode_events.snapshot b/app/tests/conditional-layer/multiple-configs/keycode_events.snapshot new file mode 100644 index 00000000..a076a639 --- /dev/null +++ b/app/tests/conditional-layer/multiple-configs/keycode_events.snapshot @@ -0,0 +1,16 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 4 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +mo_pressed: position 1 layer 3 +cl_activate: layer 5 +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 1 layer 3 +cl_deactivate: layer 5 +kp_pressed: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x08 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 4 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/multiple-configs/native_posix.keymap b/app/tests/conditional-layer/multiple-configs/native_posix.keymap new file mode 100644 index 00000000..8290649f --- /dev/null +++ b/app/tests/conditional-layer/multiple-configs/native_posix.keymap @@ -0,0 +1,74 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <4>; + }; + quad_layer { + if-layers = <1 2 3>; + then-layer = <5>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &mo 3 + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp B &trans + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp C &trans + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp D &trans + &trans &trans + >; + }; + layer_4 { + bindings = < + &kp E &trans + &trans &trans + >; + }; + layer_5 { + bindings = < + &kp F &trans + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; From 6cd1734851c31884cdf14b40fddc5a9df273b296 Mon Sep 17 00:00:00 2001 From: Jonathan Rascher Date: Sat, 2 Oct 2021 00:27:49 -0400 Subject: [PATCH 13/46] test(conditional-layers): Add interleaved up/downs --- .../tri-layer-alt-order/events.patterns | 3 ++ .../keycode_events.snapshot | 8 +++ .../tri-layer-alt-order/native_posix.keymap | 52 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 app/tests/conditional-layer/tri-layer-alt-order/events.patterns create mode 100644 app/tests/conditional-layer/tri-layer-alt-order/keycode_events.snapshot create mode 100644 app/tests/conditional-layer/tri-layer-alt-order/native_posix.keymap diff --git a/app/tests/conditional-layer/tri-layer-alt-order/events.patterns b/app/tests/conditional-layer/tri-layer-alt-order/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer-alt-order/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/tri-layer-alt-order/keycode_events.snapshot b/app/tests/conditional-layer/tri-layer-alt-order/keycode_events.snapshot new file mode 100644 index 00000000..05337b29 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer-alt-order/keycode_events.snapshot @@ -0,0 +1,8 @@ +mo_pressed: position 3 layer 2 +mo_pressed: position 2 layer 1 +cl_activate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +mo_released: position 2 layer 1 +kp_released: usage_page 0x07 keycode 0x0a implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/conditional-layer/tri-layer-alt-order/native_posix.keymap b/app/tests/conditional-layer/tri-layer-alt-order/native_posix.keymap new file mode 100644 index 00000000..a3154038 --- /dev/null +++ b/app/tests/conditional-layer/tri-layer-alt-order/native_posix.keymap @@ -0,0 +1,52 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &kp B + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp C &kp D + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp E &kp F + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp G &kp H + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; From 30ed2375335acf47da0216c6832ecfd30ea7097c Mon Sep 17 00:00:00 2001 From: Jonathan Rascher Date: Sat, 2 Oct 2021 01:15:21 -0400 Subject: [PATCH 14/46] test(conditional-layers): Add tests for edge cases --- .../chained-activation/events.patterns | 3 + .../keycode_events.snapshot | 10 +++ .../chained-activation/native_posix.keymap | 62 +++++++++++++++++++ .../mo-overlap/events.patterns | 3 + .../mo-overlap/keycode_events.snapshot | 17 +++++ .../mo-overlap/native_posix.keymap | 60 ++++++++++++++++++ 6 files changed, 155 insertions(+) create mode 100644 app/tests/conditional-layer/chained-activation/events.patterns create mode 100644 app/tests/conditional-layer/chained-activation/keycode_events.snapshot create mode 100644 app/tests/conditional-layer/chained-activation/native_posix.keymap create mode 100644 app/tests/conditional-layer/mo-overlap/events.patterns create mode 100644 app/tests/conditional-layer/mo-overlap/keycode_events.snapshot create mode 100644 app/tests/conditional-layer/mo-overlap/native_posix.keymap diff --git a/app/tests/conditional-layer/chained-activation/events.patterns b/app/tests/conditional-layer/chained-activation/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/chained-activation/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/chained-activation/keycode_events.snapshot b/app/tests/conditional-layer/chained-activation/keycode_events.snapshot new file mode 100644 index 00000000..422b075c --- /dev/null +++ b/app/tests/conditional-layer/chained-activation/keycode_events.snapshot @@ -0,0 +1,10 @@ +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 3 +cl_activate: layer 4 +kp_pressed: usage_page 0x07 keycode 0x0c implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x0c implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +cl_deactivate: layer 4 +mo_released: position 2 layer 1 diff --git a/app/tests/conditional-layer/chained-activation/native_posix.keymap b/app/tests/conditional-layer/chained-activation/native_posix.keymap new file mode 100644 index 00000000..d799cc5e --- /dev/null +++ b/app/tests/conditional-layer/chained-activation/native_posix.keymap @@ -0,0 +1,62 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + conditional_layer_1 { + if-layers = <1 2>; + then-layer = <3>; + }; + conditional_layer_2 { + if-layers = <1 3>; + then-layer = <4>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &kp B + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp C &kp D + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp E &kp F + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp G &kp H + &trans &trans + >; + }; + layer_4 { + bindings = < + &kp I &kp J + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + >; +}; diff --git a/app/tests/conditional-layer/mo-overlap/events.patterns b/app/tests/conditional-layer/mo-overlap/events.patterns new file mode 100644 index 00000000..14ded795 --- /dev/null +++ b/app/tests/conditional-layer/mo-overlap/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode/kp/p +s/.*mo_keymap_binding/mo/p +s/.*conditional_layer/cl/p diff --git a/app/tests/conditional-layer/mo-overlap/keycode_events.snapshot b/app/tests/conditional-layer/mo-overlap/keycode_events.snapshot new file mode 100644 index 00000000..0200d8de --- /dev/null +++ b/app/tests/conditional-layer/mo-overlap/keycode_events.snapshot @@ -0,0 +1,17 @@ +mo_pressed: position 1 layer 3 +cl_deactivate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +mo_pressed: position 2 layer 1 +mo_pressed: position 3 layer 2 +cl_activate: layer 3 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 3 layer 2 +cl_deactivate: layer 3 +mo_released: position 2 layer 1 +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +mo_released: position 1 layer 3 +kp_pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +kp_released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 diff --git a/app/tests/conditional-layer/mo-overlap/native_posix.keymap b/app/tests/conditional-layer/mo-overlap/native_posix.keymap new file mode 100644 index 00000000..1518fc8a --- /dev/null +++ b/app/tests/conditional-layer/mo-overlap/native_posix.keymap @@ -0,0 +1,60 @@ +#include +#include +#include + +/ { + conditional_layers { + compatible = "zmk,conditional-layers"; + tri_layer { + if-layers = <1 2>; + then-layer = <3>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + default_layer { + bindings = < + &kp A &mo 3 + &mo 1 &mo 2 + >; + }; + layer_1 { + bindings = < + &kp B &trans + &trans &trans + >; + }; + layer_2 { + bindings = < + &kp C &trans + &trans &trans + >; + }; + layer_3 { + bindings = < + &kp D &trans + &trans &trans + >; + }; + }; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; From 54dabffd0d371595a8142ee4da4f5d888a310cda Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Wed, 9 Jun 2021 06:10:20 +0000 Subject: [PATCH 15/46] feat(behaviors): Add caps word (`&caps_word`). * Add new `&caps_word` behavior that acts like caps lock, but releases automatically when any "break" keycode is pressed. --- app/CMakeLists.txt | 1 + app/dts/behaviors.dtsi | 1 + app/dts/behaviors/caps_word.dtsi | 19 ++ .../behaviors/zmk,behavior-caps-word.yaml | 15 ++ app/src/behaviors/behavior_caps_word.c | 186 ++++++++++++++++++ app/tests/caps-word/behavior_keymap.dtsi | 17 ++ .../events.patterns | 4 + .../keycode_events.snapshot | 17 ++ .../native_posix.keymap | 21 ++ .../events.patterns | 4 + .../keycode_events.snapshot | 14 ++ .../native_posix.keymap | 21 ++ .../events.patterns | 3 + .../keycode_events.snapshot | 13 ++ .../native_posix.keymap | 17 ++ .../events.patterns | 3 + .../keycode_events.snapshot | 9 + .../native_posix.keymap | 17 ++ docs/docs/behaviors/caps-word.md | 74 +++++++ docs/sidebars.js | 1 + 20 files changed, 457 insertions(+) create mode 100644 app/dts/behaviors/caps_word.dtsi create mode 100644 app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml create mode 100644 app/src/behaviors/behavior_caps_word.c create mode 100644 app/tests/caps-word/behavior_keymap.dtsi create mode 100644 app/tests/caps-word/continue-with-non-alpha-continue-list-item/events.patterns create mode 100644 app/tests/caps-word/continue-with-non-alpha-continue-list-item/keycode_events.snapshot create mode 100644 app/tests/caps-word/continue-with-non-alpha-continue-list-item/native_posix.keymap create mode 100644 app/tests/caps-word/continue-with-non-modified-numeric-usage-id/events.patterns create mode 100644 app/tests/caps-word/continue-with-non-modified-numeric-usage-id/keycode_events.snapshot create mode 100644 app/tests/caps-word/continue-with-non-modified-numeric-usage-id/native_posix.keymap create mode 100644 app/tests/caps-word/deactivate-by-non-alpha-non-continuation/events.patterns create mode 100644 app/tests/caps-word/deactivate-by-non-alpha-non-continuation/keycode_events.snapshot create mode 100644 app/tests/caps-word/deactivate-by-non-alpha-non-continuation/native_posix.keymap create mode 100644 app/tests/caps-word/deactivate-by-second-press/events.patterns create mode 100644 app/tests/caps-word/deactivate-by-second-press/keycode_events.snapshot create mode 100644 app/tests/caps-word/deactivate-by-second-press/native_posix.keymap create mode 100644 docs/docs/behaviors/caps-word.md diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 9c7befec..970c6c20 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -47,6 +47,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) 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_sticky_key.c) + target_sources(app PRIVATE src/behaviors/behavior_caps_word.c) target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c) target_sources(app PRIVATE src/behaviors/behavior_mod_morph.c) target_sources(app PRIVATE src/behaviors/behavior_outputs.c) diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index 4333ceea..5b5f72b4 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -14,3 +14,4 @@ #include #include #include +#include diff --git a/app/dts/behaviors/caps_word.dtsi b/app/dts/behaviors/caps_word.dtsi new file mode 100644 index 00000000..57d5cab7 --- /dev/null +++ b/app/dts/behaviors/caps_word.dtsi @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + behaviors { + /omit-if-no-ref/ caps_word: behavior_caps_word { + compatible = "zmk,behavior-caps-word"; + label = "CAPS_WORD"; + #binding-cells = <0>; + continue-list = ; + }; + }; +}; + diff --git a/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml b/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml new file mode 100644 index 00000000..cc1dda01 --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-caps-word.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Caps word behavior + +compatible: "zmk,behavior-caps-word" + +include: zero_param.yaml + +properties: + continue-list: + type: array + required: true + mods: + type: int diff --git a/app/src/behaviors/behavior_caps_word.c b/app/src/behaviors/behavior_caps_word.c new file mode 100644 index 00000000..45e3d9d9 --- /dev/null +++ b/app/src/behaviors/behavior_caps_word.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_caps_word + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) + +struct caps_word_continue_item { + uint16_t page; + uint32_t id; + uint8_t implicit_modifiers; +}; + +struct behavior_caps_word_config { + zmk_mod_flags_t mods; + uint8_t index; + uint8_t continuations_count; + struct caps_word_continue_item continuations[]; +}; + +struct behavior_caps_word_data { + bool active; +}; + +static void activate_caps_word(const struct device *dev) { + struct behavior_caps_word_data *data = dev->data; + + data->active = true; +} + +static void deactivate_caps_word(const struct device *dev) { + struct behavior_caps_word_data *data = dev->data; + + data->active = false; +} + +static int on_caps_word_binding_pressed(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + const struct device *dev = device_get_binding(binding->behavior_dev); + struct behavior_caps_word_data *data = dev->data; + + if (data->active) { + deactivate_caps_word(dev); + } else { + activate_caps_word(dev); + } + + return ZMK_BEHAVIOR_OPAQUE; +} + +static int on_caps_word_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + return ZMK_BEHAVIOR_OPAQUE; +} + +static const struct behavior_driver_api behavior_caps_word_driver_api = { + .binding_pressed = on_caps_word_binding_pressed, + .binding_released = on_caps_word_binding_released, +}; + +static int caps_word_keycode_state_changed_listener(const zmk_event_t *eh); + +ZMK_LISTENER(behavior_caps_word, caps_word_keycode_state_changed_listener); +ZMK_SUBSCRIPTION(behavior_caps_word, zmk_keycode_state_changed); + +static const struct device *devs[DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT)]; + +static bool caps_word_is_caps_includelist(const struct behavior_caps_word_config *config, + uint16_t usage_page, uint8_t usage_id, + uint8_t implicit_modifiers) { + for (int i = 0; i < config->continuations_count; i++) { + const struct caps_word_continue_item *continuation = &config->continuations[i]; + LOG_DBG("Comparing with 0x%02X - 0x%02X (with implicit mods: 0x%02X)", continuation->page, + continuation->id, continuation->implicit_modifiers); + + if (continuation->page == usage_page && continuation->id == usage_id && + continuation->implicit_modifiers == implicit_modifiers) { + LOG_DBG("Continuing capsword, found included usage: 0x%02X - 0x%02X", usage_page, + usage_id); + return true; + } + } + + return false; +} + +static bool caps_word_is_alpha(uint8_t usage_id) { + return (usage_id >= HID_USAGE_KEY_KEYBOARD_A && usage_id <= HID_USAGE_KEY_KEYBOARD_Z); +} + +static bool caps_word_is_numeric(uint8_t usage_id) { + return (usage_id >= HID_USAGE_KEY_KEYBOARD_1_AND_EXCLAMATION && + usage_id <= HID_USAGE_KEY_KEYBOARD_0_AND_RIGHT_PARENTHESIS); +} + +static void caps_word_enhance_usage(const struct behavior_caps_word_config *config, + struct zmk_keycode_state_changed *ev) { + if (ev->usage_page != HID_USAGE_KEY || !caps_word_is_alpha(ev->keycode)) { + return; + } + + LOG_DBG("Enhancing usage 0x%02X with modifiers: 0x%02X", ev->keycode, config->mods); + ev->implicit_modifiers |= config->mods; +} + +static int caps_word_keycode_state_changed_listener(const zmk_event_t *eh) { + struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); + if (ev == NULL || !ev->state) { + return ZMK_EV_EVENT_BUBBLE; + } + + for (int i = 0; i < DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT); i++) { + const struct device *dev = devs[i]; + if (dev == NULL) { + continue; + } + + struct behavior_caps_word_data *data = dev->data; + if (!data->active) { + continue; + } + + const struct behavior_caps_word_config *config = dev->config; + + caps_word_enhance_usage(config, ev); + + if (!caps_word_is_alpha(ev->keycode) && !caps_word_is_numeric(ev->keycode) && + !caps_word_is_caps_includelist(config, ev->usage_page, ev->keycode, + ev->implicit_modifiers)) { + LOG_DBG("Deactivating caps_word for 0x%02X - 0x%02X", ev->usage_page, ev->keycode); + deactivate_caps_word(dev); + } + } + + return ZMK_EV_EVENT_BUBBLE; +} + +static int behavior_caps_word_init(const struct device *dev) { + const struct behavior_caps_word_config *config = dev->config; + devs[config->index] = dev; + return 0; +} + +#define CAPS_WORD_LABEL(i, _n) DT_INST_LABEL(i) + +#define PARSE_BREAK(i) \ + {.page = (HID_USAGE_PAGE(i) & 0xFF), \ + .id = HID_USAGE_ID(i), \ + .implicit_modifiers = SELECT_MODS(i)}, + +#define BREAK_ITEM(i, n) PARSE_BREAK(DT_INST_PROP_BY_IDX(n, continue_list, i)) + +#define KP_INST(n) \ + static struct behavior_caps_word_data behavior_caps_word_data_##n = {.active = false}; \ + static struct behavior_caps_word_config behavior_caps_word_config_##n = { \ + .index = n, \ + .mods = DT_INST_PROP_OR(n, mods, MOD_LSFT), \ + .continuations = {UTIL_LISTIFY(DT_INST_PROP_LEN(n, continue_list), BREAK_ITEM, n)}, \ + .continuations_count = DT_INST_PROP_LEN(n, continue_list), \ + }; \ + DEVICE_DT_INST_DEFINE(n, behavior_caps_word_init, device_pm_control_nop, \ + &behavior_caps_word_data_##n, &behavior_caps_word_config_##n, \ + APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \ + &behavior_caps_word_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(KP_INST) + +#endif diff --git a/app/tests/caps-word/behavior_keymap.dtsi b/app/tests/caps-word/behavior_keymap.dtsi new file mode 100644 index 00000000..04653bec --- /dev/null +++ b/app/tests/caps-word/behavior_keymap.dtsi @@ -0,0 +1,17 @@ +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + label = "Default keymap"; + + default_layer { + bindings = < + &caps_word &kp A + &kp N6 &kp MINUS + >; + }; + }; +}; diff --git a/app/tests/caps-word/continue-with-non-alpha-continue-list-item/events.patterns b/app/tests/caps-word/continue-with-non-alpha-continue-list-item/events.patterns new file mode 100644 index 00000000..dd4d3d3f --- /dev/null +++ b/app/tests/caps-word/continue-with-non-alpha-continue-list-item/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_implicit_modifiers_//p +s/.*caps_word_enhance_usage/enhance_usage/p +s/.*caps_word_is_caps_includelist/caps_includelist/p \ No newline at end of file diff --git a/app/tests/caps-word/continue-with-non-alpha-continue-list-item/keycode_events.snapshot b/app/tests/caps-word/continue-with-non-alpha-continue-list-item/keycode_events.snapshot new file mode 100644 index 00000000..fe705ba4 --- /dev/null +++ b/app/tests/caps-word/continue-with-non-alpha-continue-list-item/keycode_events.snapshot @@ -0,0 +1,17 @@ +enhance_usage: Enhancing usage 0x04 with modifiers: 0x02 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x02 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +caps_includelist: Comparing with 0x07 - 0x2d (with implicit mods: 0x02) +caps_includelist: Comparing with 0x07 - 0x2d (with implicit mods: 0x00) +caps_includelist: Continuing capsword, found included usage: 0x07 - 0x2d +pressed: usage_page 0x07 keycode 0x2d implicit_mods 0x00 explicit_mods 0x00 +press: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x2d implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +enhance_usage: Enhancing usage 0x04 with modifiers: 0x02 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x02 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 diff --git a/app/tests/caps-word/continue-with-non-alpha-continue-list-item/native_posix.keymap b/app/tests/caps-word/continue-with-non-alpha-continue-list-item/native_posix.keymap new file mode 100644 index 00000000..68c3249f --- /dev/null +++ b/app/tests/caps-word/continue-with-non-alpha-continue-list-item/native_posix.keymap @@ -0,0 +1,21 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&caps_word { + continue-list = ; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/events.patterns b/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/events.patterns new file mode 100644 index 00000000..dd4d3d3f --- /dev/null +++ b/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/events.patterns @@ -0,0 +1,4 @@ +s/.*hid_listener_keycode_//p +s/.*hid_implicit_modifiers_//p +s/.*caps_word_enhance_usage/enhance_usage/p +s/.*caps_word_is_caps_includelist/caps_includelist/p \ No newline at end of file diff --git a/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/keycode_events.snapshot b/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/keycode_events.snapshot new file mode 100644 index 00000000..23ddbe1b --- /dev/null +++ b/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/keycode_events.snapshot @@ -0,0 +1,14 @@ +enhance_usage: Enhancing usage 0x04 with modifiers: 0x02 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x02 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +pressed: usage_page 0x07 keycode 0x23 implicit_mods 0x00 explicit_mods 0x00 +press: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x23 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +enhance_usage: Enhancing usage 0x04 with modifiers: 0x02 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x02 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 diff --git a/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/native_posix.keymap b/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/native_posix.keymap new file mode 100644 index 00000000..40a4d4a9 --- /dev/null +++ b/app/tests/caps-word/continue-with-non-modified-numeric-usage-id/native_posix.keymap @@ -0,0 +1,21 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&caps_word { + continue-list = ; +}; + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/events.patterns b/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/events.patterns new file mode 100644 index 00000000..fa75ab0c --- /dev/null +++ b/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode_//p +s/.*hid_implicit_modifiers_//p +s/.*caps_word_enhance_usage/enhance_usage/p \ No newline at end of file diff --git a/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/keycode_events.snapshot b/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/keycode_events.snapshot new file mode 100644 index 00000000..eb24c4bb --- /dev/null +++ b/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/keycode_events.snapshot @@ -0,0 +1,13 @@ +enhance_usage: Enhancing usage 0x04 with modifiers: 0x02 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x02 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +pressed: usage_page 0x07 keycode 0x2d implicit_mods 0x00 explicit_mods 0x00 +press: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x2d implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +press: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 diff --git a/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/native_posix.keymap b/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/native_posix.keymap new file mode 100644 index 00000000..4219e354 --- /dev/null +++ b/app/tests/caps-word/deactivate-by-non-alpha-non-continuation/native_posix.keymap @@ -0,0 +1,17 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(1,1,10) + ZMK_MOCK_RELEASE(1,1,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/app/tests/caps-word/deactivate-by-second-press/events.patterns b/app/tests/caps-word/deactivate-by-second-press/events.patterns new file mode 100644 index 00000000..fa75ab0c --- /dev/null +++ b/app/tests/caps-word/deactivate-by-second-press/events.patterns @@ -0,0 +1,3 @@ +s/.*hid_listener_keycode_//p +s/.*hid_implicit_modifiers_//p +s/.*caps_word_enhance_usage/enhance_usage/p \ No newline at end of file diff --git a/app/tests/caps-word/deactivate-by-second-press/keycode_events.snapshot b/app/tests/caps-word/deactivate-by-second-press/keycode_events.snapshot new file mode 100644 index 00000000..5181f75b --- /dev/null +++ b/app/tests/caps-word/deactivate-by-second-press/keycode_events.snapshot @@ -0,0 +1,9 @@ +enhance_usage: Enhancing usage 0x04 with modifiers: 0x02 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x02 explicit_mods 0x00 +press: Modifiers set to 0x02 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 +pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +press: Modifiers set to 0x00 +released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00 +release: Modifiers set to 0x00 diff --git a/app/tests/caps-word/deactivate-by-second-press/native_posix.keymap b/app/tests/caps-word/deactivate-by-second-press/native_posix.keymap new file mode 100644 index 00000000..05f13fed --- /dev/null +++ b/app/tests/caps-word/deactivate-by-second-press/native_posix.keymap @@ -0,0 +1,17 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_PRESS(0,1,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; \ No newline at end of file diff --git a/docs/docs/behaviors/caps-word.md b/docs/docs/behaviors/caps-word.md new file mode 100644 index 00000000..ee493741 --- /dev/null +++ b/docs/docs/behaviors/caps-word.md @@ -0,0 +1,74 @@ +--- +title: Caps Word Behavior +sidebar_label: Caps Word +--- + +## Summary + +The caps word behavior behaves similar to a caps lock, but will automatically deactivate when one of the configured "break keycodes" is pressed, or if the caps word key is pressed again. For smaller keyboards, using [mod-taps](/docs/behaviors/mod-tap), this can help avoid repeated alternating holds when typing words in all caps. + +The modifiers are applied only to to the alphabetic (`A` to `Z`) keycodes, to avoid automatically appliying them to numeric values, etc. + +### Behavior Binding + +- Reference: `&caps_word` + +Example: + +``` +&caps_word +``` + +### Configuration + +#### Continue List + +By default, the caps word will remain active when any alphanumeric character or the underscore (`UNDERSCORE`) characters are pressed. Any other keycode sent, +will turn off caps word. If you would like to override this, you can set a new array of keys in the `continue-list` property in your keymap: + +``` +&caps_word { + continue-list = ; +}; + +/ { + keymap { + ... + }; +}; +``` + +#### Applied Modifier(s) + +In addition, if you would like _multiple_ modifiers, instead of just `MOD_LSFT`, you can override the `mods` property: + +``` +&caps_word { + mods = ; +}; + +/ { + keymap { + ... + }; +}; +``` + +### Multiple Caps Breaks + +If you want to use multiple caps breaks with different codes to break the caps, you can add additional caps words instances to use in your keymap: + +``` +/ { + prog_caps: behavior_prog_caps_word { + compatible = "zmk,behavior-caps-word"; + label = "PROG_CAPS"; + #binding-cells = <0>; + continue-list = ; + }; + + keymap { + ... + }; +}; +``` diff --git a/docs/sidebars.js b/docs/sidebars.js index 04389695..38256219 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -27,6 +27,7 @@ module.exports = { "behaviors/mod-morph", "behaviors/sticky-key", "behaviors/sticky-layer", + "behaviors/caps-word", "behaviors/reset", "behaviors/bluetooth", "behaviors/outputs", From 0b4432161338368dc4ead0aae85332521c896c3e Mon Sep 17 00:00:00 2001 From: Nick Winans Date: Sun, 28 Nov 2021 22:58:17 -0600 Subject: [PATCH 16/46] fix(shields): Fix typo on Quefrency .zmk.yml --- app/boards/shields/quefrency/quefrency.zmk.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/boards/shields/quefrency/quefrency.zmk.yml b/app/boards/shields/quefrency/quefrency.zmk.yml index f741a702..e70ae68e 100644 --- a/app/boards/shields/quefrency/quefrency.zmk.yml +++ b/app/boards/shields/quefrency/quefrency.zmk.yml @@ -8,5 +8,5 @@ features: - keys - encoder siblings: - - quenfrency_left - - quenfrency_right + - quefrency_left + - quefrency_right From b9a35c6ae7e86de637a96bd9f76b362915f309a0 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Sun, 28 Nov 2021 21:49:59 -0800 Subject: [PATCH 17/46] fix(keymaps): Locate shared conf and overlay for split boards. --- app/cmake/zmk_config.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/cmake/zmk_config.cmake b/app/cmake/zmk_config.cmake index dec31104..c8aa1a00 100644 --- a/app/cmake/zmk_config.cmake +++ b/app/cmake/zmk_config.cmake @@ -105,8 +105,10 @@ if (ZMK_CONFIG) endif() # TODO: Board revisions? + list(APPEND overlay_candidates "${ZMK_CONFIG}/${BOARD_DIR_NAME}.overlay") list(APPEND overlay_candidates "${ZMK_CONFIG}/${BOARD}.overlay") list(APPEND overlay_candidates "${ZMK_CONFIG}/default.overlay") + list(APPEND config_candidates "${ZMK_CONFIG}/${BOARD_DIR_NAME}.conf") list(APPEND config_candidates "${ZMK_CONFIG}/${BOARD}.conf") list(APPEND config_candidates "${ZMK_CONFIG}/default.conf") From 66f90dae3a46095330ef057c413baffbb56ce2fa Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Tue, 30 Nov 2021 04:39:46 +1100 Subject: [PATCH 18/46] feat(shield) Add Chalice support (#1022) * add chalice * add split bs transform * Update app/boards/shields/chalice/chalice.zmk.yml Co-authored-by: Nick Winans Co-authored-by: Nick Winans --- app/boards/shields/chalice/Kconfig.defconfig | 9 +++ app/boards/shields/chalice/Kconfig.shield | 5 ++ .../shields/chalice/boards/nice_nano.overlay | 28 +++++++ .../chalice/boards/nice_nano_v2.overlay | 28 +++++++ app/boards/shields/chalice/chalice.conf | 3 + app/boards/shields/chalice/chalice.keymap | 39 ++++++++++ app/boards/shields/chalice/chalice.overlay | 73 +++++++++++++++++++ app/boards/shields/chalice/chalice.zmk.yml | 9 +++ 8 files changed, 194 insertions(+) create mode 100644 app/boards/shields/chalice/Kconfig.defconfig create mode 100644 app/boards/shields/chalice/Kconfig.shield create mode 100644 app/boards/shields/chalice/boards/nice_nano.overlay create mode 100644 app/boards/shields/chalice/boards/nice_nano_v2.overlay create mode 100644 app/boards/shields/chalice/chalice.conf create mode 100644 app/boards/shields/chalice/chalice.keymap create mode 100644 app/boards/shields/chalice/chalice.overlay create mode 100644 app/boards/shields/chalice/chalice.zmk.yml diff --git a/app/boards/shields/chalice/Kconfig.defconfig b/app/boards/shields/chalice/Kconfig.defconfig new file mode 100644 index 00000000..9987a79a --- /dev/null +++ b/app/boards/shields/chalice/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_CHALICE + +config ZMK_KEYBOARD_NAME + default "Chalice" + +endif diff --git a/app/boards/shields/chalice/Kconfig.shield b/app/boards/shields/chalice/Kconfig.shield new file mode 100644 index 00000000..bd03bf76 --- /dev/null +++ b/app/boards/shields/chalice/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_CHALICE + def_bool $(shields_list_contains,chalice) diff --git a/app/boards/shields/chalice/boards/nice_nano.overlay b/app/boards/shields/chalice/boards/nice_nano.overlay new file mode 100644 index 00000000..21e28515 --- /dev/null +++ b/app/boards/shields/chalice/boards/nice_nano.overlay @@ -0,0 +1,28 @@ +&spi1 { + compatible = "nordic,nrf-spim"; + status = "okay"; + mosi-pin = <6>; + // Unused pins, needed for SPI definition, but not used by the ws2812 driver itself. + sck-pin = <5>; + miso-pin = <7>; + + led_strip: ws2812@0 { + compatible = "worldsemi,ws2812-spi"; + label = "WS2812"; + + /* SPI */ + reg = <0>; /* ignored, but necessary for SPI bindings */ + spi-max-frequency = <4000000>; + + /* WS2812 */ + chain-length = <14>; /* arbitrary; change at will */ + spi-one-frame = <0x70>; + spi-zero-frame = <0x40>; + }; +}; + +/ { + chosen { + zmk,underglow = &led_strip; + }; +}; diff --git a/app/boards/shields/chalice/boards/nice_nano_v2.overlay b/app/boards/shields/chalice/boards/nice_nano_v2.overlay new file mode 100644 index 00000000..21e28515 --- /dev/null +++ b/app/boards/shields/chalice/boards/nice_nano_v2.overlay @@ -0,0 +1,28 @@ +&spi1 { + compatible = "nordic,nrf-spim"; + status = "okay"; + mosi-pin = <6>; + // Unused pins, needed for SPI definition, but not used by the ws2812 driver itself. + sck-pin = <5>; + miso-pin = <7>; + + led_strip: ws2812@0 { + compatible = "worldsemi,ws2812-spi"; + label = "WS2812"; + + /* SPI */ + reg = <0>; /* ignored, but necessary for SPI bindings */ + spi-max-frequency = <4000000>; + + /* WS2812 */ + chain-length = <14>; /* arbitrary; change at will */ + spi-one-frame = <0x70>; + spi-zero-frame = <0x40>; + }; +}; + +/ { + chosen { + zmk,underglow = &led_strip; + }; +}; diff --git a/app/boards/shields/chalice/chalice.conf b/app/boards/shields/chalice/chalice.conf new file mode 100644 index 00000000..da642256 --- /dev/null +++ b/app/boards/shields/chalice/chalice.conf @@ -0,0 +1,3 @@ +# Uncomment the following lines to enable RGB underglow +# CONFIG_ZMK_RGB_UNDERGLOW=y +# CONFIG_WS2812_STRIP=y \ No newline at end of file diff --git a/app/boards/shields/chalice/chalice.keymap b/app/boards/shields/chalice/chalice.keymap new file mode 100644 index 00000000..cba93d03 --- /dev/null +++ b/app/boards/shields/chalice/chalice.keymap @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { + + bindings = < + &kp ESC &kp GRAVE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC + &kp INSERT &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH + &kp DELETE &kp CAPS &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp ENTER + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH &kp RSHFT &kp UP + &kp LCTRL &kp LALT &kp SPACE &mo 1 &kp SPACE &kp RALT &kp RCTRL &kp LEFT &kp DOWN &kp RIGHT + >; + }; + + function_layer { + + bindings = < + &bootloader &out OUT_TOG &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans + &trans &bt BT_CLR &rgb_ug RGB_TOG &rgb_ug RGB_HUD &rgb_ug RGB_HUI &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + &trans &bt BT_SEL 0 &rgb_ug RGB_EFF &rgb_ug RGB_SAD &rgb_ug RGB_SAI &trans &trans &trans &trans &trans &trans &trans &trans &trans + &bt BT_SEL 1 &rgb_ug RGB_EFR &rgb_ug RGB_BRD &rgb_ug RGB_BRI &trans &trans &trans &trans &trans &trans &trans &trans &trans &kp PG_UP + &bt BT_SEL 2 &trans &trans &trans &trans &trans &trans &kp HOME &kp PG_DN &kp END + >; + }; + }; +}; diff --git a/app/boards/shields/chalice/chalice.overlay b/app/boards/shields/chalice/chalice.overlay new file mode 100644 index 00000000..34cbd34e --- /dev/null +++ b/app/boards/shields/chalice/chalice.overlay @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <7>; + rows = <10>; + + map = < + RC(0,0) RC(1,0) RC(0,1) RC(1,1) RC(0,2) RC(1,2) RC(0,3) RC(1,3) RC(0,4) RC(1,4) RC(0,5) RC(1,5) RC(0,6) RC(1,6) RC(4,6) + RC(2,0) RC(3,0) RC(2,1) RC(3,1) RC(2,2) RC(3,2) RC(2,3) RC(3,3) RC(2,4) RC(3,4) RC(2,5) RC(3,5) RC(2,6) RC(3,6) RC(5,6) + RC(4,0) RC(5,0) RC(4,1) RC(5,1) RC(4,2) RC(5,2) RC(4,3) RC(5,3) RC(4,4) RC(5,4) RC(4,5) RC(5,5) RC(6,6) RC(7,6) + RC(6,0) RC(7,0) RC(6,1) RC(7,1) RC(6,2) RC(7,2) RC(6,3) RC(7,3) RC(6,4) RC(7,4) RC(6,5) RC(7,5) RC(8,6) RC(9,6) + RC(8,0) RC(9,1) RC(8,2) RC(9,2) RC(8,3) RC(9,3) RC(8,4) RC(9,4) RC(8,5) RC(9,5) + >; + }; + + splitbs_transform: keymap_transform_1 { + compatible = "zmk,matrix-transform"; + columns = <7>; + rows = <10>; + + map = < + RC(0,0) RC(1,0) RC(0,1) RC(1,1) RC(0,2) RC(1,2) RC(0,3) RC(1,3) RC(0,4) RC(1,4) RC(0,5) RC(1,5) RC(0,6) RC(1,6) RC(4,6) RC(8,1) + RC(2,0) RC(3,0) RC(2,1) RC(3,1) RC(2,2) RC(3,2) RC(2,3) RC(3,3) RC(2,4) RC(3,4) RC(2,5) RC(3,5) RC(2,6) RC(3,6) RC(5,6) + RC(4,0) RC(5,0) RC(4,1) RC(5,1) RC(4,2) RC(5,2) RC(4,3) RC(5,3) RC(4,4) RC(5,4) RC(4,5) RC(5,5) RC(6,6) RC(7,6) + RC(6,0) RC(7,0) RC(6,1) RC(7,1) RC(6,2) RC(7,2) RC(6,3) RC(7,3) RC(6,4) RC(7,4) RC(6,5) RC(7,5) RC(8,6) RC(9,6) + RC(8,0) RC(9,1) RC(8,2) RC(9,2) RC(8,3) RC(9,3) RC(8,4) RC(9,4) RC(8,5) RC(9,5) + >; + }; + + + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + + col-gpios + = <&pro_micro 18 GPIO_ACTIVE_HIGH> + , <&pro_micro 5 GPIO_ACTIVE_HIGH> + , <&pro_micro 15 GPIO_ACTIVE_HIGH> + , <&pro_micro 0 GPIO_ACTIVE_HIGH> + , <&pro_micro 7 GPIO_ACTIVE_HIGH> + , <&pro_micro 14 GPIO_ACTIVE_HIGH> + , <&pro_micro 6 GPIO_ACTIVE_HIGH> + ; + + row-gpios + = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 16 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + }; +}; diff --git a/app/boards/shields/chalice/chalice.zmk.yml b/app/boards/shields/chalice/chalice.zmk.yml new file mode 100644 index 00000000..a284dbe5 --- /dev/null +++ b/app/boards/shields/chalice/chalice.zmk.yml @@ -0,0 +1,9 @@ +file_format: "1" +id: chalice +name: Chalice +type: shield +url: https://customkbd.com/products/chalice-pre-order +requires: [pro_micro] +features: + - keys + - underglow From 99c5a8ee6fbda71686130a207e9a7719146be013 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Tue, 23 Nov 2021 14:23:40 +0000 Subject: [PATCH 19/46] feat(boards): Add BT60 Boards --- app/boards/arm/bt60/CMakeLists.txt | 8 + app/boards/arm/bt60/Kconfig | 7 + app/boards/arm/bt60/Kconfig.board | 12 ++ app/boards/arm/bt60/Kconfig.defconfig | 34 +++++ app/boards/arm/bt60/board.cmake | 5 + app/boards/arm/bt60/bt60.dtsi | 128 ++++++++++++++++ app/boards/arm/bt60/bt60_v1.dts | 113 ++++++++++++++ app/boards/arm/bt60/bt60_v1.keymap | 180 +++++++++++++++++++++++ app/boards/arm/bt60/bt60_v1.yaml | 15 ++ app/boards/arm/bt60/bt60_v1.zmk.yml | 12 ++ app/boards/arm/bt60/bt60_v1_defconfig | 24 +++ app/boards/arm/bt60/bt60_v1_hs.dts | 61 ++++++++ app/boards/arm/bt60/bt60_v1_hs.keymap | 37 +++++ app/boards/arm/bt60/bt60_v1_hs.yaml | 15 ++ app/boards/arm/bt60/bt60_v1_hs.zmk.yml | 12 ++ app/boards/arm/bt60/bt60_v1_hs_defconfig | 24 +++ 16 files changed, 687 insertions(+) create mode 100644 app/boards/arm/bt60/CMakeLists.txt create mode 100644 app/boards/arm/bt60/Kconfig create mode 100644 app/boards/arm/bt60/Kconfig.board create mode 100644 app/boards/arm/bt60/Kconfig.defconfig create mode 100644 app/boards/arm/bt60/board.cmake create mode 100644 app/boards/arm/bt60/bt60.dtsi create mode 100644 app/boards/arm/bt60/bt60_v1.dts create mode 100644 app/boards/arm/bt60/bt60_v1.keymap create mode 100644 app/boards/arm/bt60/bt60_v1.yaml create mode 100644 app/boards/arm/bt60/bt60_v1.zmk.yml create mode 100644 app/boards/arm/bt60/bt60_v1_defconfig create mode 100644 app/boards/arm/bt60/bt60_v1_hs.dts create mode 100644 app/boards/arm/bt60/bt60_v1_hs.keymap create mode 100644 app/boards/arm/bt60/bt60_v1_hs.yaml create mode 100644 app/boards/arm/bt60/bt60_v1_hs.zmk.yml create mode 100644 app/boards/arm/bt60/bt60_v1_hs_defconfig diff --git a/app/boards/arm/bt60/CMakeLists.txt b/app/boards/arm/bt60/CMakeLists.txt new file mode 100644 index 00000000..00952c30 --- /dev/null +++ b/app/boards/arm/bt60/CMakeLists.txt @@ -0,0 +1,8 @@ +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/../tools/uf2/utils/uf2conv.py + -c + -b 0x26000 + -f 0xADA52840 + -o ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.uf2 + ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin +) diff --git a/app/boards/arm/bt60/Kconfig b/app/boards/arm/bt60/Kconfig new file mode 100644 index 00000000..359e237d --- /dev/null +++ b/app/boards/arm/bt60/Kconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: MIT + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on (BOARD_BT60_V1_HS || BOARD_BT60_V1) diff --git a/app/boards/arm/bt60/Kconfig.board b/app/boards/arm/bt60/Kconfig.board new file mode 100644 index 00000000..0f0a9c6e --- /dev/null +++ b/app/boards/arm/bt60/Kconfig.board @@ -0,0 +1,12 @@ +# BT60 board configuration + +# Copyright (c) 2021 Polarity Works +# SPDX-License-Identifier: MIT + +config BOARD_BT60_V1 + bool "bt60" + depends on SOC_NRF52840_QIAA + +config BOARD_BT60_V1_HS + bool "bt60 hotswap" + depends on SOC_NRF52840_QIAA diff --git a/app/boards/arm/bt60/Kconfig.defconfig b/app/boards/arm/bt60/Kconfig.defconfig new file mode 100644 index 00000000..7e7ab124 --- /dev/null +++ b/app/boards/arm/bt60/Kconfig.defconfig @@ -0,0 +1,34 @@ +# Copyright (c) 2021 Polarity Works +# SPDX-License-Identifier: MIT + +if BOARD_BT60_V1_HS || BOARD_BT60_V1 + +config BOARD + default "bt60" + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config BT_CTLR + default BT + +config ZMK_BLE + default y + +config ZMK_USB + default y + +config ZMK_BATTERY_VOLTAGE_DIVIDER + default y + +config ZMK_KEYBOARD_NAME + default "BT60" + +endif # BOARD_BT60 diff --git a/app/boards/arm/bt60/board.cmake b/app/boards/arm/bt60/board.cmake new file mode 100644 index 00000000..fa847d50 --- /dev/null +++ b/app/boards/arm/bt60/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: MIT + +board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/blackmagicprobe.board.cmake) +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/app/boards/arm/bt60/bt60.dtsi b/app/boards/arm/bt60/bt60.dtsi new file mode 100644 index 00000000..48e4128b --- /dev/null +++ b/app/boards/arm/bt60/bt60.dtsi @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2021 Polarity Works +* +* SPDX-License-Identifier: MIT +*/ + +/dts-v1/; +#include +#include + +/ { + model = "BT60"; + compatible = "bt60"; + + chosen { + zephyr,code-partition = &code_partition; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&left_encoder>; + }; + + + +left_encoder: encoder_left { + compatible = "alps,ec11"; + label = "LEFT_ENCODER"; + a-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + b-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + resolution = <4>; + status = "okay"; + }; + + + leds { + compatible = "gpio-leds"; + blue_led: led_0 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; + + vbatt { + compatible = "zmk,battery-voltage-divider"; + label = "BATTERY"; + io-channels = <&adc 2>; + output-ohms = <2000000>; + full-ohms = <(2000000 + 806000)>; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&i2c0 { + compatible = "nordic,nrf-twi"; + sda-pin = <17>; + scl-pin = <20>; +}; + +&uart0 { + compatible = "nordic,nrf-uarte"; + tx-pin = <6>; + rx-pin = <8>; +}; + +&usbd { + status = "okay"; +}; + + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + sd_partition: partition@0 { + label = "softdevice"; + reg = <0x00000000 0x00026000>; + }; + code_partition: partition@26000 { + label = "code_partition"; + reg = <0x00026000 0x000c6000>; + }; + + /* + * 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@ec000 { + label = "storage"; + reg = <0x000ec000 0x00008000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; + }; + }; +}; diff --git a/app/boards/arm/bt60/bt60_v1.dts b/app/boards/arm/bt60/bt60_v1.dts new file mode 100644 index 00000000..83da2c07 --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1.dts @@ -0,0 +1,113 @@ +/* +* Copyright (c) 2021 Polarity Works +* +* SPDX-License-Identifier: MIT +*/ + +/dts-v1/; +#include "bt60.dtsi" + + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &ansi_transform; + }; + + ansi_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <15>; + rows = <5>; + 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(0,12) RC(0,13) + 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(1,12) RC(1,13) + 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(2,13) + RC(3,0) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,13) + RC(4,0) RC(4,1) RC(4,2) RC(4,6) RC(4,10) RC(4,11) RC(4,12) RC(4,13) RC(4,14) + >; + }; + + hhkb_transform: keymap_transform_1 { + compatible = "zmk,matrix-transform"; + columns = <15>; + rows = <5>; + 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(0,12) RC(0,13) RC(0,14) + 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(1,12) RC(1,13) + 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(2,13) + RC(3,0) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,14) + RC(4,0) RC(4,1) RC(4,2) RC(4,6) RC(4,10) RC(4,11) RC(4,12) RC(4,13) + >; + }; + + iso_transform: keymap_transform_2 { + compatible = "zmk,matrix-transform"; + columns = <15>; + rows = <5>; + 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(0,12) RC(0,13) + 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(1,12) + 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(2,12) RC(2,13) + RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) + RC(4,0) RC(4,1) RC(4,2) RC(4,6) RC(4,10) RC(4,11) RC(4,12) RC(4,13) + >; + }; + + all_1u_transform: keymap_transform_3 { + compatible = "zmk,matrix-transform"; + columns = <15>; + rows = <5>; + 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(0,12) RC(0,13) + 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(1,12) RC(1,13) + 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(2,13) + RC(3,0) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,13) RC(3,14) + RC(4,0) RC(4,1) RC(4,2) RC(4,6) RC(4,10) RC(4,11) RC(4,12) RC(4,13) RC(4,14) + >; + }; + + split_transform: keymap_transform_4 { + compatible = "zmk,matrix-transform"; + columns = <15>; + rows = <5>; + 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(0,12) RC(0,13) RC(0,14) + 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(1,12) RC(1,13) + 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(2,13) + RC(3,0) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,14) + RC(4,0) RC(4,1) RC(4,2) RC(4,6) RC(4,10) RC(4,11) RC(4,12) RC(4,13) + >; + }; + + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + + col-gpios + = <&gpio1 13 GPIO_ACTIVE_HIGH> + , <&gpio1 10 GPIO_ACTIVE_HIGH> + , <&gpio1 11 GPIO_ACTIVE_HIGH> + , <&gpio1 15 GPIO_ACTIVE_HIGH> + , <&gpio0 3 GPIO_ACTIVE_HIGH> + , <&gpio0 2 GPIO_ACTIVE_HIGH> + , <&gpio0 28 GPIO_ACTIVE_HIGH> + , <&gpio0 29 GPIO_ACTIVE_HIGH> + , <&gpio0 30 GPIO_ACTIVE_HIGH> + , <&gpio0 31 GPIO_ACTIVE_HIGH> + , <&gpio0 5 GPIO_ACTIVE_HIGH> + , <&gpio0 7 GPIO_ACTIVE_HIGH> + , <&gpio1 9 GPIO_ACTIVE_HIGH> + , <&gpio0 12 GPIO_ACTIVE_HIGH> + , <&gpio0 23 GPIO_ACTIVE_HIGH> + ; + + row-gpios + = <&gpio1 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 22 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + }; +}; diff --git a/app/boards/arm/bt60/bt60_v1.keymap b/app/boards/arm/bt60/bt60_v1.keymap new file mode 100644 index 00000000..0985a605 --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1.keymap @@ -0,0 +1,180 @@ +#include +#include +#include + +#define ANSI true +//#define HHKB true +//#define ISO true +//#define ALL_1U true +//#define SPLIT_BKSP_RSHFT true + + + +/ { + chosen { + #ifdef ANSI + zmk,matrix_transform = &ansi_transform; + #elif defined(HHKB) + zmk,matrix_transform = &hhkb_transform; + #elif defined(ISO) + zmk,matrix_transform = &iso_transform; + #elif defined(ALL_1U) + zmk,matrix_transform = &all_1u_transform; + #else + zmk,matrix_transform = &split_transform; + #endif + }; + + + keymap { + compatible = "zmk,keymap"; + #ifdef ANSI + default_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | BKSP | + // | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | | | + // | CAPS | A | S | D | F | G | H | J | K | L | ; | ' | ENTER | + // | SHIFT | Z | X | C | V | B | N | M | , | . | / | SHIFT | + // | CTL | WIN | ALT | SPACE | ALT | 1 | MENU | CTRL | + // ------------------------------------------------------------------------------------------ + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH + &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT + &kp LCTRL &kp LGUI &kp LALT &kp SPACE &kp RALT &mo 1 &kp K_CMENU &kp RCTRL &bt BT_CLR + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + raise { + // ------------------------------------------------------------------------------------------ + // |GRAVE| F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | DEL | + // | TAB | Q | UP | E | R | T | Y | U | INS | O |PSCRN|SLCK |PSEBRK| RESET | + // | CAPS |LEFT |DOWN |RIGHT| F | G | H | J | K | L |HOME |PGUP | BOOTLOADER | + // | PREV |VOLUP |VOLDN|MUTE | V | B | N | M | , | END | PGDN | NEXT | + // | CTL | WIN | ALT | SPACE | ALT | 1 | MENU | BT_CLR | + // ------------------------------------------------------------------------------------------ + bindings = < + &kp GRAVE &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 DEL + &trans &trans &kp UP &trans &trans &trans &trans &trans &kp INS &trans &kp PSCRN &kp SLCK &kp PAUSE_BREAK &reset + &trans &kp LEFT &kp DOWN &kp RIGHT &trans &trans &trans &trans &trans &trans &kp HOME &kp PG_UP &bootloader + &kp C_PREV &kp C_VOL_DN &kp C_VOL_UP &kp C_MUTE &trans &trans &trans &trans &trans &kp END &kp PG_DN &kp C_NEXT + &bt BT_PRV &bt BT_NXT &trans &trans &trans &trans &trans &bt BT_CLR &trans + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + #elif defined(HHKB) + default_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | \ | ` | + // | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | BSPC | + // | CTRL | A | S | D | F | G | H | J | K | L | ; | ' | ENTER | + // | SHIFT | Z | X | C | V | B | N | M | , | . | / | SHIFT | 1 | + // | CAPS | ALT | WIN | SPACE | WIN | ALT | CTRL | + // ------------------------------------------------------------------------------------------ + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSLH &kp GRAVE + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSPC + &kp LCTRL &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT &mo 1 + &kp LCTRL &kp LALT &kp LGUI &kp SPACE &kp RGUI &kp RALT &kp RCTRL + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + raise { + 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 F12 &kp INS &kp DEL + &kp CLCK &bt BT_PRV &bt BT_NXT &bt BT_CLR &trans &trans &trans &trans &trans &trans &trans &kp UP &trans &reset + &trans &kp C_VOL_DN &kp C_VOL_UP &kp C_MUTE &trans &trans &trans &trans &trans &trans &kp LEFT &kp RIGHT &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &kp DOWN &trans &trans + &trans &trans &trans &bootloader &trans &trans &trans + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + #elif defined(ISO) + default_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | BKSP | + // | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | | + // | CAPS | A | S | D | F | G | H | J | K | L | ; | ' | # | ENTER | + // | SHIFT | | | Z | X | C | V | B | N | M | , | . | / | SHIFT | + // | CTL | WIN | ALT | SPACE | ALT | 1 | MENU | CTRL | + // ------------------------------------------------------------------------------------------ + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT + &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp NON_US_HASH &kp RET + &kp LSHFT &kp NON_US_BSLH &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT + &kp LCTRL &kp LGUI &kp LALT &kp SPACE &kp RALT &mo 1 &kp K_CMENU &kp RCTRL + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + raise { + bindings = < + &kp GRAVE &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 DEL + &reset &trans &kp UP &trans &trans &trans &trans &trans &kp INS &trans &kp PSCRN &kp SLCK &kp PAUSE_BREAK + &trans &kp LEFT &kp DOWN &kp RIGHT &trans &trans &trans &trans &trans &trans &kp HOME &kp PG_UP &trans &bootloader + &kp C_PREV &kp C_VOL_DN &kp C_VOL_UP &kp C_MUTE &trans &trans &trans &trans &trans &trans &kp END &kp PG_DN &kp C_NEXT + &bt BT_PRV &bt BT_NXT &trans &trans &trans &trans &trans &bt BT_CLR + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + #elif defined(ALL_1U) + default_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | BKSP | + // | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | "|" | + // | CAPS | A | S | D | F | G | H | J | K | L | ; | ' | ENTER | + // | SHIFT | Z | X | C | V | B | N | M | , | . | / | SHFT | UP | 1 | + // | CTL | WIN | ALT | SPACE | ALT | CTRL | LEFT | DOWN | RIGHT | + // ------------------------------------------------------------------------------------------ + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH + &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT &kp UP &mo 1 + &kp LCTRL &kp LGUI &kp LALT &kp SPACE &kp RALT &kp RCTRL &kp LEFT &kp DOWN &kp RIGHT + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + raise { + bindings = < + &kp GRAVE &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 F1 + &trans &trans &kp UP &trans &trans &trans &trans &trans &kp INS &trans &kp PSCRN &kp SLCK &kp PAUSE_BREAK &reset + &trans &kp LEFT &kp DOWN &kp RIGHT &trans &trans &trans &trans &trans &trans &kp HOME &kp PG_UP &bootloader + &kp C_PREV &kp C_VOL_DN &kp C_VOL_UP &kp C_MUTE &trans &trans &trans &trans &trans &trans &trans &kp END &kp PG_DN &kp C_NEXT + &bt BT_PRV &bt BT_NXT &trans &trans &trans &trans &trans &trans &bt BT_CLR + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + #else + default_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = |BKSP| DEL | + // | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | \ | + // | CAPS | A | S | D | F | G | H | J | K | L | ; | ' | ENTER | + // | SHIFT | Z | X | C | V | B | N | M | , | . | / | SHIFT | 1 | + // | CTL | WIN | ALT | SPACE | ALT | 1 | CTRL | + // ------------------------------------------------------------------------------------------ + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC &kp DEL + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH + &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT &mo 1 + &kp LCTRL &kp LGUI &kp LALT &kp SPACE &kp RALT &kp RGUI &kp C_MENU &kp RCTRL + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + raise { + bindings = < + &kp GRAVE &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 DEL &trans + &trans &trans &kp UP &trans &trans &trans &trans &trans &kp INS &trans &kp PSCRN &kp SLCK &kp PAUSE_BREAK &reset + &trans &kp LEFT &kp DOWN &kp RIGHT &trans &trans &trans &trans &trans &trans &kp HOME &kp PG_UP &bootloader + &kp C_PREV &kp C_VOL_DN &kp C_VOL_UP &kp C_MUTE &trans &trans &trans &trans &trans &kp END &kp PG_DN &kp C_NEXT &trans + &bt BT_PRV &bt BT_NXT &trans &trans &trans &trans &trans &bt BT_CLR + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + #endif + }; +}; diff --git a/app/boards/arm/bt60/bt60_v1.yaml b/app/boards/arm/bt60/bt60_v1.yaml new file mode 100644 index 00000000..41fd7e40 --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1.yaml @@ -0,0 +1,15 @@ +identifier: bt60_v1 +name: BT60 V1 Soldered +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - usb_device + - ble + - ieee802154 + - pwm + - watchdog diff --git a/app/boards/arm/bt60/bt60_v1.zmk.yml b/app/boards/arm/bt60/bt60_v1.zmk.yml new file mode 100644 index 00000000..9909f191 --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1.zmk.yml @@ -0,0 +1,12 @@ +file_format: "1" +id: bt60_v1 +name: BT60 V1 Soldered +type: board +arch: arm +features: + - keys + - encoder +outputs: + - usb + - ble +url: https://polarityworks.com diff --git a/app/boards/arm/bt60/bt60_v1_defconfig b/app/boards/arm/bt60/bt60_v1_defconfig new file mode 100644 index 00000000..0f13395b --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_BT60_V1=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# enable GPIO +CONFIG_GPIO=y + +# encoder +CONFIG_EC11=y +CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y + +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_MPU_ALLOW_FLASH_WRITE=y +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y diff --git a/app/boards/arm/bt60/bt60_v1_hs.dts b/app/boards/arm/bt60/bt60_v1_hs.dts new file mode 100644 index 00000000..0e686fd9 --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1_hs.dts @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2021 Polarity Works +* +* SPDX-License-Identifier: MIT +*/ + +/dts-v1/; +#include "bt60.dtsi" + + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <15>; + rows = <5>; + 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(0,12) RC(0,13) RC(2,13) + 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(1,12) RC(1,13) + 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(2,12) + RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) 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,5) RC(4,8) RC(4,9) RC(4,10) RC(4,11) + >; + }; + + + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + + col-gpios + = <&gpio1 11 GPIO_ACTIVE_HIGH> + , <&gpio1 10 GPIO_ACTIVE_HIGH> + , <&gpio1 13 GPIO_ACTIVE_HIGH> + , <&gpio1 15 GPIO_ACTIVE_HIGH> + , <&gpio0 3 GPIO_ACTIVE_HIGH> + , <&gpio0 2 GPIO_ACTIVE_HIGH> + , <&gpio0 28 GPIO_ACTIVE_HIGH> + , <&gpio0 29 GPIO_ACTIVE_HIGH> + , <&gpio0 30 GPIO_ACTIVE_HIGH> + , <&gpio0 31 GPIO_ACTIVE_HIGH> + , <&gpio0 5 GPIO_ACTIVE_HIGH> + , <&gpio0 7 GPIO_ACTIVE_HIGH> + , <&gpio1 9 GPIO_ACTIVE_HIGH> + , <&gpio0 12 GPIO_ACTIVE_HIGH> + ; + + row-gpios + = <&gpio1 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 22 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 23 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + }; +}; diff --git a/app/boards/arm/bt60/bt60_v1_hs.keymap b/app/boards/arm/bt60/bt60_v1_hs.keymap new file mode 100644 index 00000000..6e62e1bb --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1_hs.keymap @@ -0,0 +1,37 @@ +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | = | BKSP | DEL + // | TAB | Q | W | E | R | T | Y | U | I | O | P | [ | ] | | | + // | CAPS | A | S | D | F | G | H | J | K | L | ; | ' | ENTER | + // | SHIFT | Z | X | C | V | B | N | M | , | . | / | SHIFT | + // | CTL | WIN | ALT | SPACE | ALT | 1 | MENU | CTRL | + // ------------------------------------------------------------------------------------------ + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC &bt BT_CLR + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH + &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT + &kp LCTRL &kp LGUI &kp LALT &kp SPACE &kp RALT &mo 1 &kp K_CMENU &kp RCTRL + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + raise { + bindings = < + &kp GRAVE &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 DEL &trans + &trans &trans &kp UP &trans &trans &trans &trans &trans &kp INS &trans &kp PSCRN &kp SLCK &kp PAUSE_BREAK &reset + &trans &kp LEFT &kp DOWN &kp RIGHT &trans &trans &trans &trans &trans &trans &kp HOME &kp PG_UP &bootloader + &kp C_PREV &kp C_VOL_DN &kp C_VOL_UP &kp C_MUTE &trans &trans &trans &trans &trans &kp END &kp PG_DN &kp C_NEXT + &bt BT_PRV &bt BT_NXT &trans &trans &trans &trans &trans &bt BT_CLR + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>; + }; + }; +}; diff --git a/app/boards/arm/bt60/bt60_v1_hs.yaml b/app/boards/arm/bt60/bt60_v1_hs.yaml new file mode 100644 index 00000000..5a73753b --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1_hs.yaml @@ -0,0 +1,15 @@ +identifier: bt60_v1_hs +name: BT60 V1 Hotswap +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - adc + - usb_device + - ble + - ieee802154 + - pwm + - watchdog diff --git a/app/boards/arm/bt60/bt60_v1_hs.zmk.yml b/app/boards/arm/bt60/bt60_v1_hs.zmk.yml new file mode 100644 index 00000000..bc9acea4 --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1_hs.zmk.yml @@ -0,0 +1,12 @@ +file_format: "1" +id: bt60_v1_hs +name: BT60 V1 Hotswap +type: board +arch: arm +features: + - keys + - encoder +outputs: + - usb + - ble +url: https://polarityworks.com diff --git a/app/boards/arm/bt60/bt60_v1_hs_defconfig b/app/boards/arm/bt60/bt60_v1_hs_defconfig new file mode 100644 index 00000000..27a22490 --- /dev/null +++ b/app/boards/arm/bt60/bt60_v1_hs_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: MIT + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_BT60_V1_HS=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# enable GPIO +CONFIG_GPIO=y + +# encoder +CONFIG_EC11=y +CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y + +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_MPU_ALLOW_FLASH_WRITE=y +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y From b8774103798fb24b07b8987ccb89ef9b2cb892d4 Mon Sep 17 00:00:00 2001 From: ReFil <31960031+ReFil@users.noreply.github.com> Date: Sun, 28 Nov 2021 22:31:10 +0000 Subject: [PATCH 20/46] fix(boards): BT60 Formatting tweaks --- app/boards/arm/bt60/bt60.dtsi | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/boards/arm/bt60/bt60.dtsi b/app/boards/arm/bt60/bt60.dtsi index 48e4128b..d5109e76 100644 --- a/app/boards/arm/bt60/bt60.dtsi +++ b/app/boards/arm/bt60/bt60.dtsi @@ -10,7 +10,7 @@ / { model = "BT60"; - compatible = "bt60"; + compatible = "polarityworks,bt60"; chosen { zephyr,code-partition = &code_partition; @@ -21,20 +21,20 @@ }; sensors { - compatible = "zmk,keymap-sensors"; - sensors = <&left_encoder>; + compatible = "zmk,keymap-sensors"; + sensors = <&left_encoder>; }; -left_encoder: encoder_left { - compatible = "alps,ec11"; - label = "LEFT_ENCODER"; - a-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; - b-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; - resolution = <4>; - status = "okay"; - }; + left_encoder: encoder_left { + compatible = "alps,ec11"; + label = "LEFT_ENCODER"; + a-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + b-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; + resolution = <4>; + status = "okay"; + }; leds { From c4ad3bc5dcfdf01f86b7538b42b7546487a694b0 Mon Sep 17 00:00:00 2001 From: Pete Johanson Date: Wed, 1 Dec 2021 16:50:50 -0500 Subject: [PATCH 21/46] fix(docs): Make the modifier function examples clearer. * Ensure the list of available modifier functions is clearly shown as macros, not as basic defines. --- docs/docs/codes/modifiers.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/codes/modifiers.mdx b/docs/docs/codes/modifiers.mdx index c573a670..483e34af 100644 --- a/docs/docs/codes/modifiers.mdx +++ b/docs/docs/codes/modifiers.mdx @@ -41,6 +41,6 @@ These functions take the form: `XX(code)` - Some basic codes already include a modifier function in their definition: - `DOLLAR` = `LS(NUMBER_4)` - There are left- and right-handed versions of each modifier (also see table above): - - `LS`, `LC`, `LA`, `LG`, `RS`, `RC`, `RA`, `RG` + - `LS(x)`, `LC(x)`, `LA(x)`, `LG(x)`, `RS(x)`, `RC(x)`, `RA(x)`, `RG(x)` - Modified keys can safely be rolled-over. Modifier functions are released when another key is pressed. - Press `&kp LS(A)`, then press `&kp B`, release `&kp LS(A)` and release `&kp B` results in **Ab**. Only the A is capitalized. From 6ef1e7034ffaed14378e6194152269ed9ed5bdd1 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 29 Nov 2021 19:34:40 +0000 Subject: [PATCH 22/46] fix(hid): Implicit mods on non-key page events * Properly send the KEY usage page report for modifier changes when there are state changes to other usages pages that include implicit modifiers. --- app/src/hid.c | 25 +++++++++++++++++-------- app/src/hid_listener.c | 41 +++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/app/src/hid.c b/app/src/hid.c index b524b09f..d6c63e1d 100644 --- a/app/src/hid.c +++ b/app/src/hid.c @@ -26,14 +26,17 @@ static zmk_mod_flags_t explicit_modifiers = 0; LOG_DBG("Modifiers set to 0x%02X", keyboard_report.body.modifiers); \ } +#define GET_MODIFIERS (keyboard_report.body.modifiers) + zmk_mod_flags_t zmk_hid_get_explicit_mods() { return explicit_modifiers; } int zmk_hid_register_mod(zmk_mod_t modifier) { explicit_modifier_counts[modifier]++; LOG_DBG("Modifier %d count %d", modifier, explicit_modifier_counts[modifier]); WRITE_BIT(explicit_modifiers, modifier, true); + zmk_mod_flags_t current = GET_MODIFIERS; SET_MODIFIERS(explicit_modifiers); - return 0; + return current == GET_MODIFIERS ? 0 : 1; } int zmk_hid_unregister_mod(zmk_mod_t modifier) { @@ -47,26 +50,30 @@ int zmk_hid_unregister_mod(zmk_mod_t modifier) { LOG_DBG("Modifier %d released", modifier); WRITE_BIT(explicit_modifiers, modifier, false); } + zmk_mod_flags_t current = GET_MODIFIERS; SET_MODIFIERS(explicit_modifiers); - return 0; + return current == GET_MODIFIERS ? 0 : 1; } int zmk_hid_register_mods(zmk_mod_flags_t modifiers) { + int ret = 0; for (zmk_mod_t i = 0; i < 8; i++) { if (modifiers & (1 << i)) { - zmk_hid_register_mod(i); + ret += zmk_hid_register_mod(i); } } - return 0; + return ret; } int zmk_hid_unregister_mods(zmk_mod_flags_t modifiers) { + int ret = 0; for (zmk_mod_t i = 0; i < 8; i++) { if (modifiers & (1 << i)) { - zmk_hid_unregister_mod(i); + ret += zmk_hid_unregister_mod(i); } } - return 0; + + return ret; } #if IS_ENABLED(CONFIG_ZMK_HID_REPORT_TYPE_NKRO) @@ -130,13 +137,15 @@ static inline int deselect_keyboard_usage(zmk_key_t usage) { } int zmk_hid_implicit_modifiers_press(zmk_mod_flags_t implicit_modifiers) { + zmk_mod_flags_t current = GET_MODIFIERS; SET_MODIFIERS(explicit_modifiers | implicit_modifiers); - return 0; + return current == GET_MODIFIERS ? 0 : 1; } int zmk_hid_implicit_modifiers_release() { + zmk_mod_flags_t current = GET_MODIFIERS; SET_MODIFIERS(explicit_modifiers); - return 0; + return current == GET_MODIFIERS ? 0 : 1; } int zmk_hid_keyboard_press(zmk_key_t code) { diff --git a/app/src/hid_listener.c b/app/src/hid_listener.c index d582c169..c0a82c34 100644 --- a/app/src/hid_listener.c +++ b/app/src/hid_listener.c @@ -17,56 +17,77 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include static int hid_listener_keycode_pressed(const struct zmk_keycode_state_changed *ev) { - int err; + int err, explicit_mods_changed, implicit_mods_changed; + LOG_DBG("usage_page 0x%02X keycode 0x%02X implicit_mods 0x%02X explicit_mods 0x%02X", ev->usage_page, ev->keycode, ev->implicit_modifiers, ev->explicit_modifiers); switch (ev->usage_page) { case HID_USAGE_KEY: err = zmk_hid_keyboard_press(ev->keycode); - if (err) { + if (err < 0) { LOG_ERR("Unable to press keycode"); return err; } break; case HID_USAGE_CONSUMER: err = zmk_hid_consumer_press(ev->keycode); - if (err) { + if (err < 0) { LOG_ERR("Unable to press keycode"); return err; } break; } - zmk_hid_register_mods(ev->explicit_modifiers); - zmk_hid_implicit_modifiers_press(ev->implicit_modifiers); + explicit_mods_changed = zmk_hid_register_mods(ev->explicit_modifiers); + implicit_mods_changed = zmk_hid_implicit_modifiers_press(ev->implicit_modifiers); + if (ev->usage_page != HID_USAGE_KEY && + (explicit_mods_changed > 0 || implicit_mods_changed > 0)) { + err = zmk_endpoints_send_report(HID_USAGE_KEY); + if (err < 0) { + LOG_ERR("Failed to send key report for changed mofifiers for consumer page event (%d)", + err); + } + } + return zmk_endpoints_send_report(ev->usage_page); } static int hid_listener_keycode_released(const struct zmk_keycode_state_changed *ev) { - int err; + int err, explicit_mods_changed, implicit_mods_changed; + LOG_DBG("usage_page 0x%02X keycode 0x%02X implicit_mods 0x%02X explicit_mods 0x%02X", ev->usage_page, ev->keycode, ev->implicit_modifiers, ev->explicit_modifiers); switch (ev->usage_page) { case HID_USAGE_KEY: err = zmk_hid_keyboard_release(ev->keycode); - if (err) { + if (err < 0) { LOG_ERR("Unable to release keycode"); return err; } break; case HID_USAGE_CONSUMER: err = zmk_hid_consumer_release(ev->keycode); - if (err) { + if (err < 0) { LOG_ERR("Unable to release keycode"); return err; } } - zmk_hid_unregister_mods(ev->explicit_modifiers); + + explicit_mods_changed = zmk_hid_unregister_mods(ev->explicit_modifiers); // 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(); + implicit_mods_changed = zmk_hid_implicit_modifiers_release(); + ; + if (ev->usage_page != HID_USAGE_KEY && + (explicit_mods_changed > 0 || implicit_mods_changed > 0)) { + err = zmk_endpoints_send_report(HID_USAGE_KEY); + if (err < 0) { + LOG_ERR("Failed to send key report for changed mofifiers for consumer page event (%d)", + err); + } + } return zmk_endpoints_send_report(ev->usage_page); } From 9148ffd05d409639a7d4088bc78bc73008316a7f Mon Sep 17 00:00:00 2001 From: toddmok <91770979+toddmok@users.noreply.github.com> Date: Thu, 2 Dec 2021 12:51:27 -0600 Subject: [PATCH 23/46] feat(shields) Add Redox Shield Support (#1002) * Add redox shield support * typo * Pull request fixes * requested changes add underglow, add copyright, remove display * remove because of no display * comment fix * bt clear --- app/boards/shields/redox/Kconfig.defconfig | 18 ++++ app/boards/shields/redox/Kconfig.shield | 7 ++ .../shields/redox/boards/nice_nano.overlay | 34 ++++++++ app/boards/shields/redox/redox.conf | 3 + app/boards/shields/redox/redox.dtsi | 48 +++++++++++ app/boards/shields/redox/redox.keymap | 82 +++++++++++++++++++ app/boards/shields/redox/redox.zmk.yml | 12 +++ app/boards/shields/redox/redox_left.overlay | 19 +++++ app/boards/shields/redox/redox_right.overlay | 23 ++++++ 9 files changed, 246 insertions(+) create mode 100644 app/boards/shields/redox/Kconfig.defconfig create mode 100644 app/boards/shields/redox/Kconfig.shield create mode 100644 app/boards/shields/redox/boards/nice_nano.overlay create mode 100644 app/boards/shields/redox/redox.conf create mode 100644 app/boards/shields/redox/redox.dtsi create mode 100644 app/boards/shields/redox/redox.keymap create mode 100644 app/boards/shields/redox/redox.zmk.yml create mode 100644 app/boards/shields/redox/redox_left.overlay create mode 100644 app/boards/shields/redox/redox_right.overlay diff --git a/app/boards/shields/redox/Kconfig.defconfig b/app/boards/shields/redox/Kconfig.defconfig new file mode 100644 index 00000000..06554def --- /dev/null +++ b/app/boards/shields/redox/Kconfig.defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT +if SHIELD_REDOX_LEFT + +config ZMK_KEYBOARD_NAME + default "Redox" + +config ZMK_SPLIT_BLE_ROLE_CENTRAL + default y + +endif + +if SHIELD_REDOX_LEFT || SHIELD_REDOX_RIGHT + +config ZMK_SPLIT + default y + +endif \ No newline at end of file diff --git a/app/boards/shields/redox/Kconfig.shield b/app/boards/shields/redox/Kconfig.shield new file mode 100644 index 00000000..2df91c11 --- /dev/null +++ b/app/boards/shields/redox/Kconfig.shield @@ -0,0 +1,7 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT +config SHIELD_REDOX_LEFT + def_bool $(shields_list_contains,redox_left) + +config SHIELD_REDOX_RIGHT + def_bool $(shields_list_contains,redox_right) diff --git a/app/boards/shields/redox/boards/nice_nano.overlay b/app/boards/shields/redox/boards/nice_nano.overlay new file mode 100644 index 00000000..b81ba195 --- /dev/null +++ b/app/boards/shields/redox/boards/nice_nano.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +&spi1 { + compatible = "nordic,nrf-spim"; + status = "okay"; + mosi-pin = <6>; + // Unused pins, needed for SPI definition, but not used by the ws2812 driver itself. + sck-pin = <5>; + miso-pin = <7>; + + led_strip: ws2812@0 { + compatible = "worldsemi,ws2812-spi"; + label = "WS2812"; + + /* SPI */ + reg = <0>; /* ignored, but necessary for SPI bindings */ + spi-max-frequency = <4000000>; + + /* WS2812 */ + chain-length = <5>; /* number of LEDs */ + spi-one-frame = <0x70>; + spi-zero-frame = <0x40>; + }; +}; + +/ { + chosen { + zmk,underglow = &led_strip; + }; +}; diff --git a/app/boards/shields/redox/redox.conf b/app/boards/shields/redox/redox.conf new file mode 100644 index 00000000..a1837ef9 --- /dev/null +++ b/app/boards/shields/redox/redox.conf @@ -0,0 +1,3 @@ +# Uncomment the following lines to enable the Redox RGB Underglow +# CONFIG_ZMK_RGB_UNDERGLOW=y +# CONFIG_WS2812_STRIP=y \ No newline at end of file diff --git a/app/boards/shields/redox/redox.dtsi b/app/boards/shields/redox/redox.dtsi new file mode 100644 index 00000000..4825a39f --- /dev/null +++ b/app/boards/shields/redox/redox.dtsi @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <14>; + rows = <5>; +// | SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | | SW6 | SW5 | SW4 | SW3 | SW2 | SW1 | +// | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | SW13 | | SW13 | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | +// | SW14 | SW15 | SW16 | SW17 | SW18 | SW19 | SW20 | | SW20 | SW19 | SW18 | SW17 | SW16 | SW15 | SW14 | +// | SW21 | SW22 | SW23 | SW24 | SW25 | SW26 | SW27 | SW28 | | SW28 | SW27 | SW26 | SW25 | SW24 | SW23 | SW22 | SW21 | +// | SW29 | SW30 | SW31 | SW32 | SW33 | SW34 | SW35 | | SW35 | SW34 | SW33 | SW32 | SW31 | SW30 | SW29 | + map = < +RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,8) RC(0,9) RC(0,10) RC(0,11) RC(0,12) RC(0,13) +RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(0,6) RC(0,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11) RC(1,12) RC(1,13) +RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(1,6) RC(1,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11) RC(2,12) RC(2,13) +RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(2,6) RC(3,6) RC(3,7) RC(2,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,13) +RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) RC(4,8) RC(4,9) RC(4,10) RC(4,11) RC(4,12) RC(4,13) + >; + }; + + kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + + diode-direction = "col2row"; + row-gpios + = <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + + }; + +}; diff --git a/app/boards/shields/redox/redox.keymap b/app/boards/shields/redox/redox.keymap new file mode 100644 index 00000000..aed22c42 --- /dev/null +++ b/app/boards/shields/redox/redox.keymap @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap" ; + + default_layer { +// -------------------------------------------------------------------------------------------------------------------------------- +// | ESC | 1 | 2 | 3 | 4 | 5 | --- | 6 | 7 | 8 | 9 | 0 | BKSP | +// | 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 | PG_UP | PG_DOWN | --- | HOME | END | N | M | , | . | / | SHFT(RET) | +// | CRTL | ALT | GUI | LOWER | GUI | LOWER | SPACE | --- | DEL | SPACE | RAISE | LEFT | DOWN | UP | RIGHT | + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp BSPC + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp LPAR &kp RPAR &kp Y &kp U &kp I &kp O &kp P &kp MINUS + &kp LCTRL &kp A &kp S &kp D &kp F &kp G &kp LBKT &kp RBKT &kp H &kp J &kp K &kp L &kp SEMI &kp SQT + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp PG_UP &kp PG_DN &kp HOME &kp END &kp N &kp M &kp COMMA &kp DOT &kp FSLH &mt RSHFT RET + &kp LCTRL &kp LALT &kp LGUI &mo 3 &kp LGUI &mo 1 &kp SPACE &kp DEL &kp SPACE &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT + >; + + }; + + lower_layer { +// -------------------------------------------------------------------------------------------------------------------------- +// | ESC | 1 | 2 | 3 | 4 | 5 | --- | 6 | 7 | 8 | 9 | 0 | DEL | +// | ESC | 1 | 2 | 3 | 4 | 5 | ( | --- | ) | 6 | 7 | 8 | 9 | 0 | DEL | +// | CTRL | - | = | [ | ] | \ | [ | --- | ] | * | 4 | 5 | 6 | + | - | +// | SHIFT | ESC | GUI | COPY | PASTE | | PG_UP | PG_DOWN | --- | HOME | END | \ | 1 | 2 | 3 | RET | RET | +// | CRTL | ALT | GUI | LOWER | GUI | LOWER | SPACE | --- | DEL | 0 | RAISE | LEFT | DOWN | UP | RIGHT | + bindings = < + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &trans &trans &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp DEL + &trans &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH &trans &trans &kp KP_MULTIPLY &kp N4 &kp N5 &kp N6 &kp KP_PLUS &kp KP_MINUS + &trans &kp ESC &kp LGUI &kp LG(C) &kp LG(V) &kp GRAVE &trans &trans &trans &trans &kp KP_DIVIDE &kp N1 &kp N2 &kp N3 &kp RET &kp RET + &trans &trans &trans &trans &trans &trans &trans &trans &kp N0 &mo 3 &trans &trans &trans &trans + >; + }; + + raise_layer { +// ---------------------------------------------------------------------------------------------------------------------------- +// | ESC | 1 | 2 | 3 | 4 | 5 | --- | 6 | 7 | 8 | 9 | 0 | DEL | +// | ESC | ! | @ | # | $ | % | ( | --- | ) | ^ | & | * | ( | ) | DEL | +// | CTRL | _ | + | { | } | "|" | [ | --- | ] | HOME | PGUP | PRSC | UP | ` | ~ | +// | SHIFT | ESC | GUI | ( | ) | | PG_UP | PG_DOWN | --- | HOME | END | END | PGDN | LEFT | DOWN | RIGHT | RET | +// | CRTL | ALT | GUI | LOWER | GUI | LOWER | SPACE | --- | DEL | SPACE | RAISE | LEFT | DOWN | UP | RIGHT | + bindings = < + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + &kp ESC &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &trans &trans &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp DEL + &trans &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE &trans &trans &kp HOME &kp PG_UP &kp PSCRN &kp UP &kp GRAVE &kp TILDE + &trans &kp ESC &kp LGUI &kp LPAR &kp RPAR &kp TILDE &trans &trans &trans &trans &kp END &kp PG_DN &kp LEFT &kp DOWN &kp RIGHT &kp RET + &trans &trans &trans &mo 3 &trans &mo 3 &trans &trans &trans &trans &trans &trans &trans &trans + >; + }; + + adjust_layer { +// ----------------------------------------------------------------------------------------- +// | F1 | F2 | F3 | F4 | F5 | F6 | --- | F7 | F8 | F9 | F10 | F11 | F12 | +// | TAB | | | | | | BOOTL | --- | ) | BT1 | BT2 | BT3 | BT4 | BT5 | OUTPUT TGL | +// | CTRL | MUTE | Vol Dn | Vol Up | Play/Pause | | RESET | --- | ] | F1 | F2 | F3 | F4 | F5 | F6 | +// | SHIFT | PSCRN | PSCRN | CAPS | | | PG_UP | PG_DOWN | --- | HOME | END | F7 | F8 | F9 | F10 | F11 | F12 | +// | CRTL | ALT | GUI | LOWER | GUI | LOWER | SPACE | --- | DEL | SPACE | RAISE | LEFT | DOWN | UP | RIGHT | + bindings = < + &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &trans &none &none &none &none &none &bootloader &bt BT_CLR &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &out OUT_TOG + &trans &kp K_MUTE &kp C_VOL_DN &kp C_VOL_UP &kp C_PLAY_PAUSE &none &reset &trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 + &trans &kp PSCRN &kp PSCRN &kp CLCK &none &none &trans &trans &trans &trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + >; + }; + }; +}; diff --git a/app/boards/shields/redox/redox.zmk.yml b/app/boards/shields/redox/redox.zmk.yml new file mode 100644 index 00000000..fd22971d --- /dev/null +++ b/app/boards/shields/redox/redox.zmk.yml @@ -0,0 +1,12 @@ +file_format: "1" +id: redox +name: Redox +type: shield +url: https://github.com/mattdibi/redox-keyboard +requires: [pro_micro] +features: + - keys + - underglow +siblings: + - redox_left + - redox_right diff --git a/app/boards/shields/redox/redox_left.overlay b/app/boards/shields/redox/redox_left.overlay new file mode 100644 index 00000000..322dca79 --- /dev/null +++ b/app/boards/shields/redox/redox_left.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "redox.dtsi" + +&kscan0 { + col-gpios + = <&pro_micro 20 GPIO_ACTIVE_HIGH> + , <&pro_micro 19 GPIO_ACTIVE_HIGH> + , <&pro_micro 18 GPIO_ACTIVE_HIGH> + , <&pro_micro 15 GPIO_ACTIVE_HIGH> + , <&pro_micro 14 GPIO_ACTIVE_HIGH> + , <&pro_micro 16 GPIO_ACTIVE_HIGH> + , <&pro_micro 10 GPIO_ACTIVE_HIGH> + ; +}; diff --git a/app/boards/shields/redox/redox_right.overlay b/app/boards/shields/redox/redox_right.overlay new file mode 100644 index 00000000..f2dcfed0 --- /dev/null +++ b/app/boards/shields/redox/redox_right.overlay @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "redox.dtsi" + +&default_transform { + col-offset = <7>; +}; + +&kscan0 { + col-gpios + = <&pro_micro 10 GPIO_ACTIVE_HIGH> + , <&pro_micro 16 GPIO_ACTIVE_HIGH> + , <&pro_micro 14 GPIO_ACTIVE_HIGH> + , <&pro_micro 15 GPIO_ACTIVE_HIGH> + , <&pro_micro 18 GPIO_ACTIVE_HIGH> + , <&pro_micro 19 GPIO_ACTIVE_HIGH> + , <&pro_micro 20 GPIO_ACTIVE_HIGH> + ; +}; From a8c7cf4f19ad80eb8e6148f872d3a9584b25befc Mon Sep 17 00:00:00 2001 From: Kyle McCreery Date: Thu, 2 Dec 2021 18:21:35 -0500 Subject: [PATCH 24/46] feat(boards): Add S40NC board definition (#1021) * initial commit * initial commit * Encode, OLED, and RGB Nice Nano support added as well as refining default keymap. * tweaking keymap * Prepared murphpad for PR. Includes adding support for second encoder, OLED, and underglow RGB * Enabled OLED by default. * Initial commit with settings updated to match schematic. * Removing test directories. * removed naked60 config files * Fixed dogbone definitions to be full working for murphpad. * Preparing S40NC for PR * Removed the murphpad test files that were not supposed to be a part of this PR. * Changing licensing to be from The ZMK Contributors. * Changed the licensing in the keymap file to be from The ZMK Contributors * Update s40nc.keymap --- app/boards/arm/s40nc/CMakeLists.txt | 8 ++ app/boards/arm/s40nc/Kconfig.board | 6 ++ app/boards/arm/s40nc/Kconfig.defconfig | 31 ++++++ app/boards/arm/s40nc/README.md | 9 ++ app/boards/arm/s40nc/board.cmake | 7 ++ app/boards/arm/s40nc/s40nc.dts | 139 +++++++++++++++++++++++++ app/boards/arm/s40nc/s40nc.keymap | 58 +++++++++++ app/boards/arm/s40nc/s40nc.yaml | 14 +++ app/boards/arm/s40nc/s40nc.zmk.yml | 11 ++ app/boards/arm/s40nc/s40nc_defconfig | 21 ++++ 10 files changed, 304 insertions(+) create mode 100644 app/boards/arm/s40nc/CMakeLists.txt create mode 100644 app/boards/arm/s40nc/Kconfig.board create mode 100644 app/boards/arm/s40nc/Kconfig.defconfig create mode 100644 app/boards/arm/s40nc/README.md create mode 100644 app/boards/arm/s40nc/board.cmake create mode 100644 app/boards/arm/s40nc/s40nc.dts create mode 100644 app/boards/arm/s40nc/s40nc.keymap create mode 100644 app/boards/arm/s40nc/s40nc.yaml create mode 100644 app/boards/arm/s40nc/s40nc.zmk.yml create mode 100644 app/boards/arm/s40nc/s40nc_defconfig diff --git a/app/boards/arm/s40nc/CMakeLists.txt b/app/boards/arm/s40nc/CMakeLists.txt new file mode 100644 index 00000000..f833ff2e --- /dev/null +++ b/app/boards/arm/s40nc/CMakeLists.txt @@ -0,0 +1,8 @@ +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/../tools/uf2/utils/uf2conv.py + -c + -b 0x1000 + -f 0xADA52840 + -o ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.uf2 + ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin +) diff --git a/app/boards/arm/s40nc/Kconfig.board b/app/boards/arm/s40nc/Kconfig.board new file mode 100644 index 00000000..673e3b24 --- /dev/null +++ b/app/boards/arm/s40nc/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config BOARD_S40NC + bool "S40NC" + depends on SOC_NRF52840_QIAA diff --git a/app/boards/arm/s40nc/Kconfig.defconfig b/app/boards/arm/s40nc/Kconfig.defconfig new file mode 100644 index 00000000..0f407151 --- /dev/null +++ b/app/boards/arm/s40nc/Kconfig.defconfig @@ -0,0 +1,31 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if BOARD_S40NC + +config ZMK_KEYBOARD_NAME + default "S40NC" + +if USB + +config USB_NRFX + default y + +config USB_DEVICE_STACK + default y + +endif # USB + +config BT_CTLR + default BT + +config ZMK_BLE + default y + +config ZMK_USB + default y + +config ZMK_BATTERY_VOLTAGE_DIVIDER + default y + +endif # BOARD_S40NC diff --git a/app/boards/arm/s40nc/README.md b/app/boards/arm/s40nc/README.md new file mode 100644 index 00000000..32db57e9 --- /dev/null +++ b/app/boards/arm/s40nc/README.md @@ -0,0 +1,9 @@ +# S40NC +![S40NC](https://i.imgur.com/fk8587n.jpg) + +Shorty40NoCordy (S40NC) is a limited run 40% bluetooth keyboard originally made and sold by MechWild. + +## Building S40NC ZMK firmware +``` +west build -p -b s40nc +``` diff --git a/app/boards/arm/s40nc/board.cmake b/app/boards/arm/s40nc/board.cmake new file mode 100644 index 00000000..c50b2d9d --- /dev/null +++ b/app/boards/arm/s40nc/board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +set(OPENOCD_NRF5_SUBFAMILY nrf52) +board_runner_args(nrfjprog "--nrf-family=NRF52" "--softreset") +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/app/boards/arm/s40nc/s40nc.dts b/app/boards/arm/s40nc/s40nc.dts new file mode 100644 index 00000000..58e0c2de --- /dev/null +++ b/app/boards/arm/s40nc/s40nc.dts @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/dts-v1/; +#include +#include + +/ { + model = "S40NC"; + compatible = "s40nc"; + + chosen { + zephyr,code-partition = &code_partition; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <12>; + 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(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,11) + RC(2,0) 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,4) RC(3,6) RC(3,8) RC(3,9) RC(3,10) RC(3,11) + >; + }; + + + kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + + diode-direction = "col2row"; + row-gpios + = <&gpio1 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&gpio0 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + col-gpios + = <&gpio1 2 GPIO_ACTIVE_HIGH> + , <&gpio1 1 GPIO_ACTIVE_HIGH> + , <&gpio1 3 GPIO_ACTIVE_HIGH> + , <&gpio1 0 GPIO_ACTIVE_HIGH> + , <&gpio0 22 GPIO_ACTIVE_HIGH> + , <&gpio1 15 GPIO_ACTIVE_HIGH> + , <&gpio0 3 GPIO_ACTIVE_HIGH> + , <&gpio0 2 GPIO_ACTIVE_HIGH> + , <&gpio0 28 GPIO_ACTIVE_HIGH> + , <&gpio0 29 GPIO_ACTIVE_HIGH> + , <&gpio0 30 GPIO_ACTIVE_HIGH> + , <&gpio0 31 GPIO_ACTIVE_HIGH> + ; + }; + + leds { + compatible = "gpio-leds"; + blue_led: led_0 { + gpios = <&gpio0 21 GPIO_ACTIVE_HIGH>; + label = "Blue LED"; + }; + }; + + vbatt { + compatible = "zmk,battery-voltage-divider"; + label = "BATTERY"; + io-channels = <&adc 2>; + output-ohms = <2000000>; + full-ohms = <(2000000 + 820000)>; + }; +}; + +&adc { + status = "okay"; +}; + +&gpiote { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&usbd { + status = "okay"; +}; + +&flash0 { + /* + * For more information, see: + * http://docs.zephyrproject.org/latest/devices/dts/flash_partitions.html + */ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + sd_partition: partition@0 { + label = "mbr"; + reg = <0x00000000 0x00001000>; + }; + + code_partition: partition@1000 { + label = "code_partition"; + reg = <0x00001000 0x000d3000>; + }; + + /* + * The flash starting at 0x000d4000 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@d4000 { + label = "storage"; + reg = <0x000d4000 0x00020000>; + }; + + boot_partition: partition@f4000 { + label = "adafruit_boot"; + reg = <0x000f4000 0x0000c000>; + }; + }; +}; diff --git a/app/boards/arm/s40nc/s40nc.keymap b/app/boards/arm/s40nc/s40nc.keymap new file mode 100644 index 00000000..d7f349d9 --- /dev/null +++ b/app/boards/arm/s40nc/s40nc.keymap @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + +#define DEFAULT 0 +#define LOWER 1 +#define RAISE 2 +#define CONTROL 3 + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { + bindings = < + &kp ESC &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSPC + &mo LOWER &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp ENTER + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp FSLH &kp UP &kp RSHFT + &kp LCTRL &kp LGUI &kp LALT < LOWER SPACE < CONTROL SPACE < RAISE SPACE &kp LEFT &kp DOWN &kp RIGHT + >; + }; + + lower_layer { + bindings = < + &kp GRAVE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp DEL + &kp PSCRN &kp MINUS &kp EQUAL &trans &trans &trans &trans &kp LBKT &kp RBKT &kp SEMI &kp APOS + &trans &trans &trans &trans &trans &trans &trans &kp COMMA &kp DOT &kp PG_UP &kp BSLH + &trans &trans &trans &kp TAB &kp TAB &kp TAB &kp HOME &kp PG_DN &kp END + >; + }; + + raise_layer { + bindings = < + &kp TILDE &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp STAR &kp LPAR &kp RPAR &trans + &kp PSCRN &kp UNDER &kp PLUS &trans &trans &trans &trans &kp LBRC &kp RBRC &kp COLON &kp DQT + &trans &trans &trans &trans &trans &trans &trans &kp LT &kp GT &kp PG_UP &kp PIPE + &trans &trans &trans &kp TAB &kp TAB &kp TAB &kp HOME &kp PG_DN &kp END + >; + }; + + control_layer { + bindings = < + &bt BT_CLR &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp C_PP + &bt BT_SEL 0 &kp F11 &kp F12 &trans &trans &trans &trans &trans &trans &trans &kp K_LOCK + &bt BT_SEL 1 &out OUT_USB &kp CAPS &kp KP_NUM &kp SLCK &trans &trans &kp COMMA &kp DOT &kp K_VOL_UP &kp K_MUTE + &bt BT_SEL 2 &out OUT_BLE &kp PAUSE_BREAK &reset &trans &bootloader &kp C_BRI_DN &kp K_VOL_DN &kp C_BRI_UP + >; + }; + }; +}; + diff --git a/app/boards/arm/s40nc/s40nc.yaml b/app/boards/arm/s40nc/s40nc.yaml new file mode 100644 index 00000000..1fb23ee3 --- /dev/null +++ b/app/boards/arm/s40nc/s40nc.yaml @@ -0,0 +1,14 @@ +identifier: s40nc +name: S40NC +type: mcu +arch: arm +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - usb_device + - ble + - ieee802154 + - pwm + - watchdog diff --git a/app/boards/arm/s40nc/s40nc.zmk.yml b/app/boards/arm/s40nc/s40nc.zmk.yml new file mode 100644 index 00000000..57b30eca --- /dev/null +++ b/app/boards/arm/s40nc/s40nc.zmk.yml @@ -0,0 +1,11 @@ +file_format: "1" +id: s40nc +name: S40NC +type: board +arch: arm +features: + - keys +outputs: + - usb + - ble +url: https://mechwild.com diff --git a/app/boards/arm/s40nc/s40nc_defconfig b/app/boards/arm/s40nc/s40nc_defconfig new file mode 100644 index 00000000..e9bbfc17 --- /dev/null +++ b/app/boards/arm/s40nc/s40nc_defconfig @@ -0,0 +1,21 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_S40NC=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# enable GPIO +CONFIG_GPIO=y + +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_MPU_ALLOW_FLASH_WRITE=y +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_FLASH=y +CONFIG_FLASH_PAGE_LAYOUT=y +CONFIG_FLASH_MAP=y From b23934cf9406ce6b00463cf705b32de455d91983 Mon Sep 17 00:00:00 2001 From: Sam Mohr Date: Fri, 10 Dec 2021 13:20:52 -0500 Subject: [PATCH 25/46] feat(shields): Add Osprette --- app/boards/shields/osprette/Kconfig.defconfig | 9 ++ app/boards/shields/osprette/Kconfig.shield | 5 + app/boards/shields/osprette/osprette.conf | 0 app/boards/shields/osprette/osprette.keymap | 113 ++++++++++++++++++ app/boards/shields/osprette/osprette.overlay | 52 ++++++++ app/boards/shields/osprette/osprette.zmk.yml | 8 ++ 6 files changed, 187 insertions(+) create mode 100644 app/boards/shields/osprette/Kconfig.defconfig create mode 100644 app/boards/shields/osprette/Kconfig.shield create mode 100644 app/boards/shields/osprette/osprette.conf create mode 100644 app/boards/shields/osprette/osprette.keymap create mode 100644 app/boards/shields/osprette/osprette.overlay create mode 100644 app/boards/shields/osprette/osprette.zmk.yml diff --git a/app/boards/shields/osprette/Kconfig.defconfig b/app/boards/shields/osprette/Kconfig.defconfig new file mode 100644 index 00000000..d765b764 --- /dev/null +++ b/app/boards/shields/osprette/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_OSPRETTE + +config ZMK_KEYBOARD_NAME + default "Osprette" + +endif diff --git a/app/boards/shields/osprette/Kconfig.shield b/app/boards/shields/osprette/Kconfig.shield new file mode 100644 index 00000000..1e9cc87b --- /dev/null +++ b/app/boards/shields/osprette/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_OSPRETTE + def_bool $(shields_list_contains,osprette) diff --git a/app/boards/shields/osprette/osprette.conf b/app/boards/shields/osprette/osprette.conf new file mode 100644 index 00000000..e69de29b diff --git a/app/boards/shields/osprette/osprette.keymap b/app/boards/shields/osprette/osprette.keymap new file mode 100644 index 00000000..9c9213b6 --- /dev/null +++ b/app/boards/shields/osprette/osprette.keymap @@ -0,0 +1,113 @@ +/* +* Copyright (c) 2021 The ZMK Contributors +* +* SPDX-License-Identifier: MIT +*/ + +#include +#include +#include + +#define MAIN 0 +#define SYM 1 +#define NAV 2 +#define BT 3 + +&mt { + flavor = "tap-preferred"; + tapping_term_ms = <140>; +}; + +/ { + combos { + compatible = "zmk,combos"; + + combo_esc { + timeout-ms = <100>; + key-positions = <21 22>; + bindings = <&kp ESC>; + }; + + combo_tab { + timeout-ms = <100>; + key-positions = <22 23>; + bindings = <&kp TAB>; + }; + + combo_minus { + timeout-ms = <100>; + key-positions = <26 27>; + bindings = <&kp MINUS>; + }; + + combo_underscore { + timeout-ms = <100>; + key-positions = <26 28>; + bindings = <&kp UNDERSCORE>; + }; + + combo_colon { + timeout-ms = <100>; + key-positions = <7 8>; + bindings = <&kp COLON>; + }; + + combo_semicolon { + timeout-ms = <100>; + key-positions = <6 8>; + bindings = <&kp SEMICOLON>; + }; + + combo_backslash { + timeout-ms = <100>; + key-positions = <27 28>; + bindings = <&kp BSLH>; + }; + + combo_grave { + timeout-ms = <100>; + key-positions = <8 9>; + bindings = <&kp GRAVE>; + }; + }; + + keymap { + compatible = "zmk,keymap"; + + MAIN_layer { + bindings = < + &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O + &kp Q &kp A &kp S &kp D < SYM F &kp G &kp H < SYM J &kp K &kp L &kp SQT &kp P + &mt LSHFT Z &mt LALT X &mt LCTRL C &mt LGUI V &kp B &kp N &mt RGUI M &mt RCTRL COMMA &mt RALT DOT &mt RSHFT FSLH + < BT ENTER < NAV SPACE &sk RSHFT &kp BSPC + >; + }; + + SYM_layer { + bindings = < + &kp N7 &kp N8 &kp N9 &kp STAR &kp DLLR &kp LBRC &kp RBRC &kp HASH + &kp AMPS &kp EXCL &kp N1 &kp N2 &kp N3 &kp EQUAL &kp LT &kp LPAR &kp RPAR &kp GT &kp PIPE &none + &kp CARET &kp N4 &kp N5 &kp N6 &kp PLUS &kp TILDE &kp LBKT &kp RBKT &kp AT &kp PRCNT + &kp DOT &kp N0 &trans &none + >; + }; + + NAV_layer { + bindings = < + &kp C_VOL_DN &kp C_VOL_UP &kp C_NEXT &kp C_PP &none &kp F7 &kp F8 &kp F9 + &kp C_PREV &kp LEFT &kp DOWN &kp UP &kp RIGHT &kp LC(TAB) &kp PSCRN &kp F1 &kp F2 &kp F3 &kp F10 &kp F12 + &kp HOME &kp PG_DN &kp PG_UP &kp END &kp LS(LC(TAB)) &kp CAPS &kp F4 &kp F5 &kp F6 &kp F11 + &none &none &trans &kp DEL + >; + }; + + BT_layer { + bindings = < + &none &none &none &none &none &none &none &none + &none &none &none &none &none &none &none &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &none + &none &none &none &none &none &none &bt BT_CLR &none &none &none + &none &none &none &none + >; + }; + }; +}; diff --git a/app/boards/shields/osprette/osprette.overlay b/app/boards/shields/osprette/osprette.overlay new file mode 100644 index 00000000..546df783 --- /dev/null +++ b/app/boards/shields/osprette/osprette.overlay @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#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,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) +RC(0,0) 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(0,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,3) RC(3,4) RC(3,5) RC(3,6) + >; + }; + + kscan0: kscan_0 { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "row2col"; + + col-gpios + = <&pro_micro 14 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 15 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 18 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + + row-gpios + = <&pro_micro 16 GPIO_ACTIVE_HIGH> + , <&pro_micro 10 GPIO_ACTIVE_HIGH> + , <&pro_micro 8 GPIO_ACTIVE_HIGH> + , <&pro_micro 9 GPIO_ACTIVE_HIGH> + ; + }; +}; diff --git a/app/boards/shields/osprette/osprette.zmk.yml b/app/boards/shields/osprette/osprette.zmk.yml new file mode 100644 index 00000000..a144c22f --- /dev/null +++ b/app/boards/shields/osprette/osprette.zmk.yml @@ -0,0 +1,8 @@ +file_format: "1" +id: osprette +name: Osprette +type: shield +url: https://github.com/smores56/osprette/ +requires: [pro_micro] +features: + - keys From eca051efa03b1dd533a6086f32699e621d24d337 Mon Sep 17 00:00:00 2001 From: Ryan Butler Date: Mon, 13 Dec 2021 14:41:52 -0500 Subject: [PATCH 26/46] Add support for keeb.io fourier split keyboard (#1056) * Add support for keeb.io fourier * Update app/boards/shields/fourier/fourier_right.overlay Co-authored-by: Nick Winans * Update app/boards/shields/fourier/fourier_left.overlay Co-authored-by: Nick Winans * Convert spaces to tabs in .dtsi Co-authored-by: Nick Winans --- app/boards/shields/fourier/Kconfig.defconfig | 20 ++++++ app/boards/shields/fourier/Kconfig.shield | 9 +++ app/boards/shields/fourier/fourier.dtsi | 43 +++++++++++++ app/boards/shields/fourier/fourier.keymap | 64 +++++++++++++++++++ app/boards/shields/fourier/fourier.zmk.yml | 12 ++++ .../shields/fourier/fourier_left.overlay | 18 ++++++ .../shields/fourier/fourier_right.overlay | 23 +++++++ 7 files changed, 189 insertions(+) create mode 100644 app/boards/shields/fourier/Kconfig.defconfig create mode 100644 app/boards/shields/fourier/Kconfig.shield create mode 100644 app/boards/shields/fourier/fourier.dtsi create mode 100644 app/boards/shields/fourier/fourier.keymap create mode 100644 app/boards/shields/fourier/fourier.zmk.yml create mode 100644 app/boards/shields/fourier/fourier_left.overlay create mode 100644 app/boards/shields/fourier/fourier_right.overlay diff --git a/app/boards/shields/fourier/Kconfig.defconfig b/app/boards/shields/fourier/Kconfig.defconfig new file mode 100644 index 00000000..74a186e1 --- /dev/null +++ b/app/boards/shields/fourier/Kconfig.defconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + + +if SHIELD_FOURIER_LEFT + +config ZMK_KEYBOARD_NAME + default "Fourier" + +config ZMK_SPLIT_BLE_ROLE_CENTRAL + default y + +endif + +if SHIELD_FOURIER_LEFT || SHIELD_FOURIER_RIGHT + +config ZMK_SPLIT + default y + +endif diff --git a/app/boards/shields/fourier/Kconfig.shield b/app/boards/shields/fourier/Kconfig.shield new file mode 100644 index 00000000..2e337410 --- /dev/null +++ b/app/boards/shields/fourier/Kconfig.shield @@ -0,0 +1,9 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + + +config SHIELD_FOURIER_LEFT + def_bool $(shields_list_contains,fourier_left) + +config SHIELD_FOURIER_RIGHT + def_bool $(shields_list_contains,fourier_right) diff --git a/app/boards/shields/fourier/fourier.dtsi b/app/boards/shields/fourier/fourier.dtsi new file mode 100644 index 00000000..99027ea9 --- /dev/null +++ b/app/boards/shields/fourier/fourier.dtsi @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + /* + * This transform correspondsto the 60% left without macro keypad and 65% right, even this + * combination of PCBs can have keys in different locations based on configuration. + */ + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <13>; + 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(0,10) RC(0, 11) RC(0,12) +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,12) +RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) /**/ RC(2,6) RC(2,8) RC(2,9) RC(2,10) RC(2,11) RC(2,12) +RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) /**/ RC(3,6) RC(3,9) RC(3,10) RC(3,11) RC(3,12) + >; + }; + + kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + + diode-direction = "col2row"; + row-gpios + = <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row A + , <&pro_micro 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row B + , <&pro_micro 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row C + , <&pro_micro 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> // Row D + ; + }; +}; diff --git a/app/boards/shields/fourier/fourier.keymap b/app/boards/shields/fourier/fourier.keymap new file mode 100644 index 00000000..f0912bf1 --- /dev/null +++ b/app/boards/shields/fourier/fourier.keymap @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + +// ---------------------------------------------- ---------------------------------------------- +// | ESC | Q | W | E | R | T | | Y | U | I | O | P | | BKSP | +// | TAB | A | S | D | F | G | | H | J | K | L | ' | ENTER | +// | SHIFT | Z | X | C | V | B | | N | M | , | . | / | RSHFT | +// | LCTRL | LALT| LGUI | SPACE | | SPACE/L1 | L2 | RGUI | RALT |RCTRL| +// ------------------------------------------- ----------------------------------------------- + + default_layer { + bindings = < + &kp ESC &kp Q &kp W &kp E &kp R &kp T /**/ &kp Y &kp U &kp I &kp O &kp P &none &kp BACKSPACE + &kp TAB &kp A &kp S &kp D &kp F &kp G /**/ &kp H &kp J &kp K &kp L &kp SQT &kp ENTER + &kp LSHFT &kp Z &kp X &kp C &kp V &kp B /**/ &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT + &kp LCTRL &kp LALT &kp LGUI &none &kp SPACE /**/ < 1 SPACE &mo 2 &kp RGUI &kp RALT &kp RCTRL + >; + }; + +// ---------------------------------------------- ---------------------------------------------- +// | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8 | 9 | O | PSCR | | DEL | +// | ` | | <- | ^ | -> | Vo+ | | [ | ] | - | = | ; | \ | +// | trans | | | | V | Vo- | | | | | | | trans | +// | trans | trans| trans | trans | | trans | trans | trans | trans|trans| +// ------------------------------------------- ----------------------------------------------- + + symbols_layer { + bindings = < + &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 /**/ &kp N7 &kp N8 &kp N9 &kp N0 &kp PSCRN &none &kp DEL + &kp GRAVE &none &kp LEFT &kp UP &kp RIGHT &kp C_VOL_UP /**/ &kp LBKT &kp RBKT &kp MINUS &kp EQUAL &kp SEMI &kp BACKSLASH + &trans &none &none &none &kp DOWN &kp C_VOL_DN /**/ &none &none &none &none &none &trans + &trans &trans &trans &none &trans /**/ &trans &trans &trans &trans &trans + >; + }; + +// ---------------------------------------------- ---------------------------------------------- +// | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F1O | F11 | | F12 | +// | CAP | | home| PgUp | End | | | | | | | | | +// | trans | RGB T | RGB M | PgDn | | | BT_NXT | BT_CLR | | | | |trans| +// | trans | trans| trans | trans | | trans | trans | trans | trans | trans | +// ------------------------------------------- ----------------------------------------------- + + fn_layer { + bindings = < + &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 /**/ &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &none &kp F12 + &kp CAPS &none &kp HOME &kp PG_UP &kp END &none /**/ &none &none &none &none &none &none + &trans &rgb_ug RGB_TOG &rgb_ug RGB_EFF &none &kp PG_DN &none /**/ &bt BT_NXT &bt BT_CLR &none &none &none &trans + &trans &trans &trans &none &trans /**/ &trans &trans &trans &trans &trans + >; + }; + }; +}; diff --git a/app/boards/shields/fourier/fourier.zmk.yml b/app/boards/shields/fourier/fourier.zmk.yml new file mode 100644 index 00000000..d4e3b3ca --- /dev/null +++ b/app/boards/shields/fourier/fourier.zmk.yml @@ -0,0 +1,12 @@ +file_format: "1" +id: fourier +name: Fourier Rev. 1 +type: shield +url: https://github.com/keebio/fourier +requires: + - pro_micro +features: + - keys +siblings: + - fourier_left + - fourier_right diff --git a/app/boards/shields/fourier/fourier_left.overlay b/app/boards/shields/fourier/fourier_left.overlay new file mode 100644 index 00000000..1d0f2c81 --- /dev/null +++ b/app/boards/shields/fourier/fourier_left.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "fourier.dtsi" + +&kscan0 { + col-gpios + = <&pro_micro 20 GPIO_ACTIVE_HIGH> // Col1 + , <&pro_micro 19 GPIO_ACTIVE_HIGH> // Col2 + , <&pro_micro 18 GPIO_ACTIVE_HIGH> // Col3 + , <&pro_micro 15 GPIO_ACTIVE_HIGH> // Col4 + , <&pro_micro 14 GPIO_ACTIVE_HIGH> // Col5 + , <&pro_micro 16 GPIO_ACTIVE_HIGH> // Col6 + ; +}; diff --git a/app/boards/shields/fourier/fourier_right.overlay b/app/boards/shields/fourier/fourier_right.overlay new file mode 100644 index 00000000..77c00d60 --- /dev/null +++ b/app/boards/shields/fourier/fourier_right.overlay @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "fourier.dtsi" + +&default_transform { + col-offset = <6>; +}; + +&kscan0 { + col-gpios + = <&pro_micro 20 GPIO_ACTIVE_HIGH> // Col1 + , <&pro_micro 19 GPIO_ACTIVE_HIGH> // Col2 + , <&pro_micro 18 GPIO_ACTIVE_HIGH> // Col3 + , <&pro_micro 15 GPIO_ACTIVE_HIGH> // Col4 + , <&pro_micro 14 GPIO_ACTIVE_HIGH> // Col5 + , <&pro_micro 16 GPIO_ACTIVE_HIGH> // Col6 + , <&pro_micro 10 GPIO_ACTIVE_HIGH> // Col7 + ; +}; From df1ae494c7f01587dc56f856fd238a7748477d75 Mon Sep 17 00:00:00 2001 From: Felix Sargent Date: Mon, 13 Dec 2021 12:24:21 -0800 Subject: [PATCH 27/46] Add boardsource5x12 (#1027) * Initial commit of boardsource5x12 * Added copyright/license header * Update app/boards/shields/boardsource5x12/Kconfig.defconfig Co-authored-by: Pete Johanson * Update app/boards/shields/boardsource5x12/boardsource5x12.overlay Co-authored-by: Pete Johanson * Update app/boards/shields/boardsource5x12/Kconfig.shield Co-authored-by: Pete Johanson * Update app/boards/shields/boardsource5x12/boardsource5x12.keymap Co-authored-by: Pete Johanson * Swapping keymap for what used in Naked60 as it's another 60 key board, so it keeps it consistent. * Update app/boards/shields/boardsource5x12/boardsource5x12.keymap Co-authored-by: Nick Winans * renamed layers in boardsource5-12 Co-authored-by: Pete Johanson Co-authored-by: Nick Winans --- .../shields/boardsource5x12/Kconfig.defconfig | 9 ++ .../shields/boardsource5x12/Kconfig.shield | 5 + .../boardsource5x12/boardsource5x12.conf | 0 .../boardsource5x12/boardsource5x12.keymap | 99 +++++++++++++++++++ .../boardsource5x12/boardsource5x12.overlay | 42 ++++++++ .../boardsource5x12/boardsource5x12.zmk.yml | 8 ++ 6 files changed, 163 insertions(+) create mode 100644 app/boards/shields/boardsource5x12/Kconfig.defconfig create mode 100644 app/boards/shields/boardsource5x12/Kconfig.shield create mode 100644 app/boards/shields/boardsource5x12/boardsource5x12.conf create mode 100644 app/boards/shields/boardsource5x12/boardsource5x12.keymap create mode 100644 app/boards/shields/boardsource5x12/boardsource5x12.overlay create mode 100644 app/boards/shields/boardsource5x12/boardsource5x12.zmk.yml diff --git a/app/boards/shields/boardsource5x12/Kconfig.defconfig b/app/boards/shields/boardsource5x12/Kconfig.defconfig new file mode 100644 index 00000000..ca7979d4 --- /dev/null +++ b/app/boards/shields/boardsource5x12/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_BOARDSOURCE5X12 + +config ZMK_KEYBOARD_NAME + default "boardsource5x12" + +endif \ No newline at end of file diff --git a/app/boards/shields/boardsource5x12/Kconfig.shield b/app/boards/shields/boardsource5x12/Kconfig.shield new file mode 100644 index 00000000..b2d7b63f --- /dev/null +++ b/app/boards/shields/boardsource5x12/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_BOARDSOURCE5X12 + def_bool $(shields_list_contains,boardsource5x12) \ No newline at end of file diff --git a/app/boards/shields/boardsource5x12/boardsource5x12.conf b/app/boards/shields/boardsource5x12/boardsource5x12.conf new file mode 100644 index 00000000..e69de29b diff --git a/app/boards/shields/boardsource5x12/boardsource5x12.keymap b/app/boards/shields/boardsource5x12/boardsource5x12.keymap new file mode 100644 index 00000000..8956ca98 --- /dev/null +++ b/app/boards/shields/boardsource5x12/boardsource5x12.keymap @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | BSPC | + // | TAB | Q | W | E | R | T | Y | U | I | O | P | \ | + // | SHIFT | A | S | D | F | G | H | J | K | L | ; | ' | + // | CTRL | Z | X | C | V | B | N | M | , | . | / | ENTER | + // |ADJUST | LCTL | LALT | LGUI | LOWR | SPACE| SPACE | RAIS | LARW | DARW | UARW | RARW | + + + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp BSPC + &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSLH + &kp LSHFT &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT + &kp LCTRL &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RET + &mo 3 &kp LCTRL &kp LALT &kp LGUI &mo 1 &kp SPACE &kp SPACE &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT + >; + }; + + lower_layer { + // ------------------------------------------------------------------------------------------- + // | ESC | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | + // | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | DEL | + // | | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | + // | | F7 | F8 | F9 | F10 | F11 | F12 | LS(#) |LS(|) | | | | + // | | | | | | | | | NEXT | Vol- | Vol+ | PLAY | + bindings = < + &kp ESC &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &kp TILDE &kp EXCL &kp AT &kp HASH &kp DLLR &kp PRCNT &kp CARET &kp AMPS &kp ASTRK &kp LPAR &kp RPAR &kp DEL + &trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE + &trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp LS(NON_US_HASH) &kp LS(NON_US_BSLH) &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &mo 3 &kp C_NEXT &kp C_VOL_DN &kp C_VOL_UP &kp C_PLAY_PAUSE + >; + }; + + raise_layer { + // ------------------------------------------------------------------------------------------ + // | ESC | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | + // | ~ | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | DEL | + // | DEL | F1 | F2 | F3 | F4 | F5 | F6 | - | = | [ | ] | \ | + // | | F7 | F8 | F9 | F10 | F11 | F12 | # | | | | | | + // | | | | | | | | | | | | | + bindings = < + &kp ESC &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &kp TILDE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp DEL + &kp DEL &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH + &trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp NON_US_HASH &kp NON_US_BSLH &trans &trans &trans + &trans &trans &trans &trans &mo 3 &trans &trans &trans &trans &trans &trans &trans + >; + }; + + adjust_layer { + // ------------------------------------------------------------------------------------------ + // |tog(4)| F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | + // | | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |LALT(PRTSN)| + // | | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | PRTSN | + // | | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA |LCTRL(DEL) | + // | | | | | |BOOTLD|BOOTLD| | | | | | + bindings = < + &tog 4 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 + &trans &none &none &none &none &none &none &none &none &none &none &kp LA(PSCRN) + &trans &none &none &none &none &none &none &none &none &none &none &kp PSCRN + &trans &none &none &none &none &none &none &none &none &none &none &kp LC(DEL) + &trans &trans &trans &trans &trans &bootloader &bootloader &trans &trans &trans &trans &trans + >; + }; + + flock_layer { + // ---------------------------------------------------------------------------------------------- + // |tog(4) | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | | + // |out tog|BT_SEL 0|BT_SEL 1|BT_SEL 2|BT_SEL 3|BT_SEL 4|BT_PRV|BT_NXT|BT_CLR| | | | + // | | | | | | | | | | | | | + // | | | | | | | | | | | | | + // | | | | | | | | | | | | | + bindings = < + &tog 4 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &trans + &out OUT_TOG &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &bt BT_PRV &bt BT_NXT &bt BT_CLR &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans + >; + }; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/boardsource5x12/boardsource5x12.overlay b/app/boards/shields/boardsource5x12/boardsource5x12.overlay new file mode 100644 index 00000000..0fafe8a1 --- /dev/null +++ b/app/boards/shields/boardsource5x12/boardsource5x12.overlay @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + }; + + kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + diode-direction = "col2row"; + + row-gpios + = <&pro_micro 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + + col-gpios + = <&pro_micro 21 GPIO_ACTIVE_HIGH> + , <&pro_micro 20 GPIO_ACTIVE_HIGH> + , <&pro_micro 19 GPIO_ACTIVE_HIGH> + , <&pro_micro 18 GPIO_ACTIVE_HIGH> + , <&pro_micro 15 GPIO_ACTIVE_HIGH> + , <&pro_micro 14 GPIO_ACTIVE_HIGH> + , <&pro_micro 16 GPIO_ACTIVE_HIGH> + , <&pro_micro 10 GPIO_ACTIVE_HIGH> + , <&pro_micro 9 GPIO_ACTIVE_HIGH> + , <&pro_micro 8 GPIO_ACTIVE_HIGH> + , <&pro_micro 7 GPIO_ACTIVE_HIGH> + , <&pro_micro 6 GPIO_ACTIVE_HIGH> + ; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/boardsource5x12/boardsource5x12.zmk.yml b/app/boards/shields/boardsource5x12/boardsource5x12.zmk.yml new file mode 100644 index 00000000..6987e27a --- /dev/null +++ b/app/boards/shields/boardsource5x12/boardsource5x12.zmk.yml @@ -0,0 +1,8 @@ +file_format: "1" +id: boardsource5x12 +name: Boardsource 5x12 +type: shield +url: https://boardsource.xyz/store/5ecb802c86879c9a0c22db61 +requires: [pro_micro] +features: + - keys From 569a2ee2cc9016b6bd7b65c557b5762f1679f278 Mon Sep 17 00:00:00 2001 From: Kyle McCreery Date: Mon, 13 Dec 2021 15:41:35 -0500 Subject: [PATCH 28/46] [New Shield] Murphpad (#806) * initial commit * initial commit * Encode, OLED, and RGB Nice Nano support added as well as refining default keymap. * tweaking keymap * Prepared murphpad for PR. Includes adding support for second encoder, OLED, and underglow RGB * Enabled OLED by default. * removed naked60 config files * Per PR feedback from ZMK maintainers, added hardware metadata file and renamed Pro Micro pins. * removed tabs from keymap and replaced with normal spaces * Update app/boards/shields/murphpad/murphpad.keymap Co-authored-by: Nick Winans * Update app/boards/shields/murphpad/murphpad.zmk.yml Co-authored-by: Nick Winans * Update app/boards/shields/murphpad/murphpad.zmk.yml Co-authored-by: Nick Winans Co-authored-by: honorless <86894501+lesshonor@users.noreply.github.com> Co-authored-by: Nick Winans --- app/boards/shields/murphpad/Kconfig.defconfig | 45 ++++++++++ app/boards/shields/murphpad/Kconfig.shield | 5 ++ .../shields/murphpad/boards/nice_nano.conf | 3 + .../shields/murphpad/boards/nice_nano.overlay | 34 ++++++++ app/boards/shields/murphpad/murphpad.conf | 9 ++ app/boards/shields/murphpad/murphpad.keymap | 85 +++++++++++++++++++ app/boards/shields/murphpad/murphpad.overlay | 74 ++++++++++++++++ app/boards/shields/murphpad/murphpad.zmk.yml | 12 +++ 8 files changed, 267 insertions(+) create mode 100644 app/boards/shields/murphpad/Kconfig.defconfig create mode 100644 app/boards/shields/murphpad/Kconfig.shield create mode 100644 app/boards/shields/murphpad/boards/nice_nano.conf create mode 100644 app/boards/shields/murphpad/boards/nice_nano.overlay create mode 100644 app/boards/shields/murphpad/murphpad.conf create mode 100644 app/boards/shields/murphpad/murphpad.keymap create mode 100644 app/boards/shields/murphpad/murphpad.overlay create mode 100644 app/boards/shields/murphpad/murphpad.zmk.yml diff --git a/app/boards/shields/murphpad/Kconfig.defconfig b/app/boards/shields/murphpad/Kconfig.defconfig new file mode 100644 index 00000000..6ec7e096 --- /dev/null +++ b/app/boards/shields/murphpad/Kconfig.defconfig @@ -0,0 +1,45 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_MURPHPAD + +config ZMK_KEYBOARD_NAME + default "MurphPad" + +endif + +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_MAX + default 128 + +config LVGL_VER_RES_MAX + 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 diff --git a/app/boards/shields/murphpad/Kconfig.shield b/app/boards/shields/murphpad/Kconfig.shield new file mode 100644 index 00000000..389caa26 --- /dev/null +++ b/app/boards/shields/murphpad/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_MURPHPAD + def_bool $(shields_list_contains,murphpad) \ No newline at end of file diff --git a/app/boards/shields/murphpad/boards/nice_nano.conf b/app/boards/shields/murphpad/boards/nice_nano.conf new file mode 100644 index 00000000..dda71c13 --- /dev/null +++ b/app/boards/shields/murphpad/boards/nice_nano.conf @@ -0,0 +1,3 @@ +# Uncomment both to enable underglow +CONFIG_ZMK_RGB_UNDERGLOW=y +CONFIG_WS2812_STRIP=y diff --git a/app/boards/shields/murphpad/boards/nice_nano.overlay b/app/boards/shields/murphpad/boards/nice_nano.overlay new file mode 100644 index 00000000..b247334e --- /dev/null +++ b/app/boards/shields/murphpad/boards/nice_nano.overlay @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +&spi1 { + compatible = "nordic,nrf-spim"; + status = "okay"; + mosi-pin = <31>; + // Unused pins, needed for SPI definition, but not used by the ws2812 driver itself. + sck-pin = <5>; + miso-pin = <7>; + + led_strip: ws2812@0 { + compatible = "worldsemi,ws2812-spi"; + label = "WS2812"; + + /* SPI */ + reg = <0>; /* ignored, but necessary for SPI bindings */ + spi-max-frequency = <4000000>; + + /* WS2812 */ + chain-length = <8>; /* number of LEDs */ + spi-one-frame = <0x70>; + spi-zero-frame = <0x40>; + }; +}; + +/ { + chosen { + zmk,underglow = &led_strip; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/murphpad/murphpad.conf b/app/boards/shields/murphpad/murphpad.conf new file mode 100644 index 00000000..bdcd4255 --- /dev/null +++ b/app/boards/shields/murphpad/murphpad.conf @@ -0,0 +1,9 @@ +# Uncomment to turn on logging, and set ZMK logging to debug output +# CONFIG_ZMK_USB_LOGGING=y + +# Uncomment both to enable encoder +CONFIG_EC11=y +CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y + +# Uncomment to enable OLED +CONFIG_ZMK_DISPLAY=y \ No newline at end of file diff --git a/app/boards/shields/murphpad/murphpad.keymap b/app/boards/shields/murphpad/murphpad.keymap new file mode 100644 index 00000000..aec58878 --- /dev/null +++ b/app/boards/shields/murphpad/murphpad.keymap @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + + +#define TIMEOUT 300 + +&encoder_1 { + status = "okay"; +}; + +&encoder_2 { + status = "okay"; +}; + +/ { + combos { + compatible = "zmk,combos"; + combo_btclr { + timeout-ms = ; + key-positions = <1 6>; + bindings = <&bt BT_CLR>; + }; + combo_reset { + timeout-ms = ; + key-positions = <1 3>; + bindings = <&reset>; + }; + combo_bootloader { + timeout-ms = ; + key-positions = <1 2>; + bindings = <&bootloader>; + }; + combo_bt_nxt { + timeout-ms = ; + key-positions = <1 4>; + bindings = <&bt BT_NXT>; + }; + }; + + sensors { + compatible = "zmk,keymap-sensors"; + sensors = <&encoder_1 &encoder_2>; + }; + + + keymap0: keymap { + compatible = "zmk,keymap"; + + default_layer { + label = "default layer"; + bindings = < + &bt BT_CLR &kp TAB &kp F5 &kp LC(LA(C)) &kp LG(D) + &rgb_ug RGB_TOG &kp ESC &kp KP_DIVIDE &kp KP_MULTIPLY &kp KP_MINUS + &rgb_ug RGB_EFF &kp KP_N7 &kp KP_N8 &kp KP_N9 &kp KP_PLUS + &kp C_MUTE &kp KP_N4 &kp KP_N5 &kp KP_N6 &trans + &mo 1 &kp KP_N1 &kp KP_N2 &kp KP_N3 &kp KP_ENTER + &kp BSPC &kp KP_N0 &trans &kp KP_DOT &trans + >; + sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN>; + + }; + + fn_layer { + label = "fn layer"; + bindings = < + &trans &trans &trans &trans &trans + &trans &kp KP_NUM &trans &trans &trans + &trans &trans &trans &trans &trans + &bt BT_CLR &trans &trans &trans &trans + &trans &trans &trans &trans &trans + &kp DEL &trans &trans &trans &trans + >; + sensor-bindings = <&inc_dec_kp PG_UP PG_DN &inc_dec_kp C_VOL_UP C_VOL_DN>; + + }; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/murphpad/murphpad.overlay b/app/boards/shields/murphpad/murphpad.overlay new file mode 100644 index 00000000..25bd10f9 --- /dev/null +++ b/app/boards/shields/murphpad/murphpad.overlay @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + }; + + kscan0: kscan { + compatible = "zmk,kscan-gpio-matrix"; + label = "KSCAN"; + + diode-direction = "col2row"; + row-gpios + = <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 16 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 14 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 15 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 18 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + col-gpios + = <&pro_micro 9 GPIO_ACTIVE_HIGH> + , <&pro_micro 6 GPIO_ACTIVE_HIGH> + , <&pro_micro 5 GPIO_ACTIVE_HIGH> + , <&pro_micro 4 GPIO_ACTIVE_HIGH> + , <&pro_micro 10 GPIO_ACTIVE_HIGH> + ; + }; + + encoder_1: encoder_1 { + compatible = "alps,ec11"; + label = "Encoder 1"; + a-gpios = <&pro_micro 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + b-gpios = <&pro_micro 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + resolution = <4>; + status = "disabled"; + }; + + encoder_2: encoder_2 { + compatible = "alps,ec11"; + label = "Encoder 2"; + a-gpios = <&pro_micro 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + b-gpios = <&pro_micro 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + resolution = <4>; + status = "disabled"; + }; + +}; + +&pro_micro_i2c { + status = "okay"; + + oled: 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>; + }; +}; diff --git a/app/boards/shields/murphpad/murphpad.zmk.yml b/app/boards/shields/murphpad/murphpad.zmk.yml new file mode 100644 index 00000000..2dda83d9 --- /dev/null +++ b/app/boards/shields/murphpad/murphpad.zmk.yml @@ -0,0 +1,12 @@ +file_format: "1" +id: murphpad +name: MurphPad +type: shield +url: https://mechwild.com/product/murphpad/ +requires: [pro_micro] +exposes: [i2c_oled] +features: + - keys + - display + - encoder + - underglow From af98a3fd6e5bd8b31e34416369d883eeb592c37c Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 13 Dec 2021 17:00:54 -0500 Subject: [PATCH 29/46] fix(shields): Don't enable SSD1306 automatically. * Fix Murphpad conditional to ensure SSD1306 driver isn't enabled whenever `ZMK_DISPLAY` is enabled. --- app/boards/shields/murphpad/Kconfig.defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/boards/shields/murphpad/Kconfig.defconfig b/app/boards/shields/murphpad/Kconfig.defconfig index 6ec7e096..8e205a8e 100644 --- a/app/boards/shields/murphpad/Kconfig.defconfig +++ b/app/boards/shields/murphpad/Kconfig.defconfig @@ -6,8 +6,6 @@ if SHIELD_MURPHPAD config ZMK_KEYBOARD_NAME default "MurphPad" -endif - if ZMK_DISPLAY config I2C @@ -43,3 +41,5 @@ choice LVGL_COLOR_DEPTH endchoice endif # LVGL + +endif From f438fb87d8765633e8550e1108a7956e9f5d70c2 Mon Sep 17 00:00:00 2001 From: Peter Johanson Date: Mon, 13 Dec 2021 17:10:47 -0500 Subject: [PATCH 30/46] chore: Add a few more items to PR template. * Kconfig.defconfig conditional correctness. * Keyboard availability. --- .github/pull_request_template.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 7443c24d..9c3543dd 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,4 +8,6 @@ - [ ] Keymaps do not use deprecated key defines (Check using the [upgrader tool](https://zmk.dev/docs/codes/keymap-upgrader)) - [ ] `&pro_micro` used in favor of `&pro_micro_d/a` if applicable - [ ] If split, no name added for the right/peripheral half + - [ ] Kconfig.defconfig file correctly wraps *all* configuration in conditional on the shield symbol - [ ] `.conf` file has optional extra features commented out + - [ ] Keyboard/PCB is part of a shipped group buy or is generally available in stock to purchase (OSH/personal projects without general availability should create a zmk-config repo instead) From 7b023affbde618835ae9943cc34bba2de4ac03c9 Mon Sep 17 00:00:00 2001 From: Alexander Krikun <54907805+krikun98@users.noreply.github.com> Date: Tue, 14 Dec 2021 20:32:59 +0300 Subject: [PATCH 31/46] Add support for the Jiran (#1048) * initial files to get stuff working * Keymap by Ladniy * Format update to new standards * keymap update * header * Fixed transform, removed left and right .conf files * Apply suggestions from code review Formatting Co-authored-by: Nick Winans Co-authored-by: Nick Winans --- app/boards/shields/jiran/Kconfig.defconfig | 19 +++++ app/boards/shields/jiran/Kconfig.shield | 8 ++ app/boards/shields/jiran/jiran.conf | 1 + app/boards/shields/jiran/jiran.dtsi | 82 ++++++++++++++++++++ app/boards/shields/jiran/jiran.keymap | 35 +++++++++ app/boards/shields/jiran/jiran.zmk.yml | 11 +++ app/boards/shields/jiran/jiran_left.overlay | 18 +++++ app/boards/shields/jiran/jiran_right.overlay | 22 ++++++ 8 files changed, 196 insertions(+) create mode 100644 app/boards/shields/jiran/Kconfig.defconfig create mode 100644 app/boards/shields/jiran/Kconfig.shield create mode 100644 app/boards/shields/jiran/jiran.conf create mode 100644 app/boards/shields/jiran/jiran.dtsi create mode 100644 app/boards/shields/jiran/jiran.keymap create mode 100644 app/boards/shields/jiran/jiran.zmk.yml create mode 100644 app/boards/shields/jiran/jiran_left.overlay create mode 100644 app/boards/shields/jiran/jiran_right.overlay diff --git a/app/boards/shields/jiran/Kconfig.defconfig b/app/boards/shields/jiran/Kconfig.defconfig new file mode 100644 index 00000000..17421970 --- /dev/null +++ b/app/boards/shields/jiran/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +if SHIELD_JIRAN_LEFT + +config ZMK_KEYBOARD_NAME + default "Jiran" + +config ZMK_SPLIT_BLE_ROLE_CENTRAL + default y + +endif + +if SHIELD_JIRAN_LEFT || SHIELD_JIRAN_RIGHT + +config ZMK_SPLIT + default y + +endif diff --git a/app/boards/shields/jiran/Kconfig.shield b/app/boards/shields/jiran/Kconfig.shield new file mode 100644 index 00000000..8a24ace0 --- /dev/null +++ b/app/boards/shields/jiran/Kconfig.shield @@ -0,0 +1,8 @@ +# Copyright (c) 2021 The ZMK Contributors +# SPDX-License-Identifier: MIT + +config SHIELD_JIRAN_LEFT + def_bool $(shields_list_contains,jiran_left) + +config SHIELD_JIRAN_RIGHT + def_bool $(shields_list_contains,jiran_right) diff --git a/app/boards/shields/jiran/jiran.conf b/app/boards/shields/jiran/jiran.conf new file mode 100644 index 00000000..406f9a44 --- /dev/null +++ b/app/boards/shields/jiran/jiran.conf @@ -0,0 +1 @@ +# CONFIG_ZMK_SLEEP=y \ No newline at end of file diff --git a/app/boards/shields/jiran/jiran.dtsi b/app/boards/shields/jiran/jiran.dtsi new file mode 100644 index 00000000..5dfaa46b --- /dev/null +++ b/app/boards/shields/jiran/jiran.dtsi @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include + +/ { + chosen { + zmk,kscan = &kscan0; + zmk,matrix_transform = &default_transform; + }; + + default_transform: keymap_transform_0 { + compatible = "zmk,matrix-transform"; + columns = <12>; + rows = <5>; + +// | SW1 | SW2 | SW3 | SW4 | SW5 | SW6 | | SW6 | SW5 | SW4 | SW3 | SW2 | SW1 | +// | SW0 | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | SW0 | +// | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | +// | SW19 | SW20 | SW21 | SW22 | SW23 | SW24 | | SW24 | SW23 | SW22 | SW21 | SW20 | SW19 | +// | SW25 | SW26 | SW27 | | SW27 | SW26 | SW25 | + 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(4,0) 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(4,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(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) + >; + }; + + jian_transform: keymap_transform_1 { + compatible = "zmk,matrix-transform"; + columns = <12>; + rows = <5>; + +// | SW0 | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | SW0 | +// | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | +// | SW19 | SW20 | SW21 | SW22 | SW23 | SW24 | | SW24 | SW23 | SW22 | SW21 | SW20 | SW19 | +// | SW25 | SW26 | SW27 | | SW27 | SW26 | SW25 | + map = < + RC(4,0) 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(4,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(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) + >; + }; + + crkbd_transform: keymap_transform_2 { + compatible = "zmk,matrix-transform"; + columns = <12>; + rows = <5>; + +// | SW7 | SW8 | SW9 | SW10 | SW11 | SW12 | | SW12 | SW11 | SW10 | SW9 | SW8 | SW7 | +// | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | +// | SW19 | SW20 | SW21 | SW22 | SW23 | SW24 | | SW24 | SW23 | SW22 | SW21 | SW20 | SW19 | +// | SW25 | SW26 | SW27 | | SW27 | SW26 | SW25 | + map = < + 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(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 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + , <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> + ; + + }; +}; diff --git a/app/boards/shields/jiran/jiran.keymap b/app/boards/shields/jiran/jiran.keymap new file mode 100644 index 00000000..e6c073cc --- /dev/null +++ b/app/boards/shields/jiran/jiran.keymap @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include + +/ { + keymap { + compatible = "zmk,keymap"; + + default_layer { + bindings = < + &kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS + &kp LGUI &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &mt RGUI RBKT + &kp LSHIFT &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &mt RSHIFT SQT + &kp LCTRL &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &mt RCTRL BSLH + &mo 1 &kp SPACE &kp LALT &mt RALT RET &kp BSPC &mo 1 + >; + }; + + lower_layer { + bindings = < + &kp GRAVE &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp EQUAL + &kp F11 &kp TAB &bt BT_CLR &kp HOME &reset &kp PG_UP &kp C_VOL_UP &kp C_VOL_UP &kp PG_UP &reset &kp HOME &kp INS &kp DEL &kp F12 + &kp LSHIFT &bt BT_NXT &kp LEFT &kp UP &kp RIGHT &kp C_MUTE &kp C_MUTE &kp LEFT &kp UP &kp RIGHT &kp PSCRN &mt RSHIFT SLCK + &kp LCTRL &bt BT_PRV &kp END &kp DOWN &kp PG_DN &kp C_VOL_DN &kp C_VOL_DN &kp PG_DN &kp DOWN &kp END &kp PAUSE_BREAK &mt RCTRL KP_NUM + &trans &kp SPACE &kp LALT &mt RALT RET &kp BSPC &trans + >; + }; + }; +}; \ No newline at end of file diff --git a/app/boards/shields/jiran/jiran.zmk.yml b/app/boards/shields/jiran/jiran.zmk.yml new file mode 100644 index 00000000..1e21df7c --- /dev/null +++ b/app/boards/shields/jiran/jiran.zmk.yml @@ -0,0 +1,11 @@ +file_format: "1" +id: jiran +name: Jiran +type: shield +url: https://github.com/Ladniy/jiran +requires: [pro_micro] +features: + - keys +siblings: + - jiran_left + - jiran_right diff --git a/app/boards/shields/jiran/jiran_left.overlay b/app/boards/shields/jiran/jiran_left.overlay new file mode 100644 index 00000000..4466202c --- /dev/null +++ b/app/boards/shields/jiran/jiran_left.overlay @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "jiran.dtsi" + +&kscan0 { + col-gpios + = <&pro_micro 1 GPIO_ACTIVE_HIGH> + , <&pro_micro 0 GPIO_ACTIVE_HIGH> + , <&pro_micro 4 GPIO_ACTIVE_HIGH> + , <&pro_micro 5 GPIO_ACTIVE_HIGH> + , <&pro_micro 6 GPIO_ACTIVE_HIGH> + , <&pro_micro 7 GPIO_ACTIVE_HIGH> + ; +}; diff --git a/app/boards/shields/jiran/jiran_right.overlay b/app/boards/shields/jiran/jiran_right.overlay new file mode 100644 index 00000000..75b9fb5a --- /dev/null +++ b/app/boards/shields/jiran/jiran_right.overlay @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#include "jiran.dtsi" + +&default_transform { + col-offset = <6>; +}; + +&kscan0 { + col-gpios + = <&pro_micro 7 GPIO_ACTIVE_HIGH> + , <&pro_micro 6 GPIO_ACTIVE_HIGH> + , <&pro_micro 5 GPIO_ACTIVE_HIGH> + , <&pro_micro 4 GPIO_ACTIVE_HIGH> + , <&pro_micro 0 GPIO_ACTIVE_HIGH> + , <&pro_micro 1 GPIO_ACTIVE_HIGH> + ; +}; From 2666bd622cde5f55366636a8fe24ca104633be85 Mon Sep 17 00:00:00 2001 From: Lucas Yunkyu Lee Date: Mon, 13 Dec 2021 21:12:38 +0900 Subject: [PATCH 32/46] fix(keymaps): add row-offset property to matrix-transform --- app/dts/bindings/zmk,matrix-transform.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/dts/bindings/zmk,matrix-transform.yaml b/app/dts/bindings/zmk,matrix-transform.yaml index b7d000c5..4392bf52 100644 --- a/app/dts/bindings/zmk,matrix-transform.yaml +++ b/app/dts/bindings/zmk,matrix-transform.yaml @@ -13,6 +13,9 @@ properties: col-offset: type: int default: 0 + row-offset: + type: int + default: 0 map: type: array required: true From 62e3b573b920b17f3f00781dde53d965dbe8a613 Mon Sep 17 00:00:00 2001 From: Evan Callicoat Date: Sun, 26 Dec 2021 13:21:58 -0600 Subject: [PATCH 33/46] Typos --- docs/docs/behaviors/hold-tap.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 972df0be..8e35f759 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -62,12 +62,12 @@ For example, if you press `&mt LEFT_SHIFT A` and then release it without pressin #### Positional hold-tap and `hold-trigger-key-positions` -- Including `hold-trigger-key-postions` in your hold-tap definition turns on the positional hold-tap feature. +- Including `hold-trigger-key-positions` in your hold-tap definition turns on the positional hold-tap feature. - With positional hold-tap enabled, if you press any key **NOT** listed in `hold-trigger-key-positions` before `tapping-term-ms` expires, it will produce a tap. - In all other situations, positional hold-tap will not modify the behavior of your hold-tap. - Positional hold-tap is useful with home-row modifiers. If you have a home-row modifier key in the left hand for example, by including only keys positions from the right hand in `hold-trigger-key-positions`, you will only get hold behaviors during cross-hand key combinations. -- Note that `hold-trigger-key-postions` is an array of key position indexes. Key positions are numbered according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera. -- See the following example, which uses a hold-tap behavior definition, configured with the `hold-preferrred` flavor, and with positional hold-tap enabled: +- Note that `hold-trigger-key-positions` is an array of key position indexes. Key positions are numbered according to your keymap, starting with 0. So if the first key in your keymap is Q, this key is in position 0. The next key (probably W) will be in position 1, et cetera. +- See the following example, which uses a hold-tap behavior definition, configured with the `hold-preferred` flavor, and with positional hold-tap enabled: ``` #include From a562578fd20c6601667206a62910a60ff3a60ee8 Mon Sep 17 00:00:00 2001 From: Albert Y <76888457+filterpaper@users.noreply.github.com> Date: Tue, 28 Dec 2021 18:04:18 +0800 Subject: [PATCH 34/46] docs: change quick_tap_ms to quick-tap-ms (#1071) --- docs/docs/behaviors/hold-tap.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 8e35f759..edb9d593 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -42,9 +42,9 @@ For basic usage, please see [mod-tap](mod-tap.md) and [layer-tap](layers.md) pag Defines how long a key must be pressed to trigger Hold behavior. -#### `quick_tap_ms` +#### `quick-tap-ms` -If you press a tapped hold-tap again within `quick_tap_ms` milliseconds, it will always trigger the tap behavior. This is useful for things like a backspace, where a quick tap+hold holds backspace pressed. Set this to a negative value to disable. The default is -1 (disabled). +If you press a tapped hold-tap again within `quick-tap-ms` milliseconds, it will always trigger the tap behavior. This is useful for things like a backspace, where a quick tap+hold holds backspace pressed. Set this to a negative value to disable. The default is -1 (disabled). In QMK, unlike ZMK, this functionality is enabled by default, and you turn it off using `TAPPING_FORCE_HOLD`. @@ -150,7 +150,7 @@ The following are suggested hold-tap configurations that work well with home row label = "HOMEROW_MODS"; #binding-cells = <2>; tapping-term-ms = <150>; - quick_tap_ms = <0>; + quick-tap-ms = <0>; flavor = "tap-preferred"; bindings = <&kp>, <&kp>; }; @@ -181,7 +181,7 @@ The following are suggested hold-tap configurations that work well with home row label = "HOMEROW_MODS"; #binding-cells = <2>; tapping-term-ms = <200>; // <---[[moderate duration]] - quick_tap_ms = <0>; + quick-tap-ms = <0>; flavor = "balanced"; bindings = <&kp>, <&kp>; }; From 3114ce00b9676625e60c49c05eb1a91db51deb7b Mon Sep 17 00:00:00 2001 From: Ivan Smirnov Date: Tue, 28 Dec 2021 03:52:16 -0700 Subject: [PATCH 35/46] docs: reiterate building from `zmk/app/` (#1031) Co-authored-by: Cem Aksoylar --- docs/docs/development/build-flash.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/docs/development/build-flash.md b/docs/docs/development/build-flash.md index cb00b1a9..ac75b835 100644 --- a/docs/docs/development/build-flash.md +++ b/docs/docs/development/build-flash.md @@ -99,6 +99,10 @@ For instance, building kyria firmware from a user `myUser`'s `zmk-config` folder west build -b nice_nano -- -DSHIELD=kyria_left -DZMK_CONFIG="C:/Users/myUser/Documents/Github/zmk-config/config" ``` +:::caution +The above command must still be invoked from the `zmk/app` directory as noted above, rather than the config directory. Otherwise, you will encounter errors such as `ERROR: source directory "." does not contain a CMakeLists.txt; is this really what you want to build?`. Alternatively you can add the `-s /path/to/zmk/app` flag to your `west` command. +::: + In order to make your `zmk-config` folder available when building within the VSCode Remote Container, you need to create a docker volume named `zmk-config` by binding it to the full path of your config directory. If you have run the VSCode Remote Container before, it is likely that docker has created this volume automatically -- we need to delete the default volume before binding it to the correct path. Follow the following steps: From 8c321063a05c0caa43f697a2724f221e8a147a7b Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Fri, 22 Oct 2021 18:31:08 -0700 Subject: [PATCH 36/46] feat(docs): Add note for USB power in outputs page --- docs/docs/behaviors/outputs.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/docs/behaviors/outputs.md b/docs/docs/behaviors/outputs.md index ae812497..198d9acc 100644 --- a/docs/docs/behaviors/outputs.md +++ b/docs/docs/behaviors/outputs.md @@ -12,6 +12,12 @@ 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. +:::note Powering the keyboard via USB +ZMK is not always able to detect if the other end of a USB connection accepts keyboard input or not. +So if you are using USB only to power your keyboard (for example with a charger or a portable power bank), you will want +to select the BLE output through below behavior to be able to send keystrokes to the selected bluetooth profile. +::: + ## 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) From ef0d088cb8c5cfafe48db24973f42637c2f75380 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Fri, 22 Oct 2021 18:40:36 -0700 Subject: [PATCH 37/46] feat(docs): Link to outputs page in troubleshooting re: BT output --- docs/docs/troubleshooting.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md index d3f3eeae..3055c131 100644 --- a/docs/docs/troubleshooting.md +++ b/docs/docs/troubleshooting.md @@ -3,9 +3,7 @@ title: Troubleshooting sidebar_title: Troubleshooting --- -### Summary - -The following page provides suggestions for common errors that may occur during firmware compilation. If the information provided is insufficient to resolve the issue, feel free to seek out help from the [ZMK Discord](https://zmk.dev/community/discord/invite). +The following page provides suggestions for common errors that may occur during firmware compilation or other issues with keyboard usage. If the information provided is insufficient to resolve the issue, feel free to seek out help from the [ZMK Discord](https://zmk.dev/community/discord/invite). ### File Transfer Error @@ -76,3 +74,7 @@ CONFIG_BT_CTLR_TX_PWR_PLUS_8=y ``` For the `nRF52840`, the value `PLUS_8` can be set to any multiple of four between `MINUS_20` and `PLUS_8`. The default value for this config is `0`, but if you are having connection issues it is recommended to set it to `PLUS_8` because the power consumption difference is negligible. For more information on changing the transmit power of your BLE device, please refer to [the Zephyr docs.](https://docs.zephyrproject.org/latest/reference/kconfig/CONFIG_BT_CTLR_TX_PWR_PLUS_8.html) + +### Other notes and warnings + +- If you want to test bluetooth output on your keyboard and are powering it through the USB connection rather than a battery, you will be able to pair with a host device but may not see keystrokes sent. In this case you need to use the [output selection behavior](../docs/behaviors/outputs.md) to prefer sending keystrokes over bluetooth rather than USB. This might be necessary even if you are not powering from a device capable of receiving USB inputs, such as a USB charger. From 93e76835e4ea1b5b058066990abea720084ca470 Mon Sep 17 00:00:00 2001 From: Cem Aksoylar Date: Wed, 22 Dec 2021 22:24:47 -0800 Subject: [PATCH 38/46] fix(setup): Use right flags for curl when wget doesn't exist. --- docs/src/templates/setup.sh.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/templates/setup.sh.mustache b/docs/src/templates/setup.sh.mustache index 54405fae..cec164a2 100644 --- a/docs/src/templates/setup.sh.mustache +++ b/docs/src/templates/setup.sh.mustache @@ -54,7 +54,7 @@ if [[ $curl_exists == "true" && $wget_exists == "true" ]]; then download_command="curl -fsOL " fi elif [[ $curl_exists == "true" ]]; then - download_command="curl -O " + download_command="curl -fsOL " elif [[ $wget_exists == "true" ]]; then download_command="wget " else From 387926761580fbfde98b2d43cfd9fce7b6fae11e Mon Sep 17 00:00:00 2001 From: KingCoinless <33333456+KingCoinless@users.noreply.github.com> Date: Wed, 29 Dec 2021 02:40:31 -0800 Subject: [PATCH 39/46] docs(codes): Windows Support: Display Adjustment Commands Co-authored-by: Cem Aksoylar --- docs/src/data/hid.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/src/data/hid.js b/docs/src/data/hid.js index 31e11d23..4432db74 100644 --- a/docs/src/data/hid.js +++ b/docs/src/data/hid.js @@ -5043,7 +5043,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: false, android: true, macos: null, @@ -5148,7 +5148,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, @@ -5169,7 +5169,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: true, linux: true, android: null, macos: true, @@ -5190,7 +5190,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: true, linux: true, android: null, macos: true, @@ -5211,7 +5211,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, @@ -5232,7 +5232,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, @@ -5253,7 +5253,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, @@ -5274,7 +5274,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, From ee0f24412b7ac0e17444245892dfa9966b9f8d26 Mon Sep 17 00:00:00 2001 From: Kiessling Date: Fri, 8 Jan 2021 14:17:07 -0800 Subject: [PATCH 40/46] docs(codes): Windows Support: Symbols, Operations, and Punctuation --- docs/src/data/hid.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/src/data/hid.js b/docs/src/data/hid.js index 4432db74..cd53b105 100644 --- a/docs/src/data/hid.js +++ b/docs/src/data/hid.js @@ -1368,7 +1368,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=84", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, @@ -1393,7 +1393,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=84", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, @@ -2711,7 +2711,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: true, macos: null, @@ -3341,7 +3341,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: true, macos: null, @@ -3362,7 +3362,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: false, android: false, macos: null, @@ -4013,7 +4013,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4034,7 +4034,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, From 4a547555bfcf28a20db502efd6963da6674f8806 Mon Sep 17 00:00:00 2001 From: Kiessling Date: Fri, 8 Jan 2021 14:02:54 -0800 Subject: [PATCH 41/46] docs(codes): Windows Support: Workflow Commands and Locks --- docs/src/data/hid.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/src/data/hid.js b/docs/src/data/hid.js index cd53b105..c45fa10e 100644 --- a/docs/src/data/hid.js +++ b/docs/src/data/hid.js @@ -3089,7 +3089,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3110,7 +3110,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3131,7 +3131,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3152,7 +3152,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3173,7 +3173,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3278,7 +3278,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: false, android: false, macos: null, @@ -3320,7 +3320,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: true, linux: false, android: false, macos: null, @@ -3866,7 +3866,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: false, android: false, macos: null, @@ -7143,7 +7143,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=150", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -7164,7 +7164,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=150", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -7185,7 +7185,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=150", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -7206,7 +7206,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=150", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -7626,7 +7626,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=152", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, From 1e4f0147ad7e269e339cd63174fe1d9d84320dfd Mon Sep 17 00:00:00 2001 From: Kiessling Date: Fri, 8 Jan 2021 13:20:10 -0800 Subject: [PATCH 42/46] docs(codes): Windows Support: Audio Controls --- docs/src/data/hid.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/src/data/hid.js b/docs/src/data/hid.js index c45fa10e..1d4c5d05 100644 --- a/docs/src/data/hid.js +++ b/docs/src/data/hid.js @@ -3215,7 +3215,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: true, macos: true, @@ -3236,7 +3236,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -3257,7 +3257,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4375,7 +4375,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4397,7 +4397,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4419,7 +4419,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -6093,7 +6093,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=139", os: { - windows: null, + windows: true, linux: true, android: true, macos: null, @@ -6114,7 +6114,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=139", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -6135,7 +6135,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=139", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, @@ -6156,7 +6156,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=139", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, From 7b2edbad43cb8da271f3f348b3171b81ba408429 Mon Sep 17 00:00:00 2001 From: Kiessling Date: Fri, 8 Jan 2021 12:52:27 -0800 Subject: [PATCH 43/46] docs(codes): Windows Support: Language/International Inputs --- docs/src/data/hid.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/src/data/hid.js b/docs/src/data/hid.js index 1d4c5d05..774cf6c7 100644 --- a/docs/src/data/hid.js +++ b/docs/src/data/hid.js @@ -3383,7 +3383,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3404,7 +3404,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3425,7 +3425,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3446,7 +3446,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3467,7 +3467,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3488,7 +3488,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3572,7 +3572,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: true, linux: true, android: false, macos: null, @@ -3593,7 +3593,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: true, linux: true, android: false, macos: null, @@ -3614,7 +3614,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3635,7 +3635,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -3656,7 +3656,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=87", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, From be343674de55bfa692cf943a06a11beb60be747f Mon Sep 17 00:00:00 2001 From: Evan Callicoat Date: Sun, 2 Jan 2022 04:34:21 -0600 Subject: [PATCH 44/46] docs: Fix typos and inconsistent spellings (#1079) --- docs/docs/development/build-flash.md | 2 +- docs/docs/development/hardware-metadata-files.md | 2 +- docs/docs/development/new-shield.md | 2 +- docs/docs/faq.md | 4 ++-- docs/docs/features/keymaps.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/development/build-flash.md b/docs/docs/development/build-flash.md index ac75b835..95719d92 100644 --- a/docs/docs/development/build-flash.md +++ b/docs/docs/development/build-flash.md @@ -26,7 +26,7 @@ From here on, building and flashing ZMK should all be done from the `app/` subdi cd app ``` -To build for your particular keyboard, the behaviour varies slightly depending on if you are building for a keyboard with +To build for your particular keyboard, the behavior varies slightly depending on if you are building for a keyboard with an onboard MCU, or one that uses an MCU board addon. ### Keyboard (Shield) + MCU Board diff --git a/docs/docs/development/hardware-metadata-files.md b/docs/docs/development/hardware-metadata-files.md index ffe896e2..5d4902dc 100644 --- a/docs/docs/development/hardware-metadata-files.md +++ b/docs/docs/development/hardware-metadata-files.md @@ -100,7 +100,7 @@ Boards and shields should document the sets of hardware features found on them u The `siblings` array is used to identify multiple hardware items designed to be used together as one logical device. Right now, that primarily is used to identify the two halves of a split keyboard, but future enhancements will include more complicated and flexible combinations. -The array should contrain the complete harware IDs of the siblings that combine in the logical device, e.g. with the `corne.zmk.yml` file: +The array should contain the complete hardware IDs of the siblings that combine in the logical device, e.g. with the `corne.zmk.yml` file: ```yaml id: corne diff --git a/docs/docs/development/new-shield.md b/docs/docs/development/new-shield.md index d8b41698..6f65d869 100644 --- a/docs/docs/development/new-shield.md +++ b/docs/docs/development/new-shield.md @@ -360,7 +360,7 @@ The two `#include` lines at the top of the keymap are required in order to bring Further documentation on behaviors and bindings is forthcoming, but a summary of the current behaviors you can bind to key positions is as follows: - `kp` is the "key press" behavior, and takes a single binding argument of the key code from the 'keyboard/keypad" HID usage table. -- `mo` is the "momentary layer" behaviour, and takes a single binding argument of the numeric ID of the layer to momentarily enable when that key is held. +- `mo` is the "momentary layer" behavior, and takes a single binding argument of the numeric ID of the layer to momentarily enable when that key is held. - `trans` is the "transparent" behavior, useful to be place in higher layers above `mo` bindings to be sure the key release is handled by the lower layer. No binding arguments are required. - `mt` is the "mod-tap" behavior, and takes two binding arguments, the modifier to use if held, and the keycode to send if tapped. diff --git a/docs/docs/faq.md b/docs/docs/faq.md index d335d11e..6a16f6f8 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -12,7 +12,7 @@ As a best-in-class RTOS, Zephyr™ brings many [benefits](https://www.zephyrproj - Powerful hardware abstraction and configuration using [DeviceTree](https://docs.zephyrproject.org/latest/guides/dts/index.html) and [Kconfig](https://docs.zephyrproject.org/latest/guides/kconfig/index.html). - A BLE stack that periodically obtains [qualification](https://docs.zephyrproject.org/latest/guides/bluetooth/bluetooth-qual.html) listings, making it easier for final products to obtain qualification from the Bluetooth® SIG. - Multi-processor support, which is critical for power efficiency in upcoming MCUs. -- Permissive licencing with its Apache 2.0 open source [license](https://www.apache.org/licenses/LICENSE-2.0). +- Permissive licensing with its Apache 2.0 open source [license](https://www.apache.org/licenses/LICENSE-2.0). - A buzzing developer [community](https://github.com/zephyrproject-rtos/zephyr) including many leading [embedded technology](https://www.zephyrproject.org/project-members) companies. - Long term support (LTS) with security updates. @@ -23,7 +23,7 @@ That’s an excellent question! There are already great keyboard firmwares avail - Zephyr™ - See [Why Zephyr™?](#why-zephyr) - Licensing - - Just like other open source firmware, ZMK is all about the free and the sharing. However, some other projects use the GPL licence which prevents integration of libraries and drivers whose licenses are not GPL-compatible (such as some embedded BLE drivers). ZMK uses the permissive [MIT](https://github.com/zmkfirmware/zmk/blob/main/LICENSE) license which doesn’t have this limitation. + - Just like other open source firmware, ZMK is all about the free and the sharing. However, some other projects use the GPL license which prevents integration of libraries and drivers whose licenses are not GPL-compatible (such as some embedded BLE drivers). ZMK uses the permissive [MIT](https://github.com/zmkfirmware/zmk/blob/main/LICENSE) license which doesn’t have this limitation. - Wireless First - ZMK is designed for the future, and we believe the future is wireless. So power efficiency plays a critical role in every design decision, just like in Zephyr™. diff --git a/docs/docs/features/keymaps.md b/docs/docs/features/keymaps.md index be0aa203..59577d8f 100644 --- a/docs/docs/features/keymaps.md +++ b/docs/docs/features/keymaps.md @@ -128,7 +128,7 @@ that defines just one layer for this keymap: Each layer should have: -1. A `bindings` property this will be a list of behaviour bindings, one for each key position for the keyboard. +1. A `bindings` property this will be a list of behavior bindings, one for each key position for the keyboard. 1. (Optional) A `sensor-bindings` property that will be a list of behavior bindings for each sensor on the keyboard. (Currently, only encoders are supported as sensor hardware, but in the future devices like trackpoints would be supported the same way) For the full set of possible behaviors, start at the [Key Press](../behaviors/key-press.md) behavior. From e7a52e2cee151bd22290cdc6228b66092d3f6268 Mon Sep 17 00:00:00 2001 From: KingCoinless <33333456+KingCoinless@users.noreply.github.com> Date: Sun, 2 Jan 2022 02:44:55 -0800 Subject: [PATCH 45/46] docs(codes): Windows Support: Media Controls Co-authored-by: Cem Aksoylar --- docs/src/data/hid.js | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/src/data/hid.js b/docs/src/data/hid.js index 774cf6c7..572ccb95 100644 --- a/docs/src/data/hid.js +++ b/docs/src/data/hid.js @@ -2664,7 +2664,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=86", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, @@ -4265,7 +4265,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4287,7 +4287,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4309,7 +4309,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4331,7 +4331,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -4507,7 +4507,7 @@ export default [ documentation: "https://source.android.com/devices/input/keyboard-devices#hid-keyboard-and-keypad-page-0x07", os: { - windows: null, + windows: false, linux: true, android: true, macos: false, @@ -5001,7 +5001,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: true, android: true, macos: null, @@ -5022,7 +5022,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=134", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, @@ -5778,7 +5778,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: true, linux: true, android: true, macos: null, @@ -5799,7 +5799,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: true, linux: true, android: true, macos: null, @@ -5820,7 +5820,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: false, linux: true, android: true, macos: null, @@ -5841,7 +5841,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: true, linux: true, android: true, macos: null, @@ -5862,7 +5862,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: true, linux: true, android: true, macos: null, @@ -5883,7 +5883,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, @@ -5904,7 +5904,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, @@ -5925,7 +5925,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: false, linux: true, android: true, macos: null, @@ -5967,7 +5967,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -5988,7 +5988,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: false, linux: true, android: false, macos: null, @@ -6009,7 +6009,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, @@ -6051,7 +6051,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=137", os: { - windows: null, + windows: true, linux: true, android: true, macos: true, @@ -6177,7 +6177,7 @@ export default [ ], documentation: "https://usb.org/sites/default/files/hut1_2.pdf#page=141", os: { - windows: null, + windows: false, linux: true, android: null, macos: null, From e0620f1a2d726bee1859b8618ea4ed24b6b2145e Mon Sep 17 00:00:00 2001 From: Midge 't Hoen Date: Mon, 3 Jan 2022 14:14:38 +0100 Subject: [PATCH 46/46] Bump init delay to 50ms for nico-nano --- app/boards/arm/nice_nano/nice_nano_v2.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/boards/arm/nice_nano/nice_nano_v2.dts b/app/boards/arm/nice_nano/nice_nano_v2.dts index b17f4787..8f72aad6 100644 --- a/app/boards/arm/nice_nano/nice_nano_v2.dts +++ b/app/boards/arm/nice_nano/nice_nano_v2.dts @@ -12,7 +12,7 @@ compatible = "zmk,ext-power-generic"; label = "EXT_POWER"; control-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; - init-delay-ms = <10>; + init-delay-ms = <50>; }; vbatt {