feat(behaviors): Add retention boot mode to reset.

Support new generic Zephyr retention boot mode API in the reset
behavior.
This commit is contained in:
Peter Johanson 2024-12-02 00:27:48 -07:00
parent c94f52147d
commit bf323bf577
3 changed files with 29 additions and 2 deletions

View File

@ -19,6 +19,7 @@
bootloader: bootload {
compatible = "zmk,behavior-reset";
type = <RST_UF2>;
bootloader;
#binding-cells = <0>;
display-name = "Bootloader";
};

View File

@ -11,3 +11,5 @@ properties:
type:
type: int
default: 0
bootloader:
type: boolean

View File

@ -14,11 +14,21 @@
#include <zmk/behavior.h>
#if IS_ENABLED(CONFIG_RETENTION_BOOT_MODE)
#include <zephyr/retention/bootmode.h>
#endif /* IS_ENABLED(CONFIG_RETENTION_BOOT_MODE) */
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
#if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
struct behavior_reset_config {
#if IS_ENABLED(CONFIG_RETENTION_BOOT_MODE)
enum BOOT_MODE_TYPES boot_mode;
#else
int type;
#endif /* IS_ENABLED(CONFIG_RETENTION_BOOT_MODE) */
};
static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
@ -26,10 +36,20 @@ static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
const struct device *dev = zmk_behavior_get_binding(binding->behavior_dev);
const struct behavior_reset_config *cfg = dev->config;
// TODO: Correct magic code for going into DFU?
#if IS_ENABLED(CONFIG_RETENTION_BOOT_MODE)
int ret = bootmode_set(cfg->boot_mode);
if (ret < 0) {
LOG_ERR("Failed to set the bootloader mode (%d)", ret);
return ZMK_BEHAVIOR_OPAQUE;
}
sys_reboot(SYS_REBOOT_WARM);
#else
// See
// https://github.com/adafruit/Adafruit_nRF52_Bootloader/blob/d6b28e66053eea467166f44875e3c7ec741cb471/src/main.c#L107
sys_reboot(cfg->type);
#endif /* IS_ENABLED(CONFIG_RETENTION_BOOT_MODE) */
return ZMK_BEHAVIOR_OPAQUE;
}
@ -43,7 +63,11 @@ static const struct behavior_driver_api behavior_reset_driver_api = {
#define RST_INST(n) \
static const struct behavior_reset_config behavior_reset_config_##n = { \
.type = DT_INST_PROP(n, type)}; \
COND_CODE_1( \
IS_ENABLED(CONFIG_RETENTION_BOOT_MODE), \
(DT_INST_PROP(n, bootloader) ? BOOT_MODE_TYPE_BOOTLOADER : BOOT_MODE_TYPE_NORMAL), \
(.type = DT_INST_PROP(n, type))), \
}; \
BEHAVIOR_DT_INST_DEFINE(n, NULL, NULL, NULL, &behavior_reset_config_##n, POST_KERNEL, \
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_reset_driver_api);