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); 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/include/zmk/battery.h b/app/include/zmk/battery.h index edc8fd7a070..112e078e417 100644 --- a/app/include/zmk/battery.h +++ b/app/include/zmk/battery.h @@ -7,3 +7,5 @@ #pragma once uint8_t zmk_battery_state_of_charge(void); +bool zmk_battery_is_charging(void); +bool zmk_is_externally_powered(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..bb652b767e6 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) @@ -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()) { + 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 ae79d5f794c..e2ffd677928 100644 --- a/app/src/battery.c +++ b/app/src/battery.c @@ -19,12 +19,23 @@ 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; } +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)); @@ -91,8 +102,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 +125,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 +191,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 +204,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); 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);