#include #include #include #define MODULE display_module #include #include #include #include #include #include #include #include "bat_state_event.h" #include "hid_led_event.h" #include "mode_switch_event.h" #include "theme_color.h" #include "ui/ui_main.h" LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF); BUILD_ASSERT(DT_HAS_CHOSEN(zephyr_display), "Missing zephyr,display chosen node"); BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_ALIAS(backlight), okay), "Missing backlight alias"); static const struct device *const display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); static const struct device *const backlight_dev = DEVICE_DT_GET(DT_PARENT(DT_ALIAS(backlight))); static const uint32_t backlight_idx = DT_NODE_CHILD_IDX(DT_ALIAS(backlight)); static struct ui_main_model ui_model = { .theme_color = LV_COLOR_MAKE(BLINKY_THEME_DEFAULT_R, BLINKY_THEME_DEFAULT_G, BLINKY_THEME_DEFAULT_B), .inactive_border_color = LV_COLOR_MAKE(0x3A, 0x44, 0x52), .mode = MODE_SWITCH_BLE, }; static bool initialized; static bool running; static bool lvgl_initialized; static int backlight_set(bool on) { if (on) { return led_on(backlight_dev, backlight_idx); } return led_off(backlight_dev, backlight_idx); } static int module_init(void) { int err; LOG_INF("Display init on %s", display_dev->name); if (!device_is_ready(display_dev)) { LOG_ERR("Display device %s not ready", display_dev->name); return -ENODEV; } if (!device_is_ready(backlight_dev)) { LOG_ERR("Backlight device %s not ready", backlight_dev->name); return -ENODEV; } err = backlight_set(false); if (err) { LOG_ERR("Backlight off failed (%d)", err); return err; } return 0; } static int module_start(void) { int err; if (running) { return 0; } if (!lvgl_initialized) { err = lvgl_init(); if (err) { LOG_ERR("lvgl_init failed (%d)", err); return err; } lvgl_initialized = true; lvgl_lock(); ui_main_init(&ui_model, "WH Mini", "Hello World"); lvgl_unlock(); } err = backlight_set(true); if (err) { LOG_ERR("Backlight enable failed (%d)", err); return err; } err = display_blanking_off(display_dev); if (err) { LOG_ERR("display_blanking_off failed (%d)", err); (void)backlight_set(false); return err; } running = true; LOG_INF("LVGL display started"); return 0; } static void module_pause(void) { if (!running) { return; } (void)display_blanking_on(display_dev); (void)backlight_set(false); running = false; LOG_INF("LVGL display paused"); } static void refresh_ui(void) { if (!lvgl_initialized) { return; } lvgl_lock(); ui_main_refresh_all(&ui_model, "WH Mini", "Hello World"); lvgl_unlock(); } static bool app_event_handler(const struct app_event_header *aeh) { if (is_bat_state_event(aeh)) { const struct bat_state_event *event = cast_bat_state_event(aeh); ui_model.battery_level = event->soc; ui_model.charging = event->charging; ui_model.full = event->full; refresh_ui(); return false; } if (is_mode_switch_event(aeh)) { const struct mode_switch_event *event = cast_mode_switch_event(aeh); ui_model.mode = event->mode; refresh_ui(); return false; } if (is_hid_led_event(aeh)) { const struct hid_led_event *event = cast_hid_led_event(aeh); ui_model.led_mask = event->led_bm; refresh_ui(); return false; } if (is_module_state_event(aeh)) { const struct module_state_event *event = cast_module_state_event(aeh); int err; if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) { if (!initialized) { err = module_init(); if (err) { module_set_state(MODULE_STATE_ERROR); return false; } initialized = true; } err = module_start(); if (err) { module_set_state(MODULE_STATE_ERROR); } else { module_set_state(MODULE_STATE_READY); } } return false; } if (is_power_down_event(aeh)) { if (initialized) { module_pause(); module_set_state(MODULE_STATE_STANDBY); } return false; } if (is_wake_up_event(aeh)) { if (initialized) { int err = module_start(); if (err) { module_set_state(MODULE_STATE_ERROR); } else { module_set_state(MODULE_STATE_READY); } } return false; } return false; } APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, bat_state_event); APP_EVENT_SUBSCRIBE(MODULE, hid_led_event); APP_EVENT_SUBSCRIBE(MODULE, module_state_event); APP_EVENT_SUBSCRIBE(MODULE, mode_switch_event); APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event); APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);