Browse Source

Merge remote-tracking branch 'upstream/main' into CrossR/Sofle

xmkb
CrossR 4 years ago
parent
commit
f8a635aaa0
  1. 10
      .github/workflows/build.yml
  2. 3
      app/CMakeLists.txt
  3. 13
      app/Kconfig
  4. 8
      app/boards/arm/bluemicro52840_v1/CMakeLists.txt
  5. 8
      app/boards/arm/bluemicro52840_v1/Kconfig
  6. 8
      app/boards/arm/bluemicro52840_v1/Kconfig.board
  7. 30
      app/boards/arm/bluemicro52840_v1/Kconfig.defconfig
  8. 52
      app/boards/arm/bluemicro52840_v1/arduino_pro_micro_pins.dtsi
  9. 96
      app/boards/arm/bluemicro52840_v1/bluemicro52840_v1.dts
  10. 15
      app/boards/arm/bluemicro52840_v1/bluemicro52840_v1.yaml
  11. 20
      app/boards/arm/bluemicro52840_v1/bluemicro52840_v1_defconfig
  12. 5
      app/boards/arm/bluemicro52840_v1/board.cmake
  13. 1
      app/boards/arm/nice_nano/Kconfig
  14. 2
      app/boards/arm/nice_nano/Kconfig.defconfig
  15. 9
      app/boards/arm/nice_nano/nice_nano.dts
  16. 17
      app/boards/shields/corne/corne.dtsi
  17. 60
      app/boards/shields/corne/corne.keymap
  18. 1
      app/boards/shields/corne/corne_left.conf
  19. 4
      app/boards/shields/corne/corne_left.overlay
  20. 1
      app/boards/shields/corne/corne_right.conf
  21. 3
      app/boards/shields/corne/corne_right.overlay
  22. 4
      app/boards/shields/kyria/kyria.dtsi
  23. 1
      app/boards/shields/kyria/kyria_left.conf
  24. 4
      app/boards/shields/kyria/kyria_left.overlay
  25. 1
      app/boards/shields/kyria/kyria_right.conf
  26. 4
      app/boards/shields/kyria/kyria_right.overlay
  27. 6
      app/boards/shields/lily58/lily58.dtsi
  28. 1
      app/boards/shields/lily58/lily58_left.conf
  29. 3
      app/boards/shields/lily58/lily58_left.overlay
  30. 1
      app/boards/shields/lily58/lily58_right.conf
  31. 3
      app/boards/shields/lily58/lily58_right.overlay
  32. 10
      app/drivers/zephyr/kscan_gpio_matrix.c
  33. 2
      app/dts/behaviors.dtsi
  34. 15
      app/dts/behaviors/none.dtsi
  35. 15
      app/dts/behaviors/toggle_layer.dtsi
  36. 8
      app/dts/bindings/behaviors/zmk,behavior-none.yaml
  37. 8
      app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml
  38. 12
      app/dts/bindings/zmk,bt-unpair-combo.yaml
  39. 2
      app/include/zmk/ble.h
  40. 2
      app/include/zmk/keymap.h
  41. 48
      app/src/behaviors/behavior_none.c
  42. 49
      app/src/behaviors/behavior_toggle_layer.c
  43. 42
      app/src/ble.c
  44. 80
      app/src/ble_unpair_combo.c
  45. 15
      app/src/keymap.c
  46. 36
      app/src/usb_hid.c
  47. 12
      app/west.yml
  48. 4
      docs/blog/2020-08-12-zmk-sotf-1.md
  49. 2
      docs/docs/behavior/key-press.md
  50. 51
      docs/docs/behavior/layers.md
  51. 41
      docs/docs/behavior/misc.md
  52. 29
      docs/docs/behavior/mod-tap.md
  53. 2
      docs/sidebars.js
  54. 3
      docs/static/setup.sh

10
.github/workflows/build.yml

@ -8,7 +8,7 @@ jobs:
name: Build Test name: Build Test
strategy: strategy:
matrix: matrix:
board: [proton_c, nice_nano] board: [proton_c, nice_nano, bluemicro52840_v1]
shield: shield:
- corne_left - corne_left
- corne_right - corne_right
@ -34,11 +34,11 @@ jobs:
tools/ tools/
zephyr/ zephyr/
bootloader/ bootloader/
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('app/west.yml') }} key: 2-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('app/west.yml') }}
restore-keys: | restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}- 2-${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build- 2-${{ runner.os }}-build-
${{ runner.os }}- 2-${{ runner.os }}-
- name: West Init - name: West Init
uses: "docker://zmkfirmware/zephyr-west-action-arm:latest" uses: "docker://zmkfirmware/zephyr-west-action-arm:latest"
id: west-init id: west-init

3
app/CMakeLists.txt

@ -38,10 +38,13 @@ target_sources(app PRIVATE src/behaviors/behavior_key_press.c)
target_sources(app PRIVATE src/behaviors/behavior_reset.c) target_sources(app PRIVATE src/behaviors/behavior_reset.c)
target_sources(app PRIVATE src/behaviors/behavior_mod_tap.c) target_sources(app PRIVATE src/behaviors/behavior_mod_tap.c)
target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c) target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c)
target_sources(app PRIVATE src/behaviors/behavior_transparent.c) target_sources(app PRIVATE src/behaviors/behavior_transparent.c)
target_sources(app PRIVATE src/behaviors/behavior_none.c)
target_sources(app PRIVATE src/behaviors/behavior_sensor_rotate_key_press.c) target_sources(app PRIVATE src/behaviors/behavior_sensor_rotate_key_press.c)
target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/behaviors/behavior_rgb_underglow.c) target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/behaviors/behavior_rgb_underglow.c)
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c) target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/ble.c)
target_sources_ifdef(CONFIG_ZMK_BLE_UNPAIR_COMBO app PRIVATE src/ble_unpair_combo.c)
target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL app PRIVATE src/split_listener.c) target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL app PRIVATE src/split_listener.c)
target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL app PRIVATE src/split/bluetooth/service.c) target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL app PRIVATE src/split/bluetooth/service.c)
target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL app PRIVATE src/split/bluetooth/central.c) target_sources_ifdef(CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL app PRIVATE src/split/bluetooth/central.c)

13
app/Kconfig

@ -40,11 +40,17 @@ menuconfig ZMK_BLE
select BT_PERIPHERAL select BT_PERIPHERAL
select BT_GATT_DIS select BT_GATT_DIS
select BT_GATT_BAS select BT_GATT_BAS
# select SETTINGS select SETTINGS
# select BT_SETTINGS select BT_SETTINGS
if ZMK_BLE if ZMK_BLE
config ZMK_BLE_UNPAIR_COMBO
bool "Enable BT unpair combo"
help
Adds a magic key combo that can be held on startup to remove all paired devices
default n
config ZMK_BLE_INIT_PRIORITY config ZMK_BLE_INIT_PRIORITY
int "Init Priority" int "Init Priority"
default 50 default 50
@ -124,6 +130,9 @@ config ZMK_USB
config BT_MAX_CONN config BT_MAX_CONN
default 5 default 5
config BT_GAP_AUTO_UPDATE_CONN_PARAMS
default n
endif endif
endchoice endchoice

8
app/boards/arm/bluemicro52840_v1/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
)

8
app/boards/arm/bluemicro52840_v1/Kconfig

@ -0,0 +1,8 @@
# SPDX-License-Identifier: MIT
config BOARD_ENABLE_DCDC
bool "Enable DCDC mode"
select SOC_DCDC_NRF52X
default y
depends on BOARD_BLUEMICRO52840_V1

8
app/boards/arm/bluemicro52840_v1/Kconfig.board

@ -0,0 +1,8 @@
# BlueMicro52840_V1 board configuration
# Copyright (c) 2020 Pete Johanson, Derek Schmell
# SPDX-License-Identifier: MIT
config BOARD_BLUEMICRO52840_V1
bool "BlueMicro52840_V1"
depends on SOC_NRF52840_QIAA

30
app/boards/arm/bluemicro52840_v1/Kconfig.defconfig

@ -0,0 +1,30 @@
# BlueMicro52840 board configuration
# Copyright (c) 2020 Pete Johanson, Derek Schmell
# SPDX-License-Identifier: MIT
if BOARD_BLUEMICRO52840_V1
config BOARD
default "bluemicro52840_v1"
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
endif # BOARD_BLUEMICRO52840_V1

52
app/boards/arm/bluemicro52840_v1/arduino_pro_micro_pins.dtsi

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020 Derek Schmell
*
* SPDX-License-Identifier: MIT
*/
/ {
pro_micro_d: connector_d {
compatible = "arduino-pro-micro";
#gpio-cells = <2>;
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map
= <0 0 &gpio0 8 0> /* D0 D2 */
, <1 0 &gpio0 6 0> /* D1 D3*/
, <2 0 &gpio0 15 0> /* D2 D1*/
, <3 0 &gpio0 17 0> /* D3 D0*/
, <4 0 &gpio0 20 0> /* D4/A6 D4*/
, <5 0 &gpio0 13 0> /* D5 C6*/
, <6 0 &gpio0 24 0> /* D6/A7 D7*/
, <7 0 &gpio0 9 0> /* D7 E6*/
, <8 0 &gpio0 10 0> /* D8/A8 B4*/
, <9 0 &gpio1 6 0> /* D9/A9 B5*/
, <10 0 &gpio1 11 0> /* D10/A10 B6*/
, <16 0 &gpio0 28 0> /* D16 B2*/
, <14 0 &gpio0 3 0> /* D14 B3*/
, <15 0 &gpio1 13 0> /* D15 B1*/
;
};
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 2 0> /* A0 F7*/
, <1 0 &gpio0 29 0> /* A1 F6*/
, <2 0 &gpio0 26 0> /* A2 F5*/
, <3 0 &gpio0 30 0> /* A3 F4*/
, <6 0 &gpio0 20 0> /* D4/A6 D4*/
, <7 0 &gpio0 24 0> /* D6/A7 D7*/
, <8 0 &gpio0 10 0> /* D8/A8 B4*/
, <9 0 &gpio1 6 0> /* D9/A9 B5*/
, <10 0 &gpio1 13 0> /* D10/A10 B6*/
;
};
};
pro_micro_i2c: &i2c0 {};
pro_micro_spi: &spi0 {};
pro_micro_serial: &uart0 {};

96
app/boards/arm/bluemicro52840_v1/bluemicro52840_v1.dts

@ -0,0 +1,96 @@
/*
* Copyright (c) 2020 Pete Johanson, Derek Schmell
*
* SPDX-License-Identifier: MIT
*/
/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "arduino_pro_micro_pins.dtsi"
/ {
model = "BlueMicro52840_V1";
compatible = "bluemicro52840,v1";
chosen {
zephyr,code-partition = &code_partition;
// zephyr,console = &uart0;
//zephyr,bt-mon-uart = &uart0;
//zephyr,bt-c2h-uart = &uart0;
zephyr,sram = &sram0;
zephyr,flash = &flash0;
};
leds {
compatible = "gpio-leds";
blue_led: led_0 {
gpios = <&gpio0 42 GPIO_ACTIVE_HIGH>;
label = "Blue LED";
};
};
};
&gpio0 {
status = "okay";
};
&gpio1 {
status = "okay";
};
&i2c0 {
compatible = "nordic,nrf-twi";
sda-pin = <15>;
scl-pin = <17>;
};
&uart0 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <115200>;
tx-pin = <39>;
rx-pin = <34>;
rts-pin = <33>;
cts-pin = <12>;
};
&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>;
boot_partition: partition@0 {
label = "adafruit_boot";
reg = <0x000000000 0x0000C000>;
};
code_partition: partition@26000 {
label = "code_partition";
reg = <0x00026000 0x000d2000>;
};
/*
* The flash starting at 0x000f8000 and ending at
* 0x000fffff is reserved for use by the application.
*/
/*
* Storage partition will be used by FCB/LittleFS/NVS
* if enabled.
*/
storage_partition: partition@f8000 {
label = "storage";
reg = <0x000f8000 0x00008000>;
};
};
};

15
app/boards/arm/bluemicro52840_v1/bluemicro52840_v1.yaml

@ -0,0 +1,15 @@
identifier: bluemicro52840_v1
name: BlueMicro52840_V1
type: mcu
arch: arm
toolchain:
- zephyr
- gnuarmemb
- xtools
supported:
- adc
- usb_device
- ble
- ieee802154
- pwm
- watchdog

20
app/boards/arm/bluemicro52840_v1/bluemicro52840_v1_defconfig

@ -0,0 +1,20 @@
# SPDX-License-Identifier: MIT
CONFIG_SOC_SERIES_NRF52X=y
CONFIG_SOC_NRF52840_QIAA=y
CONFIG_BOARD_BLUEMICRO52840_V1=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

5
app/boards/arm/bluemicro52840_v1/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)

1
app/boards/arm/nice_nano/Kconfig

@ -1,3 +1,4 @@
# SPDX-License-Identifier: MIT
config BOARD_ENABLE_DCDC config BOARD_ENABLE_DCDC
bool "Enable DCDC mode" bool "Enable DCDC mode"

2
app/boards/arm/nice_nano/Kconfig.defconfig

@ -1,5 +1,3 @@
# Electronut Labs Papyr board configuration
# Copyright (c) 2020 Pete Johanson # Copyright (c) 2020 Pete Johanson
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT

9
app/boards/arm/nice_nano/nice_nano.dts

@ -24,7 +24,7 @@
leds { leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
blue_led: led_0 { blue_led: led_0 {
gpios = <&gpio0 15 GPIO_ACTIVE_LOW>; gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
label = "Blue LED"; label = "Blue LED";
}; };
}; };
@ -39,13 +39,6 @@
status = "okay"; status = "okay";
}; };
&uart0 {
compatible = "nordic,nrf-uart";
current-speed = <115200>;
tx-pin = <6>;
rx-pin = <8>;
};
&i2c0 { &i2c0 {
compatible = "nordic,nrf-twi"; compatible = "nordic,nrf-twi";
sda-pin = <17>; sda-pin = <17>;

17
app/boards/shields/corne/corne.dtsi

@ -21,9 +21,9 @@
// | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 | // | SW13 | SW14 | SW15 | SW16 | SW17 | SW18 | | SW18 | SW17 | SW16 | SW15 | SW14 | SW13 |
// | SW19 | SW20 | SW21 | | SW21 | SW20 | SW19 | // | SW19 | SW20 | SW21 | | SW21 | SW20 | SW19 |
map = < 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,12) RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11)
RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,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,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,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(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8)
>; >;
}; };
@ -58,13 +58,17 @@ 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
}; };
bt_unpair_combo: bt_unpair_combo {
compatible = "zmk,bt-unpair-combo";
};
// TODO: per-key RGB node(s)? // TODO: per-key RGB node(s)?
}; };
&pro_micro_i2c { &pro_micro_i2c {
status = "okay"; status = "okay";
ssd1306@3c { oled: ssd1306@3c {
compatible = "solomon,ssd1306fb"; compatible = "solomon,ssd1306fb";
reg = <0x3c>; reg = <0x3c>;
label = "DISPLAY"; label = "DISPLAY";
@ -73,7 +77,10 @@ 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
segment-offset = <0>; segment-offset = <0>;
page-offset = <0>; page-offset = <0>;
display-offset = <0>; display-offset = <0>;
multiplex-ratio = <63>; multiplex-ratio = <31>;
segment-remap;
com-invdir;
com-sequential;
prechargep = <0x22>; prechargep = <0x22>;
}; };
}; };

60
app/boards/shields/corne/corne.keymap

@ -2,21 +2,49 @@
#include <dt-bindings/zmk/keys.h> #include <dt-bindings/zmk/keys.h>
/ { / {
keymap { keymap {
compatible = "zmk,keymap"; compatible = "zmk,keymap";
default_layer { default_layer {
// --------------------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
// | ESC | Q | W | E | R | T | | Y | U | I | O | P | \ | // | TAB | Q | W | E | R | T | | Y | U | I | O | P | BKSP |
// | TAB | A | S | D | F | G | | H | J | K | L | ; | ' | // | CTRL | A | S | D | F | G | | H | J | K | L | ; | ' |
// | SHIFT | Z | X | C | V | B | | N | M | , | . | / | CTRL | // | SHFT | Z | X | C | V | B | | N | M | , | . | / | SHFT |
// | GUI | DEL | RET | | TAB | BSPC | R-ALT | // | GUI | LWR | SPC | | ENT | RSE | ALT |
bindings = < bindings = <
&kp ESC &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSLH &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BKSP
&kp TAB &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SCLN &kp QUOT &kp LCTL &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SCLN &kp QUOT
&kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RCTL &kp LSFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp CMMA &kp DOT &kp FSLH &kp RSFT
&kp LGUI &kp DEL &kp RET &kp TAB &kp BKSP &kp RALT &kp LGUI &mo 1 &kp SPC &kp RET &mo 2 &kp RALT
>; >;
}; };
}; lower_layer {
// -----------------------------------------------------------------------------------------
// | ESC | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | BKSP |
// | CTRL | | | | | | | RGT | UP | DWN | LFT | | |
// | SHFT | | | | | | | | | | | | |
// | GUI | | SPC | | ENT | | ALT |
bindings = <
&kp ESC &kp NUM_1 &kp NUM_2 &kp NUM_3 &kp NUM_4 &kp NUM_5 &kp NUM_6 &kp NUM_7 &kp NUM_8 &kp NUM_9 &kp NUM_0 &kp BKSP
&kp LCTL &trans &trans &trans &trans &trans &kp RARW &kp UARW &kp DARW &kp LARW &trans &trans
&kp LSFT &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
&kp LGUI &trans &kp SPC &kp RET &trans &kp RALT
>;
};
raise_layer {
// -----------------------------------------------------------------------------------------
// | ESC | ! | @ | # | $ | % | | ^ | & | * | ( | ) | BKSP |
// | CTRL | | | | | | | - | = | { | } | "|" | ` |
// | SHFT | | | | | | | _ | + | [ | ] | \ | ~ | // TODO: Fix this row when &mkp is committed
// | GUI | | SPC | | ENT | | ALT |
bindings = <
&kp ESC &kp BANG &kp ATSN &kp HASH &kp CURU &kp PRCT &kp CRRT &kp AMPS &kp KMLT &kp LPRN &kp RPRN &kp BKSP
&kp LCTL &trans &trans &trans &trans &trans &kp MINUS &kp EQL &kp LBKT &kp RBKT &kp PIPE &trans
&kp LSFT &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
&kp LGUI &trans &kp SPC &kp RET &trans &kp RALT
>;
};
};
}; };

1
app/boards/shields/corne/corne_left.conf

@ -1,2 +1,3 @@
CONFIG_ZMK_SPLIT=y CONFIG_ZMK_SPLIT=y
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y
CONFIG_ZMK_BLE_UNPAIR_COMBO=y

4
app/boards/shields/corne/corne_left.overlay

@ -16,3 +16,7 @@
, <&pro_micro_d 14 GPIO_ACTIVE_HIGH> , <&pro_micro_d 14 GPIO_ACTIVE_HIGH>
; ;
}; };
&bt_unpair_combo {
key-positions = <0 38>;
};

1
app/boards/shields/corne/corne_right.conf

@ -1,2 +1,3 @@
CONFIG_ZMK_SPLIT=y CONFIG_ZMK_SPLIT=y
CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y
CONFIG_ZMK_BLE_UNPAIR_COMBO=y

3
app/boards/shields/corne/corne_right.overlay

@ -21,3 +21,6 @@
; ;
}; };
&bt_unpair_combo {
key-positions = <11 39>;
};

4
app/boards/shields/kyria/kyria.dtsi

@ -81,6 +81,10 @@ 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)
sensors = <&left_encoder &right_encoder>; sensors = <&left_encoder &right_encoder>;
}; };
bt_unpair_combo: bt_unpair_combo {
compatible = "zmk,bt-unpair-combo";
};
// TODO: RGB node(s) // TODO: RGB node(s)
}; };

1
app/boards/shields/kyria/kyria_left.conf

@ -1,2 +1,3 @@
CONFIG_ZMK_SPLIT=y CONFIG_ZMK_SPLIT=y
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y
CONFIG_ZMK_BLE_UNPAIR_COMBO=y

4
app/boards/shields/kyria/kyria_left.overlay

@ -22,3 +22,7 @@
&left_encoder { &left_encoder {
status = "okay"; status = "okay";
}; };
&bt_unpair_combo {
key-positions = <0 44>;
};

1
app/boards/shields/kyria/kyria_right.conf

@ -1,2 +1,3 @@
CONFIG_ZMK_SPLIT=y CONFIG_ZMK_SPLIT=y
CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y
CONFIG_ZMK_BLE_UNPAIR_COMBO=y

4
app/boards/shields/kyria/kyria_right.overlay

@ -27,3 +27,7 @@
&right_encoder { &right_encoder {
status = "okay"; status = "okay";
}; };
&bt_unpair_combo {
key-positions = <11 45>;
};

6
app/boards/shields/lily58/lily58.dtsi

@ -44,12 +44,16 @@ RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(4,5) RC(4,6) RC(3,6) RC(3,7)
; ;
}; };
bt_unpair_combo: bt_unpair_combo {
compatible = "zmk,bt-unpair-combo";
};
}; };
&pro_micro_i2c { &pro_micro_i2c {
status = "okay"; status = "okay";
ssd1306@3c { oled: ssd1306@3c {
compatible = "solomon,ssd1306fb"; compatible = "solomon,ssd1306fb";
reg = <0x3c>; reg = <0x3c>;
label = "DISPLAY"; label = "DISPLAY";

1
app/boards/shields/lily58/lily58_left.conf

@ -1,2 +1,3 @@
CONFIG_ZMK_SPLIT=y CONFIG_ZMK_SPLIT=y
CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL=y
CONFIG_ZMK_BLE_UNPAIR_COMBO=y

3
app/boards/shields/lily58/lily58_left.overlay

@ -17,3 +17,6 @@
; ;
}; };
&bt_unpair_combo {
key-positions = <0 42>;
};

1
app/boards/shields/lily58/lily58_right.conf

@ -1,2 +1,3 @@
CONFIG_ZMK_SPLIT=y CONFIG_ZMK_SPLIT=y
CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL=y
CONFIG_ZMK_BLE_UNPAIR_COMBO=y

3
app/boards/shields/lily58/lily58_right.overlay

@ -21,3 +21,6 @@
; ;
}; };
&bt_unpair_combo {
key-positions = <11 43>;
};

10
app/drivers/zephyr/kscan_gpio_matrix.c

@ -205,7 +205,13 @@ static int kscan_gpio_config_interrupts(struct device **devices,
} \ } \
data->callback = callback; \ data->callback = callback; \
return 0; \ return 0; \
} \ }; \
static int kscan_gpio_enable_##n(struct device *dev) \
{ \
int err = kscan_gpio_enable_interrupts_##n(dev); \
if (err) { return err; } \
return kscan_gpio_read_##n(dev); \
}; \
static int kscan_gpio_init_##n(struct device *dev) \ static int kscan_gpio_init_##n(struct device *dev) \
{ \ { \
struct kscan_gpio_data_##n *data = dev->driver_data; \ struct kscan_gpio_data_##n *data = dev->driver_data; \
@ -258,7 +264,7 @@ static int kscan_gpio_config_interrupts(struct device **devices,
} \ } \
static const struct kscan_driver_api gpio_driver_api_##n = { \ static const struct kscan_driver_api gpio_driver_api_##n = { \
.config = kscan_gpio_configure_##n, \ .config = kscan_gpio_configure_##n, \
.enable_callback = kscan_gpio_enable_interrupts_##n, \ .enable_callback = kscan_gpio_enable_##n, \
.disable_callback = kscan_gpio_disable_interrupts_##n, \ .disable_callback = kscan_gpio_disable_interrupts_##n, \
}; \ }; \
static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \ static const struct kscan_gpio_config_##n kscan_gpio_config_##n = { \

2
app/dts/behaviors.dtsi

@ -1,7 +1,9 @@
#include <behaviors/key_press.dtsi> #include <behaviors/key_press.dtsi>
#include <behaviors/transparent.dtsi> #include <behaviors/transparent.dtsi>
#include <behaviors/none.dtsi>
#include <behaviors/mod_tap.dtsi> #include <behaviors/mod_tap.dtsi>
#include <behaviors/momentary_layer.dtsi> #include <behaviors/momentary_layer.dtsi>
#include <behaviors/toggle_layer.dtsi>
#include <behaviors/reset.dtsi> #include <behaviors/reset.dtsi>
#include <behaviors/sensor_rotate_key_press.dtsi> #include <behaviors/sensor_rotate_key_press.dtsi>
#include <behaviors/rgb_underglow.dtsi> #include <behaviors/rgb_underglow.dtsi>

15
app/dts/behaviors/none.dtsi

@ -0,0 +1,15 @@
/*
* Copyright (c) 2020 Pete Johanson
*
* SPDX-License-Identifier: MIT
*/
/ {
behaviors {
none: behavior_none {
compatible = "zmk,behavior-none";
label = "NONE";
#binding-cells = <0>;
};
};
};

15
app/dts/behaviors/toggle_layer.dtsi

@ -0,0 +1,15 @@
/*
* Copyright (c) 2020 Cody McGinnis <brainwart@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
/ {
behaviors {
tog: behavior_toggle_layer {
compatible = "zmk,behavior-toggle-layer";
label = "TOGGLE_LAYER";
#binding-cells = <1>;
};
};
};

8
app/dts/bindings/behaviors/zmk,behavior-none.yaml

@ -0,0 +1,8 @@
# Copyright (c) 2020, Pete Johanson
# SPDX-License-Identifier: MIT
description: None Binding Behavior
compatible: "zmk,behavior-none"
include: zero_param.yaml

8
app/dts/bindings/behaviors/zmk,behavior-toggle-layer.yaml

@ -0,0 +1,8 @@
# Copyright (c) 2020, Cody McGinnis <brainwart@gmail.com>
# SPDX-License-Identifier: MIT
description: Toggle Layer
compatible: "zmk,behavior-toggle-layer"
include: one_param.yaml

12
app/dts/bindings/zmk,bt-unpair-combo.yaml

@ -0,0 +1,12 @@
# Copyright (c) 2020, Pete Johanson
# SPDX-License-Identifier: MIT
description: |
Defines a set of key positions that will unpair all BT devices if held on startup.
compatible: "zmk,bt-unpair-combo"
properties:
key-positions:
type: array
required: true

2
app/include/zmk/ble.h

@ -3,5 +3,5 @@
#include <zmk/keys.h> #include <zmk/keys.h>
int zmk_ble_init(); int zmk_ble_unpair_all();
bool zmk_ble_handle_key_user(struct zmk_key_event *key_event); bool zmk_ble_handle_key_user(struct zmk_key_event *key_event);

2
app/include/zmk/keymap.h

@ -1,6 +1,8 @@
#pragma once #pragma once
bool zmk_keymap_layer_active(u8_t layer);
int zmk_keymap_layer_activate(u8_t layer); int zmk_keymap_layer_activate(u8_t layer);
int zmk_keymap_layer_deactivate(u8_t layer); int zmk_keymap_layer_deactivate(u8_t layer);
int zmk_keymap_layer_toggle(u8_t layer);
int zmk_keymap_position_state_changed(u32_t position, bool pressed); int zmk_keymap_position_state_changed(u32_t position, bool pressed);

48
app/src/behaviors/behavior_none.c

@ -0,0 +1,48 @@
/*
* Copyright (c) 2020 Peter Johanson <peter@peterjohanson.com>
*
* SPDX-License-Identifier: MIT
*/
#define DT_DRV_COMPAT zmk_behavior_none
#include <device.h>
#include <power/reboot.h>
#include <drivers/behavior.h>
#include <logging/log.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
struct behavior_none_config { };
struct behavior_none_data { };
static int behavior_none_init(struct device *dev)
{
return 0;
};
static int on_keymap_binding_pressed(struct device *dev, u32_t position, u32_t _param1, u32_t _param2)
{
return 1;
}
static int on_keymap_binding_released(struct device *dev, u32_t position, u32_t _param1, u32_t _param2)
{
return 1;
}
static const struct behavior_driver_api behavior_none_driver_api = {
.binding_pressed = on_keymap_binding_pressed,
.binding_released = on_keymap_binding_released,
};
static const struct behavior_none_config behavior_none_config = {};
static struct behavior_none_data behavior_none_data;
DEVICE_AND_API_INIT(behavior_none, DT_INST_LABEL(0), behavior_none_init,
&behavior_none_data,
&behavior_none_config,
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&behavior_none_driver_api);

49
app/src/behaviors/behavior_toggle_layer.c

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 Cody McGinnis <brainwart@gmail.com>
*
* SPDX-License-Identifier: MIT
*/
#define DT_DRV_COMPAT zmk_behavior_toggle_layer
#include <device.h>
#include <drivers/behavior.h>
#include <logging/log.h>
#include <zmk/keymap.h>
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
struct behavior_tog_config { };
struct behavior_tog_data { };
static int behavior_tog_init(struct device *dev)
{
return 0;
};
static int tog_keymap_binding_pressed(struct device *dev, u32_t position, u32_t layer, u32_t _)
{
return zmk_keymap_layer_toggle(layer);
}
static int tog_keymap_binding_released(struct device *dev, u32_t position, u32_t layer, u32_t _)
{
return 0;
}
static const struct behavior_driver_api behavior_tog_driver_api = {
.binding_pressed = tog_keymap_binding_pressed,
.binding_released = tog_keymap_binding_released,
};
static const struct behavior_tog_config behavior_tog_config = {};
static struct behavior_tog_data behavior_tog_data;
DEVICE_AND_API_INIT(behavior_tog, DT_INST_LABEL(0), behavior_tog_init,
&behavior_tog_data,
&behavior_tog_config,
APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&behavior_tog_driver_api);

42
app/src/ble.c

@ -1,3 +1,8 @@
/*
* Copyright (c) 2020 Peter Johanson
*
* SPDX-License-Identifier: MIT
*/
#include <device.h> #include <device.h>
#include <init.h> #include <init.h>
@ -23,6 +28,16 @@ static struct bt_conn *auth_passkey_entry_conn;
static u8_t passkey_entries[6] = {0, 0, 0, 0, 0, 0}; static u8_t passkey_entries[6] = {0, 0, 0, 0, 0, 0};
static u8_t passkey_digit = 0; static u8_t passkey_digit = 0;
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
#define ZMK_ADV_PARAMS BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | \
BT_LE_ADV_OPT_USE_NAME | \
BT_LE_ADV_OPT_ONE_TIME, \
BT_GAP_ADV_FAST_INT_MIN_2, \
BT_GAP_ADV_FAST_INT_MAX_2, NULL)
#else
#define ZMK_ADV_PARAMS BT_LE_ADV_CONN_NAME
#endif
static void connected(struct bt_conn *conn, u8_t err) static void connected(struct bt_conn *conn, u8_t err)
{ {
char addr[BT_ADDR_LE_STR_LEN]; char addr[BT_ADDR_LE_STR_LEN];
@ -76,29 +91,10 @@ static void security_changed(struct bt_conn *conn, bt_security_t level,
} }
} }
#if !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param) {
static struct bt_conn_info info;
bt_conn_get_info(conn, &info);
/* This captures a param change from central half of a split board connection
to stop default params from getting set over the top of our preferred ones */
if (info.role == BT_CONN_ROLE_MASTER && (param->interval_min != 6 || param->latency != 30)) {
return false;
}
return true;
}
#endif
static struct bt_conn_cb conn_callbacks = { static struct bt_conn_cb conn_callbacks = {
.connected = connected, .connected = connected,
.disconnected = disconnected, .disconnected = disconnected,
.security_changed = security_changed, .security_changed = security_changed,
#if !IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_ROLE_PERIPHERAL)
.le_param_req = le_param_req,
#endif
}; };
static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey) static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
@ -173,7 +169,7 @@ static void zmk_ble_ready(int err)
return; return;
} }
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0); err = bt_le_adv_start(ZMK_ADV_PARAMS, zmk_ble_ad, ARRAY_SIZE(zmk_ble_ad), NULL, 0);
if (err) if (err)
{ {
LOG_ERR("Advertising failed to start (err %d)", err); LOG_ERR("Advertising failed to start (err %d)", err);
@ -204,6 +200,12 @@ static int zmk_ble_init(struct device *_arg)
return 0; return 0;
} }
int zmk_ble_unpair_all()
{
LOG_DBG("");
return bt_unpair(BT_ID_DEFAULT, NULL);
};
bool zmk_ble_handle_key_user(struct zmk_key_event *key_event) bool zmk_ble_handle_key_user(struct zmk_key_event *key_event)
{ {
zmk_key key = key_event->key; zmk_key key = key_event->key;

80
app/src/ble_unpair_combo.c

@ -0,0 +1,80 @@
/*
* Copyright (c) 2020 Peter Johanson
*
* SPDX-License-Identifier: MIT
*/
#include <device.h>
#include <init.h>
#include <logging/log.h>
#define DT_DRV_COMPAT zmk_bt_unpair_combo
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#include <zmk/ble.h>
#include <zmk/event-manager.h>
#include <zmk/events/position-state-changed.h>
static u8_t combo_state;
const u32_t key_positions[] = DT_INST_PROP(0, key_positions);
#define KP_LEN DT_INST_PROP_LEN(0, key_positions)
int index_for_key_position(u32_t kp)
{
for (int i = 0; i < KP_LEN; i++) {
if (key_positions[i] == kp) {
return i;
}
}
return -1;
}
int unpair_combo_listener(const struct zmk_event_header *eh)
{
if (is_position_state_changed(eh)) {
const struct position_state_changed *psc = cast_position_state_changed(eh);
int kp_index = index_for_key_position(psc->position);
if (kp_index < 0) {
return 0;
}
WRITE_BIT(combo_state, kp_index, psc->state);
}
return 0;
};
void unpair_combo_work_handler(struct k_work *work)
{
for (int i = 0; i < KP_LEN; i++) {
if (!(combo_state & BIT(i))) {
LOG_DBG("Key position %d not held, skipping unpair combo", key_positions[i]);
return;
}
}
zmk_ble_unpair_all();
};
struct k_delayed_work unpair_combo_work;
int zmk_ble_unpair_combo_init(struct device *_unused)
{
k_delayed_work_init(&unpair_combo_work, unpair_combo_work_handler);
k_delayed_work_submit(&unpair_combo_work, K_SECONDS(2));
return 0;
};
ZMK_LISTENER(zmk_ble_unpair_combo, unpair_combo_listener);
ZMK_SUBSCRIPTION(zmk_ble_unpair_combo, position_state_changed);
SYS_INIT(zmk_ble_unpair_combo_init,
APPLICATION,
CONFIG_APPLICATION_INIT_PRIORITY);

15
app/src/keymap.c

@ -76,6 +76,11 @@ static struct zmk_behavior_binding zmk_sensor_keymap[ZMK_KEYMAP_LAYERS_LEN][ZMK_
WRITE_BIT(zmk_keymap_layer_state, layer, state); \ WRITE_BIT(zmk_keymap_layer_state, layer, state); \
return 0; return 0;
bool zmk_keymap_layer_active(u8_t layer)
{
return (zmk_keymap_layer_state & (BIT(layer))) == (BIT(layer));
};
int zmk_keymap_layer_activate(u8_t layer) int zmk_keymap_layer_activate(u8_t layer)
{ {
SET_LAYER_STATE(layer, true); SET_LAYER_STATE(layer, true);
@ -86,6 +91,16 @@ int zmk_keymap_layer_deactivate(u8_t layer)
SET_LAYER_STATE(layer, false); SET_LAYER_STATE(layer, false);
}; };
int zmk_keymap_layer_toggle(u8_t layer)
{
if (zmk_keymap_layer_active(layer))
{
return zmk_keymap_layer_deactivate(layer);
}
return zmk_keymap_layer_activate(layer);
};
bool is_active_position(u32_t position, u8_t layer) bool is_active_position(u32_t position, u8_t layer)
{ {
return (zmk_keymap_layer_state & BIT(layer)) == BIT(layer) return (zmk_keymap_layer_state & BIT(layer)) == BIT(layer)

36
app/src/usb_hid.c

@ -11,18 +11,42 @@
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
static enum usb_dc_status_code usb_status; static enum usb_dc_status_code usb_status = USB_DC_UNKNOWN;
static struct device *hid_dev; static struct device *hid_dev;
static K_SEM_DEFINE(hid_sem, 1, 1);
static void in_ready_cb(void)
{
k_sem_give(&hid_sem);
}
static const struct hid_ops ops =
{
.int_in_ready = in_ready_cb,
};
int zmk_usb_hid_send_report(const u8_t *report, size_t len) int zmk_usb_hid_send_report(const u8_t *report, size_t len)
{ {
if (usb_status == USB_DC_SUSPEND) switch(usb_status) {
{ case USB_DC_SUSPEND:
return usb_wakeup_request(); return usb_wakeup_request();
case USB_DC_ERROR:
case USB_DC_RESET:
case USB_DC_DISCONNECTED:
case USB_DC_UNKNOWN:
return -ENODEV;
default:
k_sem_take(&hid_sem, K_MSEC(30));
int err = hid_int_ep_write(hid_dev, report, len, NULL);
if (err) {
k_sem_give(&hid_sem);
}
return err;
} }
return hid_int_ep_write(hid_dev, report, len, NULL);
} }
void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params) void usb_hid_status_cb(enum usb_dc_status_code status, const u8_t *params)
@ -43,7 +67,7 @@ static int zmk_usb_hid_init(struct device *_arg)
usb_hid_register_device(hid_dev, usb_hid_register_device(hid_dev,
zmk_hid_report_desc, sizeof(zmk_hid_report_desc), zmk_hid_report_desc, sizeof(zmk_hid_report_desc),
NULL); &ops);
usb_hid_init(hid_dev); usb_hid_init(hid_dev);

12
app/west.yml

@ -21,6 +21,18 @@ manifest:
- hal_microchip - hal_microchip
- hal_nxp - hal_nxp
- hal_openisa - hal_openisa
- hal_silabs
- hal_xtensa
- hal_st
- hal_ti
- loramac-node
- mcuboot
- mcumgr
- net-tools
- segger
- openthread
- edtt
- trusted-firmware-m
- name: uf2 - name: uf2
remote: microsoft remote: microsoft
path: tools/uf2 path: tools/uf2

4
docs/blog/2020-08-12-zmk-sotf-1.md

@ -28,10 +28,10 @@ There's been lots of various activity in ZMK land!
Despite the flurry of activity, there are still some serious bugs and show stoppers that potential ZMK users should be aware of: Despite the flurry of activity, there are still some serious bugs and show stoppers that potential ZMK users should be aware of:
- [Bluetooth Related](https://github.com/zmkfirmware/zmk/issues/58) - There are several key bugs and fixes needed, including one complete show stopper: - [Bluetooth Related](https://github.com/zmkfirmware/zmk/issues/58) - There are several key bugs and fixes needed, including one complete show stopper:
- Fully working split wireless is not working. In particular, both split halves can properly pair, but once they do so, pairing with the _central_ host will not work. Workaround: You can currently have both halves pair, and use USB on the central side (Left side right now for Kyria, Corne, Lily58) and receive HID events over USB. - <del>Fully working split wireless is not working. In particular, both split halves can properly pair, but once they do so, pairing with the _central_ host will not work. Workaround: You can currently have both halves pair, and use USB on the central side (Left side right now for Kyria, Corne, Lily58) and receive HID events over USB.</del> - Fixed in <a href="https://github.com/zmkfirmware/zmk/commit/8b61beb2bbc62f754db670ad77266f84edde041d">8b61beb</a>.
- BT bond information is not currently stored to the devices, so after powering off or restarting your device, users need to re-pair - BT bond information is not currently stored to the devices, so after powering off or restarting your device, users need to re-pair
- USB - There is one important USB related bug which is a showstopper: - USB - There is one important USB related bug which is a showstopper:
- The Zephyr USB stack does not have a built in queue for endpoint data being written. As a result, HID events sent by ZMK are sometimes [dropped, or lost](https://github.com/zmkfirmware/zmk/issues/84). - <del>The Zephyr USB stack does not have a built in queue for endpoint data being written. As a result, HID events sent by ZMK are sometimes <a href="https://github.com/zmkfirmware/zmk/issues/84">dropped, or lost</a>.</del> - Fixed by <a href="https://github.com/careyk007">careyk007</a> in <a href="https://github.com/zmkfirmware/zmk/pull/93">#93</a>.
## Next Steps ## Next Steps

2
docs/docs/behavior/key-press.md

@ -4,7 +4,7 @@ title: Key Presses
## Summary ## Summary
The most basic of behaiors, is the ability to send certain keycode presses and releases in response to activating The most basic of behaviors, is the ability to send certain keycode presses and releases in response to activating
a certain key. a certain key.
For reference on keycode values, see the [USB HID Usage Tables](https://www.usb.org/document-library/hid-usage-tables-12). For reference on keycode values, see the [USB HID Usage Tables](https://www.usb.org/document-library/hid-usage-tables-12).

51
docs/docs/behavior/layers.md

@ -39,3 +39,54 @@ Example:
``` ```
&mo LOWER &mo LOWER
``` ```
## Toggle Layer
The "toggle layer" behavior allows you to enable a layer until the layer is manually disabled.
### Behavior Binding
- Reference: `&tog`
- Parameter: The layer number to enable/disable, e.g. `1`
Example:
```
&tog LOWER
```
"Toggle layer" for a :
```
#define DEFAULT 0
#define NAVI 1
#define NONE 0
/ {
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&tog NAVI &kp KDIV &kp KMLT &kp KMIN
&kp NUM_7 &kp NUM_8 &kp NUM_9 &kp KPLS
&kp NUM_4 &kp NUM_5 &kp NUM_6 &kp KPLS
&kp NUM_1 &kp NUM_2 &kp NUM_3 &kp RET
&kp NUM_0 &kp NUM_0 &kp DOT &kp RET
>;
};
nav_layer {
bindings = <
&tog NAVI &kp KDIV &kp KMLT &kp KMIN
&kp HOME &kp UARW &kp PGUP &kp KPLS
&kp LARW &none &kp RARW &kp KPLS
&kp END &kp DARW &kp PGDN &kp RET
&kp INS &kp INS &kp DEL &kp RET
>;
};
};
};
```
It is possible to use "toggle layer" to have keys that raise and lower the layers as well.

41
docs/docs/behavior/misc.md

@ -0,0 +1,41 @@
---
title: Miscellaneous
---
## Summary
There are a few miscellaneous behaviors that are helpful when working with layers in keymaps,
in particular, with handling what happens in higher layers, and if events are passed to
the next layer or not
## Transparent
The transparent behavior simply ignores key position presses/releases, so they will be
passed down to the next active layer in the stack.
### Behavior Binding
- Reference: `&trans`
- Parameters: None
Example:
```
&trans
```
## None
The none behavior simply swallows and stops key position presses/releases, so they will **not**
be passed down to the next active layer in the stack.
### Behavior Binding
- Reference: `&none`
- Parameters: None
Example:
```
&none
```

29
docs/docs/behavior/mod-tap.md

@ -0,0 +1,29 @@
---
title: Mod-Tap
---
## Summary
The Mod-Tap behavior allows varying the effect of pressing and releasing a key position depending
on whether it is used with other simultaneous key presses at the same time.
If pressed and released independently, the Mod-Tap behavior will send the press and release events
for the configure keycode. If pressed and held while another key is pressed and released, then
the configured modifiers will be applied to that _other_ key press, and no press will be generated
on the release of the Mod-Tap key.
## Mod-Tap
The Mod-Tap behavior either acts as a held modifier, or as a tapped keycode.
### Behavior Binding
- Reference: `&mt`
- Parameter #1: The modifiers to be used when activating as a modifier, e.g. `MOD_LSFT`
- Parameter #2: The keycode to sent when used as a tap, e.g. `A`, `B`.
Example:
```
&mt MOD_LSFT A
```

2
docs/sidebars.js

@ -10,6 +10,8 @@ module.exports = {
Behaviors: [ Behaviors: [
"behavior/key-press", "behavior/key-press",
"behavior/layers", "behavior/layers",
"behavior/misc",
"behavior/mod-tap",
"behavior/lighting", "behavior/lighting",
], ],
Development: [ Development: [

3
docs/static/setup.sh vendored

@ -11,7 +11,7 @@ title="ZMK Config Setup:"
# TODO: Check for user.name and user.email git configs being set # TODO: Check for user.name and user.email git configs being set
prompt="Pick an MCU board:" prompt="Pick an MCU board:"
options=("nice!nano" "QMK Proton-C") options=("nice!nano" "QMK Proton-C" "BlueMicro52840 (v1)")
echo "$title" echo "$title"
echo "" echo ""
@ -23,6 +23,7 @@ select opt in "${options[@]}" "Quit"; do
1 ) board="nice_nano"; break;; 1 ) board="nice_nano"; break;;
2 ) board="proton_c"; break;; 2 ) board="proton_c"; break;;
3 ) board="bluemicro52840_v1"; break;;
$(( ${#options[@]}+1 )) ) echo "Goodbye!"; exit;; $(( ${#options[@]}+1 )) ) echo "Goodbye!"; exit;;
*) echo "Invalid option. Try another one.";continue;; *) echo "Invalid option. Try another one.";continue;;

Loading…
Cancel
Save