From 8af876c094d65f81410c790767818cd901fc31cf Mon Sep 17 00:00:00 2001 From: Chengxin Wang Date: Sat, 26 Aug 2023 10:53:13 +0000 Subject: [PATCH] feat(ble): automatically turn off BLE indicator doing so will balance power usage for the left and right parts, as previously the BLE indicator stays on for the left half all the time. --- app/Kconfig | 4 +++ app/include/zmk/ble.h | 4 +++ app/src/ble.c | 4 +++ app/src/rgb_underglow.c | 60 +++++++++++++++++++++++++++++++++++--- docs/docs/config/system.md | 6 +++- 5 files changed, 73 insertions(+), 5 deletions(-) diff --git a/app/Kconfig b/app/Kconfig index 75bceaff910..3b6d4963ea1 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -172,6 +172,10 @@ config ZMK_HANDLE_BLE_DISCONNECTION bool "Experimental: Respect user disconnection request from computer" default n +config ZMK_BLE_INDICATOR_AUTO_OFF + bool "Experimental: automatically turn off BLE indicator" + default n + config BT_PERIPHERAL_PREF_MIN_INT default 6 diff --git a/app/include/zmk/ble.h b/app/include/zmk/ble.h index 99ca0c99ca6..25121b4e10b 100644 --- a/app/include/zmk/ble.h +++ b/app/include/zmk/ble.h @@ -38,3 +38,7 @@ int zmk_ble_unpair_all(); bt_addr_le_t *zmk_ble_get_peripheral_addr(); int zmk_ble_put_peripheral_addr(const bt_addr_le_t *addr); #endif /* IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL) */ + +#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) +bool ble_seeking_connection(); +#endif diff --git a/app/src/ble.c b/app/src/ble.c index f2b228ce1d6..7b92be6f009 100644 --- a/app/src/ble.c +++ b/app/src/ble.c @@ -106,6 +106,10 @@ bool zmk_ble_active_profile_is_open() { return !bt_addr_le_cmp(&profiles[active_profile].peer, BT_ADDR_LE_ANY); } +#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) +bool ble_seeking_connection() { return active_profile_seeking_connection; } +#endif + void set_profile_address(uint8_t index, const bt_addr_le_t *addr) { char setting_name[15]; char addr_str[BT_ADDR_LE_STR_LEN]; diff --git a/app/src/rgb_underglow.c b/app/src/rgb_underglow.c index 2bb53b2c598..6b8aa9c4e70 100644 --- a/app/src/rgb_underglow.c +++ b/app/src/rgb_underglow.c @@ -84,8 +84,14 @@ static struct rgb_underglow_state state; static struct zmk_periph_led led_data; #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) -static bool last_ble_state[2]; -#endif + +static bool last_ble_state[3]; + +#if IS_ENABLED(CONFIG_ZMK_BLE_INDICATOR_AUTO_OFF) +bool reset_auto_off_counter = true; +#endif /* CONFIG_ZMK_BLE_INDICATOR_AUTO_OFF */ + +#endif /* CONFIG_ZMK_SPLIT_BLE */ static bool triggered; @@ -261,6 +267,9 @@ static void zmk_rgb_underglow_effect_kinesis() { } // blink second led slowly if bluetooth not paired, quickly if not connected if (zmk_ble_active_profile_is_open()) { +#if IS_ENABLED(CONFIG_ZMK_BLE_INDICATOR_AUTO_OFF) + reset_auto_off_counter = true; +#endif pixels[1].r = pixels[1].r * last_ble_state[0]; pixels[1].g = pixels[1].g * last_ble_state[0]; pixels[1].b = pixels[1].b * last_ble_state[0]; @@ -270,6 +279,27 @@ static void zmk_rgb_underglow_effect_kinesis() { } state.animation_step++; } else if (!zmk_ble_active_profile_is_connected()) { +#if IS_ENABLED(CONFIG_ZMK_BLE_INDICATOR_AUTO_OFF) + reset_auto_off_counter = true; +#endif + +#if IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) + /* only blink the led when BLE is advertising for connection */ + if (ble_seeking_connection()) { + pixels[1].r = pixels[1].r * last_ble_state[1]; + pixels[1].g = pixels[1].g * last_ble_state[1]; + pixels[1].b = pixels[1].b * last_ble_state[1]; + if (state.animation_step > 14) { + last_ble_state[1] = !last_ble_state[1]; + state.animation_step = 0; + } + state.animation_step++; + } else { + pixels[1].r = 0; + pixels[1].g = 0; + pixels[1].b = 0; + } +#else /* IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) */ pixels[1].r = pixels[1].r * last_ble_state[1]; pixels[1].g = pixels[1].g * last_ble_state[1]; pixels[1].b = pixels[1].b * last_ble_state[1]; @@ -278,7 +308,29 @@ static void zmk_rgb_underglow_effect_kinesis() { state.animation_step = 0; } state.animation_step++; +#endif /* IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) */ } +#if IS_ENABLED(CONFIG_ZMK_BLE_INDICATOR_AUTO_OFF) + else { // ble is connected + if (led_data.layer == 3) { // when mod key is pressed, + // show current BLE profile for few seconds and then off + reset_auto_off_counter = true; + } + if (reset_auto_off_counter) { + state.animation_step = 0; + last_ble_state[2] = true; + reset_auto_off_counter = false; + } + pixels[1].r = pixels[1].r * last_ble_state[2]; + pixels[1].g = pixels[1].g * last_ble_state[2]; + pixels[1].b = pixels[1].b * last_ble_state[2]; + if (state.animation_step > 84) { + last_ble_state[2] = false; + } else { + state.animation_step++; + } + } +#endif /* IS_ENABLED(CONFIG_ZMK_HANDLE_BLE_DISCONNECTION) */ // set third led as layer state switch (led_data.layer) { case 0: @@ -330,7 +382,7 @@ static void zmk_rgb_underglow_effect_kinesis() { if (old_led_data.layer != led_data.layer || old_led_data.indicators != led_data.indicators) { zmk_rgb_underglow_central_send(); } -#else +#else /* ZMK_BLE_IS_CENTRAL */ #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) // leds for peripheral(right) side /* if (zmk_ble_active_profile_is_open()) { @@ -431,7 +483,7 @@ static void zmk_rgb_underglow_effect_kinesis() { #if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE) } #endif -#endif +#endif /* ZMK_BLE_IS_CENTRAL */ } static void zmk_rgb_underglow_effect_test() { diff --git a/docs/docs/config/system.md b/docs/docs/config/system.md index b4235a17eea..0e05cb0daf1 100644 --- a/docs/docs/config/system.md +++ b/docs/docs/config/system.md @@ -78,8 +78,12 @@ for more information on configuring Bluetooth. | `CONFIG_ZMK_BLE_THREAD_STACK_SIZE` | int | Stack size of the BLE notify thread | 512 | | `CONFIG_ZMK_BLE_PASSKEY_ENTRY` | bool | Experimental: require typing passkey from host to pair BLE connection | n | | `CONFIG_ZMK_HANDLE_BLE_DISCONNECTION` | bool | Experimental: respect user BLE disconnection request from computer | n | +| `CONFIG_ZMK_BLE_INDICATOR_AUTO_OFF` | bool | Experimental (Adv360): only show BLE profile indicator when triggered | n | -Note that `CONFIG_BT_MAX_CONN` and `CONFIG_BT_MAX_PAIRED` should be set to the same value. On a split keyboard they should only be set for the central and must be set to one greater than the desired number of bluetooth profiles. +Note: + +1. `CONFIG_BT_MAX_CONN` and `CONFIG_BT_MAX_PAIRED` should be set to the same value. On a split keyboard they should only be set for the central and must be set to one greater than the desired number of bluetooth profiles. +2. When `CONFIG_ZMK_BLE_INDICATOR_AUTO_OFF=y`, the BLE indicator will automatically turn off when there is no Bluetooth related activity. It will also be triggered to show the current BLE profile number when the 'Mod' key is pressed on the Adv360. ### Logging