Merge branch 'zmkfirmware:main' into main
This commit is contained in:
commit
88ba9c4429
96 changed files with 1337 additions and 58 deletions
2
.github/workflows/clang-format-lint.yml
vendored
2
.github/workflows/clang-format-lint.yml
vendored
|
@ -23,7 +23,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: DoozyX/clang-format-lint-action@v0.12
|
- uses: DoozyX/clang-format-lint-action@v0.13
|
||||||
with:
|
with:
|
||||||
source: "./app"
|
source: "./app"
|
||||||
extensions: "h,c"
|
extensions: "h,c"
|
||||||
|
|
|
@ -167,6 +167,7 @@ menuconfig ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||||
bool "Central"
|
bool "Central"
|
||||||
select BT_CENTRAL
|
select BT_CENTRAL
|
||||||
select BT_GATT_CLIENT
|
select BT_GATT_CLIENT
|
||||||
|
select BT_GATT_AUTO_DISCOVER_CCC
|
||||||
|
|
||||||
if ZMK_SPLIT_BLE_ROLE_CENTRAL
|
if ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||||
|
|
||||||
|
|
14
app/boards/arm/mikoto/CMakeLists.txt
Normal file
14
app/boards/arm/mikoto/CMakeLists.txt
Normal file
|
@ -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()
|
29
app/boards/arm/mikoto/Kconfig
Normal file
29
app/boards/arm/mikoto/Kconfig
Normal file
|
@ -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
|
8
app/boards/arm/mikoto/Kconfig.board
Normal file
8
app/boards/arm/mikoto/Kconfig.board
Normal file
|
@ -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
|
40
app/boards/arm/mikoto/Kconfig.defconfig
Normal file
40
app/boards/arm/mikoto/Kconfig.defconfig
Normal file
|
@ -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
|
59
app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi
Normal file
59
app/boards/arm/mikoto/arduino_pro_micro_pins.dtsi
Normal file
|
@ -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 {};
|
5
app/boards/arm/mikoto/board.cmake
Normal file
5
app/boards/arm/mikoto/board.cmake
Normal file
|
@ -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)
|
115
app/boards/arm/mikoto/mikoto_520.dts
Normal file
115
app/boards/arm/mikoto/mikoto_520.dts
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/dts-v1/;
|
||||||
|
#include <nordic/nrf52840_qiaa.dtsi>
|
||||||
|
#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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
15
app/boards/arm/mikoto/mikoto_520.yaml
Normal file
15
app/boards/arm/mikoto/mikoto_520.yaml
Normal file
|
@ -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
|
10
app/boards/arm/mikoto/mikoto_520.zmk.yml
Normal file
10
app/boards/arm/mikoto/mikoto_520.zmk.yml
Normal file
|
@ -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]
|
20
app/boards/arm/mikoto/mikoto_520_defconfig
Normal file
20
app/boards/arm/mikoto/mikoto_520_defconfig
Normal file
|
@ -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
|
48
app/boards/arm/mikoto/pinmux.c
Normal file
48
app/boards/arm/mikoto/pinmux.c
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <sys/sys_io.h>
|
||||||
|
#include <devicetree.h>
|
||||||
|
|
||||||
|
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);
|
|
@ -35,8 +35,8 @@
|
||||||
// | | | RET | ADJ | |
|
// | | | RET | ADJ | |
|
||||||
bindings = <
|
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 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 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 SQT &kp HOME &kp END &kp PG_UP &kp PG_DN &kp PSCRN &mt RSHFT RET
|
&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
|
&trans &trans &kp RET &mo 3 &trans
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
bindings = <
|
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 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 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
|
&trans &mo 3 &kp BSPC &trans &trans
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
adjust_layer {
|
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 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 | | | | | |
|
// | | | | | | | | RESET | | | | | |
|
||||||
// | | | | | |
|
// | | | | | |
|
||||||
bindings = <
|
bindings = <
|
||||||
|
|
|
@ -28,5 +28,10 @@ properties:
|
||||||
- "hold-preferred"
|
- "hold-preferred"
|
||||||
- "balanced"
|
- "balanced"
|
||||||
- "tap-preferred"
|
- "tap-preferred"
|
||||||
|
- "tap-unless-interrupted"
|
||||||
retro-tap:
|
retro-tap:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
hold-trigger-key-positions:
|
||||||
|
type: array
|
||||||
|
required: false
|
||||||
|
default: []
|
||||||
|
|
|
@ -143,12 +143,14 @@ static const uint8_t zmk_hid_report_desc[] = {
|
||||||
/* LOGICAL_MINIMUM (0) */
|
/* LOGICAL_MINIMUM (0) */
|
||||||
HID_GI_LOGICAL_MIN(1),
|
HID_GI_LOGICAL_MIN(1),
|
||||||
0x00,
|
0x00,
|
||||||
/* LOGICAL_MAXIMUM (0xFFFF) */
|
/* LOGICAL_MAXIMUM (0x00FF) - little endian, and requires two bytes because logical max is
|
||||||
HID_GI_LOGICAL_MAX(1),
|
signed */
|
||||||
|
HID_GI_LOGICAL_MAX(2),
|
||||||
0xFF,
|
0xFF,
|
||||||
|
0x00,
|
||||||
HID_LI_USAGE_MIN(1),
|
HID_LI_USAGE_MIN(1),
|
||||||
0x00,
|
0x00,
|
||||||
/* USAGE_MAXIMUM (0xFFFF) */
|
/* USAGE_MAXIMUM (0xFF) */
|
||||||
HID_LI_USAGE_MAX(1),
|
HID_LI_USAGE_MAX(1),
|
||||||
0xFF,
|
0xFF,
|
||||||
/* INPUT (Data,Ary,Abs) */
|
/* INPUT (Data,Ary,Abs) */
|
||||||
|
|
|
@ -34,6 +34,7 @@ enum flavor {
|
||||||
FLAVOR_HOLD_PREFERRED,
|
FLAVOR_HOLD_PREFERRED,
|
||||||
FLAVOR_BALANCED,
|
FLAVOR_BALANCED,
|
||||||
FLAVOR_TAP_PREFERRED,
|
FLAVOR_TAP_PREFERRED,
|
||||||
|
FLAVOR_TAP_UNLESS_INTERRUPTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum status {
|
enum status {
|
||||||
|
@ -58,6 +59,8 @@ struct behavior_hold_tap_config {
|
||||||
int quick_tap_ms;
|
int quick_tap_ms;
|
||||||
enum flavor flavor;
|
enum flavor flavor;
|
||||||
bool retro_tap;
|
bool retro_tap;
|
||||||
|
int32_t hold_trigger_key_positions_len;
|
||||||
|
int32_t hold_trigger_key_positions[];
|
||||||
};
|
};
|
||||||
|
|
||||||
// this data is specific for each hold-tap
|
// this data is specific for each hold-tap
|
||||||
|
@ -70,6 +73,9 @@ struct active_hold_tap {
|
||||||
const struct behavior_hold_tap_config *config;
|
const struct behavior_hold_tap_config *config;
|
||||||
struct k_delayed_work work;
|
struct k_delayed_work work;
|
||||||
bool work_is_cancelled;
|
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
|
// The undecided hold tap is the hold tap that needs to be decided before
|
||||||
|
@ -206,6 +212,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_hold = param_hold;
|
||||||
active_hold_taps[i].param_tap = param_tap;
|
active_hold_taps[i].param_tap = param_tap;
|
||||||
active_hold_taps[i].timestamp = timestamp;
|
active_hold_taps[i].timestamp = timestamp;
|
||||||
|
active_hold_taps[i].position_of_first_other_key_pressed = -1;
|
||||||
return &active_hold_taps[i];
|
return &active_hold_taps[i];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -252,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) {
|
static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case HT_KEY_UP:
|
case HT_KEY_UP:
|
||||||
|
@ -279,6 +306,8 @@ static inline const char *flavor_str(enum flavor flavor) {
|
||||||
return "balanced";
|
return "balanced";
|
||||||
case FLAVOR_TAP_PREFERRED:
|
case FLAVOR_TAP_PREFERRED:
|
||||||
return "tap-preferred";
|
return "tap-preferred";
|
||||||
|
case FLAVOR_TAP_UNLESS_INTERRUPTED:
|
||||||
|
return "tap-unless-interrupted";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN FLAVOR";
|
return "UNKNOWN FLAVOR";
|
||||||
}
|
}
|
||||||
|
@ -359,6 +388,39 @@ static int release_binding(struct active_hold_tap *hold_tap) {
|
||||||
return behavior_keymap_binding_released(&binding, event);
|
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,
|
static void decide_hold_tap(struct active_hold_tap *hold_tap,
|
||||||
enum decision_moment decision_moment) {
|
enum decision_moment decision_moment) {
|
||||||
if (hold_tap->status != STATUS_UNDECIDED) {
|
if (hold_tap->status != STATUS_UNDECIDED) {
|
||||||
|
@ -370,19 +432,30 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the hold-tap behavior is still undecided, attempt to decide it.
|
||||||
switch (hold_tap->config->flavor) {
|
switch (hold_tap->config->flavor) {
|
||||||
case FLAVOR_HOLD_PREFERRED:
|
case FLAVOR_HOLD_PREFERRED:
|
||||||
decide_hold_preferred(hold_tap, decision_moment);
|
decide_hold_preferred(hold_tap, decision_moment);
|
||||||
|
break;
|
||||||
case FLAVOR_BALANCED:
|
case FLAVOR_BALANCED:
|
||||||
decide_balanced(hold_tap, decision_moment);
|
decide_balanced(hold_tap, decision_moment);
|
||||||
|
break;
|
||||||
case FLAVOR_TAP_PREFERRED:
|
case FLAVOR_TAP_PREFERRED:
|
||||||
decide_tap_preferred(hold_tap, decision_moment);
|
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) {
|
if (hold_tap->status == STATUS_UNDECIDED) {
|
||||||
return;
|
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,
|
LOG_DBG("%d decided %s (%s decision moment %s)", hold_tap->position,
|
||||||
status_str(hold_tap->status), flavor_str(hold_tap->config->flavor),
|
status_str(hold_tap->status), flavor_str(hold_tap->config->flavor),
|
||||||
decision_moment_str(decision_moment));
|
decision_moment_str(decision_moment));
|
||||||
|
@ -501,6 +574,14 @@ static int position_state_changed_listener(const zmk_event_t *eh) {
|
||||||
return ZMK_EV_EVENT_BUBBLE;
|
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 (undecided_hold_tap->position == ev->position) {
|
||||||
if (ev->state) { // keydown
|
if (ev->state) { // keydown
|
||||||
LOG_ERR("hold-tap listener should be called before before most other listeners!");
|
LOG_ERR("hold-tap listener should be called before before most other listeners!");
|
||||||
|
@ -604,6 +685,8 @@ static struct behavior_hold_tap_data behavior_hold_tap_data;
|
||||||
.quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \
|
.quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \
|
||||||
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
|
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
|
||||||
.retro_tap = DT_INST_PROP(n, retro_tap), \
|
.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, \
|
DEVICE_DT_INST_DEFINE(n, behavior_hold_tap_init, device_pm_control_nop, \
|
||||||
&behavior_hold_tap_data, &behavior_hold_tap_config_##n, APPLICATION, \
|
&behavior_hold_tap_data, &behavior_hold_tap_config_##n, APPLICATION, \
|
||||||
|
|
|
@ -29,9 +29,10 @@ static int start_scan(void);
|
||||||
|
|
||||||
static struct bt_conn *default_conn;
|
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_discover_params discover_params;
|
||||||
static struct bt_gatt_subscribe_params subscribe_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),
|
K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed),
|
||||||
CONFIG_ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE, 4);
|
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;
|
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);
|
int err = bt_gatt_subscribe(conn, &subscribe_params);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case -EALREADY:
|
case -EALREADY:
|
||||||
LOG_DBG("[ALREADY SUBSCRIBED]");
|
LOG_DBG("[ALREADY SUBSCRIBED]");
|
||||||
break;
|
break;
|
||||||
// break;
|
|
||||||
// bt_gatt_unsubscribe(conn, &subscribe_params);
|
|
||||||
// return split_central_subscribe(conn);
|
|
||||||
case 0:
|
case 0:
|
||||||
LOG_DBG("[SUBSCRIBED]");
|
LOG_DBG("[SUBSCRIBED]");
|
||||||
break;
|
break;
|
||||||
|
@ -99,14 +97,44 @@ static int split_central_subscribe(struct bt_conn *conn) {
|
||||||
LOG_ERR("Subscribe failed (err %d)", err);
|
LOG_ERR("Subscribe failed (err %d)", err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
|
static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn,
|
||||||
|
const struct bt_gatt_attr *attr,
|
||||||
struct bt_gatt_discover_params *params) {
|
struct bt_gatt_discover_params *params) {
|
||||||
int err;
|
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) {
|
if (!attr) {
|
||||||
LOG_DBG("Discover complete");
|
LOG_DBG("Discover complete");
|
||||||
(void)memset(params, 0, sizeof(*params));
|
(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);
|
LOG_DBG("[ATTRIBUTE] handle %u", attr->handle);
|
||||||
|
|
||||||
if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID))) {
|
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));
|
LOG_DBG("Found other service");
|
||||||
discover_params.uuid = &uuid.uuid;
|
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.start_handle = attr->handle + 1;
|
||||||
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
|
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
|
||||||
|
|
||||||
err = bt_gatt_discover(conn, &discover_params);
|
int err = bt_gatt_discover(conn, &discover_params);
|
||||||
if (err) {
|
if (err) {
|
||||||
LOG_ERR("Discover failed (err %d)", err);
|
LOG_ERR("Failed to start discovering split service characteristics (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;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BT_GATT_ITER_STOP;
|
return BT_GATT_ITER_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,9 +172,9 @@ static void split_central_process_connection(struct bt_conn *conn) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn == default_conn && !subscribe_params.value) {
|
if (conn == default_conn && !subscribe_params.value_handle) {
|
||||||
discover_params.uuid = &uuid.uuid;
|
discover_params.uuid = &split_service_uuid.uuid;
|
||||||
discover_params.func = split_central_discovery_func;
|
discover_params.func = split_central_service_discovery_func;
|
||||||
discover_params.start_handle = 0x0001;
|
discover_params.start_handle = 0x0001;
|
||||||
discover_params.end_handle = 0xffff;
|
discover_params.end_handle = 0xffff;
|
||||||
discover_params.type = BT_GATT_DISCOVER_PRIMARY;
|
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);
|
bt_conn_unref(default_conn);
|
||||||
default_conn = NULL;
|
default_conn = NULL;
|
||||||
|
|
||||||
|
// Clean up previously discovered handles;
|
||||||
|
subscribe_params.value_handle = 0;
|
||||||
|
|
||||||
start_scan();
|
start_scan();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,5 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,500)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(1,1,200) // non trigger key
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,1,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(1,0,200) // trigger key
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
|
||||||
|
/ {
|
||||||
|
behaviors {
|
||||||
|
ht_bal: behavior_hold_tap_balanced {
|
||||||
|
compatible = "zmk,behavior-hold-tap";
|
||||||
|
label = "HOLD_TAP_BALANCED";
|
||||||
|
#binding-cells = <2>;
|
||||||
|
flavor = "balanced";
|
||||||
|
tapping-term-ms = <300>;
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,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
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(1,0,10) // 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)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,5 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,500)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(1,1,200) // non trigger key
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,1,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(1,0,200) // trigger key
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
|
||||||
|
/ {
|
||||||
|
behaviors {
|
||||||
|
ht_hold: behavior_hold_hold_tap {
|
||||||
|
compatible = "zmk,behavior-hold-tap";
|
||||||
|
label = "hold_hold_tap";
|
||||||
|
#binding-cells = <2>;
|
||||||
|
flavor = "hold-preferred";
|
||||||
|
tapping-term-ms = <300>;
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,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
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(1,0,10) // 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)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,5 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,500)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(1,1,200) // non trigger key
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,1,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(1,0,200) // trigger key
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
|
||||||
|
/ {
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,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
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(1,0,10) // 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)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,5 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided tap (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
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,5 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided 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
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,500)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0xe4 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
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(1,1,10) /*ctrl*/
|
||||||
|
ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */
|
||||||
|
ZMK_MOCK_RELEASE(1,1,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0xe4 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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(1,1,10) /*ctrl*/
|
||||||
|
ZMK_MOCK_PRESS(0,0,50) /*mt f-shift */
|
||||||
|
ZMK_MOCK_RELEASE(1,1,300)
|
||||||
|
/*timer*/
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0x07 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
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(1,0,10) /*d*/
|
||||||
|
ZMK_MOCK_PRESS(0,0,100) /*mt f-shift */
|
||||||
|
ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0x07 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
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(1,0,10) /* d */
|
||||||
|
ZMK_MOCK_PRESS(0,0,100) /* mt f-shift */
|
||||||
|
ZMK_MOCK_RELEASE(1,0,400)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,10 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(0,1,200)
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(0,1,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,200)
|
||||||
|
ZMK_MOCK_PRESS(1,0,200)
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,100)
|
||||||
|
ZMK_MOCK_PRESS(1,0,100)
|
||||||
|
ZMK_MOCK_RELEASE(1,0,200)
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,10)
|
||||||
|
ZMK_MOCK_PRESS(1,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
/* timer */
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,7 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,100)
|
||||||
|
ZMK_MOCK_PRESS(1,0,100)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,200)
|
||||||
|
/* timer fires */
|
||||||
|
ZMK_MOCK_RELEASE(1,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,10 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided 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
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
#include "../behavior_keymap.dtsi"
|
||||||
|
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,10)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
ZMK_MOCK_PRESS(0,0,400)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/ {
|
||||||
|
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>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
|
@ -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 '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 '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-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.
|
When the hold-tap key is released and the hold behavior has not been triggered, the tap behavior will trigger.
|
||||||
|
|
||||||
|
@ -59,9 +60,84 @@ 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 <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
/ {
|
||||||
|
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
|
#### 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 <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
/ {
|
||||||
|
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 <behaviors.dtsi>
|
#include <behaviors.dtsi>
|
||||||
|
@ -82,7 +158,6 @@ This example configures a hold-tap that works well for homerow mods:
|
||||||
|
|
||||||
keymap {
|
keymap {
|
||||||
compatible = "zmk,keymap";
|
compatible = "zmk,keymap";
|
||||||
|
|
||||||
default_layer {
|
default_layer {
|
||||||
bindings = <
|
bindings = <
|
||||||
&hm LCTRL A &hm LGUI S &hm LALT D &hm LSHIFT F
|
&hm LCTRL A &hm LGUI S &hm LALT D &hm LSHIFT F
|
||||||
|
@ -93,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 <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
|
||||||
|
/ {
|
||||||
|
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
|
#### Comparison to QMK
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ title: Tests
|
||||||
sidebar_label: Tests
|
sidebar_label: Tests
|
||||||
---
|
---
|
||||||
|
|
||||||
Running tests requires [native posix support](posix-board.md). Any folder under `/app/tests`
|
- Running tests requires [native posix support](posix-board.md).
|
||||||
containing `native_posix.keymap` will be selected when running `west test`.
|
- 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 <testname>`, like `west test tests/toggle-layer/normal`.
|
- Run a single test with `west test <testname>`, like `west test tests/toggle-layer/normal`.
|
||||||
|
|
||||||
## Creating a New Test Set
|
## Creating a New Test Set
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue