From 02ca35130d3244bf10298f9b2fd2af83ad4d41a3 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 | 3 +- app/src/battery.c | 33 +++++++++++++++++-- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/app/include/zmk/battery.h b/app/include/zmk/battery.h index edc8fd7a..8d7abc19 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 157490d9..fe0d3340 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 8f421f85..ba9ee5f9 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -20,6 +20,7 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include +#include #include #if IS_ENABLED(CONFIG_USB_DEVICE_STACK) @@ -126,7 +127,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 1295f822..6efb275f 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)); @@ -51,8 +55,19 @@ static int zmk_battery_update(const struct device *battery) { return rc; } - 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); @@ -63,8 +78,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; @@ -127,6 +144,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; } @@ -134,4 +157,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 670ddb2b8c41944fb3f9527e969bd25a63237e98 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 | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/app/boards/arm/corneish_zen/widgets/battery_status.c b/app/boards/arm/corneish_zen/widgets/battery_status.c index 39b811b5..d3f2f1c1 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) */ } @@ -68,11 +66,9 @@ 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) { + 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 4bdbd29b015be78be475c4bfe422a2b91ce23273 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 | 18 ++++++------------ app/boards/shields/nice_view/widgets/status.c | 14 +++----------- app/boards/shields/nice_view/widgets/util.h | 4 +--- app/src/display/widgets/battery_status.c | 18 ++++-------------- 4 files changed, 14 insertions(+), 40 deletions(-) diff --git a/app/boards/shields/nice_view/widgets/peripheral_status.c b/app/boards/shields/nice_view/widgets/peripheral_status.c index b9da1996..c0a368af 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) { - 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) */ + const struct zmk_battery_state_changed *ev = as_zmk_battery_state_changed(eh); + + return (struct battery_status_state){ + .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 061b7127..e6ff02c8 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); @@ -212,11 +209,9 @@ 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) { + 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 fbcb616f..7b942de1 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 bec6964b..51f2b01e 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] = {}; @@ -65,11 +60,9 @@ 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) { + 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 54fae8a18a7dd76f5ffb7b2d9c3d04615268f3a8 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 8d7abc19..112e078e 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 ba9ee5f9..7b8855dd 100644 --- a/app/src/activity.c +++ b/app/src/activity.c @@ -84,14 +84,6 @@ static void zmk_pm_resume_devices(void) { #endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */ #endif /* CONFIG_PM_DEVICE */ -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; @@ -127,7 +119,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 6efb275f..60640565 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));