From 5a82ebe5dff26dff4c3be24ad0c71a6aa5a9e25e Mon Sep 17 00:00:00 2001 From: zhiayang Date: Fri, 23 Feb 2024 01:27:32 -0500 Subject: [PATCH 1/4] (re)implement charging state support --- app/include/zmk/battery.h | 1 + .../zmk/events/battery_state_changed.h | 4 ++- app/src/activity.c | 4 +-- app/src/battery.c | 33 +++++++++++++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/include/zmk/battery.h b/app/include/zmk/battery.h index edc8fd7a070..8d7abc1912c 100644 --- a/app/include/zmk/battery.h +++ b/app/include/zmk/battery.h @@ -7,3 +7,4 @@ #pragma once uint8_t zmk_battery_state_of_charge(void); +bool zmk_battery_is_charging(void); diff --git a/app/include/zmk/events/battery_state_changed.h b/app/include/zmk/events/battery_state_changed.h index 157490d9849..fe0d33401e7 100644 --- a/app/include/zmk/events/battery_state_changed.h +++ b/app/include/zmk/events/battery_state_changed.h @@ -12,6 +12,7 @@ struct zmk_battery_state_changed { // TODO: Other battery channels uint8_t state_of_charge; + bool is_charging; }; ZMK_EVENT_DECLARE(zmk_battery_state_changed); @@ -20,6 +21,7 @@ struct zmk_peripheral_battery_state_changed { uint8_t source; // TODO: Other battery channels uint8_t state_of_charge; + bool is_charging; }; -ZMK_EVENT_DECLARE(zmk_peripheral_battery_state_changed); \ No newline at end of file +ZMK_EVENT_DECLARE(zmk_peripheral_battery_state_changed); diff --git a/app/src/activity.c b/app/src/activity.c index b109d46d841..78c9ebbb1f0 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -19,7 +19,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include - +#include #include #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) @@ -75,7 +75,7 @@ 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() || zmk_battery_is_charging())) { // Put devices in suspend power mode before sleeping set_state(ZMK_ACTIVITY_SLEEP); diff --git a/app/src/battery.c b/app/src/battery.c index ae79d5f794c..bf37cee8ba5 100644 --- a/app/src/battery.c +++ b/app/src/battery.c @@ -19,12 +19,16 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include #include +#include #include #include +#include static uint8_t last_state_of_charge = 0; +static bool last_battery_is_charging = false; uint8_t zmk_battery_state_of_charge(void) { return last_state_of_charge; } +bool zmk_battery_is_charging(void) { return last_battery_is_charging; } #if DT_HAS_CHOSEN(zmk_battery) static const struct device *const battery = DEVICE_DT_GET(DT_CHOSEN(zmk_battery)); @@ -91,8 +95,19 @@ static int zmk_battery_update(const struct device *battery) { #error "Not a supported reporting fetch mode" #endif - if (last_state_of_charge != state_of_charge.val1) { + // TODO: for now, battery charging is determined solely by USB being plugged in +#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) + const bool batt_is_charging = zmk_usb_is_powered(); +#else + const bool batt_is_charging = false; +#endif + + if (last_state_of_charge != state_of_charge.val1 || + last_battery_is_charging != batt_is_charging) { + last_state_of_charge = state_of_charge.val1; + last_battery_is_charging = batt_is_charging; + #if IS_ENABLED(CONFIG_BT_BAS) LOG_DBG("Setting BAS GATT battery level to %d.", last_state_of_charge); @@ -103,8 +118,10 @@ static int zmk_battery_update(const struct device *battery) { return rc; } #endif - rc = raise_zmk_battery_state_changed( - (struct zmk_battery_state_changed){.state_of_charge = last_state_of_charge}); + rc = raise_zmk_battery_state_changed((struct zmk_battery_state_changed){ + .state_of_charge = last_state_of_charge, + .is_charging = batt_is_charging, + }); } return rc; @@ -167,6 +184,12 @@ static int battery_event_listener(const zmk_event_t *eh) { break; } } +#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) + else if (as_zmk_usb_conn_state_changed(eh)) { + // update the battery on the workqueue if usb connection changed. + k_work_submit_to_queue(zmk_workqueue_lowprio_work_q(), &battery_work); + } +#endif return -ENOTSUP; } @@ -174,4 +197,8 @@ ZMK_LISTENER(battery, battery_event_listener); ZMK_SUBSCRIPTION(battery, zmk_activity_state_changed); +#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) +ZMK_SUBSCRIPTION(battery, zmk_usb_conn_state_changed); +#endif + SYS_INIT(zmk_battery_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); From 5a8d573785b4ce62c55ec5ae6e6b29d640c0f078 Mon Sep 17 00:00:00 2001 From: zhiayang Date: Fri, 23 Feb 2024 01:29:22 -0500 Subject: [PATCH 2/4] update corneish-zen display widget --- .../arm/corneish_zen/widgets/battery_status.c | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/app/boards/arm/corneish_zen/widgets/battery_status.c b/app/boards/arm/corneish_zen/widgets/battery_status.c index 622e39df6f0..d3f2f1c10a2 100644 --- a/app/boards/arm/corneish_zen/widgets/battery_status.c +++ b/app/boards/arm/corneish_zen/widgets/battery_status.c @@ -22,9 +22,7 @@ static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); struct battery_status_state { uint8_t level; -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - bool usb_present; -#endif + bool is_charging; }; LV_IMG_DECLARE(batt_100); @@ -45,17 +43,17 @@ static void set_battery_symbol(lv_obj_t *icon, struct battery_status_state state #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) if (level > 95) { - lv_img_set_src(icon, state.usb_present ? &batt_100_chg : &batt_100); + lv_img_set_src(icon, state.is_charging ? &batt_100_chg : &batt_100); } else if (level > 74) { - lv_img_set_src(icon, state.usb_present ? &batt_75_chg : &batt_75); + lv_img_set_src(icon, state.is_charging ? &batt_75_chg : &batt_75); } else if (level > 49) { - lv_img_set_src(icon, state.usb_present ? &batt_50_chg : &batt_50); + lv_img_set_src(icon, state.is_charging ? &batt_50_chg : &batt_50); } else if (level > 24) { - lv_img_set_src(icon, state.usb_present ? &batt_25_chg : &batt_25); + lv_img_set_src(icon, state.is_charging ? &batt_25_chg : &batt_25); } else if (level > 5) { - lv_img_set_src(icon, state.usb_present ? &batt_5_chg : &batt_5); + lv_img_set_src(icon, state.is_charging ? &batt_5_chg : &batt_5); } else { - lv_img_set_src(icon, state.usb_present ? &batt_0_chg : &batt_0); + lv_img_set_src(icon, state.is_charging ? &batt_0_chg : &batt_0); } #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ } @@ -70,9 +68,7 @@ static struct battery_status_state battery_status_get_state(const zmk_event_t *e return (struct battery_status_state){ .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - .usb_present = zmk_usb_is_powered(), -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ + .is_charging = (ev != NULL) ? ev->is_charging : zmk_battery_is_charging(), }; } @@ -80,9 +76,6 @@ ZMK_DISPLAY_WIDGET_LISTENER(widget_battery_status, struct battery_status_state, battery_status_update_cb, battery_status_get_state) ZMK_SUBSCRIPTION(widget_battery_status, zmk_battery_state_changed); -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) -ZMK_SUBSCRIPTION(widget_battery_status, zmk_usb_conn_state_changed); -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ int zmk_widget_battery_status_init(struct zmk_widget_battery_status *widget, lv_obj_t *parent) { widget->obj = lv_img_create(parent); From 6a3463e7e91b7de676f12a2dd7b9f5790600d0eb Mon Sep 17 00:00:00 2001 From: zhiayang Date: Fri, 23 Feb 2024 01:34:38 -0500 Subject: [PATCH 3/4] update nice_view and default battery widgets --- .../nice_view/widgets/peripheral_status.c | 16 +++++----------- app/boards/shields/nice_view/widgets/status.c | 12 ++---------- app/boards/shields/nice_view/widgets/util.h | 4 +--- app/src/display/widgets/battery_status.c | 16 +++------------- 4 files changed, 11 insertions(+), 37 deletions(-) diff --git a/app/boards/shields/nice_view/widgets/peripheral_status.c b/app/boards/shields/nice_view/widgets/peripheral_status.c index e9002b33e75..c0a368af1cd 100644 --- a/app/boards/shields/nice_view/widgets/peripheral_status.c +++ b/app/boards/shields/nice_view/widgets/peripheral_status.c @@ -56,10 +56,7 @@ static void draw_top(lv_obj_t *widget, lv_color_t cbuf[], const struct status_st static void set_battery_status(struct zmk_widget_status *widget, struct battery_status_state state) { -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - widget->state.charging = state.usb_present; -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ - + widget->state.charging = state.is_charging; widget->state.battery = state.level; draw_top(widget->obj, widget->cbuf, &widget->state); @@ -71,11 +68,11 @@ static void battery_status_update_cb(struct battery_status_state state) { } static struct battery_status_state battery_status_get_state(const zmk_event_t *eh) { + const struct zmk_battery_state_changed *ev = as_zmk_battery_state_changed(eh); + return (struct battery_status_state){ - .level = zmk_battery_state_of_charge(), -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - .usb_present = zmk_usb_is_powered(), -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ + .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), + .is_charging = (ev != NULL) ? ev->is_charging : zmk_battery_is_charging(), }; } @@ -83,9 +80,6 @@ ZMK_DISPLAY_WIDGET_LISTENER(widget_battery_status, struct battery_status_state, battery_status_update_cb, battery_status_get_state) ZMK_SUBSCRIPTION(widget_battery_status, zmk_battery_state_changed); -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) -ZMK_SUBSCRIPTION(widget_battery_status, zmk_usb_conn_state_changed); -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ static struct peripheral_status_state get_state(const zmk_event_t *_eh) { return (struct peripheral_status_state){.connected = zmk_split_bt_peripheral_is_connected()}; diff --git a/app/boards/shields/nice_view/widgets/status.c b/app/boards/shields/nice_view/widgets/status.c index 5cbbd91cd2d..536cb2d567a 100644 --- a/app/boards/shields/nice_view/widgets/status.c +++ b/app/boards/shields/nice_view/widgets/status.c @@ -195,10 +195,7 @@ static void draw_bottom(lv_obj_t *widget, lv_color_t cbuf[], const struct status static void set_battery_status(struct zmk_widget_status *widget, struct battery_status_state state) { -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - widget->state.charging = state.usb_present; -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ - + widget->state.charging = state.is_charging; widget->state.battery = state.level; draw_top(widget->obj, widget->cbuf, &widget->state); @@ -214,9 +211,7 @@ static struct battery_status_state battery_status_get_state(const zmk_event_t *e return (struct battery_status_state){ .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - .usb_present = zmk_usb_is_powered(), -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ + .is_charging = (ev != NULL) ? ev->is_charging : zmk_battery_is_charging(), }; } @@ -224,9 +219,6 @@ ZMK_DISPLAY_WIDGET_LISTENER(widget_battery_status, struct battery_status_state, battery_status_update_cb, battery_status_get_state) ZMK_SUBSCRIPTION(widget_battery_status, zmk_battery_state_changed); -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) -ZMK_SUBSCRIPTION(widget_battery_status, zmk_usb_conn_state_changed); -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ static void set_output_status(struct zmk_widget_status *widget, const struct output_status_state *state) { diff --git a/app/boards/shields/nice_view/widgets/util.h b/app/boards/shields/nice_view/widgets/util.h index fbcb616fad3..7b942de10ba 100644 --- a/app/boards/shields/nice_view/widgets/util.h +++ b/app/boards/shields/nice_view/widgets/util.h @@ -33,9 +33,7 @@ struct status_state { struct battery_status_state { uint8_t level; -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - bool usb_present; -#endif + bool is_charging; }; void rotate_canvas(lv_obj_t *canvas, lv_color_t cbuf[]); diff --git a/app/src/display/widgets/battery_status.c b/app/src/display/widgets/battery_status.c index 22e73fafa9e..51f2b01e99f 100644 --- a/app/src/display/widgets/battery_status.c +++ b/app/src/display/widgets/battery_status.c @@ -21,21 +21,16 @@ static sys_slist_t widgets = SYS_SLIST_STATIC_INIT(&widgets); struct battery_status_state { uint8_t level; -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - bool usb_present; -#endif + bool is_charging; }; static void set_battery_symbol(lv_obj_t *label, struct battery_status_state state) { char text[9] = {}; uint8_t level = state.level; - -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - if (state.usb_present) { + if (state.is_charging) { strcpy(text, LV_SYMBOL_CHARGE " "); } -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ #if IS_ENABLED(CONFIG_ZMK_WIDGET_BATTERY_STATUS_SHOW_PERCENTAGE) char perc[5] = {}; @@ -67,9 +62,7 @@ static struct battery_status_state battery_status_get_state(const zmk_event_t *e return (struct battery_status_state){ .level = (ev != NULL) ? ev->state_of_charge : zmk_battery_state_of_charge(), -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - .usb_present = zmk_usb_is_powered(), -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ + .is_charging = (ev != NULL) ? ev->is_charging : zmk_battery_is_charging(), }; } @@ -77,9 +70,6 @@ ZMK_DISPLAY_WIDGET_LISTENER(widget_battery_status, struct battery_status_state, battery_status_update_cb, battery_status_get_state) ZMK_SUBSCRIPTION(widget_battery_status, zmk_battery_state_changed); -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) -ZMK_SUBSCRIPTION(widget_battery_status, zmk_usb_conn_state_changed); -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ int zmk_widget_battery_status_init(struct zmk_widget_battery_status *widget, lv_obj_t *parent) { widget->obj = lv_label_create(parent); From 8bee741d890ca0f597e07c4e22bee301e50a0f68 Mon Sep 17 00:00:00 2001 From: zhiayang Date: Fri, 23 Feb 2024 01:44:59 -0500 Subject: [PATCH 4/4] add zmk_is_externally_powered --- app/include/zmk/battery.h | 1 + app/src/activity.c | 10 +--------- app/src/battery.c | 7 +++++++ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/include/zmk/battery.h b/app/include/zmk/battery.h index 8d7abc1912c..112e078e417 100644 --- a/app/include/zmk/battery.h +++ b/app/include/zmk/battery.h @@ -8,3 +8,4 @@ uint8_t zmk_battery_state_of_charge(void); bool zmk_battery_is_charging(void); +bool zmk_is_externally_powered(void); diff --git a/app/src/activity.c b/app/src/activity.c index 78c9ebbb1f0..bb652b767e6 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -30,14 +30,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #endif -bool is_usb_power_present(void) { -#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) - return zmk_usb_is_powered(); -#else - return false; -#endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK) */ -} - static enum zmk_activity_state activity_state; static uint32_t activity_last_uptime; @@ -75,7 +67,7 @@ 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() || zmk_battery_is_charging())) { + if (inactive_time > MAX_SLEEP_MS && !zmk_is_externally_powered()) { // Put devices in suspend power mode before sleeping set_state(ZMK_ACTIVITY_SLEEP); diff --git a/app/src/battery.c b/app/src/battery.c index bf37cee8ba5..e2ffd677928 100644 --- a/app/src/battery.c +++ b/app/src/battery.c @@ -29,6 +29,13 @@ static bool last_battery_is_charging = false; uint8_t zmk_battery_state_of_charge(void) { return last_state_of_charge; } bool zmk_battery_is_charging(void) { return last_battery_is_charging; } +bool zmk_is_externally_powered(void) { + bool ret = zmk_battery_is_charging(); +#if IS_ENABLED(CONFIG_USB_DEVICE_STACK) + ret |= zmk_usb_is_powered(); +#endif + return ret; +} #if DT_HAS_CHOSEN(zmk_battery) static const struct device *const battery = DEVICE_DT_GET(DT_CHOSEN(zmk_battery));