Merge branch 'main' of github.com:zmkfirmware/zmk into pillbug
This commit is contained in:
commit
107183158b
107 changed files with 2062 additions and 158 deletions
2
.github/workflows/build-user-config.yml
vendored
2
.github/workflows/build-user-config.yml
vendored
|
@ -61,7 +61,7 @@ jobs:
|
|||
set -x
|
||||
if [ -n "${{ matrix.shield }}" ]
|
||||
then
|
||||
EXTRA_CMAKE_ARGS="-DSHIELD=${{ matrix.shield }}"
|
||||
EXTRA_CMAKE_ARGS="-DSHIELD=\"${{ matrix.shield }}\""
|
||||
ARTIFACT_NAME="${{ matrix.shield }}-${{ matrix.board }}-zmk"
|
||||
DISPLAY_NAME="${{ matrix.shield }} - ${{ matrix.board }}"
|
||||
else
|
||||
|
|
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
|
@ -35,11 +35,11 @@ jobs:
|
|||
tools/
|
||||
zephyr/
|
||||
bootloader/
|
||||
key: 4-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('app/west.yml') }}
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('app/west.yml') }}
|
||||
restore-keys: |
|
||||
4-${{ runner.os }}-build-${{ env.cache-name }}-
|
||||
4-${{ runner.os }}-build-
|
||||
4-${{ runner.os }}-
|
||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||
${{ runner.os }}-build-
|
||||
${{ runner.os }}-
|
||||
timeout-minutes: 2
|
||||
continue-on-error: true
|
||||
- name: Initialize workspace (west init)
|
||||
|
@ -71,7 +71,7 @@ jobs:
|
|||
|
||||
for (const shieldArgs of buildShieldArgs) {
|
||||
try {
|
||||
const output = execSync(`west build -s app -p -b ${{ matrix.board }} -- ${shieldArgs.shield ? '-DSHIELD=' + shieldArgs.shield : ''} ${shieldArgs['cmake-args'] || ''}`);
|
||||
const output = execSync(`west build -s app -p -b ${{ matrix.board }} -- ${shieldArgs.shield ? '-DSHIELD="' + shieldArgs.shield + '"' : ''} ${shieldArgs['cmake-args'] || ''}`);
|
||||
|
||||
console.log(`::group::${{ matrix.board}} ${shieldArgs.shield} Build`)
|
||||
console.log(output.toString());
|
||||
|
@ -246,6 +246,9 @@ jobs:
|
|||
return hm.requires.flatMap(i =>
|
||||
metadata.interconnects[i].boards.flatMap(b => boardAndShield(b, hm))
|
||||
);
|
||||
} else {
|
||||
console.warn("Unhandled shield without keys");
|
||||
return [];
|
||||
}
|
||||
break;
|
||||
case "interconnect":
|
||||
|
|
8
.github/workflows/test.yml
vendored
8
.github/workflows/test.yml
vendored
|
@ -47,11 +47,11 @@ jobs:
|
|||
tools/
|
||||
zephyr/
|
||||
bootloader/
|
||||
key: 4-${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('app/west.yml') }}
|
||||
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('app/west.yml') }}
|
||||
restore-keys: |
|
||||
4-${{ runner.os }}-build-${{ env.cache-name }}-
|
||||
4-${{ runner.os }}-build-
|
||||
4-${{ runner.os }}-
|
||||
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||
${{ runner.os }}-build-
|
||||
${{ runner.os }}-
|
||||
timeout-minutes: 2
|
||||
continue-on-error: true
|
||||
- name: Initialize workspace (west init)
|
||||
|
|
12
app/Kconfig
12
app/Kconfig
|
@ -25,6 +25,18 @@ config USB_DEVICE_PID
|
|||
config USB_DEVICE_MANUFACTURER
|
||||
default "ZMK Project"
|
||||
|
||||
config BT_DIS_PNP_VID
|
||||
default 0x1D50
|
||||
|
||||
config BT_DIS_PNP_PID
|
||||
default 0x615E
|
||||
|
||||
config BT_DIS_MODEL
|
||||
default ZMK_KEYBOARD_NAME
|
||||
|
||||
config BT_DIS_MANUF
|
||||
default "ZMK Project"
|
||||
|
||||
menu "HID"
|
||||
|
||||
choice ZMK_HID_REPORT_TYPE
|
||||
|
|
|
@ -2,9 +2,9 @@ config BOARD_ENABLE_DCDC
|
|||
bool "Enable DCDC mode"
|
||||
select SOC_DCDC_NRF52X
|
||||
default y
|
||||
depends on (BOARD_NRFMICRO_11 || BOARD_NRFMICRO_11_FLIPPED || BOARD_NRFMICRO_13)
|
||||
depends on (BOARD_NRFMICRO_11 || BOARD_NRFMICRO_11_FLIPPED || BOARD_NRFMICRO_13 || BOARD_NRFMICRO_13_52833)
|
||||
|
||||
config BOARD_NRFMICRO_CHARGER
|
||||
bool "Enable battery charger"
|
||||
default y
|
||||
depends on (BOARD_NRFMICRO_13)
|
||||
depends on (BOARD_NRFMICRO_13 || BOARD_NRFMICRO_13_52833)
|
||||
|
|
|
@ -14,3 +14,7 @@ config BOARD_NRFMICRO_11_FLIPPED
|
|||
config BOARD_NRFMICRO_13
|
||||
bool "nrfmicro_13"
|
||||
depends on SOC_NRF52840_QIAA
|
||||
|
||||
config BOARD_NRFMICRO_13_52833
|
||||
bool "nrfmicro_13_52833"
|
||||
depends on SOC_NRF52833_QIAA
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if BOARD_NRFMICRO_11 || BOARD_NRFMICRO_11_FLIPPED || BOARD_NRFMICRO_13
|
||||
if BOARD_NRFMICRO_11 || BOARD_NRFMICRO_11_FLIPPED || BOARD_NRFMICRO_13 || BOARD_NRFMICRO_13_52833
|
||||
|
||||
config BOARD
|
||||
default "nrfmicro"
|
||||
|
@ -27,11 +27,11 @@ config ZMK_USB
|
|||
config PINMUX
|
||||
default y
|
||||
|
||||
if BOARD_NRFMICRO_13
|
||||
if BOARD_NRFMICRO_13 || BOARD_NRFMICRO_13_52833
|
||||
|
||||
config BOARD_NRFMICRO_CHARGER
|
||||
default y
|
||||
|
||||
endif # BOARD_NRFMICRO_13
|
||||
endif # BOARD_NRFMICRO_13 || BOARD_NRFMICRO_13_52833
|
||||
|
||||
endif # BOARD_NRFMICRO_11 || BOARD_NRFMICRO_11_FLIPPED || BOARD_NRFMICRO_13
|
||||
endif # BOARD_NRFMICRO_11 || BOARD_NRFMICRO_11_FLIPPED || BOARD_NRFMICRO_13 || BOARD_NRFMICRO_13_52833
|
||||
|
|
59
app/boards/arm/nrfmicro/arduino_pro_micro_pins_52833.dtsi
Normal file
59
app/boards/arm/nrfmicro/arduino_pro_micro_pins_52833.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 8 0> /* D0 */
|
||||
, <1 0 &gpio0 6 0> /* D1 */
|
||||
, <2 0 &gpio0 15 0> /* D2 */
|
||||
, <3 0 &gpio0 17 0> /* D3 */
|
||||
, <4 0 &gpio0 20 0> /* D4/A6 */
|
||||
, <5 0 &gpio0 13 0> /* D5 */
|
||||
, <6 0 &gpio0 24 0> /* D6/A7 */
|
||||
, <7 0 &gpio0 9 0> /* D7 */
|
||||
, <8 0 &gpio0 10 0> /* D8/A8 */
|
||||
, <9 0 &gpio1 6 0> /* D9/A9 */
|
||||
, <10 0 &gpio1 4 0> /* D10/A10 */
|
||||
, <16 0 &gpio0 28 0> /* D16 */
|
||||
, <14 0 &gpio0 3 0> /* D14 */
|
||||
, <15 0 &gpio1 5 0> /* D15 */
|
||||
, <18 0 &gpio0 2 0> /* D18/A0 */
|
||||
, <19 0 &gpio0 29 0> /* D19/A1 */
|
||||
, <20 0 &gpio0 31 0> /* D20/A2 */
|
||||
, <21 0 &gpio0 30 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 2 0> /* D18/A0 */
|
||||
, <1 0 &gpio0 29 0> /* D19/A1 */
|
||||
, <2 0 &gpio0 31 0> /* D20/A2 */
|
||||
, <3 0 &gpio0 30 0> /* D21/A3 */
|
||||
, <6 0 &gpio0 20 0> /* D4/A6 */
|
||||
, <7 0 &gpio0 24 0> /* D6/A7 */
|
||||
, <8 0 &gpio0 10 0> /* D8/A8 */
|
||||
, <9 0 &gpio1 6 0> /* D9/A9 */
|
||||
, <10 0 &gpio1 11 0> /* D10/A10 */
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
pro_micro_d: &pro_micro {};
|
||||
pro_micro_i2c: &i2c0 {};
|
||||
pro_micro_spi: &spi0 {};
|
||||
pro_micro_serial: &uart0 {};
|
121
app/boards/arm/nrfmicro/nrfmicro_13_52833.dts
Normal file
121
app/boards/arm/nrfmicro/nrfmicro_13_52833.dts
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <nordic/nrf52833_qiaa.dtsi>
|
||||
#include "arduino_pro_micro_pins_52833.dtsi"
|
||||
|
||||
/ {
|
||||
model = "nrfmicro";
|
||||
compatible = "joric,nrfmicro";
|
||||
|
||||
chosen {
|
||||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
blue_led: led_0 {
|
||||
gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
|
||||
label = "Blue LED";
|
||||
};
|
||||
};
|
||||
|
||||
ext-power {
|
||||
compatible = "zmk,ext-power-generic";
|
||||
label = "EXT_POWER";
|
||||
control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
vbatt: vbatt {
|
||||
compatible = "zmk,battery-voltage-divider";
|
||||
label = "BATTERY";
|
||||
io-channels = <&adc 2>;
|
||||
output-ohms = <2000000>;
|
||||
full-ohms = <(2000000 + 820000)>;
|
||||
};
|
||||
};
|
||||
|
||||
&adc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpiote {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
compatible = "nordic,nrf-twi";
|
||||
sda-pin = <15>;
|
||||
scl-pin = <17>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
tx-pin = <6>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
label = "CDC_ACM_0";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
&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 0x00046000>;
|
||||
};
|
||||
|
||||
/*
|
||||
* The flash starting at 0x0006c000 and ending at
|
||||
* 0x00073fff is reserved for use by the application.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Storage partition will be used by FCB/LittleFS/NVS
|
||||
* if enabled.
|
||||
*/
|
||||
storage_partition: partition@6c000 {
|
||||
label = "storage";
|
||||
reg = <0x0006c000 0x00008000>;
|
||||
};
|
||||
|
||||
boot_partition: partition@74000 {
|
||||
label = "adafruit_boot";
|
||||
reg = <0x00074000 0x0000c000>;
|
||||
};
|
||||
};
|
||||
};
|
15
app/boards/arm/nrfmicro/nrfmicro_13_52833.yaml
Normal file
15
app/boards/arm/nrfmicro/nrfmicro_13_52833.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
identifier: nrfmicro_13_52833
|
||||
name: nrfmicro_13_52833
|
||||
type: mcu
|
||||
arch: arm
|
||||
toolchain:
|
||||
- zephyr
|
||||
- gnuarmemb
|
||||
- xtools
|
||||
supported:
|
||||
- adc
|
||||
- usb_device
|
||||
- ble
|
||||
- ieee802154
|
||||
- pwm
|
||||
- watchdog
|
10
app/boards/arm/nrfmicro/nrfmicro_13_52833.zmk.yml
Normal file
10
app/boards/arm/nrfmicro/nrfmicro_13_52833.zmk.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
file_format: "1"
|
||||
id: nrfmicro_13_52833
|
||||
name: nRFMicro 1.3/1.4 (nRF52833)
|
||||
type: board
|
||||
arch: arm
|
||||
outputs:
|
||||
- usb
|
||||
- ble
|
||||
url: https://github.com/joric/nrfmicro/
|
||||
exposes: [pro_micro]
|
23
app/boards/arm/nrfmicro/nrfmicro_13_52833_defconfig
Normal file
23
app/boards/arm/nrfmicro/nrfmicro_13_52833_defconfig
Normal file
|
@ -0,0 +1,23 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
|
||||
CONFIG_SOC_SERIES_NRF52X=y
|
||||
CONFIG_SOC_NRF52833_QIAA=y
|
||||
CONFIG_BOARD_NRFMICRO_13_52833=y
|
||||
|
||||
# Enable MPU
|
||||
CONFIG_ARM_MPU=y
|
||||
|
||||
# enable GPIO
|
||||
CONFIG_GPIO=y
|
||||
|
||||
CONFIG_USE_DT_CODE_PARTITION=y
|
||||
CONFIG_BUILD_OUTPUT_UF2=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
|
||||
CONFIG_CLOCK_CONTROL_NRF=y
|
||||
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
|
|
@ -14,7 +14,7 @@
|
|||
static int pinmux_nrfmicro_init(const struct device *port) {
|
||||
ARG_UNUSED(port);
|
||||
|
||||
#if CONFIG_BOARD_NRFMICRO_13
|
||||
#if (CONFIG_BOARD_NRFMICRO_13 || CONFIG_BOARD_NRFMICRO_13_52833)
|
||||
const struct device *p0 = device_get_binding("GPIO_0");
|
||||
#if CONFIG_BOARD_NRFMICRO_CHARGER
|
||||
gpio_pin_configure(p0, 5, GPIO_OUTPUT);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/keys.h>
|
||||
|
||||
|
@ -6,16 +12,34 @@
|
|||
compatible = "zmk,keymap";
|
||||
|
||||
default_layer {
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// | TAB | Q | W | E | R | T | Y | U | I | O | P | BSPC |
|
||||
// | ESC | A | S | D | F | G | H | J | K | L | ; | ' |
|
||||
// | SHIFT | Z | X | C | V | B | N | M | , | . | / | RET |
|
||||
// | FN | LGUI | LALT | LCTL | LOWR | SPACE | RAIS | LARW | DARW | UARW | RARW |
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// | TAB | Q | W | E | R | T | Y | U | I | O | P | BSPC |
|
||||
// | ESC | A | S | D | F | G | H | J | K | L | ; | ' |
|
||||
// | SHIFT | Z | X | C | V | B | N | M | , | . | / | RET |
|
||||
// | | LCTL | LALT | LGUI | LOWR | SPACE | RAIS | LARW | DARW | UARW | RARW |
|
||||
bindings = <
|
||||
&kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp DEL
|
||||
&kp ESC &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT
|
||||
&kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp BSLH &kp RET
|
||||
&trans &kp LGUI &kp LALT &kp LCTRL &trans &trans &kp SPACE &trans &kp LEFT &kp DOWN &kp UP &kp RIGHT
|
||||
&kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSPC
|
||||
&kp ESC &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT
|
||||
&kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH &kp RET
|
||||
&trans &kp LCTL &kp LALT &kp LGUI &mo 1 &trans &kp SPACE &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT
|
||||
>;
|
||||
};
|
||||
|
||||
lower {
|
||||
bindings = <
|
||||
&kp LS(GRAVE) &kp LS(N1) &kp LS(N2) &kp LS(N3) &kp LS(N4) &kp LS(N5) &kp LS(N6) &kp LS(N7) &kp LS(N8) &kp LS(N9) &kp LS(N0) &kp DEL
|
||||
&kp DEL &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE
|
||||
&trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp LS(HASH) &kp LS(BSLH) &kp HOME &kp END &trans
|
||||
&trans &trans &trans &trans &trans &trans &trans &trans &kp C_NEXT &kp C_VOL_DN &kp C_VOL_UP &kp C_PP
|
||||
>;
|
||||
};
|
||||
|
||||
raise {
|
||||
bindings = <
|
||||
&kp GRAVE &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp BSPC
|
||||
&kp DEL &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp MINUS &kp EQUAL &kp LBKT &kp RBKT &kp BSLH
|
||||
&trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp HASH &kp BSLH &kp PG_UP &kp PG_DN &trans
|
||||
&reset &bootloader &trans &trans &trans &trans &trans &trans &kp C_NEXT &kp C_VOL_DN &kp C_VOL_UP &kp C_PP
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
|
6
app/boards/arm/puchi_ble/CMakeLists.txt
Normal file
6
app/boards/arm/puchi_ble/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
|
||||
if(CONFIG_PINMUX)
|
||||
zephyr_library()
|
||||
zephyr_library_sources(pinmux.c)
|
||||
zephyr_library_include_directories(${ZEPHYR_BASE}/drivers)
|
||||
endif()
|
3
app/boards/arm/puchi_ble/Kconfig
Normal file
3
app/boards/arm/puchi_ble/Kconfig
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
8
app/boards/arm/puchi_ble/Kconfig.board
Normal file
8
app/boards/arm/puchi_ble/Kconfig.board
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Puchi-BLE board configuration
|
||||
|
||||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config BOARD_PUCHI_BLE_v1
|
||||
bool "puchi_ble_v1"
|
||||
depends on SOC_NRF52840_QIAA
|
28
app/boards/arm/puchi_ble/Kconfig.defconfig
Normal file
28
app/boards/arm/puchi_ble/Kconfig.defconfig
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if BOARD_PUCHI_BLE_v1
|
||||
|
||||
config BOARD
|
||||
default "puchi_ble"
|
||||
|
||||
if USB_DEVICE_STACK
|
||||
|
||||
config USB_NRFX
|
||||
default y
|
||||
|
||||
endif # USB_DEVICE_STACK
|
||||
|
||||
config BT_CTLR
|
||||
default BT
|
||||
|
||||
config ZMK_BLE
|
||||
default y
|
||||
|
||||
config ZMK_USB
|
||||
default y
|
||||
|
||||
config PINMUX
|
||||
default y
|
||||
|
||||
endif # BOARD_PUCHI_BLE_v1
|
59
app/boards/arm/puchi_ble/arduino_pro_micro_pins.dtsi
Normal file
59
app/boards/arm/puchi_ble/arduino_pro_micro_pins.dtsi
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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 8 0> /* D0 */
|
||||
, <1 0 &gpio0 6 0> /* D1 */
|
||||
, <2 0 &gpio0 15 0> /* D2 */
|
||||
, <3 0 &gpio0 17 0> /* D3 */
|
||||
, <4 0 &gpio0 20 0> /* D4/A6 */
|
||||
, <5 0 &gpio0 13 0> /* D5 */
|
||||
, <6 0 &gpio0 24 0> /* D6/A7 */
|
||||
, <7 0 &gpio0 9 0> /* D7 */
|
||||
, <8 0 &gpio0 10 0> /* D8/A8 */
|
||||
, <9 0 &gpio1 6 0> /* D9/A9 */
|
||||
, <10 0 &gpio1 11 0> /* D10/A10 */
|
||||
, <16 0 &gpio0 28 0> /* D16 */
|
||||
, <14 0 &gpio0 3 0> /* D14 */
|
||||
, <15 0 &gpio1 13 0> /* D15 */
|
||||
, <18 0 &gpio0 2 0> /* D18/A0 */
|
||||
, <19 0 &gpio0 29 0> /* D19/A1 */
|
||||
, <20 0 &gpio0 31 0> /* D20/A2 */
|
||||
, <21 0 &gpio0 30 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 2 0> /* D18/A0 */
|
||||
, <1 0 &gpio0 29 0> /* D19/A1 */
|
||||
, <2 0 &gpio0 31 0> /* D20/A2 */
|
||||
, <3 0 &gpio0 30 0> /* D21/A3 */
|
||||
, <6 0 &gpio0 20 0> /* D4/A6 */
|
||||
, <7 0 &gpio0 24 0> /* D6/A7 */
|
||||
, <8 0 &gpio0 10 0> /* D8/A8 */
|
||||
, <9 0 &gpio1 6 0> /* D9/A9 */
|
||||
, <10 0 &gpio1 11 0> /* D10/A10 */
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
pro_micro_d: &pro_micro {};
|
||||
pro_micro_i2c: &i2c0 {};
|
||||
pro_micro_spi: &spi0 {};
|
||||
pro_micro_serial: &uart0 {};
|
6
app/boards/arm/puchi_ble/board.cmake
Normal file
6
app/boards/arm/puchi_ble/board.cmake
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# 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)
|
29
app/boards/arm/puchi_ble/pinmux.c
Normal file
29
app/boards/arm/puchi_ble/pinmux.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2022 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_puchi_ble_init(const struct device *port) {
|
||||
ARG_UNUSED(port);
|
||||
|
||||
#if CONFIG_BOARD_PUCHI_BLE_v1
|
||||
const struct device *p0 = device_get_binding("GPIO_0");
|
||||
#if CONFIG_BOARD_PUCHI_BLE_CHARGER
|
||||
gpio_pin_configure(p0, 5, GPIO_OUTPUT);
|
||||
gpio_pin_set(p0, 5, 0);
|
||||
#else
|
||||
gpio_pin_configure(p0, 5, GPIO_INPUT);
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(pinmux_puchi_ble_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
121
app/boards/arm/puchi_ble/puchi_ble_v1.dts
Normal file
121
app/boards/arm/puchi_ble/puchi_ble_v1.dts
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <nordic/nrf52840_qiaa.dtsi>
|
||||
#include "arduino_pro_micro_pins.dtsi"
|
||||
|
||||
/ {
|
||||
model = "puchi_ble";
|
||||
compatible = "puchi_ble";
|
||||
|
||||
chosen {
|
||||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
blue_led: led_0 {
|
||||
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
|
||||
label = "Blue LED";
|
||||
};
|
||||
};
|
||||
|
||||
ext-power {
|
||||
compatible = "zmk,ext-power-generic";
|
||||
label = "EXT_POWER";
|
||||
control-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
vbatt: vbatt {
|
||||
compatible = "zmk,battery-voltage-divider";
|
||||
label = "BATTERY";
|
||||
io-channels = <&adc 2>;
|
||||
output-ohms = <2000000>;
|
||||
full-ohms = <(2000000 + 820000)>;
|
||||
};
|
||||
};
|
||||
|
||||
&adc {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpiote {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gpio1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
compatible = "nordic,nrf-twi";
|
||||
sda-pin = <15>;
|
||||
scl-pin = <17>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
tx-pin = <6>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
label = "CDC_ACM_0";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
&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/puchi_ble/puchi_ble_v1.yaml
Normal file
15
app/boards/arm/puchi_ble/puchi_ble_v1.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
identifier: puchi_ble_v1
|
||||
name: puchi_ble_v1
|
||||
type: mcu
|
||||
arch: arm
|
||||
toolchain:
|
||||
- zephyr
|
||||
- gnuarmemb
|
||||
- xtools
|
||||
supported:
|
||||
- adc
|
||||
- usb_device
|
||||
- ble
|
||||
- ieee802154
|
||||
- pwm
|
||||
- watchdog
|
10
app/boards/arm/puchi_ble/puchi_ble_v1.zmk.yml
Normal file
10
app/boards/arm/puchi_ble/puchi_ble_v1.zmk.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
file_format: "1"
|
||||
id: puchi_ble_v1
|
||||
name: Puchi-BLE V1
|
||||
type: board
|
||||
arch: arm
|
||||
outputs:
|
||||
- usb
|
||||
- ble
|
||||
url: https://keycapsss.com/keyboard-parts/mcu-controller/202/puchi-ble-wireless-microcontroller
|
||||
exposes: [pro_micro]
|
24
app/boards/arm/puchi_ble/puchi_ble_v1_defconfig
Normal file
24
app/boards/arm/puchi_ble/puchi_ble_v1_defconfig
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
CONFIG_SOC_SERIES_NRF52X=y
|
||||
CONFIG_SOC_NRF52840_QIAA=y
|
||||
CONFIG_BOARD_PUCHI_BLE_v1=y
|
||||
|
||||
# Enable MPU
|
||||
CONFIG_ARM_MPU=y
|
||||
|
||||
# enable GPIO
|
||||
CONFIG_GPIO=y
|
||||
|
||||
CONFIG_USE_DT_CODE_PARTITION=y
|
||||
CONFIG_BUILD_OUTPUT_UF2=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
|
||||
CONFIG_CLOCK_CONTROL_NRF=y
|
||||
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
|
|
@ -1 +0,0 @@
|
|||
A 40% Ortho keyboard made by Polarity Works
|
|
@ -13,16 +13,16 @@
|
|||
compatible = "zmk,keymap";
|
||||
|
||||
default_layer {
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// | TAB | Q | W | E | R | T | Y | U | I | O | P | BSPC |
|
||||
// | ESC | A | S | D | F | G | H | J | K | L | ; | ' |
|
||||
// | SHIFT | Z | X | C | V | B | N | M | , | . | / | RET |
|
||||
// | FN | LGUI | LALT | LCTL | LOWR | SPACE | RAIS | LARW | DARW | UARW | RARW |
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// | TAB | Q | W | E | R | T | Y | U | I | O | P | BSPC |
|
||||
// | ESC | A | S | D | F | G | H | J | K | L | ; | ' |
|
||||
// | SHIFT | Z | X | C | V | B | N | M | , | . | / | RET |
|
||||
// | | LCTL | LALT | LGUI | LOWR | SPACE | RAIS | LARW | DARW | UARW | RARW |
|
||||
bindings = <
|
||||
&kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp BSPC
|
||||
&kp ESC &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT
|
||||
&kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp BSLH &kp RET
|
||||
&trans &kp LGUI &kp LALT &kp LCTRL &mo 1 &kp SPACE &trans &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT
|
||||
&kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp SLASH &kp RET
|
||||
&trans &kp LCTL &kp LALT &kp LGUI &mo 1 &kp SPACE &trans &mo 2 &kp LEFT &kp DOWN &kp UP &kp RIGHT
|
||||
>;
|
||||
|
||||
sensor-bindings = <&inc_dec_kp PG_UP PG_DN>;
|
||||
|
@ -31,7 +31,7 @@
|
|||
lower {
|
||||
bindings = <
|
||||
&kp LS(GRAVE) &kp LS(N1) &kp LS(N2) &kp LS(N3) &kp LS(N4) &kp LS(N5) &kp LS(N6) &kp LS(N7) &kp LS(N8) &kp LS(N9) &kp LS(N0) &kp DEL
|
||||
&kp DEL &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp UNDER &kp PLUS &kp LT &kp GT &kp PIPE
|
||||
&kp DEL &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp UNDER &kp PLUS &kp LBRC &kp RBRC &kp PIPE
|
||||
&trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp LS(HASH) &kp LS(BSLH) &kp HOME &kp END &trans
|
||||
&trans &trans &trans &trans &trans &trans &trans &mo 3 &kp C_NEXT &kp C_VOL_DN &kp C_VOL_UP &kp C_PP
|
||||
>;
|
||||
|
@ -46,12 +46,14 @@
|
|||
&trans &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &kp HASH &kp BSLH &kp PG_UP &kp PG_DN &trans
|
||||
&trans &trans &trans &trans &mo 3 &trans &trans &trans &kp C_NEXT &kp C_VOL_DN &kp C_VOL_UP &kp C_PP
|
||||
>;
|
||||
|
||||
sensor-bindings = <&inc_dec_kp PG_UP PG_DN>;
|
||||
};
|
||||
|
||||
|
||||
control {
|
||||
bindings = <
|
||||
&reset &bootloader &bt BT_CLR &bt BT_PRV &bt BT_NXT &trans &trans &trans &trans &trans &trans &trans
|
||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
>;
|
||||
|
|
9
app/boards/shields/eternal_keypad/Kconfig.defconfig
Normal file
9
app/boards/shields/eternal_keypad/Kconfig.defconfig
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if SHIELD_ETERNAL_KEYPAD || SHIELD_ETERNAL_KEYPAD_LEFTY
|
||||
|
||||
config ZMK_KEYBOARD_NAME
|
||||
default "Eternal Keypad"
|
||||
|
||||
endif
|
8
app/boards/shields/eternal_keypad/Kconfig.shield
Normal file
8
app/boards/shields/eternal_keypad/Kconfig.shield
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config SHIELD_ETERNAL_KEYPAD
|
||||
def_bool $(shields_list_contains,eternal_keypad)
|
||||
|
||||
config SHIELD_ETERNAL_KEYPAD_LEFTY
|
||||
def_bool $(shields_list_contains,eternal_keypad_lefty)
|
10
app/boards/shields/eternal_keypad/README.md
Normal file
10
app/boards/shields/eternal_keypad/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Eternal Keypad
|
||||
|
||||
Eternal Keypad is an open-source input device for gaming that can be assembled for both right and left hand mouse users.
|
||||
|
||||
Firmware is described in the [Eternal Keypad](https://github.com/duckyb/eternal-keypad) repository [README](https://github.com/duckyb/eternal-keypad#firmware).
|
||||
|
||||
Two keymaps are included:
|
||||
|
||||
- eternal_keypad (default)
|
||||
- eternal_keypad_lefty (for left handed users)
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <dt-bindings/led/led.h>
|
||||
|
||||
&spi1 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
/* Cannot be used together with i2c0. */
|
||||
status = "okay";
|
||||
mosi-pin = <6>;
|
||||
// Unused pins, needed for SPI definition, but not used by the ws2812 driver itself.
|
||||
sck-pin = <5>;
|
||||
miso-pin = <7>;
|
||||
|
||||
led_strip: ws2812@0 {
|
||||
compatible = "worldsemi,ws2812-spi";
|
||||
label = "SK6812mini";
|
||||
|
||||
/* SPI */
|
||||
reg = <0>; /* ignored, but necessary for SPI bindings */
|
||||
spi-max-frequency = <4000000>;
|
||||
|
||||
/* WS2812 */
|
||||
chain-length = <8>;
|
||||
spi-one-frame = <0x70>;
|
||||
spi-zero-frame = <0x40>;
|
||||
color-mapping = <LED_COLOR_ID_GREEN LED_COLOR_ID_RED LED_COLOR_ID_BLUE>;
|
||||
};
|
||||
};
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zmk,underglow = &led_strip;
|
||||
};
|
||||
};
|
9
app/boards/shields/eternal_keypad/eternal_keypad.conf
Normal file
9
app/boards/shields/eternal_keypad/eternal_keypad.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Uncomment to turn on logging, and set ZMK logging to debug output
|
||||
# CONFIG_ZMK_USB_LOGGING=y
|
||||
|
||||
# Uncomment the following lines to enable RGB underglow
|
||||
# CONFIG_ZMK_RGB_UNDERGLOW=y
|
||||
# CONFIG_WS2812_STRIP=y
|
53
app/boards/shields/eternal_keypad/eternal_keypad.dtsi
Normal file
53
app/boards/shields/eternal_keypad/eternal_keypad.dtsi
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <dt-bindings/zmk/matrix_transform.h>
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix_transform = &default_transform;
|
||||
};
|
||||
|
||||
kscan0: kscan {
|
||||
compatible = "zmk,kscan-gpio-matrix";
|
||||
label = "KSCAN";
|
||||
|
||||
diode-direction = "col2row";
|
||||
|
||||
row-gpios
|
||||
= <&pro_micro 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
;
|
||||
|
||||
col-gpios
|
||||
= <&pro_micro 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 16 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 14 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 15 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 18 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro 21 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
;
|
||||
};
|
||||
|
||||
default_transform: keymap_transform_0 {
|
||||
compatible = "zmk,matrix-transform";
|
||||
columns = <8>;
|
||||
rows = <5>;
|
||||
map = <
|
||||
RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7)
|
||||
RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7)
|
||||
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(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7)
|
||||
RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,5) RC(4,7)
|
||||
>;
|
||||
};
|
||||
};
|
56
app/boards/shields/eternal_keypad/eternal_keypad.keymap
Normal file
56
app/boards/shields/eternal_keypad/eternal_keypad.keymap
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <dt-bindings/zmk/bt.h>
|
||||
#include <dt-bindings/zmk/outputs.h>
|
||||
#include <dt-bindings/zmk/rgb.h>
|
||||
|
||||
#define BASE 0
|
||||
#define ARROW 1
|
||||
#define FUNC 2
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix_transform = &default_transform;
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6
|
||||
&kp TAB &kp Q &kp W &kp E &kp R &kp T &kp N7
|
||||
&kp F13 &kp ENTER &kp A &kp S &kp D &kp F &kp G &kp N8
|
||||
&kp F14 &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N9
|
||||
&kp F15 &kp LCTRL &sl FUNC &kp LALT &kp SPACE < ARROW N0
|
||||
>;
|
||||
};
|
||||
|
||||
arrow_layer {
|
||||
bindings = <
|
||||
&bt BT_SEL 0 &bt BT_SEL 1 &trans &trans &trans &out OUT_USB &out OUT_BLE
|
||||
&trans &trans &kp UP &trans &rgb_ug RGB_TOG &rgb_ug RGB_HUI &rgb_ug RGB_HUD
|
||||
&bt BT_CLR &trans &kp LEFT &kp DOWN &kp RIGHT &trans &rgb_ug RGB_BRI &rgb_ug RGB_BRD
|
||||
&reset &trans &trans &trans &trans &trans &rgb_ug RGB_EFF &rgb_ug RGB_EFR
|
||||
&bootloader &trans &trans &trans &trans &trans
|
||||
>;
|
||||
};
|
||||
|
||||
function_layer {
|
||||
bindings = <
|
||||
&trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6
|
||||
&trans &kp P &kp O &kp I &kp U &kp Y &kp F7
|
||||
&bt BT_CLR &kp BSPC &kp SEMI &kp L &kp K &kp J &kp H &kp F8
|
||||
&reset &trans &kp LGUI &kp M &kp N &kp F12 &kp F11 &kp F9
|
||||
&bootloader &trans &trans &trans &trans &kp F10
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
7
app/boards/shields/eternal_keypad/eternal_keypad.overlay
Normal file
7
app/boards/shields/eternal_keypad/eternal_keypad.overlay
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "eternal_keypad.dtsi"
|
9
app/boards/shields/eternal_keypad/eternal_keypad.zmk.yml
Normal file
9
app/boards/shields/eternal_keypad/eternal_keypad.zmk.yml
Normal file
|
@ -0,0 +1,9 @@
|
|||
file_format: "1"
|
||||
id: eternal_keypad
|
||||
name: Eternal Keypad
|
||||
type: shield
|
||||
url: https://github.com/duckyb/eternal-keypad
|
||||
requires: [pro_micro]
|
||||
features:
|
||||
- keys
|
||||
- underglow
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <dt-bindings/zmk/bt.h>
|
||||
#include <dt-bindings/zmk/outputs.h>
|
||||
#include <dt-bindings/zmk/rgb.h>
|
||||
|
||||
#define BASE 0
|
||||
#define ARROW 1
|
||||
#define FUNC 2
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix_transform = &default_transform;
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6
|
||||
&kp TAB &kp Q &kp W &kp E &kp R &kp T &kp N7
|
||||
&kp F13 &kp ENTER &kp D &kp S &kp A &kp F &kp G &kp N8
|
||||
&kp F14 &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N9
|
||||
&kp F15 &kp LCTRL &sl FUNC &kp LALT &kp SPACE < ARROW N0
|
||||
>;
|
||||
};
|
||||
|
||||
arrow_layer {
|
||||
bindings = <
|
||||
&bt BT_SEL 0 &bt BT_SEL 1 &trans &trans &trans &out OUT_USB &out OUT_BLE
|
||||
&trans &trans &kp UP &trans &rgb_ug RGB_TOG &rgb_ug RGB_HUI &rgb_ug RGB_HUD
|
||||
&bt BT_CLR &trans &kp RIGHT &kp DOWN &kp RIGHT &trans &rgb_ug RGB_BRI &rgb_ug RGB_BRD
|
||||
&reset &trans &trans &trans &trans &trans &rgb_ug RGB_EFF &rgb_ug RGB_EFR
|
||||
&bootloader &trans &trans &trans &trans &trans
|
||||
>;
|
||||
};
|
||||
|
||||
function_layer {
|
||||
bindings = <
|
||||
&trans &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6
|
||||
&trans &kp P &kp O &kp I &kp U &kp Y &kp F7
|
||||
&bt BT_CLR &kp BSPC &kp SEMI &kp L &kp K &kp J &kp H &kp F8
|
||||
&reset &trans &kp LGUI &kp M &kp N &kp F12 &kp F11 &kp F9
|
||||
&bootloader &trans &trans &trans &trans &kp F10
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 202 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "eternal_keypad.dtsi"
|
|
@ -0,0 +1,9 @@
|
|||
file_format: "1"
|
||||
id: eternal_keypad_lefty
|
||||
name: Eternal Keypad Lefty
|
||||
type: shield
|
||||
url: https://github.com/duckyb/eternal-keypad
|
||||
requires: [pro_micro]
|
||||
features:
|
||||
- keys
|
||||
- underglow
|
22
app/boards/shields/nice_view/Kconfig.defconfig
Normal file
22
app/boards/shields/nice_view/Kconfig.defconfig
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
if SHIELD_NICE_VIEW
|
||||
|
||||
config ZMK_DISPLAY
|
||||
select LVGL_FONT_MONTSERRAT_26
|
||||
|
||||
if ZMK_DISPLAY
|
||||
|
||||
config SPI
|
||||
default y
|
||||
|
||||
config LS0XX
|
||||
default y
|
||||
|
||||
config ZMK_WIDGET_WPM_STATUS
|
||||
default y if !ZMK_SPLIT || ZMK_SPLIT_ROLE_CENTRAL
|
||||
|
||||
endif # ZMK_DISPLAY
|
||||
|
||||
endif
|
5
app/boards/shields/nice_view/Kconfig.shield
Normal file
5
app/boards/shields/nice_view/Kconfig.shield
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config SHIELD_NICE_VIEW
|
||||
def_bool $(shields_list_contains,nice_view)
|
5
app/boards/shields/nice_view/README.md
Normal file
5
app/boards/shields/nice_view/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# nice!view
|
||||
|
||||
The nice!view is a low power, high refresh rate display meant to replace I2C OLEDs traditionally used.
|
||||
|
||||
This shield requires that an `&nice_view_spi` labelled SPI bus is provided with *at least* MOSI, SCK, and CS pins defined.
|
5
app/boards/shields/nice_view/nice_view.conf
Normal file
5
app/boards/shields/nice_view/nice_view.conf
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Enable nice!view
|
||||
CONFIG_ZMK_DISPLAY=y
|
||||
CONFIG_LVGL_THEME_DEFAULT_FONT_SMALL_MONTSERRAT_26=y
|
||||
CONFIG_LVGL_THEME_DEFAULT_FONT_NORMAL_MONTSERRAT_26=y
|
||||
CONFIG_ZMK_DISPLAY_BLANK_ON_IDLE=n
|
23
app/boards/shields/nice_view/nice_view.overlay
Normal file
23
app/boards/shields/nice_view/nice_view.overlay
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
&nice_view_spi {
|
||||
status = "okay";
|
||||
nice_view: ls0xx@0 {
|
||||
compatible = "sharp,ls0xx";
|
||||
label = "DISPLAY";
|
||||
spi-max-frequency = <1000000>;
|
||||
reg = <0>;
|
||||
width = <160>;
|
||||
height = <68>;
|
||||
};
|
||||
};
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zephyr,display = &nice_view;
|
||||
};
|
||||
};
|
8
app/boards/shields/nice_view/nice_view.zmk.yml
Normal file
8
app/boards/shields/nice_view/nice_view.zmk.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
file_format: "1"
|
||||
id: nice_view
|
||||
name: nice!view
|
||||
type: shield
|
||||
url: https://nicekeyboards.com/nice-view
|
||||
requires: [nice_view_header]
|
||||
features:
|
||||
- display
|
2
app/boards/shields/nice_view_adapter/Kconfig.defconfig
Normal file
2
app/boards/shields/nice_view_adapter/Kconfig.defconfig
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
5
app/boards/shields/nice_view_adapter/Kconfig.shield
Normal file
5
app/boards/shields/nice_view_adapter/Kconfig.shield
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config SHIELD_NICE_VIEW_ADAPTER
|
||||
def_bool $(shields_list_contains,nice_view_adapter)
|
11
app/boards/shields/nice_view_adapter/README.md
Normal file
11
app/boards/shields/nice_view_adapter/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# nice!view Adapter
|
||||
|
||||
This shield is used as an adapter between the nice!view and existing shields/boards that expose an I2C OLED header.
|
||||
|
||||
To use this shield, you should add this shield to your list of shields *before* `nice_view`.
|
||||
|
||||
The nice!view will use the SDA/SCL pins of the OLED, and then the adapter expects a final pin to be "bodged" from your microcontroller to the nice!view CS pin. This adapter assumes that the CS pin bodged is the `&pro_micro 1` pin or "D1", which is the top left pin when looking at the front of the board. If you can't use this pin, you'll need to override the `cs-gpios` for the `&nice_view_spi` bus (in your `zmk-config` keymap for example) or you will want to define your own `&nice_view_spi` bus without using this adapter.
|
||||
|
||||
```
|
||||
west build -b nice_nano_v2 -- -DSHIELD="lily58_left nice_view_adapter nice_view"
|
||||
```
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <17>;
|
||||
mosi-pin = <15>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <20>;
|
||||
mosi-pin = <17>;
|
||||
miso-pin = <5>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <20>;
|
||||
mosi-pin = <17>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <20>;
|
||||
mosi-pin = <17>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <17>;
|
||||
mosi-pin = <15>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <31>;
|
||||
mosi-pin = <30>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <17>;
|
||||
mosi-pin = <15>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
nice_view_spi: &spi0 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
sck-pin = <17>;
|
||||
mosi-pin = <15>;
|
||||
miso-pin = <25>;
|
||||
cs-gpios = <&pro_micro 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "disabled";
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
# Disable OLED
|
||||
CONFIG_SSD1306=n
|
|
@ -0,0 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
|
@ -0,0 +1,7 @@
|
|||
file_format: "1"
|
||||
id: nice_view_adapter
|
||||
name: nice!view adapter
|
||||
type: shield
|
||||
url: https://nicekeyboards.com/nice-view
|
||||
requires: [i2c_oled]
|
||||
exposes: [nice_view_header]
|
|
@ -30,3 +30,6 @@ include:
|
|||
shield: romac_plus
|
||||
cmake-args: "-DCONFIG_ZMK_RGB_UNDERGLOW=y -DCONFIG_WS2812_STRIP=y"
|
||||
nickname: "underglow"
|
||||
- board: nice_nano_v2
|
||||
shield: lily58_left nice_view_adapter nice_view
|
||||
nickname: "niceview"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
zephyr_library_named(zmk__drivers__gpio)
|
||||
|
@ -6,3 +6,4 @@ zephyr_library_include_directories(${CMAKE_SOURCE_DIR}/include)
|
|||
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_595 gpio_595.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_MCP23017 gpio_mcp23017.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GPIO_MAX7318 gpio_max7318.c)
|
||||
|
|
|
@ -2,4 +2,5 @@ menuconfig ZMK_DRIVERS_GPIO
|
|||
bool "GPIO"
|
||||
|
||||
rsource "Kconfig.mcp23017"
|
||||
rsource "Kconfig.595"
|
||||
rsource "Kconfig.max7318"
|
||||
rsource "Kconfig.595"
|
||||
|
|
25
app/drivers/gpio/Kconfig.max7318
Normal file
25
app/drivers/gpio/Kconfig.max7318
Normal file
|
@ -0,0 +1,25 @@
|
|||
# MAX7318 GPIO configuration options
|
||||
|
||||
# Copyright (c) 2022 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
DT_COMPAT_MAXIM_MAX7318 := maxim,max7318
|
||||
|
||||
menuconfig GPIO_MAX7318
|
||||
bool "MAX7318 I2C-based GPIO chip"
|
||||
default $(dt_compat_enabled,$(DT_COMPAT_MAXIM_MAX7318))
|
||||
depends on I2C
|
||||
select HAS_DTS_GPIO
|
||||
select ZMK_DRIVERS_GPIO
|
||||
help
|
||||
Enable driver for MAX7318 I2C-based GPIO chip.
|
||||
|
||||
if GPIO_MAX7318
|
||||
|
||||
config GPIO_MAX7318_INIT_PRIORITY
|
||||
int "Init priority"
|
||||
default 75
|
||||
help
|
||||
Device driver initialization priority.
|
||||
|
||||
endif #GPIO_MAX7318
|
336
app/drivers/gpio/gpio_max7318.c
Normal file
336
app/drivers/gpio/gpio_max7318.c
Normal file
|
@ -0,0 +1,336 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT maxim_max7318
|
||||
|
||||
/**
|
||||
* @file Driver for MAX7318 I2C-based GPIO driver.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <kernel.h>
|
||||
#include <device.h>
|
||||
#include <init.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <drivers/ext_power.h>
|
||||
|
||||
#define LOG_LEVEL CONFIG_GPIO_LOG_LEVEL
|
||||
#include <logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(gpio_max7318);
|
||||
|
||||
// Register definitions
|
||||
#define REG_INPUT_PORTA 0x00
|
||||
#define REG_INPUT_PORTB 0x01
|
||||
#define REG_OUTPUT_PORTA 0x02
|
||||
#define REG_OUTPUT_PORTB 0x03
|
||||
#define REG_IPOL_PORTA 0x04
|
||||
#define REG_IPOL_PORTB 0x05
|
||||
#define REG_CONFIG_PORTA 0x06
|
||||
#define REG_CONFIG_PORTB 0x07
|
||||
|
||||
// Configuration data
|
||||
struct max7318_config {
|
||||
struct gpio_driver_config common;
|
||||
|
||||
struct i2c_dt_spec i2c_bus;
|
||||
uint8_t ngpios;
|
||||
};
|
||||
|
||||
// Runtime driver data
|
||||
struct max7318_drv_data {
|
||||
// gpio_driver_data needs to be first
|
||||
struct gpio_driver_config data;
|
||||
|
||||
struct k_sem lock;
|
||||
|
||||
struct {
|
||||
uint16_t ipol;
|
||||
uint16_t config;
|
||||
uint16_t output;
|
||||
} reg_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Read the value of two consecutive registers
|
||||
*
|
||||
* Read two consecutive bytes from the register at address `reg` and `reg + 1`,
|
||||
* typically reading from registers for port 0 and 1 simultaneously.
|
||||
*
|
||||
* @param dev The max7318 device.
|
||||
* @param reg Register to read (the PORT0 of the pair of registers).
|
||||
* @param buf Buffer to read data into.
|
||||
*
|
||||
* @return 0 if successful, failed otherwise.
|
||||
*/
|
||||
static int read_registers(const struct device *dev, uint8_t reg, uint16_t *buf) {
|
||||
const struct max7318_config *config = dev->config;
|
||||
|
||||
uint16_t data = 0;
|
||||
int ret = i2c_burst_read_dt(&config->i2c_bus, reg, (uint8_t *)&data, sizeof(data));
|
||||
if (ret) {
|
||||
LOG_DBG("i2c_write_read FAIL %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*buf = sys_le16_to_cpu(data);
|
||||
|
||||
LOG_DBG("max7318: read: reg[0x%X] = 0x%X, reg[0x%X] = 0x%X", reg, (*buf & 0xFF), (reg + 1),
|
||||
(*buf >> 8));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the value of two consecutive registers
|
||||
*
|
||||
* Write two consecutive bytes from the register at address `reg` and `reg + 1`,
|
||||
* typically to registers for port 0 and 1 simultaneously.
|
||||
*
|
||||
* @param dev The max7318 device.
|
||||
* @param reg Register to write (usually the register for PORT0).
|
||||
* @param value The value to write
|
||||
*
|
||||
* @return 0 if successful, failed otherwise.
|
||||
*/
|
||||
static int write_registers(const struct device *dev, uint8_t reg, uint16_t value) {
|
||||
const struct max7318_config *config = dev->config;
|
||||
|
||||
LOG_DBG("max7318: write: reg[0x%X] = 0x%X, reg[0x%X] = 0x%X", reg, (value & 0xFF), (reg + 1),
|
||||
(value >> 8));
|
||||
|
||||
uint16_t data = sys_cpu_to_le16(value);
|
||||
|
||||
return i2c_burst_write_dt(&config->i2c_bus, reg, (uint8_t *)&data, sizeof(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup the pin direction (input or output)
|
||||
*
|
||||
* @param dev The max7318 device.
|
||||
* @param pin The pin number.
|
||||
* @param flags Flags of pin or port.
|
||||
*
|
||||
* @return 0 if successful, failed otherwise
|
||||
*/
|
||||
static int set_pin_direction(const struct device *dev, uint32_t pin, int flags) {
|
||||
struct max7318_drv_data *const drv_data = (struct max7318_drv_data *const)dev->data;
|
||||
uint16_t *dir = &drv_data->reg_cache.config;
|
||||
uint16_t *output = &drv_data->reg_cache.output;
|
||||
|
||||
/*
|
||||
The output register is 1=high, 0=low; the direction (config) register
|
||||
is 1=input, 0=output.
|
||||
*/
|
||||
if ((flags & GPIO_OUTPUT) != 0U) {
|
||||
if ((flags & GPIO_OUTPUT_INIT_HIGH) != 0U) {
|
||||
*output |= BIT(pin);
|
||||
} else if ((flags & GPIO_OUTPUT_INIT_LOW) != 0U) {
|
||||
*output &= ~BIT(pin);
|
||||
}
|
||||
*dir &= ~BIT(pin);
|
||||
} else {
|
||||
*dir |= BIT(pin);
|
||||
}
|
||||
|
||||
int ret = write_registers(dev, REG_OUTPUT_PORTA, *output);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return write_registers(dev, REG_CONFIG_PORTA, *dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup the pin pull up/pull down status. This function doesn't actually set any
|
||||
* registers, since the max7318 only supports a pullup, and it can't be controlled.
|
||||
*
|
||||
* @param dev The max7318 device.
|
||||
* @param pin The pin number
|
||||
* @param flags Flags of pin or port
|
||||
*
|
||||
* @return 0 if successful, failed otherwise
|
||||
*/
|
||||
static int set_pin_pull_direction(const struct device *dev, uint32_t pin, int flags) {
|
||||
// actually, this chip only supports pull-up, and it can't be disabled.
|
||||
// so, if we try to set anything else, return enotsup; we don't actually
|
||||
// need to set any registers.
|
||||
if ((flags & GPIO_PULL_DOWN) != 0U) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max7318_config(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags) {
|
||||
struct max7318_drv_data *const drv_data = (struct max7318_drv_data *const)dev->data;
|
||||
|
||||
/* Can't do I2C bus operations from an ISR */
|
||||
if (k_is_in_isr()) {
|
||||
return -EWOULDBLOCK;
|
||||
}
|
||||
|
||||
k_sem_take(&drv_data->lock, K_FOREVER);
|
||||
|
||||
int ret = 0;
|
||||
if ((flags & GPIO_OPEN_DRAIN) != 0U) {
|
||||
ret = -ENOTSUP;
|
||||
goto done;
|
||||
};
|
||||
|
||||
ret = set_pin_direction(dev, pin, flags);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("error setting pin direction (%d)", ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = set_pin_pull_direction(dev, pin, flags);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("error setting pin pull up/down (%d)", ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
k_sem_give(&drv_data->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max7318_port_get_raw(const struct device *dev, uint32_t *value) {
|
||||
struct max7318_drv_data *const drv_data = (struct max7318_drv_data *const)dev->data;
|
||||
|
||||
/* Can't do I2C bus operations from an ISR */
|
||||
if (k_is_in_isr()) {
|
||||
return -EWOULDBLOCK;
|
||||
}
|
||||
|
||||
k_sem_take(&drv_data->lock, K_FOREVER);
|
||||
|
||||
uint16_t buf = 0;
|
||||
int ret = read_registers(dev, REG_INPUT_PORTA, &buf);
|
||||
if (ret != 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
*value = buf;
|
||||
|
||||
done:
|
||||
k_sem_give(&drv_data->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max7318_port_set_masked_raw(const struct device *dev, uint32_t mask, uint32_t value) {
|
||||
struct max7318_drv_data *const drv_data = (struct max7318_drv_data *const)dev->data;
|
||||
|
||||
/* Can't do I2C bus operations from an ISR */
|
||||
if (k_is_in_isr()) {
|
||||
return -EWOULDBLOCK;
|
||||
}
|
||||
|
||||
k_sem_take(&drv_data->lock, K_FOREVER);
|
||||
|
||||
uint16_t buf = drv_data->reg_cache.output;
|
||||
buf = (buf & ~mask) | (mask & value);
|
||||
|
||||
int ret = write_registers(dev, REG_OUTPUT_PORTA, buf);
|
||||
if (ret == 0) {
|
||||
drv_data->reg_cache.output = buf;
|
||||
}
|
||||
|
||||
k_sem_give(&drv_data->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max7318_port_set_bits_raw(const struct device *dev, uint32_t mask) {
|
||||
return max7318_port_set_masked_raw(dev, mask, mask);
|
||||
}
|
||||
|
||||
static int max7318_port_clear_bits_raw(const struct device *dev, uint32_t mask) {
|
||||
return max7318_port_set_masked_raw(dev, mask, 0);
|
||||
}
|
||||
|
||||
static int max7318_port_toggle_bits(const struct device *dev, uint32_t mask) {
|
||||
struct max7318_drv_data *const drv_data = (struct max7318_drv_data *const)dev->data;
|
||||
|
||||
/* Can't do I2C bus operations from an ISR */
|
||||
if (k_is_in_isr()) {
|
||||
return -EWOULDBLOCK;
|
||||
}
|
||||
|
||||
k_sem_take(&drv_data->lock, K_FOREVER);
|
||||
|
||||
uint16_t buf = drv_data->reg_cache.output;
|
||||
buf ^= mask;
|
||||
|
||||
int ret = write_registers(dev, REG_OUTPUT_PORTA, buf);
|
||||
if (ret == 0) {
|
||||
drv_data->reg_cache.output = buf;
|
||||
}
|
||||
|
||||
k_sem_give(&drv_data->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max7318_pin_interrupt_configure(const struct device *dev, gpio_pin_t pin,
|
||||
enum gpio_int_mode mode, enum gpio_int_trig trig) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static const struct gpio_driver_api api_table = {
|
||||
.pin_configure = max7318_config,
|
||||
.port_get_raw = max7318_port_get_raw,
|
||||
.port_set_masked_raw = max7318_port_set_masked_raw,
|
||||
.port_set_bits_raw = max7318_port_set_bits_raw,
|
||||
.port_clear_bits_raw = max7318_port_clear_bits_raw,
|
||||
.port_toggle_bits = max7318_port_toggle_bits,
|
||||
.pin_interrupt_configure = max7318_pin_interrupt_configure,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialisation function of MAX7318
|
||||
*
|
||||
* @param dev Device struct
|
||||
* @return 0 if successful, failed otherwise.
|
||||
*/
|
||||
static int max7318_init(const struct device *dev) {
|
||||
const struct max7318_config *const config = dev->config;
|
||||
struct max7318_drv_data *const drv_data = (struct max7318_drv_data *const)dev->data;
|
||||
|
||||
if (!device_is_ready(config->i2c_bus.bus)) {
|
||||
LOG_WRN("i2c bus not ready!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOG_INF("device initialised at 0x%x", config->i2c_bus.addr);
|
||||
|
||||
k_sem_init(&drv_data->lock, 1, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GPIO_PORT_PIN_MASK_FROM_NGPIOS(ngpios) ((gpio_port_pins_t)(((uint64_t)1 << (ngpios)) - 1U))
|
||||
|
||||
#define GPIO_PORT_PIN_MASK_FROM_DT_INST(inst) \
|
||||
GPIO_PORT_PIN_MASK_FROM_NGPIOS(DT_INST_PROP(inst, ngpios))
|
||||
|
||||
#define MAX7318_INIT(inst) \
|
||||
static struct max7318_config max7318_##inst##_config = { \
|
||||
.common = {.port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(inst)}, \
|
||||
.i2c_bus = I2C_DT_SPEC_INST_GET(inst)}; \
|
||||
\
|
||||
static struct max7318_drv_data max7318_##inst##_drvdata = { \
|
||||
/* Default for registers according to datasheet */ \
|
||||
.reg_cache.ipol = 0x0, \
|
||||
.reg_cache.config = 0xFFFF, \
|
||||
.reg_cache.output = 0xFFFF, \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, max7318_init, NULL, &max7318_##inst##_drvdata, \
|
||||
&max7318_##inst##_config, POST_KERNEL, \
|
||||
CONFIG_GPIO_MAX7318_INIT_PRIORITY, &api_table);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(MAX7318_INIT)
|
|
@ -32,6 +32,16 @@ config ZMK_KSCAN_GPIO_MATRIX
|
|||
|
||||
if ZMK_KSCAN_GPIO_MATRIX
|
||||
|
||||
config ZMK_KSCAN_MATRIX_WAIT_BEFORE_INPUTS
|
||||
int "Ticks to wait before reading inputs after an output set active"
|
||||
default 0
|
||||
help
|
||||
When iterating over each output to drive it active, read inputs, then set
|
||||
inactive again, some boards may take time for output to propagate to the
|
||||
inputs. In that scenario, set this value to a positive value to configure
|
||||
the number of ticks to wait after setting an output active before reading
|
||||
the inputs for their active state.
|
||||
|
||||
config ZMK_KSCAN_MATRIX_WAIT_BETWEEN_OUTPUTS
|
||||
int "Ticks to wait between each output when scanning"
|
||||
default 0
|
||||
|
@ -40,7 +50,7 @@ config ZMK_KSCAN_MATRIX_WAIT_BETWEEN_OUTPUTS
|
|||
inactive again, some boards may take time for the previous output to
|
||||
"settle" before reading inputs for the next active output column. In that
|
||||
scenario, set this value to a positive value to configure the number of
|
||||
usecs to wait after reading each column of keys.
|
||||
ticks to wait after reading each column of keys.
|
||||
|
||||
endif # ZMK_KSCAN_GPIO_MATRIX
|
||||
|
||||
|
|
|
@ -235,6 +235,10 @@ static int kscan_matrix_read(const struct device *dev) {
|
|||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_ZMK_KSCAN_MATRIX_WAIT_BEFORE_INPUTS > 0
|
||||
k_busy_wait(CONFIG_ZMK_KSCAN_MATRIX_WAIT_BEFORE_INPUTS);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < config->inputs.len; i++) {
|
||||
const struct gpio_dt_spec *in_gpio = &config->inputs.gpios[i];
|
||||
|
||||
|
|
29
app/drivers/zephyr/dts/bindings/gpio/maxim,max7318.yaml
Normal file
29
app/drivers/zephyr/dts/bindings/gpio/maxim,max7318.yaml
Normal file
|
@ -0,0 +1,29 @@
|
|||
#
|
||||
# Copyright (c) 2022 The ZMK Contributors
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
|
||||
description: >
|
||||
This is a representation of the Maxim MAX7318 I2C Gpio Expander.
|
||||
|
||||
compatible: "maxim,max7318"
|
||||
|
||||
include: [gpio-controller.yaml, i2c-device.yaml]
|
||||
|
||||
properties:
|
||||
label:
|
||||
required: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
ngpios:
|
||||
type: int
|
||||
required: true
|
||||
const: 16
|
||||
description: Number of gpios supported
|
||||
|
||||
gpio-cells:
|
||||
- pin
|
||||
- flags
|
|
@ -14,3 +14,6 @@ properties:
|
|||
mods:
|
||||
type: int
|
||||
required: true
|
||||
keep-mods:
|
||||
type: int
|
||||
required: false
|
||||
|
|
|
@ -135,6 +135,8 @@ int zmk_hid_register_mods(zmk_mod_flags_t explicit_modifiers);
|
|||
int zmk_hid_unregister_mods(zmk_mod_flags_t explicit_modifiers);
|
||||
int zmk_hid_implicit_modifiers_press(zmk_mod_flags_t implicit_modifiers);
|
||||
int zmk_hid_implicit_modifiers_release();
|
||||
int zmk_hid_masked_modifiers_set(zmk_mod_flags_t masked_modifiers);
|
||||
int zmk_hid_masked_modifiers_clear();
|
||||
|
||||
int zmk_hid_keyboard_press(zmk_key_t key);
|
||||
int zmk_hid_keyboard_release(zmk_key_t key);
|
||||
|
|
|
@ -75,7 +75,7 @@ static void backlight_save_work_handler(struct k_work *work) {
|
|||
settings_save_one("backlight/state", &state, sizeof(state));
|
||||
}
|
||||
|
||||
static K_DELAYED_WORK_DEFINE(backlight_save_work, backlight_save_work_handler);
|
||||
static struct k_work_delayable backlight_save_work;
|
||||
#endif
|
||||
|
||||
static int zmk_backlight_init(const struct device *_arg) {
|
||||
|
@ -90,6 +90,7 @@ static int zmk_backlight_init(const struct device *_arg) {
|
|||
if (rc != 0) {
|
||||
LOG_ERR("Failed to load backlight settings: %d", rc);
|
||||
}
|
||||
k_work_init_delayable(&backlight_save_work, backlight_save_work_handler);
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB)
|
||||
state.on = zmk_usb_is_powered();
|
||||
|
@ -104,8 +105,8 @@ static int zmk_backlight_update_and_save() {
|
|||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_SETTINGS)
|
||||
k_delayed_work_cancel(&backlight_save_work);
|
||||
return k_delayed_work_submit(&backlight_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
|
||||
int ret = k_work_reschedule(&backlight_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
|
||||
return MIN(ret, 0);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,7 @@ struct behavior_mod_morph_config {
|
|||
struct zmk_behavior_binding normal_binding;
|
||||
struct zmk_behavior_binding morph_binding;
|
||||
zmk_mod_flags_t mods;
|
||||
zmk_mod_flags_t masked_mods;
|
||||
};
|
||||
|
||||
struct behavior_mod_morph_data {
|
||||
|
@ -45,6 +46,7 @@ static int on_mod_morph_binding_pressed(struct zmk_behavior_binding *binding,
|
|||
}
|
||||
|
||||
if (zmk_hid_get_explicit_mods() & cfg->mods) {
|
||||
zmk_hid_masked_modifiers_set(cfg->masked_mods);
|
||||
data->pressed_binding = (struct zmk_behavior_binding *)&cfg->morph_binding;
|
||||
} else {
|
||||
data->pressed_binding = (struct zmk_behavior_binding *)&cfg->normal_binding;
|
||||
|
@ -64,7 +66,10 @@ static int on_mod_morph_binding_released(struct zmk_behavior_binding *binding,
|
|||
|
||||
struct zmk_behavior_binding *pressed_binding = data->pressed_binding;
|
||||
data->pressed_binding = NULL;
|
||||
return behavior_keymap_binding_released(pressed_binding, event);
|
||||
int err;
|
||||
err = behavior_keymap_binding_released(pressed_binding, event);
|
||||
zmk_hid_masked_modifiers_clear();
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_mod_morph_driver_api = {
|
||||
|
@ -88,6 +93,8 @@ static int behavior_mod_morph_init(const struct device *dev) { return 0; }
|
|||
.normal_binding = _TRANSFORM_ENTRY(0, n), \
|
||||
.morph_binding = _TRANSFORM_ENTRY(1, n), \
|
||||
.mods = DT_INST_PROP(n, mods), \
|
||||
.masked_mods = COND_CODE_0(DT_INST_NODE_HAS_PROP(n, keep_mods), (DT_INST_PROP(n, mods)), \
|
||||
(DT_INST_PROP(n, mods) & ~DT_INST_PROP(n, keep_mods))), \
|
||||
}; \
|
||||
static struct behavior_mod_morph_data behavior_mod_morph_data_##n = {}; \
|
||||
DEVICE_DT_INST_DEFINE(n, behavior_mod_morph_init, NULL, &behavior_mod_morph_data_##n, \
|
||||
|
|
|
@ -20,10 +20,12 @@ static struct zmk_hid_consumer_report consumer_report = {.report_id = 2, .body =
|
|||
// Only release the modifier if the count is 0.
|
||||
static int explicit_modifier_counts[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
static zmk_mod_flags_t explicit_modifiers = 0;
|
||||
static zmk_mod_flags_t implicit_modifiers = 0;
|
||||
static zmk_mod_flags_t masked_modifiers = 0;
|
||||
|
||||
#define SET_MODIFIERS(mods) \
|
||||
{ \
|
||||
keyboard_report.body.modifiers = mods; \
|
||||
keyboard_report.body.modifiers = (mods & ~masked_modifiers) | implicit_modifiers; \
|
||||
LOG_DBG("Modifiers set to 0x%02X", keyboard_report.body.modifiers); \
|
||||
}
|
||||
|
||||
|
@ -158,13 +160,29 @@ static inline int check_keyboard_usage(zmk_key_t usage) {
|
|||
} \
|
||||
}
|
||||
|
||||
int zmk_hid_implicit_modifiers_press(zmk_mod_flags_t implicit_modifiers) {
|
||||
int zmk_hid_implicit_modifiers_press(zmk_mod_flags_t new_implicit_modifiers) {
|
||||
implicit_modifiers = new_implicit_modifiers;
|
||||
zmk_mod_flags_t current = GET_MODIFIERS;
|
||||
SET_MODIFIERS(explicit_modifiers | implicit_modifiers);
|
||||
SET_MODIFIERS(explicit_modifiers);
|
||||
return current == GET_MODIFIERS ? 0 : 1;
|
||||
}
|
||||
|
||||
int zmk_hid_implicit_modifiers_release() {
|
||||
implicit_modifiers = 0;
|
||||
zmk_mod_flags_t current = GET_MODIFIERS;
|
||||
SET_MODIFIERS(explicit_modifiers);
|
||||
return current == GET_MODIFIERS ? 0 : 1;
|
||||
}
|
||||
|
||||
int zmk_hid_masked_modifiers_set(zmk_mod_flags_t new_masked_modifiers) {
|
||||
masked_modifiers = new_masked_modifiers;
|
||||
zmk_mod_flags_t current = GET_MODIFIERS;
|
||||
SET_MODIFIERS(explicit_modifiers);
|
||||
return current == GET_MODIFIERS ? 0 : 1;
|
||||
}
|
||||
|
||||
int zmk_hid_masked_modifiers_clear() {
|
||||
masked_modifiers = 0;
|
||||
zmk_mod_flags_t current = GET_MODIFIERS;
|
||||
SET_MODIFIERS(explicit_modifiers);
|
||||
return current == GET_MODIFIERS ? 0 : 1;
|
||||
|
|
|
@ -33,6 +33,7 @@ enum zmk_usb_conn_state zmk_usb_get_conn_state() {
|
|||
switch (usb_status) {
|
||||
case USB_DC_SUSPEND:
|
||||
case USB_DC_CONFIGURED:
|
||||
case USB_DC_RESUME:
|
||||
return ZMK_USB_CONN_HID;
|
||||
|
||||
case USB_DC_DISCONNECTED:
|
||||
|
|
8
app/tests/mod-morph/1-no-morph/events.patterns
Normal file
8
app/tests/mod-morph/1-no-morph/events.patterns
Normal file
|
@ -0,0 +1,8 @@
|
|||
s/.*hid_listener_keycode_pressed.*keycode/pressed: keycode/p
|
||||
s/.*hid_listener_keycode_released.*keycode/released: keycode/p
|
||||
s/.*hid_register_mod.*Modifiers set to /reg explicit: Modifiers set to /p
|
||||
s/.*hid_unregister_mod.*Modifiers set to /unreg explicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_press.*Modifiers set to /reg implicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_release.*Modifiers set to /unreg implicit: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_set.*Modifiers set to /mask mods: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_clear.*Modifiers set to /unmask mods: Modifiers set to /p
|
5
app/tests/mod-morph/1-no-morph/keycode_events.snapshot
Normal file
5
app/tests/mod-morph/1-no-morph/keycode_events.snapshot
Normal file
|
@ -0,0 +1,5 @@
|
|||
pressed: keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg implicit: Modifiers set to 0x00
|
||||
released: keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
||||
unmask mods: Modifiers set to 0x00
|
11
app/tests/mod-morph/1-no-morph/native_posix_64.keymap
Normal file
11
app/tests/mod-morph/1-no-morph/native_posix_64.keymap
Normal file
|
@ -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,1,10)
|
||||
ZMK_MOCK_RELEASE(0,1,10)
|
||||
>;
|
||||
};
|
8
app/tests/mod-morph/2a-masked-morph/events.patterns
Normal file
8
app/tests/mod-morph/2a-masked-morph/events.patterns
Normal file
|
@ -0,0 +1,8 @@
|
|||
s/.*hid_listener_keycode_pressed.*keycode/pressed: keycode/p
|
||||
s/.*hid_listener_keycode_released.*keycode/released: keycode/p
|
||||
s/.*hid_register_mod.*Modifiers set to /reg explicit: Modifiers set to /p
|
||||
s/.*hid_unregister_mod.*Modifiers set to /unreg explicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_press.*Modifiers set to /reg implicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_release.*Modifiers set to /unreg implicit: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_set.*Modifiers set to /mask mods: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_clear.*Modifiers set to /unmask mods: Modifiers set to /p
|
12
app/tests/mod-morph/2a-masked-morph/keycode_events.snapshot
Normal file
12
app/tests/mod-morph/2a-masked-morph/keycode_events.snapshot
Normal file
|
@ -0,0 +1,12 @@
|
|||
pressed: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg explicit: Modifiers set to 0x02
|
||||
reg implicit: Modifiers set to 0x02
|
||||
mask mods: Modifiers set to 0x00
|
||||
pressed: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg implicit: Modifiers set to 0x00
|
||||
released: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
||||
unmask mods: Modifiers set to 0x02
|
||||
released: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg explicit: Modifiers set to 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
13
app/tests/mod-morph/2a-masked-morph/native_posix_64.keymap
Normal file
13
app/tests/mod-morph/2a-masked-morph/native_posix_64.keymap
Normal file
|
@ -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)
|
||||
ZMK_MOCK_PRESS(0,1,10)
|
||||
ZMK_MOCK_RELEASE(0,1,10)
|
||||
ZMK_MOCK_RELEASE(1,0,10)
|
||||
>;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
s/.*hid_listener_keycode_pressed.*keycode/pressed: keycode/p
|
||||
s/.*hid_listener_keycode_released.*keycode/released: keycode/p
|
||||
s/.*hid_register_mod.*Modifiers set to /reg explicit: Modifiers set to /p
|
||||
s/.*hid_unregister_mod.*Modifiers set to /unreg explicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_press.*Modifiers set to /reg implicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_release.*Modifiers set to /unreg implicit: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_set.*Modifiers set to /mask mods: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_clear.*Modifiers set to /unmask mods: Modifiers set to /p
|
|
@ -0,0 +1,12 @@
|
|||
pressed: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg explicit: Modifiers set to 0x02
|
||||
reg implicit: Modifiers set to 0x02
|
||||
mask mods: Modifiers set to 0x00
|
||||
pressed: keycode 0x05 implicit_mods 0x02 explicit_mods 0x00
|
||||
reg implicit: Modifiers set to 0x02
|
||||
released: keycode 0x05 implicit_mods 0x02 explicit_mods 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
||||
unmask mods: Modifiers set to 0x02
|
||||
released: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg explicit: Modifiers set to 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
|
@ -0,0 +1,37 @@
|
|||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/kscan_mock.h>
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
mod_morph: mod_morph {
|
||||
compatible = "zmk,behavior-mod-morph";
|
||||
label = "MOD_MORPH_TEST";
|
||||
#binding-cells = <0>;
|
||||
bindings = <&kp A>, <&kp LS(B)>; // implict mod overwrite
|
||||
mods = <(MOD_LSFT|MOD_RSFT)>;
|
||||
};
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
label ="Default keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp LEFT_ALT &mod_morph
|
||||
&kp LEFT_SHIFT &kp RIGHT_SHIFT
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&kscan {
|
||||
events = <
|
||||
ZMK_MOCK_PRESS(1,0,10)
|
||||
ZMK_MOCK_PRESS(0,1,10)
|
||||
ZMK_MOCK_RELEASE(0,1,10)
|
||||
ZMK_MOCK_RELEASE(1,0,10)
|
||||
>;
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
s/.*hid_listener_keycode_pressed.*keycode/pressed: keycode/p
|
||||
s/.*hid_listener_keycode_released.*keycode/released: keycode/p
|
||||
s/.*hid_register_mod.*Modifiers set to /reg explicit: Modifiers set to /p
|
||||
s/.*hid_unregister_mod.*Modifiers set to /unreg explicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_press.*Modifiers set to /reg implicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_release.*Modifiers set to /unreg implicit: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_set.*Modifiers set to /mask mods: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_clear.*Modifiers set to /unmask mods: Modifiers set to /p
|
|
@ -0,0 +1,18 @@
|
|||
pressed: keycode 0xE2 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg explicit: Modifiers set to 0x04
|
||||
reg implicit: Modifiers set to 0x04
|
||||
pressed: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg explicit: Modifiers set to 0x06
|
||||
reg implicit: Modifiers set to 0x06
|
||||
mask mods: Modifiers set to 0x04
|
||||
pressed: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg implicit: Modifiers set to 0x04
|
||||
released: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg implicit: Modifiers set to 0x04
|
||||
unmask mods: Modifiers set to 0x06
|
||||
released: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg explicit: Modifiers set to 0x04
|
||||
unreg implicit: Modifiers set to 0x04
|
||||
released: keycode 0xE2 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg explicit: Modifiers set to 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
|
@ -0,0 +1,15 @@
|
|||
#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_PRESS(0,1,10)
|
||||
ZMK_MOCK_RELEASE(0,1,10)
|
||||
ZMK_MOCK_RELEASE(1,0,10)
|
||||
ZMK_MOCK_RELEASE(0,0,10)
|
||||
>;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
s/.*hid_listener_keycode_pressed.*keycode/pressed: keycode/p
|
||||
s/.*hid_listener_keycode_released.*keycode/released: keycode/p
|
||||
s/.*hid_register_mod.*Modifiers set to /reg explicit: Modifiers set to /p
|
||||
s/.*hid_unregister_mod.*Modifiers set to /unreg explicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_press.*Modifiers set to /reg implicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_release.*Modifiers set to /unreg implicit: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_set.*Modifiers set to /mask mods: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_clear.*Modifiers set to /unmask mods: Modifiers set to /p
|
|
@ -0,0 +1,12 @@
|
|||
pressed: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg explicit: Modifiers set to 0x02
|
||||
reg implicit: Modifiers set to 0x02
|
||||
mask mods: Modifiers set to 0x00
|
||||
pressed: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg implicit: Modifiers set to 0x00
|
||||
released: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
||||
unmask mods: Modifiers set to 0x02
|
||||
released: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg explicit: Modifiers set to 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
|
@ -0,0 +1,45 @@
|
|||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/kscan_mock.h>
|
||||
|
||||
&kscan {
|
||||
events = <
|
||||
/* Shift + tap &mod_morph --> expect B (but get Shift + B) */
|
||||
ZMK_MOCK_PRESS(0,0,10)
|
||||
ZMK_MOCK_PRESS(0,1,10)
|
||||
ZMK_MOCK_RELEASE(0,1,10)
|
||||
ZMK_MOCK_RELEASE(0,0,10)
|
||||
>;
|
||||
};
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
mod_morph: mod_morph {
|
||||
compatible = "zmk,behavior-mod-morph";
|
||||
label = "MOD_MORPH_TEST";
|
||||
#binding-cells = <0>;
|
||||
bindings = <&kp A>, << 1 B>;
|
||||
mods = <(MOD_LSFT|MOD_RSFT)>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
label ="Default keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp LEFT_SHIFT &mod_morph
|
||||
&kp C &none
|
||||
>;
|
||||
};
|
||||
|
||||
second_layer {
|
||||
bindings = <
|
||||
&trans &trans
|
||||
&kp D &trans
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
s/.*hid_listener_keycode_pressed.*keycode/pressed: keycode/p
|
||||
s/.*hid_listener_keycode_released.*keycode/released: keycode/p
|
||||
s/.*hid_register_mod.*Modifiers set to /reg explicit: Modifiers set to /p
|
||||
s/.*hid_unregister_mod.*Modifiers set to /unreg explicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_press.*Modifiers set to /reg implicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_release.*Modifiers set to /unreg implicit: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_set.*Modifiers set to /mask mods: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_clear.*Modifiers set to /unmask mods: Modifiers set to /p
|
|
@ -0,0 +1,12 @@
|
|||
pressed: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg explicit: Modifiers set to 0x02
|
||||
reg implicit: Modifiers set to 0x02
|
||||
mask mods: Modifiers set to 0x00
|
||||
pressed: keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg implicit: Modifiers set to 0x00
|
||||
released: keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
||||
unmask mods: Modifiers set to 0x02
|
||||
released: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg explicit: Modifiers set to 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
|
@ -0,0 +1,47 @@
|
|||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/kscan_mock.h>
|
||||
|
||||
&kscan {
|
||||
events = <
|
||||
/* Shift + hold &mod_morph --> expect and get D (no shift) */
|
||||
ZMK_MOCK_PRESS(0,0,10)
|
||||
ZMK_MOCK_PRESS(0,1,200)
|
||||
ZMK_MOCK_PRESS(1,0,10)
|
||||
ZMK_MOCK_RELEASE(1,0,10)
|
||||
ZMK_MOCK_RELEASE(0,1,10)
|
||||
ZMK_MOCK_RELEASE(0,0,10)
|
||||
>;
|
||||
};
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
mod_morph: mod_morph {
|
||||
compatible = "zmk,behavior-mod-morph";
|
||||
label = "MOD_MORPH_TEST";
|
||||
#binding-cells = <0>;
|
||||
bindings = <&kp A>, << 1 B>;
|
||||
mods = <(MOD_LSFT|MOD_RSFT)>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
label ="Default keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp LEFT_SHIFT &mod_morph
|
||||
&kp C &none
|
||||
>;
|
||||
};
|
||||
|
||||
second_layer {
|
||||
bindings = <
|
||||
&trans &trans
|
||||
&kp D &trans
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
8
app/tests/mod-morph/3-unmasked-morph/events.patterns
Normal file
8
app/tests/mod-morph/3-unmasked-morph/events.patterns
Normal file
|
@ -0,0 +1,8 @@
|
|||
s/.*hid_listener_keycode_pressed.*keycode/pressed: keycode/p
|
||||
s/.*hid_listener_keycode_released.*keycode/released: keycode/p
|
||||
s/.*hid_register_mod.*Modifiers set to /reg explicit: Modifiers set to /p
|
||||
s/.*hid_unregister_mod.*Modifiers set to /unreg explicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_press.*Modifiers set to /reg implicit: Modifiers set to /p
|
||||
s/.*hid_implicit_modifiers_release.*Modifiers set to /unreg implicit: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_set.*Modifiers set to /mask mods: Modifiers set to /p
|
||||
s/.*hid_masked_modifiers_clear.*Modifiers set to /unmask mods: Modifiers set to /p
|
12
app/tests/mod-morph/3-unmasked-morph/keycode_events.snapshot
Normal file
12
app/tests/mod-morph/3-unmasked-morph/keycode_events.snapshot
Normal file
|
@ -0,0 +1,12 @@
|
|||
pressed: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg explicit: Modifiers set to 0x02
|
||||
reg implicit: Modifiers set to 0x02
|
||||
mask mods: Modifiers set to 0x02
|
||||
pressed: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
reg implicit: Modifiers set to 0x02
|
||||
released: keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg implicit: Modifiers set to 0x02
|
||||
unmask mods: Modifiers set to 0x02
|
||||
released: keycode 0xE1 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg explicit: Modifiers set to 0x00
|
||||
unreg implicit: Modifiers set to 0x00
|
37
app/tests/mod-morph/3-unmasked-morph/native_posix_64.keymap
Normal file
37
app/tests/mod-morph/3-unmasked-morph/native_posix_64.keymap
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <behaviors.dtsi>
|
||||
#include <dt-bindings/zmk/kscan_mock.h>
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
mod_morph: mod_morph {
|
||||
compatible = "zmk,behavior-mod-morph";
|
||||
label = "MOD_MORPH_TEST";
|
||||
#binding-cells = <0>;
|
||||
bindings = <&kp A>, <&kp B>;
|
||||
mods = <(MOD_LSFT|MOD_RSFT)>;
|
||||
keep-mods = <(MOD_LSFT|MOD_RSFT)>; // no masking
|
||||
};
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
label ="Default keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp LEFT_ALT &mod_morph
|
||||
&kp LEFT_SHIFT &kp RIGHT_SHIFT
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&kscan {
|
||||
events = <
|
||||
ZMK_MOCK_PRESS(1,0,10)
|
||||
ZMK_MOCK_PRESS(0,1,10)
|
||||
ZMK_MOCK_RELEASE(0,1,10)
|
||||
ZMK_MOCK_RELEASE(1,0,10)
|
||||
>;
|
||||
};
|
23
app/tests/mod-morph/behavior_keymap.dtsi
Normal file
23
app/tests/mod-morph/behavior_keymap.dtsi
Normal file
|
@ -0,0 +1,23 @@
|
|||
/ {
|
||||
behaviors {
|
||||
mod_morph: mod_morph {
|
||||
compatible = "zmk,behavior-mod-morph";
|
||||
label = "MOD_MORPH_TEST";
|
||||
#binding-cells = <0>;
|
||||
bindings = <&kp A>, <&kp B>;
|
||||
mods = <(MOD_LSFT|MOD_RSFT)>;
|
||||
};
|
||||
};
|
||||
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
label ="Default keymap";
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp LEFT_ALT &mod_morph
|
||||
&kp LEFT_SHIFT &kp RIGHT_SHIFT
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -7,7 +7,7 @@ mods: Modifiers set to 0x03
|
|||
released: usage_page 0x07 keycode 0xE0 implicit_mods 0x00 explicit_mods 0x00
|
||||
unreg: Modifier 0 count: 0
|
||||
unreg: Modifier 0 released
|
||||
unreg: Modifiers set to 0x00
|
||||
unreg: Modifiers set to 0x02
|
||||
mods: Modifiers set to 0x00
|
||||
released: usage_page 0x07 keycode 0x05 implicit_mods 0x02 explicit_mods 0x00
|
||||
mods: Modifiers set to 0x00
|
||||
|
|
|
@ -28,7 +28,7 @@ We call this the 'hold-preferred' flavor of hold-taps. While this flavor may wor
|
|||
|
||||
- The 'hold-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired or another key is pressed.
|
||||
- The 'balanced' flavor will trigger the hold behavior when the `tapping-term-ms` has expired or another key is pressed and released.
|
||||
- The 'tap-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired. It triggers the tap behavior when another key is pressed.
|
||||
- The 'tap-preferred' flavor triggers the hold behavior when the `tapping-term-ms` has expired. Pressing another key within `tapping-term-ms` does not affect the decision.
|
||||
- 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.
|
||||
|
@ -139,7 +139,7 @@ defaultValue="homerow_mods"
|
|||
values={[
|
||||
{label: 'Homerow Mods', value: 'homerow_mods'},
|
||||
{label: 'Autoshift', value: 'autoshift'},
|
||||
{label: 'Toggle-on-Tap, Momentary-on-Hold Layers', value: 'tog_mo'},
|
||||
{label: 'Toggle-on-Tap, Momentary-on-Hold Layers', value: 'mo_tog'},
|
||||
]}>
|
||||
|
||||
<TabItem value="homerow_mods">
|
||||
|
@ -276,25 +276,25 @@ A popular method of implementing Autoshift in ZMK involves a C-preprocessor macr
|
|||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="tog_mo">
|
||||
<TabItem value="mo_tog">
|
||||
|
||||
This hold-tap example implements a [toggle-layer](layers.md/#toggle-layer) when the keybind is tapped and a [momentary-layer](layers.md/#momentary-layer) when it is held. Similarly to the Autoshift and Sticky Hold use-cases, a `TOG_MO(layer)` macro is defined such that the `&tog` and `&mo` behaviors can target a single layer.
|
||||
This hold-tap example implements a [momentary-layer](layers.md/#momentary-layer) when the keybind is held and a [toggle-layer](layers.md/#toggle-layer) when it is tapped. Similar to the Autoshift and Sticky Hold use-cases, a `MO_TOG(layer)` macro is defined such that the `&mo` and `&tog` behaviors can target a single layer.
|
||||
|
||||
```dtsi title="Hold-Tap Example: Toggle layer on Tap, Momentary layer on Hold"
|
||||
```dtsi title="Hold-Tap Example: Momentary layer on Hold, Toggle layer on Tap"
|
||||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <behaviors.dtsi>
|
||||
|
||||
#define TOG_MO(layer) &tog_mo layer layer // Macro to apply toggle-layer-on-tap/momentary-layer-on-hold to a specific layer
|
||||
#define MO_TOG(layer) &mo_tog layer layer // Macro to apply momentary-layer-on-hold/toggle-layer-on-tap to a specific layer
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
tog_mo: behavior_mo_tog {
|
||||
mo_tog: behavior_mo_tog {
|
||||
compatible = "zmk,behavior-hold-tap";
|
||||
label = "mo_tog";
|
||||
#binding-cells = <2>;
|
||||
flavor = "hold-preferred";
|
||||
tapping-term-ms = <200>;
|
||||
bindings = <&tog>, <&mo>;
|
||||
bindings = <&mo>, <&tog>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -302,8 +302,8 @@ This hold-tap example implements a [toggle-layer](layers.md/#toggle-layer) when
|
|||
compatible = "zmk,keymap";
|
||||
default_layer {
|
||||
bindings = <
|
||||
&tog_mo 2 1 // &mo 2 on hold, &tog 1 on tap
|
||||
TOG_MO(3) // &mo 3 on hold, &tog 3 on tap
|
||||
&mo_tog 2 1 // &mo 2 on hold, &tog 1 on tap
|
||||
MO_TOG(3) // &mo 3 on hold, &tog 3 on tap
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -14,8 +14,6 @@ The Mod-Morph behavior sends a different keypress, depending on whether a specif
|
|||
|
||||
The Mod-Morph behavior acts as one of two keycodes, depending on if the required modifier is being held during the keypress.
|
||||
|
||||
When the modifier is being held it is sent along with the morphed keycode. This can cause problems when the morphed keycode and modifier have an existing relationship (such as `shift-delete` or `ctrl-v` on many operating systems).
|
||||
|
||||
### Configuration
|
||||
|
||||
An example of how to implement the mod-morph "Grave Escape":
|
||||
|
@ -31,10 +29,6 @@ An example of how to implement the mod-morph "Grave Escape":
|
|||
mods = <(MOD_LGUI|MOD_LSFT|MOD_RGUI|MOD_RSFT)>;
|
||||
};
|
||||
};
|
||||
|
||||
keymap {
|
||||
...
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -71,3 +65,26 @@ Example:
|
|||
```
|
||||
mods = <(MOD_LGUI|MOD_LSFT|MOD_RGUI|MOD_RSFT)>;
|
||||
```
|
||||
|
||||
### Advanced configuration
|
||||
|
||||
`keep-mods`
|
||||
|
||||
When a modifier specified in `mods` is being held, it won't be sent along with the morphed keycode unless it is also specified in `keep-mods`. By default `keep-mods` equals `0`, which means no modifier specified in `mods` will be sent along with the morphed keycode.
|
||||
|
||||
For example, the following configuration morphs `LEFT_SHIFT` + `BACKSPACE` into `DELETE`, and morphs `RIGHT_SHIFT` + `BACKSPACE` into `RIGHT_SHIFT` + `DELETE`.
|
||||
|
||||
```
|
||||
/ {
|
||||
behaviors {
|
||||
bspc_del: backspace_delete {
|
||||
compatible = "zmk,behavior-mod-morph";
|
||||
label = "BACKSPACE_DELETE";
|
||||
#binding-cells = <0>;
|
||||
bindings = <&kp BACKSPACE>, <&kp DELETE>;
|
||||
mods = <(MOD_LSFT|MOD_RSFT)>;
|
||||
keep-mods = <(MOD_RSFT)>;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
|
|
@ -5,6 +5,7 @@ hide_title: true
|
|||
slug: ./
|
||||
---
|
||||
|
||||
import SpellingCaution from "@site/src/components/codes/SpellingCaution";
|
||||
import OsLegend from "@site/src/components/codes/OsLegend";
|
||||
import ToastyContainer from "@site/src/components/codes/ToastyContainer";
|
||||
import Key, { toc as keyToc } from "./_keyboard-keypad.mdx";
|
||||
|
@ -23,6 +24,7 @@ export const toc = [
|
|||
...powerToc,
|
||||
];
|
||||
|
||||
<SpellingCaution />
|
||||
<OsLegend />
|
||||
<ToastyContainer />
|
||||
<Key />
|
||||
|
|
|
@ -93,9 +93,11 @@ Keyboard scan driver where keys are arranged on a matrix with one GPIO per row a
|
|||
|
||||
Definition file: [zmk/app/drivers/kscan/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/app/drivers/kscan/Kconfig)
|
||||
|
||||
| Config | Type | Description | Default |
|
||||
| --------------------------------- | ---- | ------------------------------------------------ | ------- |
|
||||
| `CONFIG_ZMK_KSCAN_MATRIX_POLLING` | bool | Poll for key presses instead of using interrupts | n |
|
||||
| Config | Type | Description | Default |
|
||||
| ---------------------------------------------- | ----------- | ------------------------------------------------------------------------- | ------- |
|
||||
| `CONFIG_ZMK_KSCAN_MATRIX_POLLING` | bool | Poll for key presses instead of using interrupts | n |
|
||||
| `CONFIG_ZMK_KSCAN_MATRIX_WAIT_BEFORE_INPUTS` | int (ticks) | How long to wait before reading input pins after setting output active | 0 |
|
||||
| `CONFIG_ZMK_KSCAN_MATRIX_WAIT_BETWEEN_OUTPUTS` | int (ticks) | How long to wait between each output to allow previous output to "settle" | 0 |
|
||||
|
||||
### Devicetree
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue