Merge branch 'zmkfirmware:main' into main
This commit is contained in:
commit
8dcef74c39
138 changed files with 1908 additions and 825 deletions
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
|
@ -12,6 +12,12 @@ on:
|
|||
schedule:
|
||||
- cron: "22 4 * * *"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name == 'schedule' }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: ${{ always() }}
|
||||
|
@ -25,6 +31,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Cache west modules
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
|
@ -131,7 +139,7 @@ jobs:
|
|||
throw new Error('Failed to build one or more configurations');
|
||||
}
|
||||
compile-matrix:
|
||||
if: ${{ always() }}
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: [core-coverage, board-changes, nightly]
|
||||
outputs:
|
||||
|
@ -179,6 +187,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
|
@ -284,7 +294,7 @@ jobs:
|
|||
});
|
||||
}))).flat();
|
||||
nightly:
|
||||
if: ${{ github.event_name == 'schedule' }}
|
||||
if: ${{ github.event_name == 'schedule' && github.repository_owner == 'zmkfirmware' }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: get-grouped-hardware
|
||||
outputs:
|
||||
|
@ -335,6 +345,8 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
|
@ -413,7 +425,11 @@ jobs:
|
|||
board-changes: ${{ steps.board-changes.outputs.result }}
|
||||
core-changes: ${{ steps.core-changes.outputs.result }}
|
||||
steps:
|
||||
- uses: tj-actions/changed-files@v42
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: tj-actions/changed-files@v44
|
||||
id: changed-files
|
||||
with:
|
||||
json: true
|
||||
|
|
12
app/Kconfig
12
app/Kconfig
|
@ -113,6 +113,12 @@ config ZMK_HID_INDICATORS
|
|||
Enable HID indicators, used for detecting state of Caps/Scroll/Num Lock,
|
||||
Kata, and Compose.
|
||||
|
||||
config ZMK_HID_SEPARATE_MOD_RELEASE_REPORT
|
||||
bool "Release Modifiers Separately"
|
||||
help
|
||||
Send a separate release event for the modifiers, to make sure the release
|
||||
of the modifier doesn't get recognized before the actual key's release event.
|
||||
|
||||
menu "Output Types"
|
||||
|
||||
config ZMK_USB
|
||||
|
@ -490,7 +496,11 @@ if USB_DEVICE_STACK
|
|||
|
||||
config ZMK_USB_INIT_PRIORITY
|
||||
int "USB Init Priority"
|
||||
default 50
|
||||
default 94
|
||||
|
||||
config ZMK_USB_HID_INIT_PRIORITY
|
||||
int "USB HID Init Priority"
|
||||
default 95
|
||||
|
||||
#USB
|
||||
endif
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
# Copyright (c) 2023 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config ZMK_BEHAVIOR_METADATA
|
||||
bool "Metadata"
|
||||
help
|
||||
Enabling this option adds APIs for documenting and fetching
|
||||
metadata describing a behaviors name, and supported parameters.
|
||||
|
||||
config ZMK_BEHAVIOR_KEY_TOGGLE
|
||||
bool
|
||||
default y
|
||||
|
@ -35,4 +41,4 @@ config ZMK_BEHAVIOR_SENSOR_ROTATE_VAR
|
|||
config ZMK_BEHAVIOR_MACRO
|
||||
bool
|
||||
default y
|
||||
depends on DT_HAS_ZMK_BEHAVIOR_MACRO_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_ONE_PARAM_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_TWO_PARAM_ENABLED
|
||||
depends on DT_HAS_ZMK_BEHAVIOR_MACRO_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_ONE_PARAM_ENABLED || DT_HAS_ZMK_BEHAVIOR_MACRO_TWO_PARAM_ENABLED
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "usb_console.dtsi"
|
||||
|
||||
&xiao_serial { status = "disabled"; };
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "usb_console.dtsi"
|
||||
|
||||
&pro_micro_serial { status = "disabled"; };
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "usb_console.dtsi"
|
||||
|
||||
&xiao_serial { status = "disabled"; };
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,backlight = &backlight;
|
||||
zmk,battery = &vbatt;
|
||||
|
@ -90,11 +89,8 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,kscan = &kscan;
|
||||
zmk,underglow = &led_strip;
|
||||
};
|
||||
|
@ -106,13 +105,10 @@
|
|||
apb1-prescaler = <1>;
|
||||
};
|
||||
|
||||
&usb {
|
||||
zephyr_udc0: &usb {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>;
|
||||
pinctrl-names = "default";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&rtc {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -82,11 +81,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix-transform = &default_transform;
|
||||
|
@ -70,11 +69,8 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
zephyr,flash = &flash0;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,display = &epd;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,matrix-transform = &default_transform;
|
||||
};
|
||||
|
||||
|
@ -76,11 +75,8 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix-transform = &default_transform;
|
||||
};
|
||||
|
@ -65,11 +64,8 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,5) RC(
|
|||
|
||||
};
|
||||
|
||||
&usb {
|
||||
zephyr_udc0: &usb {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,kscan = &kscan;
|
||||
zmk,matrix-transform = &transform;
|
||||
/* TODO: Enable once we support the IC for underglow
|
||||
|
@ -110,14 +109,11 @@
|
|||
};
|
||||
};
|
||||
|
||||
&usb {
|
||||
zephyr_udc0: &usb {
|
||||
status = "okay";
|
||||
|
||||
pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>;
|
||||
pinctrl-names = "default";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&clk_hsi {
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
};
|
||||
|
||||
default_transform: keymap_transform_0 {
|
||||
|
@ -59,11 +58,8 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zephyr,shell-uart = &cdc_acm_uart;
|
||||
zephyr,code-partition = &code_partition;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix-transform = &default_transform;
|
||||
|
@ -108,11 +106,8 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,6) RC(4,8) RC(4,9)
|
|||
};
|
||||
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -81,11 +80,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix-transform = &default_transform;
|
||||
|
@ -129,11 +128,8 @@ RC(4,0) RC(4,1) RC(4,2) RC(4,5) R
|
|||
};
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
};
|
||||
|
||||
leds {
|
||||
|
@ -65,11 +64,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -57,12 +56,9 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
compatible = "nordic,nrf-usbd";
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
};
|
||||
|
||||
leds {
|
||||
|
@ -69,11 +68,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
};
|
||||
|
||||
leds {
|
||||
|
@ -69,11 +68,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -81,11 +80,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -81,11 +80,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -83,11 +82,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix-transform = &layout_grid_transform;
|
||||
};
|
||||
|
@ -96,13 +95,10 @@ layout_2x2u_transform:
|
|||
};
|
||||
};
|
||||
|
||||
&usb {
|
||||
zephyr_udc0: &usb {
|
||||
pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&clk_hse {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix-transform = &layout_grid_transform;
|
||||
};
|
||||
|
@ -90,13 +89,10 @@
|
|||
};
|
||||
};
|
||||
|
||||
&usb {
|
||||
zephyr_udc0: &usb {
|
||||
pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&clk_hse {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
chosen {
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart0;
|
||||
};
|
||||
|
||||
aliases {
|
||||
|
@ -66,13 +65,10 @@
|
|||
apb2-prescaler = <1>;
|
||||
};
|
||||
|
||||
&usb {
|
||||
zephyr_udc0: &usb {
|
||||
pinctrl-0 = <&usb_dm_pa11 &usb_dp_pa12>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
cdc_acm_uart0: cdc_acm_uart0 {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&rtc {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -72,11 +71,8 @@
|
|||
pinctrl-names = "default", "sleep";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
zephyr,code-partition = &code_partition;
|
||||
zephyr,sram = &sram0;
|
||||
zephyr,flash = &flash0;
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
zmk,kscan = &kscan0;
|
||||
zmk,matrix-transform = &default_transform;
|
||||
|
@ -93,11 +92,8 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
zephyr_udc0: &usbd {
|
||||
status = "okay";
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&flash0 {
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "usb_console.dtsi"
|
||||
|
||||
&pro_micro_serial { status = "disabled"; };
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "usb_console.dtsi"
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
};
|
||||
};
|
||||
|
||||
&usb0 {
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
/ {
|
||||
chosen {
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
zmk,battery = &vbatt;
|
||||
};
|
||||
|
||||
|
@ -24,12 +23,6 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&usbd {
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
||||
&qspi {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&qspi_default>;
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "usb_console.dtsi"
|
||||
|
||||
&xiao_serial { status = "disabled"; };
|
||||
|
|
|
@ -4,6 +4,4 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "usb_console.dtsi"
|
||||
|
||||
&pro_micro_serial { status = "disabled"; };
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zephyr,console = &cdc_acm_uart;
|
||||
};
|
||||
};
|
||||
|
||||
&usbd {
|
||||
cdc_acm_uart: cdc_acm_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
||||
|
|
@ -22,6 +22,9 @@ include:
|
|||
shield: kyria_left
|
||||
cmake-args: "-DCONFIG_ZMK_DISPLAY=y"
|
||||
nickname: "display"
|
||||
- board: sparkfun_pro_micro_rp2040
|
||||
shield: reviung41
|
||||
cmake-args: "-DSNIPPET='zmk-usb-logging'"
|
||||
- board: nice_nano_v2
|
||||
shield: kyria_right
|
||||
cmake-args: "-DCONFIG_ZMK_DISPLAY=y"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
/omit-if-no-ref/ bl: bcklight {
|
||||
compatible = "zmk,behavior-backlight";
|
||||
#binding-cells = <2>;
|
||||
display-name = "Backlight";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ bt: bluetooth {
|
||||
compatible = "zmk,behavior-bluetooth";
|
||||
#binding-cells = <2>;
|
||||
display-name = "Bluetooth";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
compatible = "zmk,behavior-caps-word";
|
||||
#binding-cells = <0>;
|
||||
continue-list = <UNDERSCORE BACKSPACE DELETE>;
|
||||
display-name = "Caps Word";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
ext_power: extpower {
|
||||
compatible = "zmk,behavior-ext-power";
|
||||
#binding-cells = <1>;
|
||||
display-name = "External Power";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#binding-cells = <0>;
|
||||
bindings = <&kp ESC>, <&kp GRAVE>;
|
||||
mods = <(MOD_LGUI|MOD_LSFT|MOD_RGUI|MOD_RSFT)>;
|
||||
display-name = "Grave/Escape";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
/omit-if-no-ref/ cp: kp: key_press {
|
||||
compatible = "zmk,behavior-key-press";
|
||||
#binding-cells = <1>;
|
||||
display-name = "Key Press";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
compatible = "zmk,behavior-key-repeat";
|
||||
#binding-cells = <0>;
|
||||
usage-pages = <HID_USAGE_KEY>;
|
||||
display-name = "Key Repeat";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ kt: key_toggle {
|
||||
compatible = "zmk,behavior-key-toggle";
|
||||
#binding-cells = <1>;
|
||||
display-name = "Key Toggle";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
flavor = "tap-preferred";
|
||||
tapping-term-ms = <200>;
|
||||
bindings = <&mo>, <&kp>;
|
||||
display-name = "Layer-Tap";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
flavor = "hold-preferred";
|
||||
tapping-term-ms = <200>;
|
||||
bindings = <&kp>, <&kp>;
|
||||
display-name = "Mod-Tap";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ mo: momentary_layer {
|
||||
compatible = "zmk,behavior-momentary-layer";
|
||||
#binding-cells = <1>;
|
||||
display-name = "Momentary Layer";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ none: none {
|
||||
compatible = "zmk,behavior-none";
|
||||
#binding-cells = <0>;
|
||||
display-name = "None";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ out: outputs {
|
||||
compatible = "zmk,behavior-outputs";
|
||||
#binding-cells = <1>;
|
||||
display-name = "Output Selection";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
sys_reset: sysreset {
|
||||
compatible = "zmk,behavior-reset";
|
||||
#binding-cells = <0>;
|
||||
display-name = "Reset";
|
||||
};
|
||||
|
||||
// Behavior can be invoked on peripherals, so name must be <= 8 characters.
|
||||
|
@ -19,6 +20,7 @@
|
|||
compatible = "zmk,behavior-reset";
|
||||
type = <RST_UF2>;
|
||||
#binding-cells = <0>;
|
||||
display-name = "Bootloader";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
rgb_ug: rgb_ug {
|
||||
compatible = "zmk,behavior-rgb-underglow";
|
||||
#binding-cells = <2>;
|
||||
display-name = "Underglow";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
release-after-ms = <1000>;
|
||||
bindings = <&kp>;
|
||||
ignore-modifiers;
|
||||
display-name = "Sticky Key";
|
||||
};
|
||||
/omit-if-no-ref/ sl: sticky_layer {
|
||||
compatible = "zmk,behavior-sticky-key";
|
||||
|
@ -19,6 +20,7 @@
|
|||
release-after-ms = <1000>;
|
||||
bindings = <&mo>;
|
||||
quick-release;
|
||||
display-name = "Sticky Layer";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ to: to_layer {
|
||||
compatible = "zmk,behavior-to-layer";
|
||||
#binding-cells = <1>;
|
||||
display-name = "To Layer";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ tog: toggle_layer {
|
||||
compatible = "zmk,behavior-toggle-layer";
|
||||
#binding-cells = <1>;
|
||||
display-name = "Toggle Layer";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/omit-if-no-ref/ trans: transparent {
|
||||
compatible = "zmk,behavior-transparent";
|
||||
#binding-cells = <0>;
|
||||
display-name = "Transparent";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
6
app/dts/bindings/behaviors/behavior-metadata.yaml
Normal file
6
app/dts/bindings/behaviors/behavior-metadata.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2024 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
properties:
|
||||
display-name:
|
||||
type: string
|
|
@ -1,6 +1,8 @@
|
|||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
include: behavior-metadata.yaml
|
||||
|
||||
properties:
|
||||
label:
|
||||
type: string
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
include: behavior-metadata.yaml
|
||||
|
||||
properties:
|
||||
label:
|
||||
type: string
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
include: behavior-metadata.yaml
|
||||
|
||||
properties:
|
||||
label:
|
||||
type: string
|
||||
|
|
|
@ -23,6 +23,39 @@
|
|||
* (Internal use only.)
|
||||
*/
|
||||
|
||||
struct behavior_parameter_value_metadata {
|
||||
char *display_name;
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
int32_t min;
|
||||
int32_t max;
|
||||
} range;
|
||||
};
|
||||
|
||||
enum {
|
||||
BEHAVIOR_PARAMETER_VALUE_TYPE_NIL = 0,
|
||||
BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE = 1,
|
||||
BEHAVIOR_PARAMETER_VALUE_TYPE_RANGE = 2,
|
||||
BEHAVIOR_PARAMETER_VALUE_TYPE_HID_USAGE = 3,
|
||||
BEHAVIOR_PARAMETER_VALUE_TYPE_LAYER_INDEX = 4,
|
||||
} type;
|
||||
};
|
||||
|
||||
struct behavior_parameter_metadata_set {
|
||||
size_t param1_values_len;
|
||||
const struct behavior_parameter_value_metadata *param1_values;
|
||||
|
||||
size_t param2_values_len;
|
||||
const struct behavior_parameter_value_metadata *param2_values;
|
||||
};
|
||||
|
||||
struct behavior_parameter_metadata {
|
||||
size_t sets_len;
|
||||
const struct behavior_parameter_metadata_set *sets;
|
||||
};
|
||||
|
||||
enum behavior_sensor_binding_process_mode {
|
||||
BEHAVIOR_SENSOR_BINDING_PROCESS_MODE_TRIGGER,
|
||||
BEHAVIOR_SENSOR_BINDING_PROCESS_MODE_DISCARD,
|
||||
|
@ -37,6 +70,10 @@ typedef int (*behavior_sensor_keymap_binding_accept_data_callback_t)(
|
|||
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event,
|
||||
const struct zmk_sensor_config *sensor_config, size_t channel_data_size,
|
||||
const struct zmk_sensor_channel_data channel_data[channel_data_size]);
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
typedef int (*behavior_get_parameter_metadata_t)(
|
||||
const struct device *behavior, struct behavior_parameter_metadata *param_metadata);
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
enum behavior_locality {
|
||||
BEHAVIOR_LOCALITY_CENTRAL,
|
||||
|
@ -51,23 +88,54 @@ __subsystem struct behavior_driver_api {
|
|||
behavior_keymap_binding_callback_t binding_released;
|
||||
behavior_sensor_keymap_binding_accept_data_callback_t sensor_binding_accept_data;
|
||||
behavior_sensor_keymap_binding_process_callback_t sensor_binding_process;
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
behavior_get_parameter_metadata_t get_parameter_metadata;
|
||||
const struct behavior_parameter_metadata *parameter_metadata;
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
struct zmk_behavior_metadata {
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
const char *display_name;
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
struct zmk_behavior_ref {
|
||||
const struct device *device;
|
||||
const struct zmk_behavior_metadata metadata;
|
||||
};
|
||||
|
||||
#define ZMK_BEHAVIOR_REF_DT_NAME(node_id) _CONCAT(zmk_behavior_, DEVICE_DT_NAME_GET(node_id))
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
#define ZMK_BEHAVIOR_METADATA_INITIALIZER(node_id) \
|
||||
{ .display_name = DT_PROP_OR(node_id, display_name, DEVICE_DT_NAME(node_id)), }
|
||||
|
||||
#else
|
||||
|
||||
#define ZMK_BEHAVIOR_METADATA_INITIALIZER(node_id) \
|
||||
{}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
#define ZMK_BEHAVIOR_REF_INITIALIZER(node_id, _dev) \
|
||||
{ .device = _dev, .metadata = ZMK_BEHAVIOR_METADATA_INITIALIZER(node_id), }
|
||||
|
||||
#define ZMK_BEHAVIOR_REF_DEFINE(name, node_id, _dev) \
|
||||
static const STRUCT_SECTION_ITERABLE(zmk_behavior_ref, name) = \
|
||||
ZMK_BEHAVIOR_REF_INITIALIZER(node_id, _dev)
|
||||
|
||||
#define ZMK_BEHAVIOR_REF_DT_DEFINE(node_id) \
|
||||
ZMK_BEHAVIOR_REF_DEFINE(ZMK_BEHAVIOR_REF_DT_NAME(node_id), node_id, DEVICE_DT_GET(node_id))
|
||||
|
||||
/**
|
||||
* Registers @p node_id as a behavior.
|
||||
*/
|
||||
#define BEHAVIOR_DEFINE(node_id) \
|
||||
static const STRUCT_SECTION_ITERABLE(zmk_behavior_ref, \
|
||||
_CONCAT(zmk_behavior_, DEVICE_DT_NAME_GET(node_id))) = { \
|
||||
.device = DEVICE_DT_GET(node_id), \
|
||||
}
|
||||
#define BEHAVIOR_DEFINE(node_id) ZMK_BEHAVIOR_REF_DT_DEFINE(node_id)
|
||||
|
||||
/**
|
||||
* @brief Like DEVICE_DT_DEFINE(), but also registers the device as a behavior.
|
||||
|
@ -89,6 +157,52 @@ struct zmk_behavior_ref {
|
|||
DEVICE_DT_INST_DEFINE(inst, __VA_ARGS__); \
|
||||
BEHAVIOR_DEFINE(DT_DRV_INST(inst))
|
||||
|
||||
/**
|
||||
* @brief Validate a given behavior binding is valid, including parameter validation
|
||||
* if the metadata feature is enablued.
|
||||
*
|
||||
* @param binding The behavior binding to validate.
|
||||
*
|
||||
* @retval 0 if the passed in binding is valid.
|
||||
* @retval -ENODEV if the binding references a non-existant behavior.
|
||||
* @retval -EINVAL if parameters are not valid for the behavior metadata.
|
||||
*/
|
||||
int zmk_behavior_validate_binding(const struct zmk_behavior_binding *binding);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
int zmk_behavior_get_empty_param_metadata(const struct device *dev,
|
||||
struct behavior_parameter_metadata *metadata);
|
||||
|
||||
/**
|
||||
* @brief Validate a given behavior parameters match the behavior metadata.
|
||||
*
|
||||
* @param metadata The behavior metadata to validate against
|
||||
* @param param1 The first parameter value
|
||||
* @param param2 The second parameter value
|
||||
*
|
||||
* @retval 0 if the passed in parameters are valid.
|
||||
* @retval -ENODEV if metadata is NULL.
|
||||
* @retval -EINVAL if parameters are not valid for the metadata.
|
||||
*/
|
||||
int zmk_behavior_check_params_match_metadata(const struct behavior_parameter_metadata *metadata,
|
||||
uint32_t param1, uint32_t param2);
|
||||
/**
|
||||
* @brief Validate a given behavior parameter matches the behavior metadata parameter values.
|
||||
*
|
||||
* @param values The values to validate against
|
||||
* @param values_len How many values to check
|
||||
* @param param The value to check.
|
||||
*
|
||||
* @retval 0 if the passed in parameter is valid.
|
||||
* @retval -ENODEV if values is NULL.
|
||||
* @retval -EINVAL if parameter is not valid for the value metadata.
|
||||
*/
|
||||
int zmk_behavior_validate_param_values(const struct behavior_parameter_value_metadata *values,
|
||||
size_t values_len, uint32_t param);
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
/**
|
||||
* Syscall wrapper for zmk_behavior_get_binding().
|
||||
*
|
||||
|
@ -120,6 +234,40 @@ static inline int z_impl_behavior_keymap_binding_convert_central_state_dependent
|
|||
return api->binding_convert_central_state_dependent_params(binding, event);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
/**
|
||||
* @brief Determine where the behavior should be run
|
||||
* @param behavior Pointer to the device structure for the driver instance.
|
||||
*
|
||||
* @retval Zero if successful.
|
||||
* @retval Negative errno code if failure.
|
||||
*/
|
||||
__syscall int behavior_get_parameter_metadata(const struct device *behavior,
|
||||
struct behavior_parameter_metadata *param_metadata);
|
||||
|
||||
static inline int
|
||||
z_impl_behavior_get_parameter_metadata(const struct device *behavior,
|
||||
struct behavior_parameter_metadata *param_metadata) {
|
||||
if (behavior == NULL || param_metadata == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
const struct behavior_driver_api *api = (const struct behavior_driver_api *)behavior->api;
|
||||
|
||||
if (api->get_parameter_metadata) {
|
||||
return api->get_parameter_metadata(behavior, param_metadata);
|
||||
} else if (api->parameter_metadata) {
|
||||
*param_metadata = *api->parameter_metadata;
|
||||
} else {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
/**
|
||||
* @brief Determine where the behavior should be run
|
||||
* @param behavior Pointer to the device structure for the driver instance.
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#define ZMK_BEHAVIOR_TRANSPARENT 1
|
||||
|
||||
struct zmk_behavior_binding {
|
||||
char *behavior_dev;
|
||||
const char *behavior_dev;
|
||||
uint32_t param1;
|
||||
uint32_t param2;
|
||||
};
|
||||
|
|
4
app/snippets/zmk-usb-logging/snippet.yml
Normal file
4
app/snippets/zmk-usb-logging/snippet.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
name: zmk-usb-logging
|
||||
append:
|
||||
EXTRA_CONF_FILE: zmk-usb-logging.conf
|
||||
EXTRA_DTC_OVERLAY_FILE: zmk-usb-logging.overlay
|
2
app/snippets/zmk-usb-logging/zmk-usb-logging.conf
Normal file
2
app/snippets/zmk-usb-logging/zmk-usb-logging.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
CONFIG_ZMK_USB_LOGGING=y
|
||||
|
18
app/snippets/zmk-usb-logging/zmk-usb-logging.overlay
Normal file
18
app/snippets/zmk-usb-logging/zmk-usb-logging.overlay
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2024 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zephyr,console = &snippet_zmk_usb_logging_uart;
|
||||
zephyr,shell-uart = &snippet_zmk_usb_logging_uart;
|
||||
};
|
||||
};
|
||||
|
||||
&zephyr_udc0 {
|
||||
snippet_zmk_usb_logging_uart: snippet_zmk_usb_logging_uart {
|
||||
compatible = "zephyr,cdc-acm-uart";
|
||||
};
|
||||
};
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <drivers/behavior.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/hid.h>
|
||||
#include <zmk/matrix.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
@ -39,6 +41,150 @@ const struct device *z_impl_behavior_get_binding(const char *name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
int zmk_behavior_get_empty_param_metadata(const struct device *dev,
|
||||
struct behavior_parameter_metadata *metadata) {
|
||||
metadata->sets_len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
static int validate_hid_usage(uint16_t usage_page, uint16_t usage_id) {
|
||||
LOG_DBG("Validate usage %d in page %d", usage_id, usage_page);
|
||||
switch (usage_page) {
|
||||
case HID_USAGE_KEY:
|
||||
if (usage_id == 0 || (usage_id > ZMK_HID_KEYBOARD_NKRO_MAX_USAGE &&
|
||||
usage_id < LEFT_CONTROL && usage_id > RIGHT_GUI)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case HID_USAGE_CONSUMER:
|
||||
if (usage_id >
|
||||
COND_CODE_1(IS_ENABLED(CONFIG_ZMK_HID_CONSUMER_REPORT_USAGES_BASIC), (0xFF), (0xFFF))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_WRN("Unsupported HID usage page %d", usage_page);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PARAM_MATCHES 0
|
||||
|
||||
static int check_param_matches_value(const struct behavior_parameter_value_metadata *value_meta,
|
||||
uint32_t param) {
|
||||
switch (value_meta->type) {
|
||||
case BEHAVIOR_PARAMETER_VALUE_TYPE_NIL:
|
||||
if (param == 0) {
|
||||
return PARAM_MATCHES;
|
||||
}
|
||||
break;
|
||||
case BEHAVIOR_PARAMETER_VALUE_TYPE_HID_USAGE:
|
||||
if (validate_hid_usage(ZMK_HID_USAGE_PAGE(param), ZMK_HID_USAGE_ID(param)) >= 0) {
|
||||
return PARAM_MATCHES;
|
||||
}
|
||||
|
||||
break;
|
||||
case BEHAVIOR_PARAMETER_VALUE_TYPE_LAYER_INDEX:
|
||||
if (param >= 0 && param < ZMK_KEYMAP_LEN) {
|
||||
return PARAM_MATCHES;
|
||||
}
|
||||
break;
|
||||
/* TODO: Restore with HSV -> RGB refactor
|
||||
case BEHAVIOR_PARAMETER_STANDARD_DOMAIN_HSV:
|
||||
// TODO: No real way to validate? Maybe max brightness?
|
||||
break;
|
||||
*/
|
||||
case BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE:
|
||||
if (param == value_meta->value) {
|
||||
return PARAM_MATCHES;
|
||||
}
|
||||
break;
|
||||
case BEHAVIOR_PARAMETER_VALUE_TYPE_RANGE:
|
||||
if (param >= value_meta->range.min && param <= value_meta->range.max) {
|
||||
return PARAM_MATCHES;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_WRN("Unknown type %d", value_meta->type);
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
int zmk_behavior_validate_param_values(const struct behavior_parameter_value_metadata *values,
|
||||
size_t values_len, uint32_t param) {
|
||||
if (values_len == 0) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (int v = 0; v < values_len; v++) {
|
||||
int ret = check_param_matches_value(&values[v], param);
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int zmk_behavior_check_params_match_metadata(const struct behavior_parameter_metadata *metadata,
|
||||
uint32_t param1, uint32_t param2) {
|
||||
if (!metadata || metadata->sets_len == 0) {
|
||||
if (!metadata) {
|
||||
LOG_ERR("No metadata to check against");
|
||||
}
|
||||
|
||||
return (param1 == 0 && param2 == 0) ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
for (int s = 0; s < metadata->sets_len; s++) {
|
||||
const struct behavior_parameter_metadata_set *set = &metadata->sets[s];
|
||||
int param1_ret =
|
||||
zmk_behavior_validate_param_values(set->param1_values, set->param1_values_len, param1);
|
||||
int param2_ret =
|
||||
zmk_behavior_validate_param_values(set->param2_values, set->param2_values_len, param2);
|
||||
|
||||
if ((param1_ret >= 0 || (param1_ret == -ENODEV && param1 == 0)) &&
|
||||
(param2_ret >= 0 || (param2_ret == -ENODEV && param2 == 0))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
int zmk_behavior_validate_binding(const struct zmk_behavior_binding *binding) {
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
const struct device *behavior = zmk_behavior_get_binding(binding->behavior_dev);
|
||||
|
||||
if (!behavior) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
struct behavior_parameter_metadata metadata;
|
||||
int ret = behavior_get_parameter_metadata(behavior, &metadata);
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_WRN("Failed getting metadata for %s: %d", binding->behavior_dev, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return zmk_behavior_check_params_match_metadata(&metadata, binding->param1, binding->param2);
|
||||
#else
|
||||
return 0;
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_LOG)
|
||||
static int check_behavior_names(void) {
|
||||
// Behavior names must be unique, but we don't have a good way to enforce this
|
||||
|
|
|
@ -18,6 +18,82 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata no_arg_values[] = {
|
||||
{
|
||||
.display_name = "Toggle On/Off",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BL_TOG_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Turn On",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BL_ON_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Turn OFF",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BL_OFF_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Increase Brightness",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BL_INC_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Decrease Brightness",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BL_DEC_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Cycle Brightness",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BL_CYCLE_CMD,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_value_metadata one_arg_p1_values[] = {
|
||||
{
|
||||
.display_name = "Set Brightness",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BL_SET_CMD,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_value_metadata one_arg_p2_values[] = {
|
||||
{
|
||||
.display_name = "Brightness",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_RANGE,
|
||||
.range =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 255,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set no_args_set = {
|
||||
.param1_values = no_arg_values,
|
||||
.param1_values_len = ARRAY_SIZE(no_arg_values),
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set one_args_set = {
|
||||
.param1_values = one_arg_p1_values,
|
||||
.param1_values_len = ARRAY_SIZE(one_arg_p1_values),
|
||||
.param2_values = one_arg_p2_values,
|
||||
.param2_values_len = ARRAY_SIZE(one_arg_p2_values),
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set sets[] = {no_args_set, one_args_set};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(sets),
|
||||
.sets = sets,
|
||||
};
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static int behavior_backlight_init(const struct device *dev) { return 0; }
|
||||
|
||||
static int
|
||||
|
@ -89,6 +165,9 @@ static const struct behavior_driver_api behavior_backlight_driver_api = {
|
|||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
.locality = BEHAVIOR_LOCALITY_GLOBAL,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif
|
||||
};
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_backlight_init, NULL, NULL, NULL, POST_KERNEL,
|
||||
|
|
|
@ -20,6 +20,74 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata no_arg_values[] = {
|
||||
{
|
||||
.display_name = "Next Profile",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BT_NXT_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Previous Profile",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BT_PRV_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Clear All Profiles",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BT_CLR_ALL_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Clear Selected Profile",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BT_CLR_CMD,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set no_args_set = {
|
||||
.param1_values = no_arg_values,
|
||||
.param1_values_len = ARRAY_SIZE(no_arg_values),
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_value_metadata prof_index_param1_values[] = {
|
||||
{
|
||||
.display_name = "Select Profile",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BT_SEL_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Disconnect Profile",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = BT_DISC_CMD,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_value_metadata prof_index_param2_values[] = {
|
||||
{
|
||||
.display_name = "Profile",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_RANGE,
|
||||
.range = {.min = 0, .max = ZMK_BLE_PROFILE_COUNT},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set profile_index_metadata_set = {
|
||||
.param1_values = prof_index_param1_values,
|
||||
.param1_values_len = ARRAY_SIZE(prof_index_param1_values),
|
||||
.param2_values = prof_index_param2_values,
|
||||
.param2_values_len = ARRAY_SIZE(prof_index_param2_values),
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set metadata_sets[] = {no_args_set,
|
||||
profile_index_metadata_set};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(metadata_sets),
|
||||
.sets = metadata_sets,
|
||||
};
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
switch (binding->param1) {
|
||||
|
@ -54,6 +122,9 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
static const struct behavior_driver_api behavior_bt_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_bt_init, NULL, NULL, NULL, POST_KERNEL,
|
||||
|
|
|
@ -75,6 +75,9 @@ static int on_caps_word_binding_released(struct zmk_behavior_binding *binding,
|
|||
static const struct behavior_driver_api behavior_caps_word_driver_api = {
|
||||
.binding_pressed = on_caps_word_binding_pressed,
|
||||
.binding_released = on_caps_word_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = zmk_behavior_get_empty_param_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static int caps_word_keycode_state_changed_listener(const zmk_event_t *eh);
|
||||
|
|
|
@ -68,6 +68,12 @@ struct behavior_hold_tap_config {
|
|||
int32_t hold_trigger_key_positions[];
|
||||
};
|
||||
|
||||
struct behavior_hold_tap_data {
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
struct behavior_parameter_metadata_set set;
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
// this data is specific for each hold-tap
|
||||
struct active_hold_tap {
|
||||
int32_t position;
|
||||
|
@ -652,9 +658,52 @@ static int on_hold_tap_binding_released(struct zmk_behavior_binding *binding,
|
|||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
static int hold_tap_parameter_metadata(const struct device *hold_tap,
|
||||
struct behavior_parameter_metadata *param_metadata) {
|
||||
const struct behavior_hold_tap_config *cfg = hold_tap->config;
|
||||
struct behavior_hold_tap_data *data = hold_tap->data;
|
||||
int err;
|
||||
struct behavior_parameter_metadata child_meta;
|
||||
|
||||
err = behavior_get_parameter_metadata(zmk_behavior_get_binding(cfg->hold_behavior_dev),
|
||||
&child_meta);
|
||||
if (err < 0) {
|
||||
LOG_WRN("Failed to get the hold behavior parameter: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (child_meta.sets_len > 0) {
|
||||
data->set.param1_values = child_meta.sets[0].param1_values;
|
||||
data->set.param1_values_len = child_meta.sets[0].param1_values_len;
|
||||
}
|
||||
|
||||
err = behavior_get_parameter_metadata(zmk_behavior_get_binding(cfg->tap_behavior_dev),
|
||||
&child_meta);
|
||||
if (err < 0) {
|
||||
LOG_WRN("Failed to get the tap behavior parameter: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (child_meta.sets_len > 0) {
|
||||
data->set.param2_values = child_meta.sets[0].param1_values;
|
||||
data->set.param2_values_len = child_meta.sets[0].param1_values_len;
|
||||
}
|
||||
|
||||
param_metadata->sets = &data->set;
|
||||
param_metadata->sets_len = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_driver_api behavior_hold_tap_driver_api = {
|
||||
.binding_pressed = on_hold_tap_binding_pressed,
|
||||
.binding_released = on_hold_tap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = hold_tap_parameter_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static int position_state_changed_listener(const zmk_event_t *eh) {
|
||||
|
@ -791,7 +840,7 @@ static int behavior_hold_tap_init(const struct device *dev) {
|
|||
}
|
||||
|
||||
#define KP_INST(n) \
|
||||
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
||||
static const struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
||||
.tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \
|
||||
.hold_behavior_dev = DEVICE_DT_NAME(DT_INST_PHANDLE_BY_IDX(n, bindings, 0)), \
|
||||
.tap_behavior_dev = DEVICE_DT_NAME(DT_INST_PHANDLE_BY_IDX(n, bindings, 1)), \
|
||||
|
@ -807,9 +856,10 @@ static int behavior_hold_tap_init(const struct device *dev) {
|
|||
.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), \
|
||||
}; \
|
||||
BEHAVIOR_DT_INST_DEFINE(n, behavior_hold_tap_init, NULL, NULL, &behavior_hold_tap_config_##n, \
|
||||
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||
&behavior_hold_tap_driver_api);
|
||||
static struct behavior_hold_tap_data behavior_hold_tap_data_##n = {}; \
|
||||
BEHAVIOR_DT_INST_DEFINE(n, behavior_hold_tap_init, NULL, &behavior_hold_tap_data_##n, \
|
||||
&behavior_hold_tap_config_##n, POST_KERNEL, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_hold_tap_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
||||
|
||||
|
|
|
@ -16,6 +16,27 @@
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata param_values[] = {
|
||||
{
|
||||
.display_name = "Key",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_HID_USAGE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set param_metadata_set[] = {{
|
||||
.param1_values = param_values,
|
||||
.param1_values_len = ARRAY_SIZE(param_values),
|
||||
}};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(param_metadata_set),
|
||||
.sets = param_metadata_set,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static int behavior_key_press_init(const struct device *dev) { return 0; };
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
|
@ -31,7 +52,12 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_key_press_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed, .binding_released = on_keymap_binding_released};
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
#define KP_INST(n) \
|
||||
BEHAVIOR_DT_INST_DEFINE(n, behavior_key_press_init, NULL, NULL, NULL, POST_KERNEL, \
|
||||
|
|
|
@ -19,6 +19,27 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata param_values[] = {
|
||||
{
|
||||
.display_name = "Key",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_HID_USAGE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set param_metadata_set[] = {{
|
||||
.param1_values = param_values,
|
||||
.param1_values_len = ARRAY_SIZE(param_values),
|
||||
}};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(param_metadata_set),
|
||||
.sets = param_metadata_set,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct behavior_key_repeat_config {
|
||||
uint8_t index;
|
||||
uint8_t usage_pages_count;
|
||||
|
@ -67,6 +88,9 @@ static int on_key_repeat_binding_released(struct zmk_behavior_binding *binding,
|
|||
static const struct behavior_driver_api behavior_key_repeat_driver_api = {
|
||||
.binding_pressed = on_key_repeat_binding_pressed,
|
||||
.binding_released = on_key_repeat_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static int key_repeat_keycode_state_changed_listener(const zmk_event_t *eh);
|
||||
|
|
|
@ -31,9 +31,34 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata param_values[] = {
|
||||
{
|
||||
.display_name = "Key",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_STANDARD,
|
||||
.standard = BEHAVIOR_PARAMETER_STANDARD_DOMAIN_HID_USAGE,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set param_metadata_set[] = {{
|
||||
.param1_values = param_values,
|
||||
.param1_values_len = ARRAY_SIZE(param_values),
|
||||
}};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(param_metadata_set),
|
||||
.sets = param_metadata_set,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const struct behavior_driver_api behavior_key_toggle_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
#define KT_INST(n) \
|
||||
|
|
|
@ -34,6 +34,10 @@ struct behavior_macro_trigger_state {
|
|||
struct behavior_macro_state {
|
||||
struct behavior_macro_trigger_state release_state;
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
struct behavior_parameter_metadata_set set;
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
uint32_t press_bindings_count;
|
||||
};
|
||||
|
||||
|
@ -209,9 +213,100 @@ static int on_macro_binding_released(struct zmk_behavior_binding *binding,
|
|||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static void assign_values_to_set(enum param_source param_source,
|
||||
struct behavior_parameter_metadata_set *set,
|
||||
const struct behavior_parameter_value_metadata *values,
|
||||
size_t values_len) {
|
||||
if (param_source == PARAM_SOURCE_MACRO_1ST) {
|
||||
set->param1_values = values;
|
||||
set->param1_values_len = values_len;
|
||||
} else {
|
||||
set->param2_values = values;
|
||||
set->param2_values_len = values_len;
|
||||
}
|
||||
}
|
||||
|
||||
// This function will dynamically determine the parameter metadata for a particular macro by
|
||||
// inspecting the macro *bindings* to see what behaviors in that list receive the macro parameters,
|
||||
// and then using the metadata from those behaviors for the macro itself.
|
||||
//
|
||||
// Care need be taken, where a behavior in the list takes two parameters, and the macro passes along
|
||||
// a value for the *second* parameter, we need to make sure we find the right metadata set for the
|
||||
// referenced behavior that matches the first parameter.
|
||||
static int get_macro_parameter_metadata(const struct device *macro,
|
||||
struct behavior_parameter_metadata *param_metadata) {
|
||||
const struct behavior_macro_config *cfg = macro->config;
|
||||
struct behavior_macro_state *data = macro->data;
|
||||
struct behavior_macro_trigger_state state = {0};
|
||||
|
||||
for (int i = 0; (i < cfg->count) && (!data->set.param1_values || !data->set.param2_values);
|
||||
i++) {
|
||||
if (handle_control_binding(&state, &cfg->bindings[i]) ||
|
||||
(state.param1_source == PARAM_SOURCE_BINDING &&
|
||||
state.param2_source == PARAM_SOURCE_BINDING)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_DBG("checking %d for the given state", i);
|
||||
|
||||
struct behavior_parameter_metadata binding_meta;
|
||||
int err = behavior_get_parameter_metadata(
|
||||
zmk_behavior_get_binding(cfg->bindings[i].behavior_dev), &binding_meta);
|
||||
if (err < 0 || binding_meta.sets_len == 0) {
|
||||
LOG_WRN("Failed to fetch macro binding parameter details %d", err);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
// If both macro parameters get passed to this one entry, use
|
||||
// the metadata for this behavior verbatim.
|
||||
if (state.param1_source != PARAM_SOURCE_BINDING &&
|
||||
state.param2_source != PARAM_SOURCE_BINDING) {
|
||||
param_metadata->sets_len = binding_meta.sets_len;
|
||||
param_metadata->sets = binding_meta.sets;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (state.param1_source != PARAM_SOURCE_BINDING) {
|
||||
assign_values_to_set(state.param1_source, &data->set,
|
||||
binding_meta.sets[0].param1_values,
|
||||
binding_meta.sets[0].param1_values_len);
|
||||
}
|
||||
|
||||
if (state.param2_source != PARAM_SOURCE_BINDING) {
|
||||
// For the param2 metadata, we need to find a set that matches fully bound first
|
||||
// parameter of our macro entry, and use the metadata from that set.
|
||||
for (int s = 0; s < binding_meta.sets_len; s++) {
|
||||
if (zmk_behavior_validate_param_values(binding_meta.sets[s].param1_values,
|
||||
binding_meta.sets[s].param1_values_len,
|
||||
cfg->bindings[i].param1) >= 0) {
|
||||
assign_values_to_set(state.param2_source, &data->set,
|
||||
binding_meta.sets[s].param2_values,
|
||||
binding_meta.sets[s].param2_values_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.param1_source = PARAM_SOURCE_BINDING;
|
||||
state.param2_source = PARAM_SOURCE_BINDING;
|
||||
}
|
||||
|
||||
param_metadata->sets_len = 1;
|
||||
param_metadata->sets = &data->set;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_driver_api behavior_macro_driver_api = {
|
||||
.binding_pressed = on_macro_binding_pressed,
|
||||
.binding_released = on_macro_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = get_macro_parameter_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
#define TRANSFORMED_BEHAVIORS(n) \
|
||||
|
|
|
@ -75,6 +75,9 @@ static int on_mod_morph_binding_released(struct zmk_behavior_binding *binding,
|
|||
static const struct behavior_driver_api behavior_mod_morph_driver_api = {
|
||||
.binding_pressed = on_mod_morph_binding_pressed,
|
||||
.binding_released = on_mod_morph_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = zmk_behavior_get_empty_param_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static int behavior_mod_morph_init(const struct device *dev) { return 0; }
|
||||
|
|
|
@ -15,6 +15,27 @@
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata param_values[] = {
|
||||
{
|
||||
.display_name = "Layer",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_LAYER_INDEX,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set param_metadata_set[] = {{
|
||||
.param1_values = param_values,
|
||||
.param1_values_len = ARRAY_SIZE(param_values),
|
||||
}};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(param_metadata_set),
|
||||
.sets = param_metadata_set,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct behavior_mo_config {};
|
||||
struct behavior_mo_data {};
|
||||
|
||||
|
@ -33,7 +54,12 @@ static int mo_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_mo_driver_api = {
|
||||
.binding_pressed = mo_keymap_binding_pressed, .binding_released = mo_keymap_binding_released};
|
||||
.binding_pressed = mo_keymap_binding_pressed,
|
||||
.binding_released = mo_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static const struct behavior_mo_config behavior_mo_config = {};
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
static const struct behavior_driver_api behavior_none_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = zmk_behavior_get_empty_param_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_none_init, NULL, NULL, NULL, POST_KERNEL,
|
||||
|
|
|
@ -20,6 +20,42 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata std_values[] = {
|
||||
{
|
||||
.value = OUT_TOG,
|
||||
.display_name = "Toggle Outputs",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
},
|
||||
#if IS_ENABLED(CONFIG_ZMK_USB)
|
||||
{
|
||||
.value = OUT_USB,
|
||||
.display_name = "USB Output",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
},
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_USB)
|
||||
#if IS_ENABLED(CONFIG_ZMK_BLE)
|
||||
{
|
||||
.value = OUT_BLE,
|
||||
.display_name = "BLE Output",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
},
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BLE)
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set std_set = {
|
||||
.param1_values = std_values,
|
||||
.param1_values_len = ARRAY_SIZE(std_values),
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = 1,
|
||||
.sets = &std_set,
|
||||
};
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
switch (binding->param1) {
|
||||
|
@ -40,6 +76,9 @@ static int behavior_out_init(const struct device *dev) { return 0; }
|
|||
|
||||
static const struct behavior_driver_api behavior_outputs_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_out_init, NULL, NULL, NULL, POST_KERNEL,
|
||||
|
|
|
@ -38,6 +38,9 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
|||
static const struct behavior_driver_api behavior_reset_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.locality = BEHAVIOR_LOCALITY_EVENT_SOURCE,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = zmk_behavior_get_empty_param_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
#define RST_INST(n) \
|
||||
|
|
|
@ -18,6 +18,119 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata no_arg_values[] = {
|
||||
{
|
||||
.display_name = "Toggle On/Off",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_TOG_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Turn On",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_ON_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Turn OFF",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_OFF_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Hue Up",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_HUI_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Hue Down",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_HUD_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Saturation Up",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_SAI_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Saturation Down",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_SAD_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Brightness Up",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_BRI_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Brightness Down",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_BRD_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Speed Up",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_SPI_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Speed Down",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_SPD_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Next Effect",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_EFF_CMD,
|
||||
},
|
||||
{
|
||||
.display_name = "Previous Effect",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_EFR_CMD,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set no_args_set = {
|
||||
.param1_values = no_arg_values,
|
||||
.param1_values_len = ARRAY_SIZE(no_arg_values),
|
||||
};
|
||||
|
||||
/*
|
||||
static const struct behavior_parameter_value_metadata hsv_p1_value_metadata_values[] = {
|
||||
{
|
||||
.display_name = "Set Color",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_VALUE,
|
||||
.value = RGB_COLOR_HSB_CMD,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_value_metadata hsv_p2_value_metadata_values[] = {
|
||||
{
|
||||
.display_name = "Color",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_STANDARD,
|
||||
.standard = BEHAVIOR_PARAMETER_STANDARD_DOMAIN_HSV,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set hsv_value_metadata_set = {
|
||||
.param1_values = hsv_p1_value_metadata_values,
|
||||
.param1_values_len = ARRAY_SIZE(hsv_p1_value_metadata_values),
|
||||
.param_values = hsv_p2_value_metadata_values,
|
||||
.param_values_len = ARRAY_SIZE(hsv_p2_value_metadata_values),
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
static const struct behavior_parameter_metadata_set sets[] = {
|
||||
no_args_set,
|
||||
// hsv_value_metadata_set,
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(sets),
|
||||
.sets = sets,
|
||||
};
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static int behavior_rgb_underglow_init(const struct device *dev) { return 0; }
|
||||
|
||||
static int
|
||||
|
@ -147,6 +260,9 @@ static const struct behavior_driver_api behavior_rgb_underglow_driver_api = {
|
|||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
.locality = BEHAVIOR_LOCALITY_GLOBAL,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif
|
||||
};
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_rgb_underglow_init, NULL, NULL, NULL, POST_KERNEL,
|
||||
|
|
|
@ -74,6 +74,9 @@ static const struct behavior_driver_api behavior_soft_off_driver_api = {
|
|||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
.locality = BEHAVIOR_LOCALITY_GLOBAL,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = zmk_behavior_get_empty_param_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
#define BSO_INST(n) \
|
||||
|
|
|
@ -188,9 +188,41 @@ static int on_sticky_key_binding_released(struct zmk_behavior_binding *binding,
|
|||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static int sticky_key_parameter_domains(const struct device *sk,
|
||||
struct behavior_parameter_metadata *param_metadata) {
|
||||
const struct behavior_sticky_key_config *cfg = sk->config;
|
||||
|
||||
struct behavior_parameter_metadata child_metadata;
|
||||
|
||||
int err = behavior_get_parameter_metadata(zmk_behavior_get_binding(cfg->behavior.behavior_dev),
|
||||
&child_metadata);
|
||||
if (err < 0) {
|
||||
LOG_WRN("Failed to get the sticky key bound behavior parameter: %d", err);
|
||||
}
|
||||
|
||||
for (int s = 0; s < child_metadata.sets_len; s++) {
|
||||
const struct behavior_parameter_metadata_set *set = &child_metadata.sets[s];
|
||||
|
||||
if (set->param2_values_len > 0) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
}
|
||||
|
||||
*param_metadata = child_metadata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_driver_api behavior_sticky_key_driver_api = {
|
||||
.binding_pressed = on_sticky_key_binding_pressed,
|
||||
.binding_released = on_sticky_key_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = sticky_key_parameter_domains,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static int sticky_key_keycode_state_changed_listener(const zmk_event_t *eh);
|
||||
|
@ -337,7 +369,7 @@ struct behavior_sticky_key_data {};
|
|||
static struct behavior_sticky_key_data behavior_sticky_key_data;
|
||||
|
||||
#define KP_INST(n) \
|
||||
static struct behavior_sticky_key_config behavior_sticky_key_config_##n = { \
|
||||
static const struct behavior_sticky_key_config behavior_sticky_key_config_##n = { \
|
||||
.behavior = ZMK_KEYMAP_EXTRACT_BINDING(0, DT_DRV_INST(n)), \
|
||||
.release_after_ms = DT_INST_PROP(n, release_after_ms), \
|
||||
.quick_release = DT_INST_PROP(n, quick_release), \
|
||||
|
|
|
@ -189,6 +189,9 @@ void behavior_tap_dance_timer_handler(struct k_work *item) {
|
|||
static const struct behavior_driver_api behavior_tap_dance_driver_api = {
|
||||
.binding_pressed = on_tap_dance_binding_pressed,
|
||||
.binding_released = on_tap_dance_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = zmk_behavior_get_empty_param_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static int tap_dance_position_state_changed_listener(const zmk_event_t *eh);
|
||||
|
|
|
@ -32,9 +32,34 @@ static int to_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata param_values[] = {
|
||||
{
|
||||
.display_name = "Layer",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_STANDARD,
|
||||
.standard = BEHAVIOR_PARAMETER_STANDARD_DOMAIN_LAYER_INDEX,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set param_metadata_set[] = {{
|
||||
.param1_values = param_values,
|
||||
.param1_values_len = ARRAY_SIZE(param_values),
|
||||
}};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(param_metadata_set),
|
||||
.sets = param_metadata_set,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const struct behavior_driver_api behavior_to_driver_api = {
|
||||
.binding_pressed = to_keymap_binding_pressed,
|
||||
.binding_released = to_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_to_init, NULL, NULL, NULL, POST_KERNEL,
|
||||
|
|
|
@ -34,9 +34,34 @@ static int tog_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
|
||||
static const struct behavior_parameter_value_metadata param_values[] = {
|
||||
{
|
||||
.display_name = "Layer",
|
||||
.type = BEHAVIOR_PARAMETER_VALUE_TYPE_STANDARD,
|
||||
.standard = BEHAVIOR_PARAMETER_STANDARD_DOMAIN_LAYER_INDEX,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct behavior_parameter_metadata_set param_metadata_set[] = {{
|
||||
.param1_values = param_values,
|
||||
.param1_values_len = ARRAY_SIZE(param_values),
|
||||
}};
|
||||
|
||||
static const struct behavior_parameter_metadata metadata = {
|
||||
.sets_len = ARRAY_SIZE(param_metadata_set),
|
||||
.sets = param_metadata_set,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const struct behavior_driver_api behavior_tog_driver_api = {
|
||||
.binding_pressed = tog_keymap_binding_pressed,
|
||||
.binding_released = tog_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.parameter_metadata = &metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
static const struct behavior_tog_config behavior_tog_config = {};
|
||||
|
|
|
@ -31,6 +31,9 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
static const struct behavior_driver_api behavior_transparent_driver_api = {
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
#if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
.get_parameter_metadata = zmk_behavior_get_empty_param_metadata,
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA)
|
||||
};
|
||||
|
||||
BEHAVIOR_DT_INST_DEFINE(0, behavior_transparent_init, NULL, NULL, NULL, POST_KERNEL,
|
||||
|
|
|
@ -66,6 +66,17 @@ static int hid_listener_keycode_released(const struct zmk_keycode_state_changed
|
|||
return err;
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ZMK_HID_SEPARATE_MOD_RELEASE_REPORT)
|
||||
|
||||
// send report of normal key release early to fix the issue
|
||||
// of some programs recognizing the implicit_mod release before the actual key release
|
||||
err = zmk_endpoints_send_report(ev->usage_page);
|
||||
if (err < 0) {
|
||||
LOG_ERR("Failed to send key report for the released keycode (%d)", err);
|
||||
}
|
||||
|
||||
#endif // IS_ENABLED(CONFIG_ZMK_HID_SEPARATE_MOD_RELEASE_REPORT)
|
||||
|
||||
explicit_mods_changed = zmk_hid_unregister_mods(ev->explicit_modifiers);
|
||||
// There is a minor issue with this code.
|
||||
// If LC(A) is pressed, then LS(B), then LC(A) is released, the shift for B will be released
|
||||
|
@ -73,7 +84,7 @@ static int hid_listener_keycode_released(const struct zmk_keycode_state_changed
|
|||
// Solving this would require keeping track of which key's implicit modifiers are currently
|
||||
// active and only releasing modifiers at that time.
|
||||
implicit_mods_changed = zmk_hid_implicit_modifiers_release();
|
||||
;
|
||||
|
||||
if (ev->usage_page != HID_USAGE_KEY &&
|
||||
(explicit_mods_changed > 0 || implicit_mods_changed > 0)) {
|
||||
err = zmk_endpoints_send_report(HID_USAGE_KEY);
|
||||
|
|
|
@ -195,4 +195,4 @@ static int zmk_usb_hid_init(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(zmk_usb_hid_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||
SYS_INIT(zmk_usb_hid_init, APPLICATION, CONFIG_ZMK_USB_HID_INIT_PRIORITY);
|
||||
|
|
|
@ -19,7 +19,7 @@ There's been lots of various activity in ZMK land!
|
|||
- Tons of [documentation](/docs) work.
|
||||
- Refactoring ([#73](https://github.com/zmkfirmware/zmk/pull/73), [#74](https://github.com/zmkfirmware/zmk/pull/74)) of [keymaps](/docs/features/keymaps) to make them simpler for users.
|
||||
- Mod-Tap Behavior (docs coming!) is much improved ([#69](https://github.com/zmkfirmware/zmk/pull/69)) and usable now.
|
||||
- An initial [`setup.sh`](http://localhost:3000/docs/user-setup#user-config-setup-script) script was created, allowing users to quickly bootstrap a "user config" setup and push it to GitHub, where GitHub Actions will build the firmware for you.
|
||||
- An initial [`setup.sh`](/docs/user-setup#user-config-setup-script) script was created, allowing users to quickly bootstrap a "user config" setup and push it to GitHub, where GitHub Actions will build the firmware for you.
|
||||
- Corne shield ([#80](https://github.com/zmkfirmware/zmk/pull/80)) shield definition was added.
|
||||
- Initial [encoder](/docs/features/encoders) support ([#61](https://github.com/zmkfirmware/zmk/pull/61)) was added.
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ Once the container has rebuilt, VS Code will be running the 2.5 Docker image.
|
|||
|
||||
The following steps will get you building ZMK locally against Zephyr 2.5:
|
||||
|
||||
- Run the updated [toolchain installation](/docs/development/setup#toolchain-installation) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- Run the updated [toolchain installation](/docs/development/setup) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- pull the latest ZMK `main` with `git pull` for your ZMK checkout
|
||||
- run `west update` to pull the updated Zephyr version and its dependencies
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ Once the container has rebuilt, VS Code will be running the 3.0 Docker image.
|
|||
|
||||
The following steps will get you building ZMK locally against Zephyr 3.0:
|
||||
|
||||
- Run the updated [toolchain installation](/docs/development/setup#toolchain-installation) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- Run the updated [toolchain installation](/docs/development/setup) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- pull the latest ZMK `main` with `git pull` for your ZMK checkout
|
||||
- run `west update` to pull the updated Zephyr version and its dependencies
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ Another persistent bug that Apple users experienced was related to crashes and p
|
|||
The long awaited locality enhancement was finally merged by [petejohanson] in [#547](https://github.com/zmkfirmware/zmk/pull/547), allowing more fine grained control of where certain behaviors are invoked. Some key improvements thanks to the changes:
|
||||
|
||||
- [RGB Underglow](/docs/features/underglow) behaviors now run globally, so enabling/disabling RGB, changing the color, animation, etc. applies to both sides of a split properly.
|
||||
- [Reset](/docs/behaviors/reset#reset)/[Bootloader](/docs/behaviors/reset#bootloader) behaviors now run wherever the key was pressed. For example, adding a `&bootloader` reference to the peripheral side of a split will now put that side of the split into the bootloader when pressed.
|
||||
- [Reset](/docs/behaviors/reset#reset)/[Bootloader](/docs/behaviors/reset#bootloader-reset) behaviors now run wherever the key was pressed. For example, adding a `&bootloader` reference to the peripheral side of a split will now put that side of the split into the bootloader when pressed.
|
||||
|
||||
#### Split Connections
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ and then update it as appropriate to build the right shields/boards for your con
|
|||
|
||||
### Upgrade a manual script
|
||||
|
||||
If you have a custom GitHub Actions workflow you need to maintain for some reason, you can update the workflow to to use the `stable` Docker image tag for the build:
|
||||
If you have a custom GitHub Actions workflow you need to maintain for some reason, you can update the workflow to use the `stable` Docker image tag for the build:
|
||||
|
||||
- Open `.github/workflows/build.yml` in your editor/IDE
|
||||
- Change `zmkfirmware/zmk-build-arm:2.5` to `zmkfirmware/zmk-build-arm:stable` wherever it is found
|
||||
|
@ -87,7 +87,7 @@ Once the container has rebuilt, VS Code will be running the 3.2 Docker image.
|
|||
|
||||
The following steps will get you building ZMK locally against Zephyr 3.2:
|
||||
|
||||
- Run the updated [toolchain installation](/docs/development/setup#toolchain-installation) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- Run the updated [toolchain installation](/docs/development/setup) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- Install the latest version of `west` by running `pip3 install --user --update west`.
|
||||
- pull the latest ZMK `main` with `git pull` for your ZMK checkout
|
||||
- run `west update` to pull the updated Zephyr version and its dependencies
|
||||
|
|
|
@ -105,7 +105,7 @@ Note that documentation is still lacking for utilizing more than one peripheral
|
|||
|
||||
[petejohanson] contributed a fix to release held keys on peripheral disconnect [#1340](https://github.com/zmkfirmware/zmk/pull/1340), which makes scenarios where a split disconnects unexpectedly less painful.
|
||||
|
||||
[petejohanson] also improved [the `settings_reset` shield](/docs/troubleshooting#split-keyboard-halves-unable-to-pair) by making it clear bonds more reliably, and allow it to build for all boards in [#1879](https://github.com/zmkfirmware/zmk/pull/1879).
|
||||
[petejohanson] also improved [the `settings_reset` shield](/docs/troubleshooting/connection-issues#split-keyboard-halves-unable-to-pair) by making it clear bonds more reliably, and allow it to build for all boards in [#1879](https://github.com/zmkfirmware/zmk/pull/1879).
|
||||
|
||||
[petejohanson] and [xudongzheng] contributed additional split connectivity improvements, via using directed advertising in [#1913](https://github.com/zmkfirmware/zmk/pull/1913) and improving the robustness of central scanning in [#1912](https://github.com/zmkfirmware/zmk/pull/1912).
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ Once the container has rebuilt, VS Code will be running the 3.5 Docker image.
|
|||
|
||||
The following steps will get you building ZMK locally against Zephyr 3.5:
|
||||
|
||||
- Run the updated [toolchain installation](/docs/development/setup#toolchain-installation) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- Run the updated [toolchain installation](/docs/development/setup) steps, and once completed, remove the previously installed SDK version (optional, existing SDK should still work)
|
||||
- Install the latest version of `west` by running `pip3 install --user --update west`.
|
||||
- Pull the latest ZMK `main` with `git pull` for your ZMK checkout
|
||||
- Run `west update` to pull the updated Zephyr version and its dependencies
|
||||
|
|
|
@ -7,7 +7,7 @@ sidebar_label: Caps Word
|
|||
|
||||
The caps word behavior behaves similar to a caps lock, but will automatically deactivate when any key not in a continue list is pressed, or if the caps word key is pressed again. For smaller keyboards using [mod-taps](/docs/behaviors/mod-tap), this can help avoid repeated alternating holds when typing words in all caps.
|
||||
|
||||
The modifiers are applied only to to the alphabetic (`A` to `Z`) keycodes, to avoid automatically applying them to numeric values, etc.
|
||||
The modifiers are applied only to the alphabetic (`A` to `Z`) keycodes, to avoid automatically applying them to numeric values, etc.
|
||||
|
||||
### Behavior Binding
|
||||
|
||||
|
@ -21,7 +21,7 @@ Example:
|
|||
|
||||
### Configuration
|
||||
|
||||
#### Continue List
|
||||
#### Continue list
|
||||
|
||||
By default, the caps word will remain active when any alphanumeric character or underscore (`UNDERSCORE`), backspace (`BACKSPACE`), or delete (`DELETE`) characters are pressed. Any other non-modifier keycode sent will turn off caps word. If you would like to override this, you can set a new array of keys in the `continue-list` property in your keymap:
|
||||
|
||||
|
@ -37,7 +37,7 @@ By default, the caps word will remain active when any alphanumeric character or
|
|||
};
|
||||
```
|
||||
|
||||
#### Applied Modifier(s)
|
||||
#### Applied modifier(s)
|
||||
|
||||
In addition, if you would like _multiple_ modifiers, instead of just `MOD_LSFT`, you can override the `mods` property:
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ When the hold-tap key is released and the hold behavior has not been triggered,
|
|||
|
||||

|
||||
|
||||
### Basic usage
|
||||
### Basic Usage
|
||||
|
||||
For basic usage, please see the [mod-tap](mod-tap.md) and [layer-tap](layers.md#layer-tap) pages.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ sidebar_label: Overview
|
|||
|
||||
Below is a summary of pre-defined behavior bindings and user-definable behaviors available in ZMK, with references to documentation pages describing them.
|
||||
|
||||
## Key press behaviors
|
||||
## Key Press Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| ------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
|
@ -21,14 +21,14 @@ Below is a summary of pre-defined behavior bindings and user-definable behaviors
|
|||
| `&caps_word` | [Caps Word](caps-word.md) | Behaves similar to caps lock, but automatically deactivates when any key not in a continue list is pressed, or if the caps word key is pressed again |
|
||||
| `&key_repeat` | [Key Repeat](key-repeat.md) | Sends again whatever keycode was last sent |
|
||||
|
||||
## Miscellaneous behaviors
|
||||
## Miscellaneous Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| -------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `&trans` | [Transparent](misc.md#transparent) | Passes the key press down to the next active layer in the stack for processing |
|
||||
| `&none` | [None](misc.md#none) | Swallows and stops the key press, no keycode will be sent nor will the key press be passed down to the next active layer in the stack |
|
||||
|
||||
## Layer navigation behaviors
|
||||
## Layer Navigation Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| ------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
|
@ -38,41 +38,41 @@ Below is a summary of pre-defined behavior bindings and user-definable behaviors
|
|||
| `&tog` | [Toggle Layer](layers.md#toggle-layer) | Enables a layer until the layer is manually disabled |
|
||||
| `&sl` | [Sticky Layer](sticky-layer.md) | Activates a layer until another key is pressed, then deactivates it |
|
||||
|
||||
## Mouse emulation behaviors
|
||||
## Mouse Emulation Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| ------- | ----------------------------------------------------------- | ------------------------------- |
|
||||
| `&mkp` | [Mouse Button Press](mouse-emulation.md#mouse-button-press) | Emulates pressing mouse buttons |
|
||||
|
||||
## Reset behaviors
|
||||
## Reset Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| ------------- | --------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| `&sys_reset` | [Reset](reset.md#reset) | Resets the keyboard and re-runs the firmware flashed to the device |
|
||||
| `&bootloader` | [Bootloader](reset.md#bootloader) | Resets the keyboard and puts it into bootloader mode, allowing you to flash new firmware |
|
||||
| Binding | Behavior | Description |
|
||||
| ------------- | --------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| `&sys_reset` | [Reset](reset.md#reset) | Resets the keyboard and re-runs the firmware flashed to the device |
|
||||
| `&bootloader` | [Bootloader](reset.md#bootloader-reset) | Resets the keyboard and puts it into bootloader mode, allowing you to flash new firmware |
|
||||
|
||||
## Output selection behaviors
|
||||
## Output Selection Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| ------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `&bt` | [Bluetooth](bluetooth.md#bluetooth-behavior) | Completes a bluetooth action given on press, for example switching between devices |
|
||||
| `&out` | [Output Selection](outputs.md#output-selection-behavior) | Allows selecting whether output is sent to the USB or bluetooth connection when both are connected |
|
||||
|
||||
## Lighting behaviors
|
||||
## Lighting Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| --------- | ---------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `&rgb_ug` | [RGB Underglow](underglow.md#behavior-binding) | Controls the RGB underglow, usually placed underneath the keyboard |
|
||||
| `&bl` | [Backlight](backlight.md#behavior-binding) | Controls the keyboard backlighting, usually placed through or under switches |
|
||||
|
||||
## Power management behaviors
|
||||
## Power Management Behaviors
|
||||
|
||||
| Binding | Behavior | Description |
|
||||
| ------------ | --------------------------------------------- | --------------------------------------------------------------- |
|
||||
| `&ext_power` | [Power management](power.md#behavior-binding) | Allows enabling or disabling the VCC power output to save power |
|
||||
| `&soft_off` | [Soft off](soft-off.md#behavior-binding) | Turns the keyboard off. |
|
||||
|
||||
## User-defined behaviors
|
||||
## User-Defined Behaviors
|
||||
|
||||
| Behavior | Description |
|
||||
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
|
|
|
@ -19,7 +19,7 @@ Example:
|
|||
|
||||
### Configuration
|
||||
|
||||
#### Usage Pages
|
||||
#### Usage pages
|
||||
|
||||
By default, the key repeat will only track the last pressed key from the HID "Key" usage page, and ignore events from other usages, e.g. Consumer page.
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue