From 00101d60f3fb98a82e571abbd1cd5c1c59461220 Mon Sep 17 00:00:00 2001 From: liquidraver <504870+liquidraver@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:37:32 +0100 Subject: [PATCH] thinknode M1 (and e-ink) display fixes (partial refresh, msg count, etc) --- zephcore/helpers/ui/display.c | 9 +++++---- zephcore/helpers/ui/ui_task.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/zephcore/helpers/ui/display.c b/zephcore/helpers/ui/display.c index 635a926..2d3dc64 100644 --- a/zephcore/helpers/ui/display.c +++ b/zephcore/helpers/ui/display.c @@ -212,13 +212,14 @@ int mc_display_init(void) /* Clear CPU-side framebuffer (zeroes the RAM buffer — no SPI transfer). */ cfb_framebuffer_clear(disp_dev, false); - /* OLED: push the blank frame to hardware and unblank. - * EPD: skip — the first ui_pages_render() will push real content via - * partial refresh (fast, no visible flash). */ + /* Unblank the display so the driver uses partial refresh for all + * subsequent renders (ssd16xx: partial_refresh = !blanking_on). + * OLED: also push a blank frame first to clear stale VRAM. + * EPD: skip the frame push — partial refresh will write real content. */ if (!is_epd) { cfb_framebuffer_finalize(disp_dev); - display_blanking_off(disp_dev); } + display_blanking_off(disp_dev); backlight_set(true); disp_on = true; disp_initialized = true; diff --git a/zephcore/helpers/ui/ui_task.c b/zephcore/helpers/ui/ui_task.c index ebbdf1b..7a79a76 100644 --- a/zephcore/helpers/ui/ui_task.c +++ b/zephcore/helpers/ui/ui_task.c @@ -213,7 +213,9 @@ static void render_work_handler(struct k_work *work) } #ifdef CONFIG_ZEPHCORE_UI_DISPLAY - if (mc_display_is_on() && !splash_active) { + /* EPD: render even when backlight is off — content is always visible. + * OLED: only render when display is on (screen is black when off). */ + if ((mc_display_is_on() || mc_display_is_epd()) && !splash_active) { ui_pages_render(); } #endif @@ -955,11 +957,33 @@ void ui_set_msg_count(uint16_t count) { struct ui_state *s = get_state(); + if (s->msg_count == count) { + return; + } + s->msg_count = count; - if (ui_initialized) { + if (!ui_initialized) { + return; + } + + /* Always render when the display is already on (user is looking). */ +#ifdef CONFIG_ZEPHCORE_UI_DISPLAY + if (mc_display_is_on()) { + schedule_render(); + return; + } +#endif + + /* EPD is bistable and readable without backlight. If the user is parked + * on the messages page, update the count silently via partial refresh + * without waking the backlight. Any other page: leave it for the next + * button press to avoid a pointless flash. */ +#ifdef CONFIG_ZEPHCORE_UI_DISPLAY + if (mc_display_is_epd() && ui_pages_current() == UI_PAGE_MESSAGES) { schedule_render(); } +#endif } void ui_set_ble_status(bool connected, const char *name)