From 471d693f3acb7e308e98ab7baa215c46cef06e99 Mon Sep 17 00:00:00 2001 From: KemoNine Date: Sat, 30 Jan 2021 05:34:38 +0000 Subject: [PATCH] feat(behaviors): implement a &sleep behavior that'll put a keyboard to sleep prior to timeout --- app/CMakeLists.txt | 1 + app/dts/behaviors.dtsi | 1 + app/dts/behaviors/sleep.dtsi | 15 ++++++++++ .../behaviors/zmk,behavior-sleep.yaml | 8 +++++ app/include/zmk/activity.h | 3 +- app/src/activity.c | 13 ++++---- app/src/behaviors/behavior_sleep.c | 30 +++++++++++++++++++ 7 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 app/dts/behaviors/sleep.dtsi create mode 100644 app/dts/bindings/behaviors/zmk,behavior-sleep.yaml create mode 100644 app/src/behaviors/behavior_sleep.c diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index e283487f..76d2aa02 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -44,6 +44,7 @@ target_sources_ifdef(CONFIG_USB app PRIVATE src/events/usb_conn_state_changed.c) if ((NOT CONFIG_ZMK_SPLIT) OR CONFIG_ZMK_SPLIT_BLE_ROLE_CENTRAL) target_sources(app PRIVATE src/behaviors/behavior_key_press.c) target_sources(app PRIVATE src/behaviors/behavior_reset.c) + target_sources(app PRIVATE src/behaviors/behavior_sleep.c) 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) diff --git a/app/dts/behaviors.dtsi b/app/dts/behaviors.dtsi index 4333ceea..44cfb6ff 100644 --- a/app/dts/behaviors.dtsi +++ b/app/dts/behaviors.dtsi @@ -14,3 +14,4 @@ #include #include #include +#include diff --git a/app/dts/behaviors/sleep.dtsi b/app/dts/behaviors/sleep.dtsi new file mode 100644 index 00000000..a3f964fc --- /dev/null +++ b/app/dts/behaviors/sleep.dtsi @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +/ { + behaviors { + sleep: behavior_sleep { + compatible = "zmk,behavior-sleep"; + label = "SLEEP"; + #binding-cells = <0>; + }; + }; +}; diff --git a/app/dts/bindings/behaviors/zmk,behavior-sleep.yaml b/app/dts/bindings/behaviors/zmk,behavior-sleep.yaml new file mode 100644 index 00000000..baad15d0 --- /dev/null +++ b/app/dts/bindings/behaviors/zmk,behavior-sleep.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2020 The ZMK Contributors +# SPDX-License-Identifier: MIT + +description: Sleep Binding Behavior + +compatible: "zmk,behavior-sleep" + +include: zero_param.yaml diff --git a/app/include/zmk/activity.h b/app/include/zmk/activity.h index 9c858b15..173e5025 100644 --- a/app/include/zmk/activity.h +++ b/app/include/zmk/activity.h @@ -8,4 +8,5 @@ enum zmk_activity_state { ZMK_ACTIVITY_ACTIVE, ZMK_ACTIVITY_IDLE, ZMK_ACTIVITY_SLEEP }; -enum zmk_activity_state zmk_activity_get_state(); \ No newline at end of file +enum zmk_activity_state zmk_activity_get_state(); +int activity_set_state(enum zmk_activity_state state); diff --git a/app/src/activity.c b/app/src/activity.c index 0661b270..d4d23243 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -34,7 +34,8 @@ int raise_event() { (struct zmk_activity_state_changed){.state = activity_state})); } -int set_state(enum zmk_activity_state state) { +int activity_set_state(enum zmk_activity_state state) { + LOG_DBG("Setting activity state: %i", state); if (activity_state == state) return 0; @@ -47,19 +48,21 @@ enum zmk_activity_state zmk_activity_get_state() { return activity_state; } int activity_event_listener(const zmk_event_t *eh) { activity_last_uptime = k_uptime_get(); - return set_state(ZMK_ACTIVITY_ACTIVE); + return activity_set_state(ZMK_ACTIVITY_ACTIVE); } void activity_work_handler(struct k_work *work) { int32_t current = k_uptime_get(); int32_t inactive_time = current - activity_last_uptime; #if IS_ENABLED(CONFIG_ZMK_SLEEP) - if (inactive_time > MAX_SLEEP_MS) { - set_state(ZMK_ACTIVITY_SLEEP); + // Second half of || statement is to ensure a user using &sleep doesn't lose sleep state when + // the idle or sleep timers expire + if (inactive_time > MAX_SLEEP_MS || activity_state == ZMK_ACTIVITY_SLEEP) { + activity_set_state(ZMK_ACTIVITY_SLEEP); } else #endif /* IS_ENABLED(CONFIG_ZMK_SLEEP) */ if (inactive_time > MAX_IDLE_MS) { - set_state(ZMK_ACTIVITY_IDLE); + activity_set_state(ZMK_ACTIVITY_IDLE); } } diff --git a/app/src/behaviors/behavior_sleep.c b/app/src/behaviors/behavior_sleep.c new file mode 100644 index 00000000..7419dbd6 --- /dev/null +++ b/app/src/behaviors/behavior_sleep.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 The ZMK Contributors + * + * SPDX-License-Identifier: MIT + */ + +#define DT_DRV_COMPAT zmk_behavior_sleep + +#include +#include +#include + +#include +#include + +LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); + +static int behavior_sleep_init(const struct device *dev) { return 0; }; + +static int on_keymap_binding_released(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event) { + return activity_set_state(ZMK_ACTIVITY_SLEEP); +} + +static const struct behavior_driver_api behavior_sleep_driver_api = { + .binding_released = on_keymap_binding_released, +}; + +DEVICE_AND_API_INIT(behavior_sleep, DT_INST_LABEL(0), behavior_sleep_init, NULL, NULL, APPLICATION, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &behavior_sleep_driver_api); \ No newline at end of file