mirror of https://github.com/zmkfirmware/zmk.git
feat: Change Boot Magic Key -> Combo
This commit is contained in:
parent
f88c8bb9e7
commit
8b1eb38bed
|
|
@ -105,7 +105,7 @@ target_sources_ifdef(CONFIG_ZMK_USB app PRIVATE src/usb_hid.c)
|
|||
target_sources_ifdef(CONFIG_ZMK_RGB_UNDERGLOW app PRIVATE src/rgb_underglow.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_BACKLIGHT app PRIVATE src/backlight.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_LOW_PRIORITY_WORK_QUEUE app PRIVATE src/workqueue.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_BOOT_MAGIC_KEY app PRIVATE src/boot_magic_key.c)
|
||||
target_sources_ifdef(CONFIG_ZMK_BOOT_MAGIC_COMBO app PRIVATE src/boot_magic_combo.c)
|
||||
target_sources(app PRIVATE src/main.c)
|
||||
|
||||
add_subdirectory(src/display/)
|
||||
|
|
|
|||
|
|
@ -691,13 +691,13 @@ config ZMK_KEYMAP_SENSORS_DEFAULT_TRIGGERS_PER_ROTATION
|
|||
|
||||
endif # ZMK_KEYMAP_SENSORS
|
||||
|
||||
config ZMK_BOOT_MAGIC_KEY
|
||||
config ZMK_BOOT_MAGIC_COMBO
|
||||
bool "Enable actions when keys are held at boot"
|
||||
default y
|
||||
depends on DT_HAS_ZMK_BOOT_MAGIC_KEY_ENABLED
|
||||
depends on DT_HAS_ZMK_BOOT_MAGIC_COMBO_ENABLED
|
||||
|
||||
config ZMK_BOOT_MAGIC_KEY_TIMEOUT_MS
|
||||
int "Milliseconds to wait for a boot magic key at startup"
|
||||
config ZMK_BOOT_MAGIC_COMBO_TIMEOUT_MS
|
||||
int "Milliseconds to wait for a boot magic combo at startup"
|
||||
default 500
|
||||
|
||||
module = ZMK
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
|
||||
description: |
|
||||
Triggers one or more actions if a specific key is held while the keyboard boots.
|
||||
Triggers one or more actions if a combination of keys is held while the keyboard boots.
|
||||
This is typically used for recovering a keyboard in cases such as &bootloader
|
||||
being missing from the keymap or a split peripheral which isn't connected to
|
||||
the central, and therefore can't process the keymap.
|
||||
|
||||
compatible: "zmk,boot-magic-key"
|
||||
compatible: "zmk,boot-magic-combo"
|
||||
|
||||
properties:
|
||||
key-position:
|
||||
type: int
|
||||
default: 0
|
||||
description: Zero-based index of the key which triggers the action(s).
|
||||
combo-positions:
|
||||
type: array
|
||||
required: true
|
||||
description: Zero-based indices of the keys which must be simultaneously pressed to trigger the action(s).
|
||||
# Boot magic actions:
|
||||
jump-to-bootloader:
|
||||
type: boolean
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT zmk_boot_magic_key
|
||||
#define DT_DRV_COMPAT zmk_boot_magic_combo
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/devicetree.h>
|
||||
|
|
@ -25,25 +25,38 @@
|
|||
|
||||
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
|
||||
|
||||
#define _COMBO_LEN(inst) uint8_t _CONCAT(_len_, inst)[DT_INST_PROP_LEN(inst, combo_positions)];
|
||||
#define MAX_BOOT_COMBO_LEN sizeof(union {DT_INST_FOREACH_STATUS_OKAY(_COMBO_LEN)})
|
||||
|
||||
struct boot_key_config {
|
||||
uint16_t key_position;
|
||||
const uint16_t *combo_positions;
|
||||
uint8_t combo_positions_len;
|
||||
bool jump_to_bootloader;
|
||||
bool reset_settings;
|
||||
};
|
||||
|
||||
#define BOOT_KEY_COMBO_POSITIONS(n) \
|
||||
static const uint16_t boot_key_combo_positions_##n[] = DT_INST_PROP(n, combo_positions);
|
||||
|
||||
#define BOOT_KEY_CONFIG(n) \
|
||||
BOOT_KEY_COMBO_POSITIONS(n) \
|
||||
{ \
|
||||
.key_position = DT_INST_PROP_OR(n, key_position, 0), \
|
||||
.combo_positions = boot_key_combo_positions_##n, \
|
||||
.combo_positions_len = DT_INST_PROP_LEN(n, combo_positions), \
|
||||
.jump_to_bootloader = DT_INST_PROP_OR(n, jump_to_bootloader, false), \
|
||||
.reset_settings = DT_INST_PROP_OR(n, reset_settings, false), \
|
||||
},
|
||||
|
||||
static const struct boot_key_config boot_keys[] = {DT_INST_FOREACH_STATUS_OKAY(BOOT_KEY_CONFIG)};
|
||||
static struct boot_key_config boot_keys[] = {DT_INST_FOREACH_STATUS_OKAY(BOOT_KEY_CONFIG)};
|
||||
|
||||
static bool boot_key_states[ARRAY_SIZE(boot_keys)][MAX_BOOT_COMBO_LEN] = {};
|
||||
|
||||
static int64_t timeout_uptime;
|
||||
|
||||
static int timeout_init(const struct device *device) {
|
||||
timeout_uptime = k_uptime_get() + CONFIG_ZMK_BOOT_MAGIC_KEY_TIMEOUT_MS;
|
||||
timeout_uptime = k_uptime_get() + CONFIG_ZMK_BOOT_MAGIC_COMBO_TIMEOUT_MS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -79,10 +92,28 @@ static int event_listener(const zmk_event_t *eh) {
|
|||
}
|
||||
|
||||
const struct zmk_position_state_changed *ev = as_zmk_position_state_changed(eh);
|
||||
if (ev && ev->state) {
|
||||
for (int i = 0; i < ARRAY_SIZE(boot_keys); i++) {
|
||||
if (ev->position == boot_keys[i].key_position) {
|
||||
trigger_boot_key(&boot_keys[i]);
|
||||
if (!ev) {
|
||||
return ZMK_EV_EVENT_BUBBLE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(boot_keys); i++) {
|
||||
const struct boot_key_config *config = &boot_keys[i];
|
||||
for (int j = 0; j < config->combo_positions_len; j++) {
|
||||
if (ev->position == config->combo_positions[j]) {
|
||||
boot_key_states[i][j] = ev->state;
|
||||
if (ev->state) {
|
||||
bool all_keys_pressed = true;
|
||||
for (int k = 0; k < config->combo_positions_len; k++) {
|
||||
if (!boot_key_states[i][k]) {
|
||||
all_keys_pressed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all_keys_pressed) {
|
||||
trigger_boot_key(config);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -90,5 +121,7 @@ static int event_listener(const zmk_event_t *eh) {
|
|||
return ZMK_EV_EVENT_BUBBLE;
|
||||
}
|
||||
|
||||
ZMK_LISTENER(boot_magic_key, event_listener);
|
||||
ZMK_SUBSCRIPTION(boot_magic_key, zmk_position_state_changed);
|
||||
ZMK_LISTENER(boot_magic_combo, event_listener);
|
||||
ZMK_SUBSCRIPTION(boot_magic_combo, zmk_position_state_changed);
|
||||
|
||||
#endif /* DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) */
|
||||
|
|
@ -16,7 +16,7 @@ Definition file: [zmk/app/Kconfig](https://github.com/zmkfirmware/zmk/blob/main/
|
|||
| Config | Type | Description | Default |
|
||||
| -------------------------------------- | ------ | ------------------------------------------------------------------------------------- | ------- |
|
||||
| `CONFIG_ZMK_KEYBOARD_NAME` | string | The name of the keyboard (max 16 characters) | |
|
||||
| `CONFIG_ZMK_BOOT_MAGIC_KEY_TIMEOUT_MS` | int | Milliseconds to watch for [boot magic keys](../features/boot-magic-key.md) at startup | 500 |
|
||||
| `CONFIG_ZMK_BOOT_MAGIC_COMBO_TIMEOUT_MS` | int | Milliseconds to watch for [boot magic combos](../features/boot-magic-combo.md) at startup | 500 |
|
||||
| `CONFIG_ZMK_WPM` | bool | Enable calculating words per minute | n |
|
||||
| `CONFIG_HEAP_MEM_POOL_SIZE` | int | Size of the heap memory pool | 8192 |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
---
|
||||
title: Boot Magic Key
|
||||
sidebar_label: Boot Magic Key
|
||||
title: Boot Magic Combo
|
||||
sidebar_label: Boot Magic Combo
|
||||
---
|
||||
|
||||
A boot magic key performs one or more actions if a specific key is held while powering on the keyboard. This is useful for recovering a keyboard which doesn't have a physical reset button. It also works on the peripheral side of a split keyboard, even when it isn't connected to the central side.
|
||||
A boot magic combo performs one or more actions if a combination of keys is held while powering on the keyboard. This is useful for recovering a keyboard which doesn't have a physical reset button. It also works on the peripheral side of a split keyboard, even when it isn't connected to the central side.
|
||||
|
||||
## Magic Keys
|
||||
|
||||
To define a boot magic key on a new board or shield, add a `zmk,boot-magic-key` node to your board's `.dts` file or shield's `.overlay` file and select which key will trigger it with the `key-position` property.
|
||||
To define a boot magic combo on a new board or shield, add a `zmk,boot-magic-combo` node to your board's `.dts` file or shield's `.overlay` file and select which keys will trigger it with the `combo-positions` property. All keys in the combo must be held simultaneously to trigger the action.
|
||||
|
||||
You can also enable the feature for any keyboard by adding it to your `.keymap` file.
|
||||
|
||||
|
|
@ -15,8 +15,8 @@ You can also enable the feature for any keyboard by adding it to your `.keymap`
|
|||
/ {
|
||||
...
|
||||
bootloader_key: bootloader_key {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
key-position = <0>;
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
combo-positions = <0 1>;
|
||||
};
|
||||
...
|
||||
};
|
||||
|
|
@ -26,21 +26,21 @@ You can also enable the feature for any keyboard by adding it to your `.keymap`
|
|||
|
||||
Key positions are numbered like the keys in your keymap, starting at 0. So, if the first key in your keymap is `Q`, this key is in position `0`. The next key (possibly `W`) will have position 1, etcetera.
|
||||
|
||||
:::
|
||||
The `combo-positions` property accepts an array of key positions. All keys in the array must be held simultaneously during boot to trigger the action.
|
||||
|
||||
If `key-position` is omitted, it will trigger for the key in position `0`.
|
||||
:::
|
||||
|
||||
Next, you should add properties to determine what the magic key will do:
|
||||
|
||||
### Jump to Bootloader
|
||||
|
||||
If a boot magic key has a `jump-to-bootloader` property, it will reboot to the bootloader:
|
||||
If a boot magic combo has a `jump-to-bootloader` property, it will reboot to the bootloader:
|
||||
|
||||
```c
|
||||
/ {
|
||||
...
|
||||
bootloader_key: bootloader_key {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
...
|
||||
jump-to-bootloader;
|
||||
};
|
||||
|
|
@ -50,13 +50,13 @@ If a boot magic key has a `jump-to-bootloader` property, it will reboot to the b
|
|||
|
||||
### Reset Settings
|
||||
|
||||
If a boot magic key has a `reset-settings` property, it will reset persistent settings and then reboot:
|
||||
If a boot magic combo has a `reset-settings` property, it will reset persistent settings and then reboot:
|
||||
|
||||
```c
|
||||
/ {
|
||||
...
|
||||
reset_settings_key: reset_settings_key {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
...
|
||||
reset-settings;
|
||||
};
|
||||
|
|
@ -78,7 +78,7 @@ Currently this action _only_ clears BLE bonds. It will be updated to reset all s
|
|||
|
||||
## Multiple Actions
|
||||
|
||||
If you want a single boot magic key to perform multiple actions, simply add properties for each action to the same `zmk,boot-magic-key` node. The order of the properties does not matter.
|
||||
If you want a single boot magic combo to perform multiple actions, simply add properties for each action to the same `zmk,boot-magic-combo` node. The order of the properties does not matter.
|
||||
|
||||
For example, to make a key that resets settings and then reboots to the bootloader, add both `reset-settings` and `jump-to-bootloader`:
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ For example, to make a key that resets settings and then reboots to the bootload
|
|||
/ {
|
||||
...
|
||||
recovery_key: recovery_key {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
jump-to-bootloader;
|
||||
reset-settings;
|
||||
};
|
||||
|
|
@ -96,13 +96,13 @@ For example, to make a key that resets settings and then reboots to the bootload
|
|||
|
||||
:::info
|
||||
|
||||
You may define multiple `zmk,boot-magic-key` nodes for different keys, but note that if you hold multiple keys at boot, they will be run in an arbitrary order. If one of them reboots the keyboard, the rest of the keys will not run.
|
||||
You may define multiple `zmk,boot-magic-combo` nodes for different keys, but note that if you hold multiple keys at boot, they will be run in an arbitrary order. If one of them reboots the keyboard, the rest of the keys will not run.
|
||||
|
||||
:::
|
||||
|
||||
## Split Keyboards
|
||||
|
||||
For split keyboards, you can define multiple boot magic keys and then only enable the correct key(s) for each side. For example, if key 0 is the top-left key on the left side and key 11 is the top-right key on the right side, you could use:
|
||||
For split keyboards, you can define multiple boot magic combos and then only enable the correct key(s) for each side. For example, if key 0 is the top-left key on the left side and key 11 is the top-right key on the right side, you could use:
|
||||
|
||||
**shield.dtsi**
|
||||
|
||||
|
|
@ -110,15 +110,15 @@ For split keyboards, you can define multiple boot magic keys and then only enabl
|
|||
/ {
|
||||
...
|
||||
bootloader_key_left: bootloader_key_left {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
key-position = <0>;
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
combo-positions = <0>;
|
||||
jump-to-bootloader;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
bootloader_key_right: bootloader_key_right {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
key-position = <11>;
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
combo-positions = <11>;
|
||||
jump-to-bootloader;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
@ -150,7 +150,7 @@ For split keyboards, you can define multiple boot magic keys and then only enabl
|
|||
|
||||
Key positions are affected by the [matrix transform](../config/kscan.md#matrix-transform), so if your keyboard has multiple transforms for alternate layouts, you may need to adjust positions according to the user's selected transform. There is no automatic way to do this, but one way to simplify things for users is to add a block of commented out code to the keymap which selects the transform and updates the key positions to match if uncommented.
|
||||
|
||||
For example, consider a split keyboard which has 6 columns per side by default but supports a 5-column layout, and assume you want the top-left key on the left side and the top-right key on the right side to be boot magic keys. The top-left key will be position 0 regardless of layout, but the top-right key will be position 11 by default and position 9 in the 5-column layout.
|
||||
For example, consider a split keyboard which has 6 columns per side by default but supports a 5-column layout, and assume you want the top-left key on the left side and the top-right key on the right side to be boot magic combos. The top-left key will be position 0 regardless of layout, but the top-right key will be position 11 by default and position 9 in the 5-column layout.
|
||||
|
||||
**shield.dtsi**
|
||||
|
||||
|
|
@ -161,15 +161,15 @@ For example, consider a split keyboard which has 6 columns per side by default b
|
|||
};
|
||||
|
||||
bootloader_key_left: bootloader_key_left {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
key-position = <0>;
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
combo-positions = <0>;
|
||||
jump-to-bootloader;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
bootloader_key_right: bootloader_key_right {
|
||||
compatible = "zmk,boot-magic-key";
|
||||
key-position = <11>;
|
||||
compatible = "zmk,boot-magic-combo";
|
||||
combo-positions = <11>;
|
||||
jump-to-bootloader;
|
||||
status = "disabled";
|
||||
};
|
||||
|
|
@ -186,24 +186,24 @@ For example, consider a split keyboard which has 6 columns per side by default b
|
|||
// zmk,matrix_transform = &five_column_transform;
|
||||
// };
|
||||
// bootloader_key_right {
|
||||
// key-position = <9>;
|
||||
// combo-positions = <9>;
|
||||
// };
|
||||
// };
|
||||
```
|
||||
|
||||
## Startup Timeout
|
||||
|
||||
By default, the keyboard processes boot magic keys for 500 ms. You can change this timeout with `CONFIG_ZMK_BOOT_MAGIC_KEY_TIMEOUT_MS` if it isn't reliably triggering, for example if you have some board-specific initialization code which takes a while.
|
||||
By default, the keyboard processes boot magic combos for 500 ms. You can change this timeout with `CONFIG_ZMK_BOOT_MAGIC_COMBO_TIMEOUT_MS` if it isn't reliably triggering, for example if you have some board-specific initialization code which takes a while.
|
||||
|
||||
To change the value for a new board or shield, set this option in your `Kconfig.defconfig` file:
|
||||
|
||||
```
|
||||
config ZMK_BOOT_MAGIC_KEY_TIMEOUT_MS
|
||||
config ZMK_BOOT_MAGIC_COMBO_TIMEOUT_MS
|
||||
default 1000
|
||||
```
|
||||
|
||||
You can also set it from your keyboard's `.conf` file in a user config repo:
|
||||
|
||||
```ini
|
||||
CONFIG_ZMK_BOOT_MAGIC_KEY_TIMEOUT_MS=1000
|
||||
CONFIG_ZMK_BOOT_MAGIC_COMBO_TIMEOUT_MS=1000
|
||||
```
|
||||
Loading…
Reference in New Issue