Merge remote-tracking branch 'refs/remotes/origin/main' into main
This commit is contained in:
commit
83973250d9
307 changed files with 4852 additions and 1271 deletions
2
.github/workflows/clang-format-lint.yml
vendored
2
.github/workflows/clang-format-lint.yml
vendored
|
@ -23,7 +23,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: DoozyX/clang-format-lint-action@v0.9
|
||||
- uses: DoozyX/clang-format-lint-action@v0.11
|
||||
with:
|
||||
source: "./app"
|
||||
extensions: "h,c"
|
||||
|
|
12
.pre-commit-config.yaml
Normal file
12
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
fail_fast: false
|
||||
repos:
|
||||
- repo: https://github.com/pocc/pre-commit-hooks
|
||||
rev: v1.1.1
|
||||
hooks:
|
||||
- id: clang-format
|
||||
args:
|
||||
- -i
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v2.2.1
|
||||
hooks:
|
||||
- id: prettier
|
|
@ -81,6 +81,11 @@ documentation to areas not currently covered are greatly appreciated.
|
|||
- To get started, from the `docs/` directory, run `npm ci` and then `npm start`.
|
||||
- Enhancements should be submitted as pull requests to the `main` branch of ZMK.
|
||||
|
||||
### Formatting
|
||||
|
||||
ZMK uses `prettier` to format documentation files. You can run prettier with `npm run prettier:format`.
|
||||
You can setup git to run prettier automatically when you commit by installing the pre-commit hooks: `pip3 install pre-commit`, `pre-commit install`.
|
||||
|
||||
## Code Contributions
|
||||
|
||||
### Development Setup
|
||||
|
@ -95,6 +100,8 @@ ZMK uses `clang-format` to ensure consist formatting for our source code. Before
|
|||
changes, make sure you've manually run `clang-format`, or have your IDE configured to auto-format
|
||||
on save.
|
||||
|
||||
You can setup git to run `clang-format` automatically when you commit by installing the pre-commit hooks: `pip3 install pre-commit`, `pre-commit install`.
|
||||
|
||||
### Commit Messages
|
||||
|
||||
The ZMK project is working towards, but not yet enforcing, the use of
|
||||
|
|
|
@ -28,6 +28,7 @@ target_sources(app PRIVATE src/kscan.c)
|
|||
target_sources(app PRIVATE src/matrix_transform.c)
|
||||
target_sources(app PRIVATE src/hid.c)
|
||||
target_sources(app PRIVATE src/sensors.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/wpm.c)
|
||||
target_sources(app PRIVATE src/event_manager.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_EXT_POWER app PRIVATE src/ext_power_generic.c)
|
||||
target_sources(app PRIVATE src/events/activity_state_changed.c)
|
||||
|
@ -36,6 +37,7 @@ target_sources(app PRIVATE src/events/layer_state_changed.c)
|
|||
target_sources(app PRIVATE src/events/keycode_state_changed.c)
|
||||
target_sources(app PRIVATE src/events/modifiers_state_changed.c)
|
||||
target_sources(app PRIVATE src/events/sensor_event.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_WPM app PRIVATE src/events/wpm_state_changed.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/ble_active_profile_changed.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_BLE app PRIVATE src/events/battery_state_changed.c)
|
||||
target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c)
|
||||
|
@ -45,6 +47,7 @@ if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL)
|
|||
target_sources(app PRIVATE src/behaviors/behavior_hold_tap.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_sticky_key.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_momentary_layer.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_mod_morph.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_outputs.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_toggle_layer.c)
|
||||
target_sources(app PRIVATE src/behaviors/behavior_to_layer.c)
|
||||
|
|
51
app/Kconfig
51
app/Kconfig
|
@ -41,7 +41,7 @@ config USB_NUMOF_EP_WRITE_RETRIES
|
|||
#ZMK_USB
|
||||
endif
|
||||
|
||||
config ZMK_BLE
|
||||
menuconfig ZMK_BLE
|
||||
bool "BLE (HID over GATT)"
|
||||
select BT
|
||||
select BT_SMP
|
||||
|
@ -58,6 +58,22 @@ if ZMK_BLE
|
|||
config SYSTEM_WORKQUEUE_STACK_SIZE
|
||||
default 2048
|
||||
|
||||
config ZMK_BLE_THREAD_STACK_SIZE
|
||||
int "BLE notify thread stack size"
|
||||
default 512
|
||||
|
||||
config ZMK_BLE_THREAD_PRIORITY
|
||||
int "BLE notify thread priority"
|
||||
default 5
|
||||
|
||||
config ZMK_BLE_KEYBOARD_REPORT_QUEUE_SIZE
|
||||
int "Max number of keyboard HID reports to queue for sending over BLE"
|
||||
default 20
|
||||
|
||||
config ZMK_BLE_CONSUMER_REPORT_QUEUE_SIZE
|
||||
int "Max number of consumer HID reports to queue for sending over BLE"
|
||||
default 5
|
||||
|
||||
config ZMK_BLE_CLEAR_BONDS_ON_START
|
||||
bool "Configuration that clears all bond information from the keyboard on startup."
|
||||
default n
|
||||
|
@ -86,7 +102,7 @@ config ZMK_SPLIT
|
|||
|
||||
if ZMK_SPLIT
|
||||
|
||||
config ZMK_SPLIT_BLE
|
||||
menuconfig ZMK_SPLIT_BLE
|
||||
bool "Split keyboard support via BLE transport"
|
||||
depends on ZMK_BLE
|
||||
default y
|
||||
|
@ -94,13 +110,33 @@ config ZMK_SPLIT_BLE
|
|||
|
||||
if ZMK_SPLIT_BLE
|
||||
|
||||
config ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||
menuconfig ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||
bool "Central"
|
||||
select BT_CENTRAL
|
||||
select BT_GATT_CLIENT
|
||||
|
||||
if ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||
|
||||
config ZMK_SPLIT_BLE_CENTRAL_POSITION_QUEUE_SIZE
|
||||
int "Max number of key position state events to queue when received from peripherals"
|
||||
default 5
|
||||
|
||||
endif
|
||||
|
||||
if !ZMK_SPLIT_BLE_ROLE_CENTRAL
|
||||
|
||||
config ZMK_SPLIT_BLE_PERIPHERAL_STACK_SIZE
|
||||
int "BLE split peripheral notify thread stack size"
|
||||
default 512
|
||||
|
||||
config ZMK_SPLIT_BLE_PERIPHERAL_PRIORITY
|
||||
int "BLE split peripheral notify thread priority"
|
||||
default 5
|
||||
|
||||
config ZMK_SPLIT_BLE_PERIPHERAL_POSITION_QUEUE_SIZE
|
||||
int "Max number of key position state events to queue to send to the central"
|
||||
default 10
|
||||
|
||||
config ZMK_USB
|
||||
default n
|
||||
|
||||
|
@ -301,11 +337,9 @@ config ZMK_KSCAN_EVENT_QUEUE_SIZE
|
|||
|
||||
config ZMK_KSCAN_MOCK_DRIVER
|
||||
bool "Enable mock kscan driver to simulate key presses"
|
||||
default n
|
||||
|
||||
config ZMK_KSCAN_COMPOSITE_DRIVER
|
||||
bool "Enable composite kscan driver to combine kscan devices"
|
||||
default n
|
||||
|
||||
#KSCAN Settings
|
||||
endmenu
|
||||
|
@ -381,6 +415,13 @@ config REBOOT
|
|||
config USB
|
||||
default y if HAS_HW_NRF_USBD
|
||||
|
||||
config ZMK_WPM
|
||||
bool "Calculate WPM"
|
||||
default n
|
||||
|
||||
config SENSOR
|
||||
default y
|
||||
|
||||
module = ZMK
|
||||
module-str = zmk
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
, <7 0 &gpio0 24 0> /* D6/A7 D7*/
|
||||
, <8 0 &gpio0 10 0> /* D8/A8 B4*/
|
||||
, <9 0 &gpio1 6 0> /* D9/A9 B5*/
|
||||
, <10 0 &gpio1 13 0> /* D10/A10 B6*/
|
||||
, <10 0 &gpio1 11 0> /* D10/A10 B6*/
|
||||
;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -66,12 +66,8 @@
|
|||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
tx-pin = <19>;
|
||||
rx-pin = <21>;
|
||||
rts-pin = <23>;
|
||||
cts-pin = <25>;
|
||||
tx-pin = <6>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
|
|
|
@ -65,12 +65,8 @@
|
|||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
tx-pin = <19>;
|
||||
rx-pin = <21>;
|
||||
rts-pin = <23>;
|
||||
cts-pin = <25>;
|
||||
tx-pin = <6>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
|
|
|
@ -51,16 +51,6 @@
|
|||
status = "okay";
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
tx-pin = <19>;
|
||||
rx-pin = <21>;
|
||||
rts-pin = <23>;
|
||||
cts-pin = <25>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
compatible = "nordic,nrf-usbd";
|
||||
status = "okay";
|
||||
|
|
|
@ -53,12 +53,8 @@
|
|||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
tx-pin = <19>;
|
||||
rx-pin = <21>;
|
||||
rts-pin = <23>;
|
||||
cts-pin = <25>;
|
||||
tx-pin = <6>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
|
|
|
@ -53,12 +53,8 @@
|
|||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
tx-pin = <19>;
|
||||
rx-pin = <21>;
|
||||
rts-pin = <23>;
|
||||
cts-pin = <25>;
|
||||
tx-pin = <6>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
|
|
|
@ -65,12 +65,8 @@
|
|||
|
||||
&uart0 {
|
||||
compatible = "nordic,nrf-uarte";
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
tx-pin = <19>;
|
||||
rx-pin = <21>;
|
||||
rts-pin = <23>;
|
||||
cts-pin = <25>;
|
||||
tx-pin = <6>;
|
||||
rx-pin = <8>;
|
||||
};
|
||||
|
||||
&usbd {
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Uncomment lines below to enable encoder
|
||||
# CONFIG_EC11=y
|
||||
# CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y
|
|
@ -24,32 +24,37 @@
|
|||
&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
|
||||
>;
|
||||
|
||||
sensor-bindings = <&inc_dec_kp PG_UP PG_DN>;
|
||||
};
|
||||
|
||||
lower {
|
||||
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
|
||||
&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
|
||||
>;
|
||||
};
|
||||
|
||||
raise {
|
||||
sensor-bindings = <&inc_dec_kp C_VOL_UP C_VOL_DN>;
|
||||
};
|
||||
|
||||
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
|
||||
&trans &trans &trans &trans &mo 3 &trans &trans &trans &kp C_NEXT &kp C_VOL_DN &kp C_VOL_UP &kp C_PP
|
||||
>;
|
||||
};
|
||||
>;
|
||||
};
|
||||
|
||||
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
|
||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
>;
|
||||
};
|
||||
};
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -11,31 +11,45 @@
|
|||
zmk,kscan = &kscan0;
|
||||
};
|
||||
|
||||
kscan0: kscan_0 {
|
||||
compatible = "zmk,kscan-gpio-matrix";
|
||||
label = "KSCAN";
|
||||
diode-direction = "col2row";
|
||||
kscan0: kscan_0 {
|
||||
compatible = "zmk,kscan-gpio-matrix";
|
||||
label = "KSCAN";
|
||||
diode-direction = "col2row";
|
||||
|
||||
col-gpios
|
||||
= <&pro_micro_d 1 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 0 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 2 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 3 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 4 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 5 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 6 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 7 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 8 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 9 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 10 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 16 GPIO_ACTIVE_HIGH>
|
||||
;
|
||||
col-gpios
|
||||
= <&pro_micro_d 1 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 0 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 2 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 3 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 4 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 5 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 6 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 7 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 8 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 9 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 10 GPIO_ACTIVE_HIGH>
|
||||
, <&pro_micro_d 16 GPIO_ACTIVE_HIGH>
|
||||
;
|
||||
|
||||
row-gpios
|
||||
= <&pro_micro_d 14 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro_d 15 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro_a 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro_a 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
;
|
||||
};
|
||||
row-gpios
|
||||
= <&pro_micro_d 14 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro_d 15 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro_a 0 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
, <&pro_micro_a 1 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
|
||||
;
|
||||
};
|
||||
|
||||
encoder: encoder {
|
||||
compatible = "alps,ec11";
|
||||
label = "ENCODER";
|
||||
a-gpios = <&pro_micro_a 2 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
|
||||
b-gpios = <&pro_micro_a 3 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>;
|
||||
resolution = <2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
sensors {
|
||||
compatible = "zmk,keymap-sensors";
|
||||
sensors = <&encoder>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -58,8 +58,6 @@ RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9)
|
|||
page-offset = <0>;
|
||||
display-offset = <0>;
|
||||
multiplex-ratio = <31>;
|
||||
segment-remap;
|
||||
com-invdir;
|
||||
com-sequential;
|
||||
prechargep = <0x22>;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
col-offset = <5>;
|
||||
};
|
||||
|
||||
&oled {
|
||||
segment-remap;
|
||||
com-invdir;
|
||||
};
|
||||
|
||||
&kscan0 {
|
||||
col-gpios
|
||||
= <&pro_micro_d 15 GPIO_ACTIVE_HIGH>
|
||||
|
|
|
@ -9,5 +9,41 @@ config ZMK_KEYBOARD_NAME
|
|||
config ZMK_USB
|
||||
default y
|
||||
|
||||
endif
|
||||
|
||||
if ZMK_DISPLAY
|
||||
|
||||
config I2C
|
||||
default y
|
||||
|
||||
config SSD1306
|
||||
default y
|
||||
|
||||
config SSD1306_REVERSE_MODE
|
||||
default y
|
||||
|
||||
endif # ZMK_DISPLAY
|
||||
|
||||
if LVGL
|
||||
|
||||
config LVGL_HOR_RES_MAX
|
||||
default 128
|
||||
|
||||
config LVGL_VER_RES_MAX
|
||||
default 32
|
||||
|
||||
config LVGL_VDB_SIZE
|
||||
default 64
|
||||
|
||||
config LVGL_DPI
|
||||
default 148
|
||||
|
||||
config LVGL_BITS_PER_PIXEL
|
||||
default 1
|
||||
|
||||
choice LVGL_COLOR_DEPTH
|
||||
default LVGL_COLOR_DEPTH_1
|
||||
endchoice
|
||||
|
||||
endif # LVGL
|
||||
|
||||
endif
|
||||
|
|
29
app/boards/shields/nibble/README.md
Normal file
29
app/boards/shields/nibble/README.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Building ZMK for the Nibble
|
||||
|
||||
Some general notes/commands for building standard nibble layouts from the assembly documentation.
|
||||
|
||||
## LED Notes
|
||||
|
||||
If you built your nibble without the LEDs _and_ are using a nice!nano board, you'll need to change the following in your local nibble config or add them to the end of the file.
|
||||
|
||||
```
|
||||
CONFIG_ZMK_RGB_UNDERGLOW=n
|
||||
CONFIG_WS2812_STRIP=n
|
||||
```
|
||||
|
||||
## Encoder Notes
|
||||
|
||||
If you built your nibble without an encoder, you'll need to change the following in your local nibble config or add them to the end of the file.
|
||||
|
||||
```
|
||||
CONFIG_EC11=n
|
||||
CONFIG_EC11_TRIGGER_GLOBAL_THREAD=n
|
||||
```
|
||||
|
||||
## OLED Builds
|
||||
|
||||
If using an OLED screen, you'll need to change the following in your local nibble config or add them to the end of the file.
|
||||
|
||||
```
|
||||
CONFIG_ZMK_DISPLAY=y
|
||||
```
|
4
app/boards/shields/nibble/boards/nice_nano.conf
Normal file
4
app/boards/shields/nibble/boards/nice_nano.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Enable underglow
|
||||
CONFIG_ZMK_RGB_UNDERGLOW=y
|
||||
# Use the STRIP config specific to the LEDs you're using
|
||||
CONFIG_WS2812_STRIP=y
|
34
app/boards/shields/nibble/boards/nice_nano.overlay
Normal file
34
app/boards/shields/nibble/boards/nice_nano.overlay
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
&spi1 {
|
||||
compatible = "nordic,nrf-spim";
|
||||
status = "okay";
|
||||
mosi-pin = <11>;
|
||||
// Unused pins, needed for SPI definition, but not used by the ws2812 driver itself.
|
||||
sck-pin = <5>;
|
||||
miso-pin = <7>;
|
||||
|
||||
led_strip: ws2812@0 {
|
||||
compatible = "worldsemi,ws2812-spi";
|
||||
label = "WS2812";
|
||||
|
||||
/* SPI */
|
||||
reg = <0>; /* ignored, but necessary for SPI bindings */
|
||||
spi-max-frequency = <4000000>;
|
||||
|
||||
/* WS2812 */
|
||||
chain-length = <10>; /* number of LEDs */
|
||||
spi-one-frame = <0x70>;
|
||||
spi-zero-frame = <0x40>;
|
||||
};
|
||||
};
|
||||
|
||||
/ {
|
||||
chosen {
|
||||
zmk,underglow = &led_strip;
|
||||
};
|
||||
};
|
0
app/boards/shields/nibble/boards/proton_c.conf
Normal file
0
app/boards/shields/nibble/boards/proton_c.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
# Enable Encoders
|
||||
CONFIG_EC11=y
|
||||
CONFIG_EC11_TRIGGER_GLOBAL_THREAD=y
|
|
@ -8,30 +8,40 @@
|
|||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <dt-bindings/zmk/bt.h>
|
||||
|
||||
#define DEFAULT 0
|
||||
#define FUNC 1
|
||||
|
||||
/ {
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
sensors {
|
||||
compatible = "zmk,keymap-sensors";
|
||||
sensors = <&encoder_1>;
|
||||
};
|
||||
|
||||
default_layer {
|
||||
bindings = <
|
||||
&kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC &kp HOME
|
||||
&kp C_VOL_UP &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH &kp DEL
|
||||
&kp C_VOL_DN &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET &kp PG_UP
|
||||
&trans &kp LSHFT &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT &kp UP &kp PG_DN
|
||||
&trans &kp LCTRL &kp LGUI &kp LALT &kp SPACE &mo FUNC &kp RALT &kp RCTRL &kp LEFT &kp DOWN &kp RIGHT
|
||||
>;
|
||||
};
|
||||
func {
|
||||
bindings = <
|
||||
&kp TILDE &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &kp END
|
||||
&bt BT_CLR &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &bootloader
|
||||
&trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&bt BT_PRV &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&bt BT_NXT &trans &trans &trans &trans &trans &trans &trans &kp C_PREV &kp C_PP &kp C_NEXT
|
||||
>;
|
||||
};
|
||||
};
|
||||
keymap {
|
||||
compatible = "zmk,keymap";
|
||||
|
||||
default_layer {
|
||||
label = "Default";
|
||||
|
||||
sensor-bindings = <&inc_dec_kp C_VOLUME_UP C_VOLUME_DOWN>;
|
||||
|
||||
bindings = <
|
||||
&kp ESC &kp N1 &kp N2 &kp N3 &kp N4 &kp N5 &kp N6 &kp N7 &kp N8 &kp N9 &kp N0 &kp MINUS &kp EQUAL &kp BSPC &kp HOME
|
||||
&kp C_MUTE &kp TAB &kp Q &kp W &kp E &kp R &kp T &kp Y &kp U &kp I &kp O &kp P &kp LBKT &kp RBKT &kp BSLH &kp DEL
|
||||
&trans &kp CLCK &kp A &kp S &kp D &kp F &kp G &kp H &kp J &kp K &kp L &kp SEMI &kp SQT &kp RET &kp PG_UP
|
||||
&trans &kp LSHFT &trans &kp Z &kp X &kp C &kp V &kp B &kp N &kp M &kp COMMA &kp DOT &kp FSLH &kp RSHFT &kp UP &kp PG_DN
|
||||
&trans &kp LCTRL &kp LGUI &kp LALT &kp SPACE &mo 1 &kp RALT &kp RCTRL &kp LEFT &kp DOWN &kp RIGHT
|
||||
>;
|
||||
};
|
||||
function_layer {
|
||||
label = "Function";
|
||||
|
||||
sensor-bindings = <&inc_dec_kp C_VOLUME_UP C_VOLUME_DOWN>;
|
||||
|
||||
bindings = <
|
||||
&kp TILDE &kp F1 &kp F2 &kp F3 &kp F4 &kp F5 &kp F6 &kp F7 &kp F8 &kp F9 &kp F10 &kp F11 &kp F12 &trans &kp END
|
||||
&kp C_MUTE &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &bootloader
|
||||
&bt BT_CLR &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&bt BT_PRV &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans &trans
|
||||
&bt BT_NXT &trans &trans &trans &trans &trans &trans &trans &kp C_PREV &kp C_PP &kp C_NEXT
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -12,6 +12,15 @@
|
|||
zmk,matrix_transform = &default_transform;
|
||||
};
|
||||
|
||||
encoder_1: encoder_1 {
|
||||
compatible = "alps,ec11";
|
||||
label = "Encoder 1";
|
||||
a-gpios = <&pro_micro_d 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||
b-gpios = <&pro_micro_d 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
|
||||
resolution = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
kscan0: kscan {
|
||||
compatible = "zmk,kscan-gpio-demux";
|
||||
label = "KSCAN";
|
||||
|
@ -21,7 +30,7 @@
|
|||
, <&pro_micro_d 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
|
||||
, <&pro_micro_d 16 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
|
||||
, <&pro_micro_d 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
|
||||
, <&pro_micro_d 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
|
||||
, <&pro_micro_d 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>
|
||||
;
|
||||
output-gpios
|
||||
= <&pro_micro_a 3 GPIO_ACTIVE_HIGH>
|
||||
|
@ -36,14 +45,30 @@
|
|||
columns = <16>;
|
||||
rows = <5>;
|
||||
|
||||
//TODO: Add a keymap graphic here
|
||||
|
||||
map = <
|
||||
RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11) RC(0,12) RC(0,13) RC(0,14) RC(0,15)
|
||||
RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(0,8) RC(0,9) RC(0,10) RC(0,11) RC(0,12) RC(0,13) RC(0,14) RC(0,15)
|
||||
RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(1,6) RC(1,7) RC(1,8) RC(1,9) RC(1,10) RC(1,11) RC(1,12) RC(1,13) RC(1,14) RC(1,15)
|
||||
RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5) RC(2,6) RC(2,7) RC(2,8) RC(2,9) RC(2,10) RC(2,11) RC(2,12) RC(2,14) RC(2,15)
|
||||
RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,14) RC(3,15)
|
||||
RC(3,0) RC(3,1) RC(0,0) RC(3,2) RC(3,3) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(3,8) RC(3,9) RC(3,10) RC(3,11) RC(3,12) RC(3,14) RC(3,15)
|
||||
RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,6) RC(4,9) RC(4,10) RC(4,11) RC(4,12) RC(4,14) RC(4,15)
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&pro_micro_i2c {
|
||||
status = "okay";
|
||||
|
||||
oled: ssd1306@3c {
|
||||
compatible = "solomon,ssd1306fb";
|
||||
reg = <0x3c>;
|
||||
label = "DISPLAY";
|
||||
width = <128>;
|
||||
height = <32>;
|
||||
segment-offset = <0>;
|
||||
page-offset = <0>;
|
||||
display-offset = <0>;
|
||||
multiplex-ratio = <31>;
|
||||
com-sequential;
|
||||
prechargep = <0x22>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
compatible = "zmk,behavior-hold-tap";
|
||||
label = "homerow mods";
|
||||
#binding-cells = <2>;
|
||||
tapping_term_ms = <225>;
|
||||
tapping-term-ms = <225>;
|
||||
flavor = "tap-preferred";
|
||||
bindings = <&kp>, <&kp>;
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ endif
|
|||
if SHIELD_SPLITREUS62_RIGHT
|
||||
|
||||
config ZMK_KEYBOARD_NAME
|
||||
default "Splitreus62 Right"
|
||||
default "Splitreus62 Rt"
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
compatible = "zmk,behavior-hold-tap";
|
||||
label = "Hold Tap";
|
||||
#binding-cells = <2>;
|
||||
tapping_term_ms = <200>;
|
||||
tapping-term-ms = <200>;
|
||||
flavor = "tap-preferred";
|
||||
bindings = <&kp>, <&kp>;
|
||||
};
|
||||
|
|
|
@ -6,7 +6,6 @@ if SHIELD_TIDBIT
|
|||
config ZMK_KEYBOARD_NAME
|
||||
default "tidbit"
|
||||
|
||||
endif
|
||||
|
||||
if ZMK_DISPLAY
|
||||
|
||||
|
@ -43,3 +42,5 @@ choice LVGL_COLOR_DEPTH
|
|||
endchoice
|
||||
|
||||
endif # LVGL
|
||||
|
||||
endif
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
CONFIG_SENSOR=y
|
|
@ -2,7 +2,7 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
|
||||
config ZMK_KSCAN_GPIO_DRIVER
|
||||
bool "Enable GPIO kscan driver to simulate key presses"
|
||||
bool "Enable GPIO kscan driver to detect key presses"
|
||||
default y
|
||||
select GPIO
|
||||
|
||||
|
@ -10,11 +10,9 @@ if ZMK_KSCAN_GPIO_DRIVER
|
|||
|
||||
config ZMK_KSCAN_MATRIX_POLLING
|
||||
bool "Poll for key event triggers instead of using interrupts on matrix boards."
|
||||
default n
|
||||
|
||||
config ZMK_KSCAN_DIRECT_POLLING
|
||||
bool "Poll for key event triggers instead of using interrupts on direct wired boards."
|
||||
default n
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ static int kscan_gpio_config_interrupts(const struct device *dev, gpio_flags_t f
|
|||
int err = gpio_pin_interrupt_configure(dev, cfg->pin, flags);
|
||||
|
||||
if (err) {
|
||||
LOG_ERR("Unable to enable matrix GPIO interrupt");
|
||||
LOG_ERR("Unable to enable direct GPIO interrupt");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,11 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
}
|
||||
#endif
|
||||
|
||||
#define COND_POLLING(code) COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (code), ())
|
||||
#define COND_INTERRUPTS(code) COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (), (code))
|
||||
#define COND_POLL_OR_INTERRUPTS(pollcode, intcode) \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, pollcode, intcode)
|
||||
|
||||
#define INST_MATRIX_ROWS(n) DT_INST_PROP_LEN(n, row_gpios)
|
||||
#define INST_MATRIX_COLS(n) DT_INST_PROP_LEN(n, col_gpios)
|
||||
#define INST_OUTPUT_LEN(n) \
|
||||
|
@ -61,19 +66,21 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
(INST_MATRIX_ROWS(n)))
|
||||
|
||||
#define GPIO_INST_INIT(n) \
|
||||
struct kscan_gpio_irq_callback_##n { \
|
||||
struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) * work; \
|
||||
struct gpio_callback callback; \
|
||||
const struct device *dev; \
|
||||
}; \
|
||||
static struct kscan_gpio_irq_callback_##n irq_callbacks_##n[INST_INPUT_LEN(n)]; \
|
||||
COND_INTERRUPTS( \
|
||||
struct kscan_gpio_irq_callback_##n { \
|
||||
struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) * \
|
||||
work; \
|
||||
struct gpio_callback callback; \
|
||||
const struct device *dev; \
|
||||
}; \
|
||||
static struct kscan_gpio_irq_callback_##n irq_callbacks_##n[INST_INPUT_LEN(n)];) \
|
||||
struct kscan_gpio_config_##n { \
|
||||
struct kscan_gpio_item_config rows[INST_MATRIX_ROWS(n)]; \
|
||||
struct kscan_gpio_item_config cols[INST_MATRIX_COLS(n)]; \
|
||||
}; \
|
||||
struct kscan_gpio_data_##n { \
|
||||
kscan_callback_t callback; \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (struct k_timer poll_timer;), ()) \
|
||||
COND_POLLING(struct k_timer poll_timer;) \
|
||||
struct COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work), (k_delayed_work)) work; \
|
||||
bool matrix_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
||||
const struct device *rows[INST_MATRIX_ROWS(n)]; \
|
||||
|
@ -102,17 +109,16 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
return ( \
|
||||
COND_CODE_0(DT_ENUM_IDX(DT_DRV_INST(n), diode_direction), (cfg->rows), (cfg->cols))); \
|
||||
} \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (), \
|
||||
( \
|
||||
static int kscan_gpio_enable_interrupts_##n(const struct device *dev) { \
|
||||
return kscan_gpio_config_interrupts( \
|
||||
kscan_gpio_input_devices_##n(dev), kscan_gpio_input_configs_##n(dev), \
|
||||
INST_INPUT_LEN(n), GPIO_INT_LEVEL_ACTIVE); \
|
||||
} static int kscan_gpio_disable_interrupts_##n(const struct device *dev) { \
|
||||
return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), \
|
||||
kscan_gpio_input_configs_##n(dev), \
|
||||
INST_INPUT_LEN(n), GPIO_INT_DISABLE); \
|
||||
})) \
|
||||
COND_INTERRUPTS( \
|
||||
static int kscan_gpio_enable_interrupts_##n(const struct device *dev) { \
|
||||
return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), \
|
||||
kscan_gpio_input_configs_##n(dev), \
|
||||
INST_INPUT_LEN(n), GPIO_INT_LEVEL_ACTIVE); \
|
||||
} static int kscan_gpio_disable_interrupts_##n(const struct device *dev) { \
|
||||
return kscan_gpio_config_interrupts(kscan_gpio_input_devices_##n(dev), \
|
||||
kscan_gpio_input_configs_##n(dev), \
|
||||
INST_INPUT_LEN(n), GPIO_INT_DISABLE); \
|
||||
}) \
|
||||
static void kscan_gpio_set_output_state_##n(const struct device *dev, int value) { \
|
||||
int err; \
|
||||
for (int i = 0; i < INST_OUTPUT_LEN(n); i++) { \
|
||||
|
@ -132,17 +138,22 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
(output_index))] = value; \
|
||||
} \
|
||||
static int kscan_gpio_read_##n(const struct device *dev) { \
|
||||
bool submit_follow_up_read = false; \
|
||||
COND_INTERRUPTS(bool submit_follow_up_read = false;) \
|
||||
struct kscan_gpio_data_##n *data = dev->data; \
|
||||
static bool read_state[INST_MATRIX_ROWS(n)][INST_MATRIX_COLS(n)]; \
|
||||
int err; \
|
||||
/* Disable our interrupts temporarily while we scan, to avoid */ \
|
||||
/* re-entry while we iterate columns and set them active one by one */ \
|
||||
/* to get pressed state for each matrix cell. */ \
|
||||
kscan_gpio_set_output_state_##n(dev, 0); \
|
||||
COND_INTERRUPTS(kscan_gpio_set_output_state_##n(dev, 0);) \
|
||||
for (int o = 0; o < INST_OUTPUT_LEN(n); o++) { \
|
||||
const struct device *out_dev = kscan_gpio_output_devices_##n(dev)[o]; \
|
||||
const struct kscan_gpio_item_config *out_cfg = &kscan_gpio_output_configs_##n(dev)[o]; \
|
||||
gpio_pin_set(out_dev, out_cfg->pin, 1); \
|
||||
err = gpio_pin_set(out_dev, out_cfg->pin, 1); \
|
||||
if (err) { \
|
||||
LOG_ERR("Failed to set output active (err %d)", err); \
|
||||
return err; \
|
||||
} \
|
||||
for (int i = 0; i < INST_INPUT_LEN(n); i++) { \
|
||||
const struct device *in_dev = kscan_gpio_input_devices_##n(dev)[i]; \
|
||||
const struct kscan_gpio_item_config *in_cfg = \
|
||||
|
@ -150,16 +161,20 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
kscan_gpio_set_matrix_state_##n(read_state, i, o, \
|
||||
gpio_pin_get(in_dev, in_cfg->pin) > 0); \
|
||||
} \
|
||||
gpio_pin_set(out_dev, out_cfg->pin, 0); \
|
||||
err = gpio_pin_set(out_dev, out_cfg->pin, 0); \
|
||||
if (err) { \
|
||||
LOG_ERR("Failed to set output inactive (err %d)", err); \
|
||||
return err; \
|
||||
} \
|
||||
} \
|
||||
/* Set all our outputs as active again. */ \
|
||||
kscan_gpio_set_output_state_##n(dev, 1); \
|
||||
COND_INTERRUPTS(kscan_gpio_set_output_state_##n(dev, 1);) \
|
||||
for (int r = 0; r < INST_MATRIX_ROWS(n); r++) { \
|
||||
for (int c = 0; c < INST_MATRIX_COLS(n); c++) { \
|
||||
bool pressed = read_state[r][c]; \
|
||||
/* Follow up reads needed because further interrupts won't fire on already tripped \
|
||||
* input GPIO pins */ \
|
||||
submit_follow_up_read = (submit_follow_up_read || pressed); \
|
||||
COND_INTERRUPTS(submit_follow_up_read = (submit_follow_up_read || pressed);) \
|
||||
if (pressed != data->matrix_state[r][c]) { \
|
||||
LOG_DBG("Sending event at %d,%d state %s", r, c, (pressed ? "on" : "off")); \
|
||||
data->matrix_state[r][c] = pressed; \
|
||||
|
@ -167,33 +182,31 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
} \
|
||||
} \
|
||||
} \
|
||||
if (submit_follow_up_read) { \
|
||||
COND_CODE_0(DT_INST_PROP(n, debounce_period), ({ k_work_submit(&data->work); }), ({ \
|
||||
k_delayed_work_cancel(&data->work); \
|
||||
k_delayed_work_submit(&data->work, K_MSEC(5)); \
|
||||
})) \
|
||||
} else { \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (), \
|
||||
(kscan_gpio_enable_interrupts_##n(dev);)) \
|
||||
} \
|
||||
COND_INTERRUPTS( \
|
||||
if (submit_follow_up_read) { \
|
||||
COND_CODE_0(DT_INST_PROP(n, debounce_period), ({ k_work_submit(&data->work); }), \
|
||||
({ \
|
||||
k_delayed_work_cancel(&data->work); \
|
||||
k_delayed_work_submit(&data->work, K_MSEC(5)); \
|
||||
})) \
|
||||
} else { kscan_gpio_enable_interrupts_##n(dev); }) \
|
||||
return 0; \
|
||||
} \
|
||||
static void kscan_gpio_work_handler_##n(struct k_work *work) { \
|
||||
struct kscan_gpio_data_##n *data = CONTAINER_OF(work, struct kscan_gpio_data_##n, work); \
|
||||
kscan_gpio_read_##n(data->dev); \
|
||||
} \
|
||||
static void kscan_gpio_irq_callback_handler_##n( \
|
||||
COND_INTERRUPTS(static void kscan_gpio_irq_callback_handler_##n( \
|
||||
const struct device *dev, struct gpio_callback *cb, gpio_port_pins_t pin) { \
|
||||
struct kscan_gpio_irq_callback_##n *data = \
|
||||
CONTAINER_OF(cb, struct kscan_gpio_irq_callback_##n, callback); \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, (), \
|
||||
(kscan_gpio_disable_interrupts_##n(data->dev);)) \
|
||||
kscan_gpio_disable_interrupts_##n(data->dev); \
|
||||
COND_CODE_0(DT_INST_PROP(n, debounce_period), ({ k_work_submit(data->work); }), ({ \
|
||||
k_delayed_work_cancel(data->work); \
|
||||
k_delayed_work_submit(data->work, \
|
||||
K_MSEC(DT_INST_PROP(n, debounce_period))); \
|
||||
})) \
|
||||
} \
|
||||
}) \
|
||||
\
|
||||
static struct kscan_gpio_data_##n kscan_gpio_data_##n = { \
|
||||
.rows = {[INST_MATRIX_ROWS(n) - 1] = NULL}, .cols = {[INST_MATRIX_COLS(n) - 1] = NULL}}; \
|
||||
|
@ -207,25 +220,22 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
return 0; \
|
||||
}; \
|
||||
static int kscan_gpio_enable_##n(const struct device *dev) { \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
|
||||
(struct kscan_gpio_data_##n *data = dev->data; \
|
||||
k_timer_start(&data->poll_timer, K_MSEC(10), K_MSEC(10)); return 0;), \
|
||||
(int err = kscan_gpio_enable_interrupts_##n(dev); \
|
||||
if (err) { return err; } return kscan_gpio_read_##n(dev);)) \
|
||||
COND_POLL_OR_INTERRUPTS((struct kscan_gpio_data_##n *data = dev->data; \
|
||||
k_timer_start(&data->poll_timer, K_MSEC(10), K_MSEC(10)); \
|
||||
return 0;), \
|
||||
(int err = kscan_gpio_enable_interrupts_##n(dev); \
|
||||
if (err) { return err; } return kscan_gpio_read_##n(dev);)) \
|
||||
}; \
|
||||
static int kscan_gpio_disable_##n(const struct device *dev) { \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
|
||||
(struct kscan_gpio_data_##n *data = dev->data; \
|
||||
k_timer_stop(&data->poll_timer); return 0;), \
|
||||
(return kscan_gpio_disable_interrupts_##n(dev);)) \
|
||||
COND_POLL_OR_INTERRUPTS((struct kscan_gpio_data_##n *data = dev->data; \
|
||||
k_timer_stop(&data->poll_timer); return 0;), \
|
||||
(return kscan_gpio_disable_interrupts_##n(dev);)) \
|
||||
}; \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
|
||||
(static void kscan_gpio_timer_handler(struct k_timer *timer) { \
|
||||
struct kscan_gpio_data_##n *data = \
|
||||
CONTAINER_OF(timer, struct kscan_gpio_data_##n, poll_timer); \
|
||||
k_work_submit(&data->work.work); \
|
||||
}), \
|
||||
()) \
|
||||
COND_POLLING(static void kscan_gpio_timer_handler_##n(struct k_timer *timer) { \
|
||||
struct kscan_gpio_data_##n *data = \
|
||||
CONTAINER_OF(timer, struct kscan_gpio_data_##n, poll_timer); \
|
||||
k_work_submit(&data->work.work); \
|
||||
}) \
|
||||
static int kscan_gpio_init_##n(const struct device *dev) { \
|
||||
struct kscan_gpio_data_##n *data = dev->data; \
|
||||
int err; \
|
||||
|
@ -244,15 +254,15 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
} else { \
|
||||
LOG_DBG("Configured pin %d on %s for input", in_cfg->pin, in_cfg->label); \
|
||||
} \
|
||||
irq_callbacks_##n[i].work = &data->work; \
|
||||
irq_callbacks_##n[i].dev = dev; \
|
||||
gpio_init_callback(&irq_callbacks_##n[i].callback, \
|
||||
kscan_gpio_irq_callback_handler_##n, BIT(in_cfg->pin)); \
|
||||
err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
|
||||
if (err) { \
|
||||
LOG_ERR("Error adding the callback to the column device"); \
|
||||
return err; \
|
||||
} \
|
||||
COND_INTERRUPTS( \
|
||||
irq_callbacks_##n[i].work = &data->work; irq_callbacks_##n[i].dev = dev; \
|
||||
gpio_init_callback(&irq_callbacks_##n[i].callback, \
|
||||
kscan_gpio_irq_callback_handler_##n, BIT(in_cfg->pin)); \
|
||||
err = gpio_add_callback(input_devices[i], &irq_callbacks_##n[i].callback); \
|
||||
if (err) { \
|
||||
LOG_ERR("Error adding the callback to the input device"); \
|
||||
return err; \
|
||||
}) \
|
||||
} \
|
||||
const struct device **output_devices = kscan_gpio_output_devices_##n(dev); \
|
||||
for (int o = 0; o < INST_OUTPUT_LEN(n); o++) { \
|
||||
|
@ -262,8 +272,8 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
LOG_ERR("Unable to find output GPIO device"); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
err = gpio_pin_configure(output_devices[o], out_cfg->pin, \
|
||||
GPIO_OUTPUT_ACTIVE | out_cfg->flags); \
|
||||
err = \
|
||||
gpio_pin_configure(output_devices[o], out_cfg->pin, GPIO_OUTPUT | out_cfg->flags); \
|
||||
if (err) { \
|
||||
LOG_ERR("Unable to configure pin %d on %s for output", out_cfg->pin, \
|
||||
out_cfg->label); \
|
||||
|
@ -271,10 +281,12 @@ static int kscan_gpio_config_interrupts(const struct device **devices,
|
|||
} \
|
||||
} \
|
||||
data->dev = dev; \
|
||||
COND_CODE_1(CONFIG_ZMK_KSCAN_MATRIX_POLLING, \
|
||||
(k_timer_init(&data->poll_timer, kscan_gpio_timer_handler, NULL);), ()) \
|
||||
(COND_CODE_0(DT_INST_PROP(n, debounce_period), (k_work_init), (k_delayed_work_init)))( \
|
||||
&data->work, kscan_gpio_work_handler_##n); \
|
||||
COND_POLL_OR_INTERRUPTS( \
|
||||
(k_timer_init(&data->poll_timer, kscan_gpio_timer_handler_##n, NULL); \
|
||||
kscan_gpio_set_output_state_##n(dev, 0);), \
|
||||
(kscan_gpio_set_output_state_##n(dev, 1);)) \
|
||||
return 0; \
|
||||
} \
|
||||
static const struct kscan_driver_api gpio_driver_api_##n = { \
|
||||
|
|
|
@ -77,6 +77,9 @@ static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
|||
LOG_DBG("Failed to enable ADC power GPIO: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// wait for any capacitance to charge up
|
||||
k_sleep(K_MSEC(10));
|
||||
}
|
||||
|
||||
// Read ADC
|
||||
|
@ -90,7 +93,7 @@ static int bvd_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
|||
&val);
|
||||
|
||||
uint16_t millivolts = val * (uint64_t)drv_cfg->full_ohm / drv_cfg->output_ohm;
|
||||
LOG_DBG("ADC raw %d ~ %d mV => %d mV\n", drv_data->adc_raw, val, millivolts);
|
||||
LOG_DBG("ADC raw %d ~ %d mV => %d mV", drv_data->adc_raw, val, millivolts);
|
||||
uint8_t percent = lithium_ion_mv_to_pct(millivolts);
|
||||
LOG_DBG("Percent: %d", percent);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <behaviors/none.dtsi>
|
||||
#include <behaviors/mod_tap.dtsi>
|
||||
#include <behaviors/layer_tap.dtsi>
|
||||
#include <behaviors/gresc.dtsi>
|
||||
#include <behaviors/sticky_key.dtsi>
|
||||
#include <behaviors/momentary_layer.dtsi>
|
||||
#include <behaviors/toggle_layer.dtsi>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
bt: behavior_bluetooth {
|
||||
/omit-if-no-ref/ bt: behavior_bluetooth {
|
||||
compatible = "zmk,behavior-bluetooth";
|
||||
label = "BLUETOOTH";
|
||||
#binding-cells = <2>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
ext_power: behavior_ext_power {
|
||||
/omit-if-no-ref/ ext_power: behavior_ext_power {
|
||||
compatible = "zmk,behavior-ext-power";
|
||||
label = "EXT_POWER_BEHAVIOR";
|
||||
#binding-cells = <1>;
|
||||
|
|
19
app/dts/behaviors/gresc.dtsi
Normal file
19
app/dts/behaviors/gresc.dtsi
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <dt-bindings/zmk/keys.h>
|
||||
|
||||
/ {
|
||||
behaviors {
|
||||
/omit-if-no-ref/ gresc: grave_escape {
|
||||
compatible = "zmk,behavior-mod-morph";
|
||||
label = "GRAVE_ESCAPE";
|
||||
#binding-cells = <0>;
|
||||
bindings = <&kp ESC>, <&kp GRAVE>;
|
||||
mods = <(MOD_LGUI|MOD_LSFT|MOD_RGUI|MOD_RSFT)>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
/ {
|
||||
behaviors {
|
||||
/* DEPRECATED: `cp` will be removed in the future */
|
||||
cp: kp: behavior_key_press {
|
||||
/omit-if-no-ref/ cp: kp: behavior_key_press {
|
||||
compatible = "zmk,behavior-key-press";
|
||||
label = "KEY_PRESS";
|
||||
#binding-cells = <1>;
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
lt: behavior_layer_tap {
|
||||
/omit-if-no-ref/ lt: behavior_layer_tap {
|
||||
compatible = "zmk,behavior-hold-tap";
|
||||
label = "LAYER_TAP";
|
||||
#binding-cells = <2>;
|
||||
flavor = "tap-preferred";
|
||||
tapping_term_ms = <200>;
|
||||
tapping-term-ms = <200>;
|
||||
bindings = <&mo>, <&kp>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
mt: behavior_mod_tap {
|
||||
/omit-if-no-ref/ mt: behavior_mod_tap {
|
||||
compatible = "zmk,behavior-hold-tap";
|
||||
label = "MOD_TAP";
|
||||
#binding-cells = <2>;
|
||||
flavor = "hold-preferred";
|
||||
tapping_term_ms = <200>;
|
||||
tapping-term-ms = <200>;
|
||||
bindings = <&kp>, <&kp>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
mo: behavior_momentary_layer {
|
||||
/omit-if-no-ref/ mo: behavior_momentary_layer {
|
||||
compatible = "zmk,behavior-momentary-layer";
|
||||
label = "MO";
|
||||
#binding-cells = <1>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
none: behavior_none {
|
||||
/omit-if-no-ref/ none: behavior_none {
|
||||
compatible = "zmk,behavior-none";
|
||||
label = "NONE";
|
||||
#binding-cells = <0>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
out: behavior_outputs {
|
||||
/omit-if-no-ref/ out: behavior_outputs {
|
||||
compatible = "zmk,behavior-outputs";
|
||||
label = "OUTPUTS";
|
||||
#binding-cells = <1>;
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
reset: behavior_reset {
|
||||
/omit-if-no-ref/ reset: behavior_reset {
|
||||
compatible = "zmk,behavior-reset";
|
||||
label = "RESET";
|
||||
#binding-cells = <0>;
|
||||
};
|
||||
|
||||
bootloader: behavior_reset_dfu {
|
||||
/omit-if-no-ref/ bootloader: behavior_reset_dfu {
|
||||
compatible = "zmk,behavior-reset";
|
||||
label = "BOOTLOADER_RESET";
|
||||
type = <RST_UF2>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
rgb_ug: behavior_rgb_underglow {
|
||||
/omit-if-no-ref/ rgb_ug: behavior_rgb_underglow {
|
||||
compatible = "zmk,behavior-rgb-underglow";
|
||||
label = "RGB_UNDERGLOW";
|
||||
#binding-cells = <2>;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
/ {
|
||||
behaviors {
|
||||
/* DEPRECATED: `inc_dec_cp` will be removed in the future */
|
||||
inc_dec_cp: inc_dec_kp: behavior_sensor_rotate_key_press {
|
||||
/omit-if-no-ref/ inc_dec_cp: inc_dec_kp: behavior_sensor_rotate_key_press {
|
||||
compatible = "zmk,behavior-sensor-rotate-key-press";
|
||||
label = "ENC_KEY_PRESS";
|
||||
#sensor-binding-cells = <2>;
|
||||
|
|
|
@ -6,19 +6,20 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
sk: behavior_sticky_key {
|
||||
/omit-if-no-ref/ sk: behavior_sticky_key {
|
||||
compatible = "zmk,behavior-sticky-key";
|
||||
label = "STICKY_KEY";
|
||||
#binding-cells = <1>;
|
||||
release-after-ms = <1000>;
|
||||
bindings = <&kp>;
|
||||
};
|
||||
sl: behavior_sticky_layer {
|
||||
/omit-if-no-ref/ sl: behavior_sticky_layer {
|
||||
compatible = "zmk,behavior-sticky-key";
|
||||
label = "STICKY_LAYER";
|
||||
#binding-cells = <1>;
|
||||
release-after-ms = <1000>;
|
||||
bindings = <&mo>;
|
||||
quick-release;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
to: behavior_to_layer {
|
||||
/omit-if-no-ref/ to: behavior_to_layer {
|
||||
compatible = "zmk,behavior-to-layer";
|
||||
label = "TO_LAYER";
|
||||
#binding-cells = <1>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
tog: behavior_toggle_layer {
|
||||
/omit-if-no-ref/ tog: behavior_toggle_layer {
|
||||
compatible = "zmk,behavior-toggle-layer";
|
||||
label = "TOGGLE_LAYER";
|
||||
#binding-cells = <1>;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
/ {
|
||||
behaviors {
|
||||
trans: behavior_transparent {
|
||||
/omit-if-no-ref/ trans: behavior_transparent {
|
||||
compatible = "zmk,behavior-transparent";
|
||||
label = "TRANS";
|
||||
#binding-cells = <0>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
properties:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
properties:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
properties:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Peter Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Bluetooth Behavior
|
||||
|
|
|
@ -11,7 +11,14 @@ properties:
|
|||
bindings:
|
||||
type: phandles
|
||||
required: true
|
||||
tapping_term_ms:
|
||||
tapping-term-ms:
|
||||
type: int
|
||||
tapping_term_ms: # deprecated
|
||||
type: int
|
||||
quick-tap-ms:
|
||||
type: int
|
||||
default: -1
|
||||
quick_tap_ms: # deprecated
|
||||
type: int
|
||||
flavor:
|
||||
type: string
|
||||
|
@ -21,3 +28,5 @@ properties:
|
|||
- "hold-preferred"
|
||||
- "balanced"
|
||||
- "tap-preferred"
|
||||
retro-tap:
|
||||
type: boolean
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Key press/release behavior
|
||||
|
|
16
app/dts/bindings/behaviors/zmk,behavior-mod-morph.yaml
Normal file
16
app/dts/bindings/behaviors/zmk,behavior-mod-morph.yaml
Normal file
|
@ -0,0 +1,16 @@
|
|||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Keyboard Reset Behavior
|
||||
|
||||
compatible: "zmk,behavior-mod-morph"
|
||||
|
||||
include: zero_param.yaml
|
||||
|
||||
properties:
|
||||
bindings:
|
||||
type: phandle-array
|
||||
required: true
|
||||
mods:
|
||||
type: int
|
||||
required: true
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Momentary layer on press/release behavior
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: None Binding Behavior
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Keyboard Reset Behavior
|
||||
|
|
|
@ -13,3 +13,5 @@ properties:
|
|||
required: true
|
||||
release-after-ms:
|
||||
type: int
|
||||
quick-release:
|
||||
type: boolean
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2020 Pete Johanson
|
||||
# Copyright (c) 2020 The ZMK Contributors
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: Transparent Binding Behavior
|
||||
|
|
|
@ -20,3 +20,6 @@ child-binding:
|
|||
default: 50
|
||||
slow-release:
|
||||
type: boolean
|
||||
layers:
|
||||
type: array
|
||||
default: [-1]
|
|
@ -15,3 +15,7 @@ properties:
|
|||
label:
|
||||
type: string
|
||||
required: true
|
||||
init-delay-ms:
|
||||
type: int
|
||||
description: Number of milliseconds to delay after initializing driver
|
||||
required: false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Pete Johanson
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ typedef int (*behavior_sensor_keymap_binding_callback_t)(struct zmk_behavior_bin
|
|||
int64_t timestamp);
|
||||
|
||||
__subsystem struct behavior_driver_api {
|
||||
behavior_keymap_binding_callback_t binding_convert_central_state_dependent_params;
|
||||
behavior_keymap_binding_callback_t binding_pressed;
|
||||
behavior_keymap_binding_callback_t binding_released;
|
||||
behavior_sensor_keymap_binding_callback_t sensor_binding_triggered;
|
||||
|
@ -35,6 +36,30 @@ __subsystem struct behavior_driver_api {
|
|||
* @endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Handle the keymap binding which needs to be converted from relative "toggle" to absolute
|
||||
* "turn on"
|
||||
* @param binding Pointer to the details so of the binding
|
||||
* @param event The event that triggered use of the binding
|
||||
*
|
||||
* @retval 0 If successful.
|
||||
* @retval Negative errno code if failure.
|
||||
*/
|
||||
__syscall int behavior_keymap_binding_convert_central_state_dependent_params(
|
||||
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event);
|
||||
|
||||
static inline int z_impl_behavior_keymap_binding_convert_central_state_dependent_params(
|
||||
struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event) {
|
||||
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||
const struct behavior_driver_api *api = (const struct behavior_driver_api *)dev->api;
|
||||
|
||||
if (api->binding_convert_central_state_dependent_params == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return api->binding_convert_central_state_dependent_params(binding, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle the keymap binding being pressed
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
|
|
|
@ -5,19 +5,23 @@
|
|||
*/
|
||||
|
||||
#define RGB_TOG_CMD 0
|
||||
#define RGB_HUI_CMD 1
|
||||
#define RGB_HUD_CMD 2
|
||||
#define RGB_SAI_CMD 3
|
||||
#define RGB_SAD_CMD 4
|
||||
#define RGB_BRI_CMD 5
|
||||
#define RGB_BRD_CMD 6
|
||||
#define RGB_SPI_CMD 7
|
||||
#define RGB_SPD_CMD 8
|
||||
#define RGB_EFF_CMD 9
|
||||
#define RGB_EFR_CMD 10
|
||||
#define RGB_COLOR_HSB_CMD 11
|
||||
#define RGB_ON_CMD 1
|
||||
#define RGB_OFF_CMD 2
|
||||
#define RGB_HUI_CMD 3
|
||||
#define RGB_HUD_CMD 4
|
||||
#define RGB_SAI_CMD 5
|
||||
#define RGB_SAD_CMD 6
|
||||
#define RGB_BRI_CMD 7
|
||||
#define RGB_BRD_CMD 8
|
||||
#define RGB_SPI_CMD 9
|
||||
#define RGB_SPD_CMD 10
|
||||
#define RGB_EFF_CMD 11
|
||||
#define RGB_EFR_CMD 12
|
||||
#define RGB_COLOR_HSB_CMD 13
|
||||
|
||||
#define RGB_TOG RGB_TOG_CMD 0
|
||||
#define RGB_ON RGB_ON_CMD 0
|
||||
#define RGB_OFF RGB_OFF_CMD 0
|
||||
#define RGB_HUI RGB_HUI_CMD 0
|
||||
#define RGB_HUD RGB_HUD_CMD 0
|
||||
#define RGB_SAI RGB_SAI_CMD 0
|
||||
|
@ -28,5 +32,6 @@
|
|||
#define RGB_SPD RGB_SPD_CMD 0
|
||||
#define RGB_EFF RGB_EFF_CMD 0
|
||||
#define RGB_EFR RGB_EFR_CMD 0
|
||||
#define RGB_COLOR_HSB(h, s, v) RGB_COLOR_HSB_CMD(((h) << 16) + ((s) << 8) + (v))
|
||||
#define RGB_COLOR_HSB_VAL(h, s, v) (((h) << 16) + ((s) << 8) + (v))
|
||||
#define RGB_COLOR_HSB(h, s, v) RGB_COLOR_HSB_CMD##(RGB_COLOR_HSB_VAL(h, s, v))
|
||||
#define RGB_COLOR_HSV RGB_COLOR_HSB
|
9
app/include/zmk/battery.h
Normal file
9
app/include/zmk/battery.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
uint8_t zmk_battery_state_of_charge();
|
18
app/include/zmk/display/widgets/wpm_status.h
Normal file
18
app/include/zmk/display/widgets/wpm_status.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <kernel.h>
|
||||
|
||||
struct zmk_widget_wpm_status {
|
||||
sys_snode_t node;
|
||||
lv_obj_t *obj;
|
||||
};
|
||||
|
||||
int zmk_widget_wpm_status_init(struct zmk_widget_wpm_status *widget, lv_obj_t *parent);
|
||||
lv_obj_t *zmk_widget_wpm_status_obj(struct zmk_widget_wpm_status *widget);
|
|
@ -18,4 +18,4 @@ int zmk_endpoints_select(enum zmk_endpoint endpoint);
|
|||
int zmk_endpoints_toggle();
|
||||
enum zmk_endpoint zmk_endpoints_selected();
|
||||
|
||||
int zmk_endpoints_send_report(uint8_t usage_page);
|
||||
int zmk_endpoints_send_report(uint16_t usage_page);
|
||||
|
|
|
@ -14,16 +14,16 @@ struct zmk_event_type {
|
|||
const char *name;
|
||||
};
|
||||
|
||||
struct zmk_event_header {
|
||||
typedef struct {
|
||||
const struct zmk_event_type *event;
|
||||
uint8_t last_listener_index;
|
||||
};
|
||||
} zmk_event_t;
|
||||
|
||||
#define ZMK_EV_EVENT_BUBBLE 0
|
||||
#define ZMK_EV_EVENT_HANDLED 1
|
||||
#define ZMK_EV_EVENT_CAPTURED 2
|
||||
|
||||
typedef int (*zmk_listener_callback_t)(const struct zmk_event_header *eh);
|
||||
typedef int (*zmk_listener_callback_t)(const zmk_event_t *eh);
|
||||
struct zmk_listener {
|
||||
zmk_listener_callback_t callback;
|
||||
};
|
||||
|
@ -34,25 +34,28 @@ struct zmk_event_subscription {
|
|||
};
|
||||
|
||||
#define ZMK_EVENT_DECLARE(event_type) \
|
||||
struct event_type *new_##event_type(); \
|
||||
bool is_##event_type(const struct zmk_event_header *eh); \
|
||||
struct event_type *cast_##event_type(const struct zmk_event_header *eh); \
|
||||
struct event_type##_event { \
|
||||
zmk_event_t header; \
|
||||
struct event_type data; \
|
||||
}; \
|
||||
struct event_type##_event *new_##event_type(struct event_type); \
|
||||
struct event_type *as_##event_type(const zmk_event_t *eh); \
|
||||
extern const struct zmk_event_type zmk_event_##event_type;
|
||||
|
||||
#define ZMK_EVENT_IMPL(event_type) \
|
||||
const struct zmk_event_type zmk_event_##event_type = {.name = STRINGIFY(event_type)}; \
|
||||
const struct zmk_event_type *zmk_event_ref_##event_type __used \
|
||||
__attribute__((__section__(".event_type"))) = &zmk_event_##event_type; \
|
||||
struct event_type *new_##event_type() { \
|
||||
struct event_type *ev = (struct event_type *)k_malloc(sizeof(struct event_type)); \
|
||||
struct event_type##_event *new_##event_type(struct event_type data) { \
|
||||
struct event_type##_event *ev = \
|
||||
(struct event_type##_event *)k_malloc(sizeof(struct event_type##_event)); \
|
||||
ev->header.event = &zmk_event_##event_type; \
|
||||
ev->data = data; \
|
||||
return ev; \
|
||||
}; \
|
||||
bool is_##event_type(const struct zmk_event_header *eh) { \
|
||||
return eh->event == &zmk_event_##event_type; \
|
||||
}; \
|
||||
struct event_type *cast_##event_type(const struct zmk_event_header *eh) { \
|
||||
return (struct event_type *)eh; \
|
||||
struct event_type *as_##event_type(const zmk_event_t *eh) { \
|
||||
return (eh->event == &zmk_event_##event_type) ? &((struct event_type##_event *)eh)->data \
|
||||
: NULL; \
|
||||
};
|
||||
|
||||
#define ZMK_LISTENER(mod, cb) const struct zmk_listener zmk_listener_##mod = {.callback = cb};
|
||||
|
@ -65,18 +68,19 @@ struct zmk_event_subscription {
|
|||
.listener = &zmk_listener_##mod, \
|
||||
};
|
||||
|
||||
#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((struct zmk_event_header *)ev);
|
||||
#define ZMK_EVENT_RAISE(ev) zmk_event_manager_raise((zmk_event_t *)ev);
|
||||
|
||||
#define ZMK_EVENT_RAISE_AFTER(ev, mod) \
|
||||
zmk_event_manager_raise_after((struct zmk_event_header *)ev, &zmk_listener_##mod);
|
||||
zmk_event_manager_raise_after((zmk_event_t *)ev, &zmk_listener_##mod);
|
||||
|
||||
#define ZMK_EVENT_RAISE_AT(ev, mod) \
|
||||
zmk_event_manager_raise_at((struct zmk_event_header *)ev, &zmk_listener_##mod);
|
||||
zmk_event_manager_raise_at((zmk_event_t *)ev, &zmk_listener_##mod);
|
||||
|
||||
#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((struct zmk_event_header *)ev);
|
||||
#define ZMK_EVENT_RELEASE(ev) zmk_event_manager_release((zmk_event_t *)ev);
|
||||
|
||||
int zmk_event_manager_raise(struct zmk_event_header *event);
|
||||
int zmk_event_manager_raise_after(struct zmk_event_header *event,
|
||||
const struct zmk_listener *listener);
|
||||
int zmk_event_manager_raise_at(struct zmk_event_header *event, const struct zmk_listener *listener);
|
||||
int zmk_event_manager_release(struct zmk_event_header *event);
|
||||
#define ZMK_EVENT_FREE(ev) k_free((void *)ev);
|
||||
|
||||
int zmk_event_manager_raise(zmk_event_t *event);
|
||||
int zmk_event_manager_raise_after(zmk_event_t *event, const struct zmk_listener *listener);
|
||||
int zmk_event_manager_raise_at(zmk_event_t *event, const struct zmk_listener *listener);
|
||||
int zmk_event_manager_release(zmk_event_t *event);
|
|
@ -10,17 +10,8 @@
|
|||
#include <zmk/event_manager.h>
|
||||
#include <zmk/activity.h>
|
||||
|
||||
struct activity_state_changed {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_activity_state_changed {
|
||||
enum zmk_activity_state state;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(activity_state_changed);
|
||||
|
||||
static inline struct activity_state_changed *
|
||||
create_activity_state_changed(enum zmk_activity_state state) {
|
||||
struct activity_state_changed *ev = new_activity_state_changed();
|
||||
ev->state = state;
|
||||
|
||||
return ev;
|
||||
}
|
||||
ZMK_EVENT_DECLARE(zmk_activity_state_changed);
|
|
@ -9,10 +9,9 @@
|
|||
#include <zephyr.h>
|
||||
#include <zmk/event_manager.h>
|
||||
|
||||
struct battery_state_changed {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_battery_state_changed {
|
||||
// TODO: Other battery channels
|
||||
uint8_t state_of_charge;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(battery_state_changed);
|
||||
ZMK_EVENT_DECLARE(zmk_battery_state_changed);
|
|
@ -12,10 +12,9 @@
|
|||
|
||||
#include <zmk/ble/profile.h>
|
||||
|
||||
struct ble_active_profile_changed {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_ble_active_profile_changed {
|
||||
uint8_t index;
|
||||
struct zmk_ble_profile *profile;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(ble_active_profile_changed);
|
||||
ZMK_EVENT_DECLARE(zmk_ble_active_profile_changed);
|
||||
|
|
|
@ -7,37 +7,42 @@
|
|||
#pragma once
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <dt-bindings/zmk/modifiers.h>
|
||||
#include <dt-bindings/zmk/hid_usage_pages.h>
|
||||
#include <zmk/event_manager.h>
|
||||
#include <zmk/keys.h>
|
||||
|
||||
struct keycode_state_changed {
|
||||
struct zmk_event_header header;
|
||||
uint8_t usage_page;
|
||||
struct zmk_keycode_state_changed {
|
||||
uint16_t usage_page;
|
||||
uint32_t keycode;
|
||||
uint8_t implicit_modifiers;
|
||||
uint8_t explicit_modifiers;
|
||||
bool state;
|
||||
int64_t timestamp;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(keycode_state_changed);
|
||||
ZMK_EVENT_DECLARE(zmk_keycode_state_changed);
|
||||
|
||||
static inline struct keycode_state_changed *
|
||||
keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) {
|
||||
static inline struct zmk_keycode_state_changed_event *
|
||||
zmk_keycode_state_changed_from_encoded(uint32_t encoded, bool pressed, int64_t timestamp) {
|
||||
uint16_t page = HID_USAGE_PAGE(encoded) & 0xFF;
|
||||
uint16_t id = HID_USAGE_ID(encoded);
|
||||
zmk_mod_flags_t implicit_mods = SELECT_MODS(encoded);
|
||||
uint8_t implicit_modifiers = 0x00;
|
||||
uint8_t explicit_modifiers = 0x00;
|
||||
|
||||
if (!page) {
|
||||
page = HID_USAGE_KEY;
|
||||
}
|
||||
|
||||
struct keycode_state_changed *ev = new_keycode_state_changed();
|
||||
ev->usage_page = page;
|
||||
ev->keycode = id;
|
||||
ev->implicit_modifiers = implicit_mods;
|
||||
ev->state = pressed;
|
||||
ev->timestamp = timestamp;
|
||||
return ev;
|
||||
if (is_mod(page, id)) {
|
||||
explicit_modifiers = SELECT_MODS(encoded);
|
||||
} else {
|
||||
implicit_modifiers = SELECT_MODS(encoded);
|
||||
}
|
||||
|
||||
return new_zmk_keycode_state_changed(
|
||||
(struct zmk_keycode_state_changed){.usage_page = page,
|
||||
.keycode = id,
|
||||
.implicit_modifiers = implicit_modifiers,
|
||||
.explicit_modifiers = explicit_modifiers,
|
||||
.state = pressed,
|
||||
.timestamp = timestamp});
|
||||
}
|
||||
|
|
|
@ -9,20 +9,16 @@
|
|||
#include <zephyr.h>
|
||||
#include <zmk/event_manager.h>
|
||||
|
||||
struct layer_state_changed {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_layer_state_changed {
|
||||
uint8_t layer;
|
||||
bool state;
|
||||
int64_t timestamp;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(layer_state_changed);
|
||||
ZMK_EVENT_DECLARE(zmk_layer_state_changed);
|
||||
|
||||
static inline struct layer_state_changed *create_layer_state_changed(uint8_t layer, bool state) {
|
||||
struct layer_state_changed *ev = new_layer_state_changed();
|
||||
ev->layer = layer;
|
||||
ev->state = state;
|
||||
ev->timestamp = k_uptime_get();
|
||||
|
||||
return ev;
|
||||
static inline struct zmk_layer_state_changed_event *create_layer_state_changed(uint8_t layer,
|
||||
bool state) {
|
||||
return new_zmk_layer_state_changed((struct zmk_layer_state_changed){
|
||||
.layer = layer, .state = state, .timestamp = k_uptime_get()});
|
||||
}
|
||||
|
|
|
@ -10,19 +10,9 @@
|
|||
#include <zmk/keys.h>
|
||||
#include <zmk/event_manager.h>
|
||||
|
||||
struct modifiers_state_changed {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_modifiers_state_changed {
|
||||
zmk_mod_flags_t modifiers;
|
||||
bool state;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(modifiers_state_changed);
|
||||
|
||||
inline struct modifiers_state_changed *create_modifiers_state_changed(zmk_mod_flags_t modifiers,
|
||||
bool state) {
|
||||
struct modifiers_state_changed *ev = new_modifiers_state_changed();
|
||||
ev->modifiers = modifiers;
|
||||
ev->state = state;
|
||||
|
||||
return ev;
|
||||
}
|
||||
ZMK_EVENT_DECLARE(zmk_modifiers_state_changed);
|
|
@ -8,12 +8,10 @@
|
|||
|
||||
#include <zephyr.h>
|
||||
#include <zmk/event_manager.h>
|
||||
|
||||
struct position_state_changed {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_position_state_changed {
|
||||
uint32_t position;
|
||||
bool state;
|
||||
int64_t timestamp;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(position_state_changed);
|
||||
ZMK_EVENT_DECLARE(zmk_position_state_changed);
|
|
@ -9,12 +9,10 @@
|
|||
#include <zephyr.h>
|
||||
#include <zmk/event_manager.h>
|
||||
#include <device.h>
|
||||
|
||||
struct sensor_event {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_sensor_event {
|
||||
uint8_t sensor_number;
|
||||
const struct device *sensor;
|
||||
int64_t timestamp;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(sensor_event);
|
||||
ZMK_EVENT_DECLARE(zmk_sensor_event);
|
|
@ -12,9 +12,8 @@
|
|||
#include <zmk/event_manager.h>
|
||||
#include <zmk/usb.h>
|
||||
|
||||
struct usb_conn_state_changed {
|
||||
struct zmk_event_header header;
|
||||
struct zmk_usb_conn_state_changed {
|
||||
enum zmk_usb_conn_state conn_state;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(usb_conn_state_changed);
|
||||
ZMK_EVENT_DECLARE(zmk_usb_conn_state_changed);
|
17
app/include/zmk/events/wpm_state_changed.h
Normal file
17
app/include/zmk/events/wpm_state_changed.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <zmk/event_manager.h>
|
||||
#include <zmk/wpm.h>
|
||||
|
||||
struct zmk_wpm_state_changed {
|
||||
int state;
|
||||
};
|
||||
|
||||
ZMK_EVENT_DECLARE(zmk_wpm_state_changed);
|
|
@ -166,8 +166,11 @@ struct zmk_hid_consumer_report {
|
|||
struct zmk_hid_consumer_report_body body;
|
||||
} __packed;
|
||||
|
||||
zmk_mod_flags_t zmk_hid_get_explicit_mods();
|
||||
int zmk_hid_register_mod(zmk_mod_t modifier);
|
||||
int zmk_hid_unregister_mod(zmk_mod_t modifier);
|
||||
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_keyboard_press(zmk_key_t key);
|
||||
|
|
|
@ -19,3 +19,12 @@ int zmk_keymap_layer_to(uint8_t layer);
|
|||
const char *zmk_keymap_layer_label(uint8_t layer);
|
||||
|
||||
int zmk_keymap_position_state_changed(uint32_t position, bool pressed, int64_t timestamp);
|
||||
|
||||
#define ZMK_KEYMAP_EXTRACT_BINDING(idx, drv_inst) \
|
||||
{ \
|
||||
.behavior_dev = DT_LABEL(DT_PHANDLE_BY_IDX(drv_inst, bindings, idx)), \
|
||||
.param1 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param1), (0), \
|
||||
(DT_PHA_BY_IDX(drv_inst, bindings, idx, param1))), \
|
||||
.param2 = COND_CODE_0(DT_PHA_HAS_CELL_AT_IDX(drv_inst, bindings, idx, param2), (0), \
|
||||
(DT_PHA_BY_IDX(drv_inst, bindings, idx, param2))), \
|
||||
}
|
||||
|
|
|
@ -18,4 +18,9 @@ struct zmk_key_event {
|
|||
uint32_t row;
|
||||
zmk_key_t key;
|
||||
bool pressed;
|
||||
};
|
||||
};
|
||||
|
||||
static inline bool is_mod(uint8_t usage_page, uint32_t keycode) {
|
||||
return (keycode >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL &&
|
||||
keycode <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI && usage_page == HID_USAGE_KEY);
|
||||
}
|
|
@ -6,10 +6,22 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
struct zmk_led_hsb {
|
||||
uint16_t h;
|
||||
uint8_t s;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
int zmk_rgb_underglow_toggle();
|
||||
int zmk_rgb_underglow_get_state(bool *state);
|
||||
int zmk_rgb_underglow_on();
|
||||
int zmk_rgb_underglow_off();
|
||||
int zmk_rgb_underglow_cycle_effect(int direction);
|
||||
struct zmk_led_hsb zmk_rgb_underglow_calc_hue(int direction);
|
||||
struct zmk_led_hsb zmk_rgb_underglow_calc_sat(int direction);
|
||||
struct zmk_led_hsb zmk_rgb_underglow_calc_brt(int direction);
|
||||
int zmk_rgb_underglow_change_hue(int direction);
|
||||
int zmk_rgb_underglow_change_sat(int direction);
|
||||
int zmk_rgb_underglow_change_brt(int direction);
|
||||
int zmk_rgb_underglow_change_spd(int direction);
|
||||
int zmk_rgb_underglow_set_hsb(uint16_t hue, uint8_t saturation, uint8_t brightness);
|
||||
int zmk_rgb_underglow_set_hsb(struct zmk_led_hsb color);
|
9
app/include/zmk/wpm.h
Normal file
9
app/include/zmk/wpm.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
int zmk_wpm_get_state();
|
|
@ -17,7 +17,7 @@ testcases=$(find $path -name native_posix.keymap -exec dirname \{\} \;)
|
|||
num_cases=$(echo "$testcases" | wc -l)
|
||||
if [ $num_cases -gt 1 ]; then
|
||||
echo "" > ./build/tests/pass-fail.log
|
||||
echo "$testcases" | xargs -l -P 4 ./run-test.sh
|
||||
echo "$testcases" | xargs -L 1 -P 4 ./run-test.sh
|
||||
err=$?
|
||||
sort -k2 ./build/tests/pass-fail.log
|
||||
exit $err
|
||||
|
@ -45,4 +45,4 @@ else
|
|||
echo "PASS: $testcase" >> ./build/tests/pass-fail.log
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -29,7 +29,10 @@ static uint32_t activity_last_uptime;
|
|||
#define MAX_SLEEP_MS CONFIG_ZMK_IDLE_SLEEP_TIMEOUT
|
||||
#endif
|
||||
|
||||
int raise_event() { return ZMK_EVENT_RAISE(create_activity_state_changed(activity_state)); }
|
||||
int raise_event() {
|
||||
return ZMK_EVENT_RAISE(new_zmk_activity_state_changed(
|
||||
(struct zmk_activity_state_changed){.state = activity_state}));
|
||||
}
|
||||
|
||||
int set_state(enum zmk_activity_state state) {
|
||||
if (activity_state == state)
|
||||
|
@ -41,7 +44,7 @@ int set_state(enum zmk_activity_state state) {
|
|||
|
||||
enum zmk_activity_state zmk_activity_get_state() { return activity_state; }
|
||||
|
||||
int activity_event_listener(const struct zmk_event_header *eh) {
|
||||
int activity_event_listener(const zmk_event_t *eh) {
|
||||
activity_last_uptime = k_uptime_get();
|
||||
|
||||
return set_state(ZMK_ACTIVITY_ACTIVE);
|
||||
|
@ -74,7 +77,7 @@ int activity_init() {
|
|||
}
|
||||
|
||||
ZMK_LISTENER(activity, activity_event_listener);
|
||||
ZMK_SUBSCRIPTION(activity, position_state_changed);
|
||||
ZMK_SUBSCRIPTION(activity, sensor_event);
|
||||
ZMK_SUBSCRIPTION(activity, zmk_position_state_changed);
|
||||
ZMK_SUBSCRIPTION(activity, zmk_sensor_event);
|
||||
|
||||
SYS_INIT(activity_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);
|
||||
|
|
|
@ -15,10 +15,15 @@
|
|||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#include <zmk/event_manager.h>
|
||||
#include <zmk/battery.h>
|
||||
#include <zmk/events/battery_state_changed.h>
|
||||
|
||||
const struct device *battery;
|
||||
|
||||
static uint8_t last_state_of_charge = 0;
|
||||
|
||||
uint8_t zmk_battery_state_of_charge() { return last_state_of_charge; }
|
||||
|
||||
static int zmk_battery_update(const struct device *battery) {
|
||||
struct sensor_value state_of_charge;
|
||||
|
||||
|
@ -36,18 +41,23 @@ static int zmk_battery_update(const struct device *battery) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
LOG_DBG("Setting BAS GATT battery level to %d.", state_of_charge.val1);
|
||||
if (last_state_of_charge != state_of_charge.val1) {
|
||||
last_state_of_charge = state_of_charge.val1;
|
||||
|
||||
rc = bt_bas_set_battery_level(state_of_charge.val1);
|
||||
LOG_DBG("Setting BAS GATT battery level to %d.", last_state_of_charge);
|
||||
|
||||
if (rc != 0) {
|
||||
LOG_WRN("Failed to set BAS GATT battery level (err %d)", rc);
|
||||
return rc;
|
||||
rc = bt_bas_set_battery_level(last_state_of_charge);
|
||||
|
||||
if (rc != 0) {
|
||||
LOG_WRN("Failed to set BAS GATT battery level (err %d)", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ZMK_EVENT_RAISE(new_zmk_battery_state_changed(
|
||||
(struct zmk_battery_state_changed){.state_of_charge = last_state_of_charge}));
|
||||
}
|
||||
|
||||
struct battery_state_changed *ev = new_battery_state_changed();
|
||||
ev->state_of_charge = state_of_charge.val1;
|
||||
return ZMK_EVENT_RAISE(ev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void zmk_battery_work(struct k_work *work) {
|
||||
|
|
|
@ -17,6 +17,8 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
|
||||
#include <zmk/ble.h>
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
switch (binding->param1) {
|
||||
|
@ -49,3 +51,5 @@ static const struct behavior_driver_api behavior_bt_driver_api = {
|
|||
|
||||
DEVICE_AND_API_INIT(behavior_bt, DT_INST_LABEL(0), behavior_bt_init, NULL, NULL, APPLICATION,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_bt_driver_api);
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
|
@ -16,6 +16,24 @@
|
|||
#include <logging/log.h>
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static int
|
||||
on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
const struct device *ext_power = device_get_binding("EXT_POWER");
|
||||
if (ext_power == NULL) {
|
||||
LOG_ERR("Unable to retrieve ext_power device: %d", binding->param1);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (binding->param1 == EXT_POWER_TOGGLE_CMD) {
|
||||
binding->param1 = ext_power_get(ext_power) > 0 ? EXT_POWER_OFF_CMD : EXT_POWER_ON_CMD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
const struct device *ext_power = device_get_binding("EXT_POWER");
|
||||
|
@ -49,9 +67,13 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
static int behavior_ext_power_init(const struct device *dev) { return 0; };
|
||||
|
||||
static const struct behavior_driver_api behavior_ext_power_driver_api = {
|
||||
.binding_convert_central_state_dependent_params =
|
||||
on_keymap_binding_convert_central_state_dependent_params,
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(behavior_ext_power, DT_INST_LABEL(0), behavior_ext_power_init, NULL, NULL,
|
||||
APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY, &behavior_ext_power_driver_api);
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include <device.h>
|
||||
#include <drivers/behavior.h>
|
||||
#include <zmk/keys.h>
|
||||
#include <dt-bindings/zmk/keys.h>
|
||||
#include <dt-bindings/zmk/hid_usage_pages.h>
|
||||
#include <logging/log.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/matrix.h>
|
||||
|
@ -17,12 +17,12 @@
|
|||
#include <zmk/event_manager.h>
|
||||
#include <zmk/events/position_state_changed.h>
|
||||
#include <zmk/events/keycode_state_changed.h>
|
||||
#include <zmk/events/modifiers_state_changed.h>
|
||||
#include <zmk/behavior.h>
|
||||
#include <zmk/keymap.h>
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_NODE_EXISTS(DT_DRV_INST(0))
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
#define ZMK_BHV_HOLD_TAP_MAX_HELD 10
|
||||
#define ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS 40
|
||||
|
@ -31,31 +31,42 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
|||
#define ZMK_BHV_HOLD_TAP_POSITION_NOT_USED 9999
|
||||
|
||||
enum flavor {
|
||||
ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED = 0,
|
||||
ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED = 1,
|
||||
ZMK_BHV_HOLD_TAP_FLAVOR_TAP_PREFERRED = 2,
|
||||
FLAVOR_HOLD_PREFERRED,
|
||||
FLAVOR_BALANCED,
|
||||
FLAVOR_TAP_PREFERRED,
|
||||
};
|
||||
|
||||
struct behavior_hold_tap_behaviors {
|
||||
struct zmk_behavior_binding tap;
|
||||
struct zmk_behavior_binding hold;
|
||||
enum status {
|
||||
STATUS_UNDECIDED,
|
||||
STATUS_TAP,
|
||||
STATUS_HOLD_INTERRUPT,
|
||||
STATUS_HOLD_TIMER,
|
||||
};
|
||||
|
||||
enum decision_moment {
|
||||
HT_KEY_UP,
|
||||
HT_OTHER_KEY_DOWN,
|
||||
HT_OTHER_KEY_UP,
|
||||
HT_TIMER_EVENT,
|
||||
HT_QUICK_TAP,
|
||||
};
|
||||
|
||||
struct behavior_hold_tap_config {
|
||||
int tapping_term_ms;
|
||||
struct behavior_hold_tap_behaviors *behaviors;
|
||||
char *hold_behavior_dev;
|
||||
char *tap_behavior_dev;
|
||||
int quick_tap_ms;
|
||||
enum flavor flavor;
|
||||
bool retro_tap;
|
||||
};
|
||||
|
||||
// this data is specific for each hold-tap
|
||||
struct active_hold_tap {
|
||||
int32_t position;
|
||||
// todo: move these params into the config->behaviors->tap and
|
||||
uint32_t param_hold;
|
||||
uint32_t param_tap;
|
||||
int64_t timestamp;
|
||||
bool is_decided;
|
||||
bool is_hold;
|
||||
enum status status;
|
||||
const struct behavior_hold_tap_config *config;
|
||||
struct k_delayed_work work;
|
||||
bool work_is_cancelled;
|
||||
|
@ -69,9 +80,27 @@ struct active_hold_tap {
|
|||
struct active_hold_tap *undecided_hold_tap = NULL;
|
||||
struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {};
|
||||
// We capture most position_state_changed events and some modifiers_state_changed events.
|
||||
const struct zmk_event_header *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {};
|
||||
const zmk_event_t *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {};
|
||||
|
||||
static int capture_event(const struct zmk_event_header *event) {
|
||||
// Keep track of which key was tapped most recently for 'quick_tap_ms'
|
||||
struct last_tapped {
|
||||
int32_t position;
|
||||
int64_t tap_deadline;
|
||||
};
|
||||
|
||||
struct last_tapped last_tapped;
|
||||
|
||||
static void store_last_tapped(struct active_hold_tap *hold_tap) {
|
||||
last_tapped.position = hold_tap->position;
|
||||
last_tapped.tap_deadline = hold_tap->timestamp + hold_tap->config->quick_tap_ms;
|
||||
}
|
||||
|
||||
static bool is_quick_tap(struct active_hold_tap *hold_tap) {
|
||||
return last_tapped.position == hold_tap->position &&
|
||||
last_tapped.tap_deadline > hold_tap->timestamp;
|
||||
}
|
||||
|
||||
static int capture_event(const zmk_event_t *event) {
|
||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
||||
if (captured_events[i] == NULL) {
|
||||
captured_events[i] = event;
|
||||
|
@ -81,17 +110,18 @@ static int capture_event(const struct zmk_event_header *event) {
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static struct position_state_changed *find_captured_keydown_event(uint32_t position) {
|
||||
struct position_state_changed *last_match = NULL;
|
||||
static struct zmk_position_state_changed *find_captured_keydown_event(uint32_t position) {
|
||||
struct zmk_position_state_changed *last_match = NULL;
|
||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
||||
const struct zmk_event_header *eh = captured_events[i];
|
||||
const zmk_event_t *eh = captured_events[i];
|
||||
if (eh == NULL) {
|
||||
return last_match;
|
||||
}
|
||||
if (!is_position_state_changed(eh)) {
|
||||
struct zmk_position_state_changed *position_event = as_zmk_position_state_changed(eh);
|
||||
if (position_event == NULL) {
|
||||
continue;
|
||||
}
|
||||
struct position_state_changed *position_event = cast_position_state_changed(eh);
|
||||
|
||||
if (position_event->position == position && position_event->state) {
|
||||
last_match = position_event;
|
||||
}
|
||||
|
@ -132,7 +162,7 @@ static void release_captured_events() {
|
|||
// [k1_down, k1_up, null, null, null, ...]
|
||||
// now mt2 will start releasing it's own captured positions.
|
||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS; i++) {
|
||||
const struct zmk_event_header *captured_event = captured_events[i];
|
||||
const zmk_event_t *captured_event = captured_events[i];
|
||||
if (captured_event == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -140,14 +170,13 @@ static void release_captured_events() {
|
|||
if (undecided_hold_tap != NULL) {
|
||||
k_msleep(10);
|
||||
}
|
||||
if (is_position_state_changed(captured_event)) {
|
||||
struct position_state_changed *position_event =
|
||||
cast_position_state_changed(captured_event);
|
||||
|
||||
struct zmk_position_state_changed *position_event;
|
||||
struct zmk_keycode_state_changed *modifier_event;
|
||||
if ((position_event = as_zmk_position_state_changed(captured_event)) != NULL) {
|
||||
LOG_DBG("Releasing key position event for position %d %s", position_event->position,
|
||||
(position_event->state ? "pressed" : "released"));
|
||||
} else {
|
||||
struct keycode_state_changed *modifier_event =
|
||||
cast_keycode_state_changed(captured_event);
|
||||
} else if ((modifier_event = as_zmk_keycode_state_changed(captured_event)) != NULL) {
|
||||
LOG_DBG("Releasing mods changed event 0x%02X %s", modifier_event->keycode,
|
||||
(modifier_event->state ? "pressed" : "released"));
|
||||
}
|
||||
|
@ -172,8 +201,7 @@ static struct active_hold_tap *store_hold_tap(uint32_t position, uint32_t param_
|
|||
continue;
|
||||
}
|
||||
active_hold_taps[i].position = position;
|
||||
active_hold_taps[i].is_decided = false;
|
||||
active_hold_taps[i].is_hold = false;
|
||||
active_hold_taps[i].status = STATUS_UNDECIDED;
|
||||
active_hold_taps[i].config = config;
|
||||
active_hold_taps[i].param_hold = param_hold;
|
||||
active_hold_taps[i].param_tap = param_tap;
|
||||
|
@ -185,29 +213,24 @@ static struct active_hold_tap *store_hold_tap(uint32_t position, uint32_t param_
|
|||
|
||||
static void clear_hold_tap(struct active_hold_tap *hold_tap) {
|
||||
hold_tap->position = ZMK_BHV_HOLD_TAP_POSITION_NOT_USED;
|
||||
hold_tap->is_decided = false;
|
||||
hold_tap->is_hold = false;
|
||||
hold_tap->status = STATUS_UNDECIDED;
|
||||
hold_tap->work_is_cancelled = false;
|
||||
}
|
||||
|
||||
enum decision_moment {
|
||||
HT_KEY_UP = 0,
|
||||
HT_OTHER_KEY_DOWN = 1,
|
||||
HT_OTHER_KEY_UP = 2,
|
||||
HT_TIMER_EVENT = 3,
|
||||
};
|
||||
|
||||
static void decide_balanced(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||
switch (event) {
|
||||
case HT_KEY_UP:
|
||||
hold_tap->is_hold = 0;
|
||||
hold_tap->is_decided = true;
|
||||
break;
|
||||
hold_tap->status = STATUS_TAP;
|
||||
return;
|
||||
case HT_OTHER_KEY_UP:
|
||||
hold_tap->status = STATUS_HOLD_INTERRUPT;
|
||||
return;
|
||||
case HT_TIMER_EVENT:
|
||||
hold_tap->is_hold = 1;
|
||||
hold_tap->is_decided = true;
|
||||
break;
|
||||
hold_tap->status = STATUS_HOLD_TIMER;
|
||||
return;
|
||||
case HT_QUICK_TAP:
|
||||
hold_tap->status = STATUS_TAP;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -216,13 +239,14 @@ static void decide_balanced(struct active_hold_tap *hold_tap, enum decision_mome
|
|||
static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||
switch (event) {
|
||||
case HT_KEY_UP:
|
||||
hold_tap->is_hold = 0;
|
||||
hold_tap->is_decided = true;
|
||||
break;
|
||||
hold_tap->status = STATUS_TAP;
|
||||
return;
|
||||
case HT_TIMER_EVENT:
|
||||
hold_tap->is_hold = 1;
|
||||
hold_tap->is_decided = true;
|
||||
break;
|
||||
hold_tap->status = STATUS_HOLD_TIMER;
|
||||
return;
|
||||
case HT_QUICK_TAP:
|
||||
hold_tap->status = STATUS_TAP;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -231,33 +255,113 @@ static void decide_tap_preferred(struct active_hold_tap *hold_tap, enum decision
|
|||
static void decide_hold_preferred(struct active_hold_tap *hold_tap, enum decision_moment event) {
|
||||
switch (event) {
|
||||
case HT_KEY_UP:
|
||||
hold_tap->is_hold = 0;
|
||||
hold_tap->is_decided = true;
|
||||
break;
|
||||
hold_tap->status = STATUS_TAP;
|
||||
return;
|
||||
case HT_OTHER_KEY_DOWN:
|
||||
hold_tap->status = STATUS_HOLD_INTERRUPT;
|
||||
return;
|
||||
case HT_TIMER_EVENT:
|
||||
hold_tap->is_hold = 1;
|
||||
hold_tap->is_decided = true;
|
||||
break;
|
||||
hold_tap->status = STATUS_HOLD_TIMER;
|
||||
return;
|
||||
case HT_QUICK_TAP:
|
||||
hold_tap->status = STATUS_TAP;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline char *flavor_str(enum flavor flavor) {
|
||||
static inline const char *flavor_str(enum flavor flavor) {
|
||||
switch (flavor) {
|
||||
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED:
|
||||
case FLAVOR_HOLD_PREFERRED:
|
||||
return "hold-preferred";
|
||||
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED:
|
||||
case FLAVOR_BALANCED:
|
||||
return "balanced";
|
||||
case ZMK_BHV_HOLD_TAP_FLAVOR_TAP_PREFERRED:
|
||||
case FLAVOR_TAP_PREFERRED:
|
||||
return "tap-preferred";
|
||||
default:
|
||||
return "UNKNOWN FLAVOR";
|
||||
}
|
||||
return "UNKNOWN FLAVOR";
|
||||
}
|
||||
|
||||
static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_moment event_type) {
|
||||
if (hold_tap->is_decided) {
|
||||
static inline const char *status_str(enum status status) {
|
||||
switch (status) {
|
||||
case STATUS_UNDECIDED:
|
||||
return "undecided";
|
||||
case STATUS_HOLD_TIMER:
|
||||
return "hold-timer";
|
||||
case STATUS_HOLD_INTERRUPT:
|
||||
return "hold-interrupt";
|
||||
case STATUS_TAP:
|
||||
return "tap";
|
||||
default:
|
||||
return "UNKNOWN STATUS";
|
||||
}
|
||||
}
|
||||
|
||||
static inline const char *decision_moment_str(enum decision_moment decision_moment) {
|
||||
switch (decision_moment) {
|
||||
case HT_KEY_UP:
|
||||
return "key-up";
|
||||
case HT_OTHER_KEY_DOWN:
|
||||
return "other-key-down";
|
||||
case HT_OTHER_KEY_UP:
|
||||
return "other-key-up";
|
||||
case HT_QUICK_TAP:
|
||||
return "quick-tap";
|
||||
case HT_TIMER_EVENT:
|
||||
return "timer";
|
||||
default:
|
||||
return "UNKNOWN STATUS";
|
||||
}
|
||||
}
|
||||
|
||||
static int press_binding(struct active_hold_tap *hold_tap) {
|
||||
if (hold_tap->config->retro_tap && hold_tap->status == STATUS_HOLD_TIMER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct zmk_behavior_binding_event event = {
|
||||
.position = hold_tap->position,
|
||||
.timestamp = hold_tap->timestamp,
|
||||
};
|
||||
|
||||
struct zmk_behavior_binding binding = {0};
|
||||
if (hold_tap->status == STATUS_HOLD_TIMER || hold_tap->status == STATUS_HOLD_INTERRUPT) {
|
||||
binding.behavior_dev = hold_tap->config->hold_behavior_dev;
|
||||
binding.param1 = hold_tap->param_hold;
|
||||
} else {
|
||||
binding.behavior_dev = hold_tap->config->tap_behavior_dev;
|
||||
binding.param1 = hold_tap->param_tap;
|
||||
store_last_tapped(hold_tap);
|
||||
}
|
||||
return behavior_keymap_binding_pressed(&binding, event);
|
||||
}
|
||||
|
||||
static int release_binding(struct active_hold_tap *hold_tap) {
|
||||
if (hold_tap->config->retro_tap && hold_tap->status == STATUS_HOLD_TIMER) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct zmk_behavior_binding_event event = {
|
||||
.position = hold_tap->position,
|
||||
.timestamp = hold_tap->timestamp,
|
||||
};
|
||||
|
||||
struct zmk_behavior_binding binding = {0};
|
||||
if (hold_tap->status == STATUS_HOLD_TIMER || hold_tap->status == STATUS_HOLD_INTERRUPT) {
|
||||
binding.behavior_dev = hold_tap->config->hold_behavior_dev;
|
||||
binding.param1 = hold_tap->param_hold;
|
||||
} else {
|
||||
binding.behavior_dev = hold_tap->config->tap_behavior_dev;
|
||||
binding.param1 = hold_tap->param_tap;
|
||||
}
|
||||
return behavior_keymap_binding_released(&binding, event);
|
||||
}
|
||||
|
||||
static void decide_hold_tap(struct active_hold_tap *hold_tap,
|
||||
enum decision_moment decision_moment) {
|
||||
if (hold_tap->status != STATUS_UNDECIDED) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -267,41 +371,55 @@ static void decide_hold_tap(struct active_hold_tap *hold_tap, enum decision_mome
|
|||
}
|
||||
|
||||
switch (hold_tap->config->flavor) {
|
||||
case ZMK_BHV_HOLD_TAP_FLAVOR_HOLD_PREFERRED:
|
||||
decide_hold_preferred(hold_tap, event_type);
|
||||
case ZMK_BHV_HOLD_TAP_FLAVOR_BALANCED:
|
||||
decide_balanced(hold_tap, event_type);
|
||||
case ZMK_BHV_HOLD_TAP_FLAVOR_TAP_PREFERRED:
|
||||
decide_tap_preferred(hold_tap, event_type);
|
||||
case FLAVOR_HOLD_PREFERRED:
|
||||
decide_hold_preferred(hold_tap, decision_moment);
|
||||
case FLAVOR_BALANCED:
|
||||
decide_balanced(hold_tap, decision_moment);
|
||||
case FLAVOR_TAP_PREFERRED:
|
||||
decide_tap_preferred(hold_tap, decision_moment);
|
||||
}
|
||||
|
||||
if (!hold_tap->is_decided) {
|
||||
if (hold_tap->status == STATUS_UNDECIDED) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DBG("%d decided %s (%s event %d)", hold_tap->position, hold_tap->is_hold ? "hold" : "tap",
|
||||
flavor_str(hold_tap->config->flavor), event_type);
|
||||
LOG_DBG("%d decided %s (%s decision moment %s)", hold_tap->position,
|
||||
status_str(hold_tap->status), flavor_str(hold_tap->config->flavor),
|
||||
decision_moment_str(decision_moment));
|
||||
undecided_hold_tap = NULL;
|
||||
|
||||
struct zmk_behavior_binding_event event = {
|
||||
.position = hold_tap->position,
|
||||
.timestamp = hold_tap->timestamp,
|
||||
};
|
||||
|
||||
struct zmk_behavior_binding binding;
|
||||
if (hold_tap->is_hold) {
|
||||
binding.behavior_dev = hold_tap->config->behaviors->hold.behavior_dev;
|
||||
binding.param1 = hold_tap->param_hold;
|
||||
binding.param2 = 0;
|
||||
} else {
|
||||
binding.behavior_dev = hold_tap->config->behaviors->tap.behavior_dev;
|
||||
binding.param1 = hold_tap->param_tap;
|
||||
binding.param2 = 0;
|
||||
}
|
||||
behavior_keymap_binding_pressed(&binding, event);
|
||||
press_binding(hold_tap);
|
||||
release_captured_events();
|
||||
}
|
||||
|
||||
static void decide_retro_tap(struct active_hold_tap *hold_tap) {
|
||||
if (!hold_tap->config->retro_tap) {
|
||||
return;
|
||||
}
|
||||
if (hold_tap->status == STATUS_HOLD_TIMER) {
|
||||
release_binding(hold_tap);
|
||||
LOG_DBG("%d retro tap", hold_tap->position);
|
||||
hold_tap->status = STATUS_TAP;
|
||||
press_binding(hold_tap);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_hold_status_for_retro_tap(uint32_t ignore_position) {
|
||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
||||
struct active_hold_tap *hold_tap = &active_hold_taps[i];
|
||||
if (hold_tap->position == ignore_position ||
|
||||
hold_tap->position == ZMK_BHV_HOLD_TAP_POSITION_NOT_USED ||
|
||||
hold_tap->config->retro_tap == false) {
|
||||
continue;
|
||||
}
|
||||
if (hold_tap->status == STATUS_HOLD_TIMER) {
|
||||
LOG_DBG("Update hold tap %d status to hold-interrupt", hold_tap->position);
|
||||
hold_tap->status = STATUS_HOLD_INTERRUPT;
|
||||
press_binding(hold_tap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int on_hold_tap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||
|
@ -324,11 +442,17 @@ static int on_hold_tap_binding_pressed(struct zmk_behavior_binding *binding,
|
|||
LOG_DBG("%d new undecided hold_tap", event.position);
|
||||
undecided_hold_tap = hold_tap;
|
||||
|
||||
if (is_quick_tap(hold_tap)) {
|
||||
decide_hold_tap(hold_tap, HT_QUICK_TAP);
|
||||
}
|
||||
|
||||
// if this behavior was queued we have to adjust the timer to only
|
||||
// wait for the remaining time.
|
||||
int32_t tapping_term_ms_left = (hold_tap->timestamp + cfg->tapping_term_ms) - k_uptime_get();
|
||||
if (tapping_term_ms_left > 0) {
|
||||
k_delayed_work_submit(&hold_tap->work, K_MSEC(tapping_term_ms_left));
|
||||
} else {
|
||||
decide_hold_tap(hold_tap, HT_TIMER_EVENT);
|
||||
}
|
||||
|
||||
return ZMK_BEHAVIOR_OPAQUE;
|
||||
|
@ -350,24 +474,8 @@ static int on_hold_tap_binding_released(struct zmk_behavior_binding *binding,
|
|||
}
|
||||
|
||||
decide_hold_tap(hold_tap, HT_KEY_UP);
|
||||
|
||||
// todo: set up the binding and data items inside of the active_hold_tap struct
|
||||
struct zmk_behavior_binding_event sub_behavior_data = {
|
||||
.position = hold_tap->position,
|
||||
.timestamp = hold_tap->timestamp,
|
||||
};
|
||||
|
||||
struct zmk_behavior_binding sub_behavior_binding;
|
||||
if (hold_tap->is_hold) {
|
||||
sub_behavior_binding.behavior_dev = hold_tap->config->behaviors->hold.behavior_dev;
|
||||
sub_behavior_binding.param1 = hold_tap->param_hold;
|
||||
sub_behavior_binding.param2 = 0;
|
||||
} else {
|
||||
sub_behavior_binding.behavior_dev = hold_tap->config->behaviors->tap.behavior_dev;
|
||||
sub_behavior_binding.param1 = hold_tap->param_tap;
|
||||
sub_behavior_binding.param2 = 0;
|
||||
}
|
||||
behavior_keymap_binding_released(&sub_behavior_binding, sub_behavior_data);
|
||||
decide_retro_tap(hold_tap);
|
||||
release_binding(hold_tap);
|
||||
|
||||
if (work_cancel_result == -EINPROGRESS) {
|
||||
// let the timer handler clean up
|
||||
|
@ -387,8 +495,10 @@ static const struct behavior_driver_api behavior_hold_tap_driver_api = {
|
|||
.binding_released = on_hold_tap_binding_released,
|
||||
};
|
||||
|
||||
static int position_state_changed_listener(const struct zmk_event_header *eh) {
|
||||
struct position_state_changed *ev = cast_position_state_changed(eh);
|
||||
static int position_state_changed_listener(const zmk_event_t *eh) {
|
||||
struct zmk_position_state_changed *ev = as_zmk_position_state_changed(eh);
|
||||
|
||||
update_hold_status_for_retro_tap(ev->position);
|
||||
|
||||
if (undecided_hold_tap == NULL) {
|
||||
LOG_DBG("%d bubble (no undecided hold_tap active)", ev->position);
|
||||
|
@ -428,21 +538,16 @@ static int position_state_changed_listener(const struct zmk_event_header *eh) {
|
|||
return ZMK_EV_EVENT_CAPTURED;
|
||||
}
|
||||
|
||||
static inline bool only_mods(struct keycode_state_changed *ev) {
|
||||
return ev->usage_page == HID_USAGE_KEY && ev->keycode >= HID_USAGE_KEY_KEYBOARD_LEFTCONTROL &&
|
||||
ev->keycode <= HID_USAGE_KEY_KEYBOARD_RIGHT_GUI;
|
||||
}
|
||||
|
||||
static int keycode_state_changed_listener(const struct zmk_event_header *eh) {
|
||||
static int keycode_state_changed_listener(const zmk_event_t *eh) {
|
||||
// we want to catch layer-up events too... how?
|
||||
struct keycode_state_changed *ev = cast_keycode_state_changed(eh);
|
||||
struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh);
|
||||
|
||||
if (undecided_hold_tap == NULL) {
|
||||
// LOG_DBG("0x%02X bubble (no undecided hold_tap active)", ev->keycode);
|
||||
return ZMK_EV_EVENT_BUBBLE;
|
||||
}
|
||||
|
||||
if (!only_mods(ev)) {
|
||||
if (!is_mod(ev->usage_page, ev->keycode)) {
|
||||
// LOG_DBG("0x%02X bubble (not a mod)", ev->keycode);
|
||||
return ZMK_EV_EVENT_BUBBLE;
|
||||
}
|
||||
|
@ -455,19 +560,19 @@ static int keycode_state_changed_listener(const struct zmk_event_header *eh) {
|
|||
return ZMK_EV_EVENT_CAPTURED;
|
||||
}
|
||||
|
||||
int behavior_hold_tap_listener(const struct zmk_event_header *eh) {
|
||||
if (is_position_state_changed(eh)) {
|
||||
int behavior_hold_tap_listener(const zmk_event_t *eh) {
|
||||
if (as_zmk_position_state_changed(eh) != NULL) {
|
||||
return position_state_changed_listener(eh);
|
||||
} else if (is_keycode_state_changed(eh)) {
|
||||
} else if (as_zmk_keycode_state_changed(eh) != NULL) {
|
||||
return keycode_state_changed_listener(eh);
|
||||
}
|
||||
return ZMK_EV_EVENT_BUBBLE;
|
||||
}
|
||||
|
||||
ZMK_LISTENER(behavior_hold_tap, behavior_hold_tap_listener);
|
||||
ZMK_SUBSCRIPTION(behavior_hold_tap, position_state_changed);
|
||||
ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_position_state_changed);
|
||||
// this should be modifiers_state_changed, but unfrotunately that's not implemented yet.
|
||||
ZMK_SUBSCRIPTION(behavior_hold_tap, keycode_state_changed);
|
||||
ZMK_SUBSCRIPTION(behavior_hold_tap, zmk_keycode_state_changed);
|
||||
|
||||
void behavior_hold_tap_timer_work_handler(struct k_work *item) {
|
||||
struct active_hold_tap *hold_tap = CONTAINER_OF(item, struct active_hold_tap, work);
|
||||
|
@ -495,23 +600,14 @@ static int behavior_hold_tap_init(const struct device *dev) {
|
|||
struct behavior_hold_tap_data {};
|
||||
static struct behavior_hold_tap_data behavior_hold_tap_data;
|
||||
|
||||
/* todo: get rid of unused param1 and param2. */
|
||||
#define _TRANSFORM_ENTRY(idx, node) \
|
||||
{ \
|
||||
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \
|
||||
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \
|
||||
(DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
|
||||
.param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \
|
||||
(DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \
|
||||
},
|
||||
|
||||
#define KP_INST(n) \
|
||||
static struct behavior_hold_tap_behaviors behavior_hold_tap_behaviors_##n = { \
|
||||
.hold = _TRANSFORM_ENTRY(0, n).tap = _TRANSFORM_ENTRY(1, n)}; \
|
||||
static struct behavior_hold_tap_config behavior_hold_tap_config_##n = { \
|
||||
.behaviors = &behavior_hold_tap_behaviors_##n, \
|
||||
.tapping_term_ms = DT_INST_PROP(n, tapping_term_ms), \
|
||||
.hold_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 0)), \
|
||||
.tap_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 1)), \
|
||||
.quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \
|
||||
.flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \
|
||||
.retro_tap = DT_INST_PROP(n, retro_tap), \
|
||||
}; \
|
||||
DEVICE_AND_API_INIT(behavior_hold_tap_##n, DT_INST_LABEL(n), behavior_hold_tap_init, \
|
||||
&behavior_hold_tap_data, &behavior_hold_tap_config_##n, APPLICATION, \
|
||||
|
@ -519,4 +615,4 @@ static struct behavior_hold_tap_data behavior_hold_tap_data;
|
|||
|
||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
||||
|
||||
#endif
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
|
@ -22,14 +22,14 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
|||
struct zmk_behavior_binding_event event) {
|
||||
LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1);
|
||||
return ZMK_EVENT_RAISE(
|
||||
keycode_state_changed_from_encoded(binding->param1, true, event.timestamp));
|
||||
zmk_keycode_state_changed_from_encoded(binding->param1, true, event.timestamp));
|
||||
}
|
||||
|
||||
static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
LOG_DBG("position %d keycode 0x%02X", event.position, binding->param1);
|
||||
return ZMK_EVENT_RAISE(
|
||||
keycode_state_changed_from_encoded(binding->param1, false, event.timestamp));
|
||||
zmk_keycode_state_changed_from_encoded(binding->param1, false, event.timestamp));
|
||||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_key_press_driver_api = {
|
||||
|
|
99
app/src/behaviors/behavior_mod_morph.c
Normal file
99
app/src/behaviors/behavior_mod_morph.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The ZMK Contributors
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT zmk_behavior_mod_morph
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/behavior.h>
|
||||
#include <logging/log.h>
|
||||
#include <zmk/behavior.h>
|
||||
|
||||
#include <zmk/matrix.h>
|
||||
#include <zmk/endpoints.h>
|
||||
#include <zmk/event_manager.h>
|
||||
#include <zmk/events/position_state_changed.h>
|
||||
#include <zmk/events/keycode_state_changed.h>
|
||||
#include <zmk/events/modifiers_state_changed.h>
|
||||
#include <zmk/hid.h>
|
||||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
struct behavior_mod_morph_config {
|
||||
struct zmk_behavior_binding normal_binding;
|
||||
struct zmk_behavior_binding morph_binding;
|
||||
zmk_mod_flags_t mods;
|
||||
};
|
||||
|
||||
struct behavior_mod_morph_data {
|
||||
struct zmk_behavior_binding *pressed_binding;
|
||||
};
|
||||
|
||||
static int on_mod_morph_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||
const struct behavior_mod_morph_config *cfg = dev->config;
|
||||
struct behavior_mod_morph_data *data = dev->data;
|
||||
|
||||
if (data->pressed_binding != NULL) {
|
||||
LOG_ERR("Can't press the same mod-morph twice");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (zmk_hid_get_explicit_mods() & cfg->mods) {
|
||||
data->pressed_binding = (struct zmk_behavior_binding *)&cfg->morph_binding;
|
||||
} else {
|
||||
data->pressed_binding = (struct zmk_behavior_binding *)&cfg->normal_binding;
|
||||
}
|
||||
return behavior_keymap_binding_pressed(data->pressed_binding, event);
|
||||
}
|
||||
|
||||
static int on_mod_morph_binding_released(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
const struct device *dev = device_get_binding(binding->behavior_dev);
|
||||
struct behavior_mod_morph_data *data = dev->data;
|
||||
|
||||
if (data->pressed_binding == NULL) {
|
||||
LOG_ERR("Mod-morph already released");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
struct zmk_behavior_binding *pressed_binding = data->pressed_binding;
|
||||
data->pressed_binding = NULL;
|
||||
return behavior_keymap_binding_released(pressed_binding, event);
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
static int behavior_mod_morph_init(const struct device *dev) { return 0; }
|
||||
|
||||
#define _TRANSFORM_ENTRY(idx, node) \
|
||||
{ \
|
||||
.behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(node, bindings, idx)), \
|
||||
.param1 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param1), (0), \
|
||||
(DT_INST_PHA_BY_IDX(node, bindings, idx, param1))), \
|
||||
.param2 = COND_CODE_0(DT_INST_PHA_HAS_CELL_AT_IDX(node, bindings, idx, param2), (0), \
|
||||
(DT_INST_PHA_BY_IDX(node, bindings, idx, param2))), \
|
||||
}
|
||||
|
||||
#define KP_INST(n) \
|
||||
static struct behavior_mod_morph_config behavior_mod_morph_config_##n = { \
|
||||
.normal_binding = _TRANSFORM_ENTRY(0, n), \
|
||||
.morph_binding = _TRANSFORM_ENTRY(1, n), \
|
||||
.mods = DT_INST_PROP(n, mods), \
|
||||
}; \
|
||||
static struct behavior_mod_morph_data behavior_mod_morph_data_##n = {}; \
|
||||
DEVICE_AND_API_INIT(behavior_mod_morph_##n, DT_INST_LABEL(n), behavior_mod_morph_init, \
|
||||
&behavior_mod_morph_data_##n, &behavior_mod_morph_config_##n, APPLICATION, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_mod_morph_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
||||
|
||||
#endif
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
struct behavior_none_config {};
|
||||
struct behavior_none_data {};
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static int behavior_none_init(const struct device *dev) { return 0; };
|
||||
|
||||
|
@ -35,10 +34,7 @@ static const struct behavior_driver_api behavior_none_driver_api = {
|
|||
.binding_released = on_keymap_binding_released,
|
||||
};
|
||||
|
||||
static const struct behavior_none_config behavior_none_config = {};
|
||||
DEVICE_AND_API_INIT(behavior_none, DT_INST_LABEL(0), behavior_none_init, NULL, NULL, APPLICATION,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_none_driver_api);
|
||||
|
||||
static struct behavior_none_data behavior_none_data;
|
||||
|
||||
DEVICE_AND_API_INIT(behavior_none, DT_INST_LABEL(0), behavior_none_init, &behavior_none_data,
|
||||
&behavior_none_config, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&behavior_none_driver_api);
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
|
@ -18,6 +18,8 @@
|
|||
#include <logging/log.h>
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
switch (binding->param1) {
|
||||
|
@ -42,3 +44,5 @@ static const struct behavior_driver_api behavior_outputs_driver_api = {
|
|||
|
||||
DEVICE_AND_API_INIT(behavior_out, DT_INST_LABEL(0), behavior_out_init, NULL, NULL, APPLICATION,
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_outputs_driver_api);
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
struct behavior_reset_config {
|
||||
int type;
|
||||
};
|
||||
|
@ -44,4 +45,6 @@ static const struct behavior_driver_api behavior_reset_driver_api = {
|
|||
&behavior_reset_config_##n, APPLICATION, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_reset_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(RST_INST)
|
||||
DT_INST_FOREACH_STATUS_OKAY(RST_INST)
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
||||
|
|
|
@ -16,13 +16,85 @@
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static int behavior_rgb_underglow_init(const struct device *dev) { return 0; }
|
||||
|
||||
static int
|
||||
on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
switch (binding->param1) {
|
||||
case RGB_TOG_CMD: {
|
||||
bool state;
|
||||
int err = zmk_rgb_underglow_get_state(&state);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to get RGB underglow state (err %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
binding->param1 = state ? RGB_OFF_CMD : RGB_ON_CMD;
|
||||
break;
|
||||
}
|
||||
case RGB_BRI_CMD: {
|
||||
struct zmk_led_hsb color = zmk_rgb_underglow_calc_brt(1);
|
||||
|
||||
binding->param1 = RGB_COLOR_HSB_CMD;
|
||||
binding->param2 = RGB_COLOR_HSB_VAL(color.h, color.s, color.b);
|
||||
break;
|
||||
}
|
||||
case RGB_BRD_CMD: {
|
||||
struct zmk_led_hsb color = zmk_rgb_underglow_calc_brt(-1);
|
||||
|
||||
binding->param1 = RGB_COLOR_HSB_CMD;
|
||||
binding->param2 = RGB_COLOR_HSB_VAL(color.h, color.s, color.b);
|
||||
break;
|
||||
}
|
||||
case RGB_HUI_CMD: {
|
||||
struct zmk_led_hsb color = zmk_rgb_underglow_calc_hue(1);
|
||||
|
||||
binding->param1 = RGB_COLOR_HSB_CMD;
|
||||
binding->param2 = RGB_COLOR_HSB_VAL(color.h, color.s, color.b);
|
||||
break;
|
||||
}
|
||||
case RGB_HUD_CMD: {
|
||||
struct zmk_led_hsb color = zmk_rgb_underglow_calc_hue(-1);
|
||||
|
||||
binding->param1 = RGB_COLOR_HSB_CMD;
|
||||
binding->param2 = RGB_COLOR_HSB_VAL(color.h, color.s, color.b);
|
||||
break;
|
||||
}
|
||||
case RGB_SAI_CMD: {
|
||||
struct zmk_led_hsb color = zmk_rgb_underglow_calc_sat(1);
|
||||
|
||||
binding->param1 = RGB_COLOR_HSB_CMD;
|
||||
binding->param2 = RGB_COLOR_HSB_VAL(color.h, color.s, color.b);
|
||||
break;
|
||||
}
|
||||
case RGB_SAD_CMD: {
|
||||
struct zmk_led_hsb color = zmk_rgb_underglow_calc_sat(-1);
|
||||
|
||||
binding->param1 = RGB_COLOR_HSB_CMD;
|
||||
binding->param2 = RGB_COLOR_HSB_VAL(color.h, color.s, color.b);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_DBG("RGB relative convert to absolute (%d/%d)", binding->param1, binding->param2);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||
struct zmk_behavior_binding_event event) {
|
||||
switch (binding->param1) {
|
||||
case RGB_TOG_CMD:
|
||||
return zmk_rgb_underglow_toggle();
|
||||
case RGB_ON_CMD:
|
||||
return zmk_rgb_underglow_on();
|
||||
case RGB_OFF_CMD:
|
||||
return zmk_rgb_underglow_off();
|
||||
case RGB_HUI_CMD:
|
||||
return zmk_rgb_underglow_change_hue(1);
|
||||
case RGB_HUD_CMD:
|
||||
|
@ -44,8 +116,9 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
|
|||
case RGB_EFR_CMD:
|
||||
return zmk_rgb_underglow_cycle_effect(-1);
|
||||
case RGB_COLOR_HSB_CMD:
|
||||
return zmk_rgb_underglow_set_hsb((binding->param2 >> 16) & 0xFFFF,
|
||||
(binding->param2 >> 8) & 0xFF, binding->param2 & 0xFF);
|
||||
return zmk_rgb_underglow_set_hsb((struct zmk_led_hsb){.h = (binding->param2 >> 16) & 0xFFFF,
|
||||
.s = (binding->param2 >> 8) & 0xFF,
|
||||
.b = binding->param2 & 0xFF});
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
|
@ -57,10 +130,14 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
|
|||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_rgb_underglow_driver_api = {
|
||||
.binding_convert_central_state_dependent_params =
|
||||
on_keymap_binding_convert_central_state_dependent_params,
|
||||
.binding_pressed = on_keymap_binding_pressed,
|
||||
.binding_released = on_keymap_binding_released,
|
||||
};
|
||||
|
||||
DEVICE_AND_API_INIT(behavior_rgb_underglow, DT_INST_LABEL(0), behavior_rgb_underglow_init, NULL,
|
||||
NULL, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
||||
&behavior_rgb_underglow_driver_api);
|
||||
&behavior_rgb_underglow_driver_api);
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
static int behavior_sensor_rotate_key_press_init(const struct device *dev) { return 0; };
|
||||
|
||||
static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding,
|
||||
|
@ -45,12 +47,12 @@ static int on_sensor_binding_triggered(struct zmk_behavior_binding *binding,
|
|||
|
||||
LOG_DBG("SEND %d", keycode);
|
||||
|
||||
ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(keycode, true, timestamp));
|
||||
ZMK_EVENT_RAISE(zmk_keycode_state_changed_from_encoded(keycode, true, timestamp));
|
||||
|
||||
// TODO: Better way to do this?
|
||||
k_msleep(5);
|
||||
|
||||
return ZMK_EVENT_RAISE(keycode_state_changed_from_encoded(keycode, false, timestamp));
|
||||
return ZMK_EVENT_RAISE(zmk_keycode_state_changed_from_encoded(keycode, false, timestamp));
|
||||
}
|
||||
|
||||
static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_api = {
|
||||
|
@ -62,4 +64,6 @@ static const struct behavior_driver_api behavior_sensor_rotate_key_press_driver_
|
|||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||
&behavior_sensor_rotate_key_press_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
||||
DT_INST_FOREACH_STATUS_OKAY(KP_INST)
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue