underglow-layer: track layer changes with event & battery life optimization
I tried using event instead of the 25ms underglow_tick to update the underglow on layer change only. That didn't improve the battery life much.... The second change is cutting off the led strip power if the underglow is not defined for a layer. Power is restored if a layer with rgb is activated, and cut off as soon as the layer is disabled. This, on the other hand, improves the battery life a lot, especially if you don't use rgb on your base layer. If you are using rgb on your base layer, setting CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE is highly recommended.
This commit is contained in:
parent
6f9a411793
commit
0ca086a845
8 changed files with 61 additions and 16 deletions
|
|
@ -96,6 +96,7 @@ target_sources_ifdef(CONFIG_ZMK_BATTERY_REPORTING app PRIVATE src/battery.c)
|
||||||
target_sources_ifdef(CONFIG_ZMK_HID_INDICATORS app PRIVATE src/events/hid_indicators_changed.c)
|
target_sources_ifdef(CONFIG_ZMK_HID_INDICATORS app PRIVATE src/events/hid_indicators_changed.c)
|
||||||
|
|
||||||
target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_peripheral_status_changed.c)
|
target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_peripheral_status_changed.c)
|
||||||
|
target_sources_ifdef(CONFIG_ZMK_SPLIT app PRIVATE src/events/split_peripheral_layer_changed.c)
|
||||||
add_subdirectory_ifdef(CONFIG_ZMK_SPLIT src/split)
|
add_subdirectory_ifdef(CONFIG_ZMK_SPLIT src/split)
|
||||||
|
|
||||||
target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/usb.c)
|
target_sources_ifdef(CONFIG_USB_DEVICE_STACK app PRIVATE src/usb.c)
|
||||||
|
|
|
||||||
16
app/include/zmk/events/split_peripheral_layer_changed.h
Normal file
16
app/include/zmk/events/split_peripheral_layer_changed.h
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zmk/event_manager.h>
|
||||||
|
|
||||||
|
struct zmk_split_peripheral_layer_changed {
|
||||||
|
uint32_t layers;
|
||||||
|
};
|
||||||
|
|
||||||
|
ZMK_EVENT_DECLARE(zmk_split_peripheral_layer_changed);
|
||||||
|
|
@ -14,5 +14,5 @@
|
||||||
(DT_FOREACH_CHILD(DT_INST(0, zmk_underglow_layer), ZMK_RGB_CHILD_LEN_PLUS_ONE) 0)
|
(DT_FOREACH_CHILD(DT_INST(0, zmk_underglow_layer), ZMK_RGB_CHILD_LEN_PLUS_ONE) 0)
|
||||||
|
|
||||||
const int zmk_rgbmap_id(uint8_t layer);
|
const int zmk_rgbmap_id(uint8_t layer);
|
||||||
uint32_t *rgb_underglow_get_bindings(void);
|
uint32_t *rgb_underglow_get_bindings(uint8_t layer);
|
||||||
uint8_t rgb_underglow_top_layer(void);
|
uint8_t rgb_underglow_top_layer_with_state(uint32_t state_to_test);
|
||||||
10
app/src/events/split_peripheral_layer_changed.c
Normal file
10
app/src/events/split_peripheral_layer_changed.c
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 The ZMK Contributors
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zmk/events/split_peripheral_layer_changed.h>
|
||||||
|
|
||||||
|
ZMK_EVENT_IMPL(zmk_split_peripheral_layer_changed);
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#include <zmk/events/activity_state_changed.h>
|
#include <zmk/events/activity_state_changed.h>
|
||||||
#include <zmk/events/usb_conn_state_changed.h>
|
#include <zmk/events/usb_conn_state_changed.h>
|
||||||
#include <zmk/workqueue.h>
|
#include <zmk/workqueue.h>
|
||||||
|
#include <zmk/events/split_peripheral_layer_changed.h>
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING)
|
#if IS_ENABLED(CONFIG_ZMK_SPLIT_BLE_CENTRAL_BATTERY_LEVEL_FETCHING)
|
||||||
#include <zmk/split/central.h>
|
#include <zmk/split/central.h>
|
||||||
|
|
@ -467,15 +468,19 @@ static void zmk_rgb_underglow_apply_rgbmap(uint32_t rgbmap[], size_t rgbmap_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_rgb_underglow_set_layer(void) {
|
static void zmk_rgb_underglow_set_layer(uint8_t layer) {
|
||||||
uint32_t *rgbmap = rgb_underglow_get_bindings();
|
state.on = true;
|
||||||
|
uint32_t *rgbmap = rgb_underglow_get_bindings(layer);
|
||||||
if (rgbmap != NULL) {
|
if (rgbmap != NULL) {
|
||||||
zmk_rgb_underglow_apply_rgbmap(rgbmap, ZMK_KEYMAP_LEN);
|
zmk_rgb_underglow_apply_rgbmap(rgbmap, ZMK_KEYMAP_LEN);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
|
||||||
pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0};
|
pixels[i] = (struct led_rgb){r : 0, g : 0, b : 0};
|
||||||
}
|
}
|
||||||
|
state.on = false;
|
||||||
}
|
}
|
||||||
|
zmk_led_write_pixels();
|
||||||
|
zmk_rgb_set_ext_power();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zmk_rgb_underglow_tick(struct k_work *work) {
|
static void zmk_rgb_underglow_tick(struct k_work *work) {
|
||||||
|
|
@ -493,7 +498,7 @@ static void zmk_rgb_underglow_tick(struct k_work *work) {
|
||||||
zmk_rgb_underglow_effect_swirl();
|
zmk_rgb_underglow_effect_swirl();
|
||||||
break;
|
break;
|
||||||
case UNDERGLOW_EFFECT_LAYER_INDICATORS:
|
case UNDERGLOW_EFFECT_LAYER_INDICATORS:
|
||||||
zmk_rgb_underglow_set_layer();
|
//zmk_rgb_underglow_set_layer();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,7 +508,7 @@ static void zmk_rgb_underglow_tick(struct k_work *work) {
|
||||||
K_WORK_DEFINE(underglow_tick_work, zmk_rgb_underglow_tick);
|
K_WORK_DEFINE(underglow_tick_work, zmk_rgb_underglow_tick);
|
||||||
|
|
||||||
static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) {
|
static void zmk_rgb_underglow_tick_handler(struct k_timer *timer) {
|
||||||
if (!state.on) {
|
if (!state.on && state.current_effect == UNDERGLOW_EFFECT_LAYER_INDICATORS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -860,6 +865,15 @@ static int rgb_underglow_event_listener(const zmk_event_t *eh) {
|
||||||
if (as_zmk_activity_state_changed(eh)) {
|
if (as_zmk_activity_state_changed(eh)) {
|
||||||
return rgb_underglow_auto_state(zmk_activity_get_state() == ZMK_ACTIVITY_ACTIVE);
|
return rgb_underglow_auto_state(zmk_activity_get_state() == ZMK_ACTIVITY_ACTIVE);
|
||||||
}
|
}
|
||||||
|
if (as_zmk_split_peripheral_layer_changed(eh)) {
|
||||||
|
const struct zmk_split_peripheral_layer_changed *ev = as_zmk_split_peripheral_layer_changed(eh);
|
||||||
|
LOG_DBG("zmk_split_peripheral_layer_changed: %08x", ev->layers);
|
||||||
|
|
||||||
|
uint8_t layer = rgb_underglow_top_layer_with_state(ev->layers);
|
||||||
|
LOG_DBG("top layer: %d", layer);
|
||||||
|
zmk_rgb_underglow_set_layer(layer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
||||||
|
|
@ -877,6 +891,7 @@ ZMK_LISTENER(rgb_underglow, rgb_underglow_event_listener);
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE)
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_IDLE)
|
||||||
ZMK_SUBSCRIPTION(rgb_underglow, zmk_activity_state_changed);
|
ZMK_SUBSCRIPTION(rgb_underglow, zmk_activity_state_changed);
|
||||||
|
ZMK_SUBSCRIPTION(rgb_underglow, zmk_split_peripheral_layer_changed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
#if IS_ENABLED(CONFIG_ZMK_RGB_UNDERGLOW_AUTO_OFF_USB)
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,7 @@ const int zmk_rgbmap_id(uint8_t layer) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *rgb_underglow_get_bindings(void) {
|
uint32_t *rgb_underglow_get_bindings(uint8_t layer) {
|
||||||
uint8_t layer = rgb_underglow_top_layer();
|
|
||||||
int rgblayer = zmk_rgbmap_id(layer);
|
int rgblayer = zmk_rgbmap_id(layer);
|
||||||
if (rgblayer == -1){
|
if (rgblayer == -1){
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -51,15 +50,12 @@ uint32_t *rgb_underglow_get_bindings(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rgb_underglow_top_layer(void) {
|
uint8_t rgb_underglow_top_layer_with_state(uint32_t state_to_test) {
|
||||||
for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) {
|
for (uint8_t layer = ZMK_KEYMAP_LAYERS_LEN - 1; layer > 0; layer--) {
|
||||||
#if IS_ENABLED(CONFIG_ZMK_SPLIT_ROLE_CENTRAL)
|
if ((state_to_test & (BIT(layer))) == (BIT(layer)) || layer == 0) {
|
||||||
if (zmk_keymap_layer_active(layer)) {
|
|
||||||
#else
|
|
||||||
if (peripheral_layer_active(layer)) {
|
|
||||||
#endif
|
|
||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
// return default layer (0)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
#include <zmk/pointing/input_split.h>
|
#include <zmk/pointing/input_split.h>
|
||||||
#include <zmk/hid_indicators_types.h>
|
#include <zmk/hid_indicators_types.h>
|
||||||
#include <zmk/physical_layouts.h>
|
#include <zmk/physical_layouts.h>
|
||||||
|
#include <zmk/events/split_peripheral_layer_changed.h>
|
||||||
|
|
||||||
static int start_scanning(void);
|
static int start_scanning(void);
|
||||||
|
|
||||||
|
|
@ -1175,6 +1176,9 @@ static void split_central_update_layers_callback(struct k_work *work) {
|
||||||
LOG_ERR("Failed to send layers to peripheral (err %d)", err);
|
LOG_ERR("Failed to send layers to peripheral (err %d)", err);
|
||||||
} else {
|
} else {
|
||||||
LOG_DBG("Sent Layers over to peripheral");
|
LOG_DBG("Sent Layers over to peripheral");
|
||||||
|
raise_zmk_split_peripheral_layer_changed(
|
||||||
|
(struct zmk_split_peripheral_layer_changed){.layers = layers});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
|
||||||
|
|
||||||
#include <zmk/events/sensor_event.h>
|
#include <zmk/events/sensor_event.h>
|
||||||
#include <zmk/sensors.h>
|
#include <zmk/sensors.h>
|
||||||
|
#include <zmk/events/split_peripheral_layer_changed.h>
|
||||||
|
|
||||||
#if ZMK_KEYMAP_HAS_SENSORS
|
#if ZMK_KEYMAP_HAS_SENSORS
|
||||||
static struct sensor_event last_sensor_event;
|
static struct sensor_event last_sensor_event;
|
||||||
|
|
@ -144,7 +145,9 @@ static uint32_t layers = 0;
|
||||||
|
|
||||||
static void split_svc_update_layers_callback(struct k_work *work) {
|
static void split_svc_update_layers_callback(struct k_work *work) {
|
||||||
LOG_DBG("Setting peripheral layers: %x", layers);
|
LOG_DBG("Setting peripheral layers: %x", layers);
|
||||||
set_peripheral_layers_state(layers);
|
// set_peripheral_layers_state(layers);
|
||||||
|
raise_zmk_split_peripheral_layer_changed(
|
||||||
|
(struct zmk_split_peripheral_layer_changed){.layers = layers});
|
||||||
}
|
}
|
||||||
|
|
||||||
static K_WORK_DEFINE(split_svc_update_layers_work, split_svc_update_layers_callback);
|
static K_WORK_DEFINE(split_svc_update_layers_work, split_svc_update_layers_callback);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue