eink full redraw after 8 partial to avoid ghosting

This commit is contained in:
liquidraver
2026-06-15 10:52:25 +02:00
parent 5fc8fd1ead
commit 109ad4ef1e
2 changed files with 37 additions and 1 deletions
+14
View File
@@ -736,6 +736,20 @@ config ZEPHCORE_DISPLAY_INSET
hardware artefacts — a small inset hides them behind a clean
background margin. Set to 0 on boards without edge artefacts.
config ZEPHCORE_DISPLAY_EPD_FULL_REFRESH_INTERVAL
int "E-paper full-refresh interval (partial refreshes)"
default 8
depends on ZEPHCORE_UI_DISPLAY
help
On e-paper panels, partial refreshes never fully clear the previous
image, so ghosting accumulates where text changes most (status bar
name/time/battery). After this many partial refreshes, perform one
full refresh to clear the panel. A full refresh is the ~2 s
black/white flash, so keep this large enough that it isn't constant
but small enough that ghosting never becomes unreadable. Set to 0 to
disable periodic full refreshes (partial-only — accumulates ghosting).
Ignored on non-EPD displays (OLED/TFT never ghost).
config ZEPHCORE_DISPLAY_LARGE_FONT
bool "Use a larger built-in CFB font"
default n
+23 -1
View File
@@ -74,6 +74,11 @@ static const struct device *panel_vdd_reg;
static uint32_t epd_frame_hash;
static uint32_t epd_last_frame_hash = UINT_MAX;
/* Periodic full refresh: count partial refreshes and force a full refresh
* every CONFIG_ZEPHCORE_DISPLAY_EPD_FULL_REFRESH_INTERVAL frames to clear
* accumulated e-paper ghosting. 0 = disabled (partial-only). */
static uint32_t epd_partial_count;
static inline void epd_hash_bytes(const void *data, size_t len)
{
if (!is_epd || !data || len == 0) {
@@ -512,7 +517,23 @@ void mc_display_finalize(void)
if (is_epd && epd_frame_hash == epd_last_frame_hash) {
return;
}
cfb_framebuffer_finalize(disp_dev);
const int full_interval = CONFIG_ZEPHCORE_DISPLAY_EPD_FULL_REFRESH_INTERVAL;
if (is_epd && full_interval > 0 && ++epd_partial_count >= (uint32_t)full_interval) {
/* Periodic full refresh to clear accumulated ghosting.
* blanking_on selects the FULL profile and loads RAM without
* updating the panel; cfb_framebuffer_finalize writes the
* current framebuffer into both RAM banks; blanking_off then
* triggers the full-refresh update with that content. */
display_blanking_on(disp_dev);
cfb_framebuffer_finalize(disp_dev);
display_blanking_off(disp_dev);
epd_partial_count = 0;
} else {
cfb_framebuffer_finalize(disp_dev);
}
if (is_epd) {
epd_last_frame_hash = epd_frame_hash;
}
@@ -553,6 +574,7 @@ void mc_display_epd_full_reset(void)
display_blanking_on(disp_dev);
display_blanking_off(disp_dev);
epd_last_frame_hash = UINT_MAX;
epd_partial_count = 0;
/* After splash handoff, keep frontlight off; next user interaction
* wakes it via mc_display_on(). */