From dc45ee4e20156887103d5c1f85e9a12cffbd944a Mon Sep 17 00:00:00 2001 From: Mayunk Kulkarni Date: Sun, 24 Nov 2024 18:13:41 -0800 Subject: [PATCH] feat(sleep): Option to enter deep sleep after BLE connection severed Introduce a new Kconfig flag to enable enter SLEEP mode on device if BT connection severed from main active profile --- app/Kconfig | 13 +++++++++ app/include/zmk/split/bluetooth/peripheral.h | 5 +++- app/src/activity.c | 30 +++++++++++++++++++- app/src/behaviors/behavior_soft_off.c | 3 +- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index b0ffc72ac02..4a710fb5068 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -449,6 +449,19 @@ config ZMK_IDLE_SLEEP_TIMEOUT #ZMK_SLEEP endif +config ZMK_SLEEP_ON_BLE_DISCONNECT + bool "Enable deep sleep on BLE disconnection" + depends on ZMK_SLEEP + +if ZMK_SLEEP_ON_BLE_DISCONNECT + +config ZMK_SLEEP_DISCONNECT_TIMER + int "Milliseconds of disconnection before entering deep sleep" + default 600000 + +# ZMK_SLEEP_ON_BLE_DISCONNECT +endif + config ZMK_EXT_POWER bool "Enable support to control external power output" default y diff --git a/app/include/zmk/split/bluetooth/peripheral.h b/app/include/zmk/split/bluetooth/peripheral.h index 44ac8062a51..8a4252ed60f 100644 --- a/app/include/zmk/split/bluetooth/peripheral.h +++ b/app/include/zmk/split/bluetooth/peripheral.h @@ -6,6 +6,9 @@ #pragma once +#define IS_SPLIT_PERIPHERAL \ + (IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)) + bool zmk_split_bt_peripheral_is_connected(void); -bool zmk_split_bt_peripheral_is_bonded(void); \ No newline at end of file +bool zmk_split_bt_peripheral_is_bonded(void); diff --git a/app/src/activity.c b/app/src/activity.c index 454e91e5da0..841ba8a5409 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -4,10 +4,13 @@ * SPDX-License-Identifier: MIT */ +#include "zephyr/sys/util_macro.h" #include #include #include #include +#include +#include #include @@ -26,8 +29,29 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #endif +#if IS_ENABLED(CONFIG_ZMK_SLEEP_ON_BLE_DISCONNECT) +#define MAX_DISCONNECT_MS CONFIG_ZMK_SLEEP_DISCONNECT_TIMER + +static uint32_t ble_last_time_connected; + +static uint32_t get_latest_ble_connection_active_timestamp(void) { +#if ZMK_BLE_IS_CENTRAL || !IS_ENABLED(CONFIG_ZMK_SPLIT) + if (zmk_ble_active_profile_is_connected()) { + ble_last_time_connected = k_uptime_get(); + } + return ble_last_time_connected; +#elif IS_SPLIT_PERIPHERAL + if (zmk_split_bt_peripheral_is_connected()) { + ble_last_time_connected = k_uptime_get(); + } + return ble_last_time_connected; +#endif +} +#endif + bool is_usb_power_present(void) { #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) + return false; return zmk_usb_is_powered(); #else return false; @@ -69,7 +93,11 @@ 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 && !is_usb_power_present()) { + if ((inactive_time > MAX_SLEEP_MS && !is_usb_power_present()) +#if IS_ENABLED(CONFIG_ZMK_SLEEP_ON_BLE_DISCONNECT) + || (current - get_latest_ble_connection_active_timestamp()) > MAX_DISCONNECT_MS +#endif + ) { // Put devices in suspend power mode before sleeping set_state(ZMK_ACTIVITY_SLEEP); diff --git a/app/src/behaviors/behavior_soft_off.c b/app/src/behaviors/behavior_soft_off.c index fcffd09ae5e..5b8f5b2a29c 100644 --- a/app/src/behaviors/behavior_soft_off.c +++ b/app/src/behaviors/behavior_soft_off.c @@ -12,6 +12,7 @@ #include #include +#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -24,8 +25,6 @@ struct behavior_soft_off_data { uint32_t press_start; }; -#define IS_SPLIT_PERIPHERAL \ - (IS_ENABLED(CONFIG_ZMK_SPLIT) && !IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)) static int behavior_soft_off_init(const struct device *dev) { return 0; };