From b5e4d97df7d52e198d9efeb4210598c9ac146ba8 Mon Sep 17 00:00:00 2001 From: linchbeta Date: Sun, 12 Apr 2026 18:06:57 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=88=A0=E9=99=A4=20alertBackupBuf?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E7=94=A8=20flash=20=E7=BC=93=E5=AD=98?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=20DRAM=20=E6=BA=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: resolve DRAM overflow and ghosting on 5.83/7.5 panels --- firmware/src/main.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 718f94f0..63658f43 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -358,8 +358,6 @@ void loop() { static unsigned long lastAlertPollAt = 0; static bool alertVisible = false; static unsigned long alertShownAt = 0; - static uint8_t alertBackupBuf[IMG_BUF_LEN]; - static bool hasAlertBackup = false; if (focusListening) { unsigned long nowMs = millis(); @@ -367,25 +365,22 @@ void loop() { const unsigned long ALERT_INTERVAL_MS = 10000UL; if (lastAlertPollAt == 0 || nowMs - lastAlertPollAt >= ALERT_INTERVAL_MS) { lastAlertPollAt = nowMs; - memcpy(alertBackupBuf, imgBuf, IMG_BUF_LEN); - hasAlertBackup = true; if (fetchFocusAlertBMP()) { - epdDisplayFast(imgBuf); + smartDisplay(imgBuf); alertVisible = true; alertShownAt = nowMs; } else { - if (hasAlertBackup) memcpy(imgBuf, alertBackupBuf, IMG_BUF_LEN); - hasAlertBackup = false; + // fetchFocusAlertBMP may have partially written imgBuf on error; + // restore from flash cache (saved after every successful fetch). + cacheLoad(imgBuf, IMG_BUF_LEN); } } } else { const unsigned long ALERT_DISPLAY_MS = 30000UL; if (nowMs - alertShownAt >= ALERT_DISPLAY_MS) { - if (hasAlertBackup) { - memcpy(imgBuf, alertBackupBuf, IMG_BUF_LEN); - epdDisplayFast(imgBuf); + if (cacheLoad(imgBuf, IMG_BUF_LEN)) { + smartDisplay(imgBuf); } - hasAlertBackup = false; alertVisible = false; } } From 9cf5ca3b9e4abfed7be2f3ad835df6c242ddd6b0 Mon Sep 17 00:00:00 2001 From: linchbeta Date: Sun, 12 Apr 2026 18:16:24 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D583=E9=AC=BC=E5=BD=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复583鬼影 --- firmware/src/display.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/firmware/src/display.cpp b/firmware/src/display.cpp index 2258487b..ba362ff1 100644 --- a/firmware/src/display.cpp +++ b/firmware/src/display.cpp @@ -390,7 +390,11 @@ void showModePreview(const char *modeName) { int loadY = H / 2 + (H < 200 ? 10 : 20); drawText(loading, loadX, loadY, loadScale); - epdDisplayFast(imgBuf); + #if defined(EPD_PANEL_583) || defined(EPD_PANEL_75) + epdDisplay(imgBuf); + #else + epdDisplayFast(imgBuf); + #endif Serial.printf("Mode preview shown: %s\n", modeName); } @@ -410,12 +414,15 @@ void smartDisplay(const uint8_t *image) { Serial.printf("smartDisplay: full refresh (cycle %d)\n", refreshCount); epdDisplay(image); } else { -#if defined(EPD_PANEL_42_GXEPD2_GYE042A87) - Serial.printf("smartDisplay: full refresh fallback (cycle %d)\n", refreshCount); +#if defined(EPD_PANEL_583) || defined(EPD_PANEL_75) || defined(EPD_PANEL_42_GXEPD2_GYE042A87) + // Large/slow panels: always full refresh to prevent ghosting. + // These devices refresh every 10-60 min so fast refresh offers no benefit. + Serial.printf("smartDisplay: full refresh (large panel, cycle %d)\n", refreshCount); + epdDisplay(image); #else Serial.printf("smartDisplay: fast refresh (cycle %d)\n", refreshCount); -#endif epdDisplayFast(image); +#endif } refreshCount++; } From 66978e4aa603e8b8b3375361b1f31e3d2662d2ee Mon Sep 17 00:00:00 2001 From: linchbeta Date: Sun, 12 Apr 2026 19:25:03 +0800 Subject: [PATCH 3/6] Modify font configuration and add Lora italic Updated font families and added italic variant for Lora. --- backend/scripts/setup_fonts.py | 45 +++++++++++++++++----------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/backend/scripts/setup_fonts.py b/backend/scripts/setup_fonts.py index 72f9f3cb..254916e8 100644 --- a/backend/scripts/setup_fonts.py +++ b/backend/scripts/setup_fonts.py @@ -1,14 +1,14 @@ #!/usr/bin/env python3 from __future__ import annotations -import argparse -import json -import os -import shutil -import sys -import tempfile -import urllib.error -import urllib.request +import argparse +import json +import os +import shutil +import sys +import tempfile +import urllib.error +import urllib.request BACKEND_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) FONTS_DIR = os.path.join(BACKEND_DIR, "fonts") @@ -28,6 +28,7 @@ "Lora": [ "Lora-Regular.ttf", "Lora-Bold.ttf", + "Lora-Italic.ttf", ], "Inter": [ "Inter_24pt-Medium.ttf", @@ -84,9 +85,9 @@ def _download_file(url: str, target: str, user_agent: str) -> None: with os.fdopen(fd, "wb") as tmp_f: tmp_f.write(data) os.replace(tmp_path, target) - except OSError: - os.unlink(tmp_path) - raise + except OSError: + os.unlink(tmp_path) + raise def _copy_if_needed(src: str, dst: str, force: bool) -> bool: @@ -125,15 +126,15 @@ def _install_vector_fonts(force: bool) -> tuple[int, int]: try: manifest = _fetch_manifest(family) url_maps[family] = _build_url_map(manifest) - except ( - json.JSONDecodeError, - OSError, - TimeoutError, - urllib.error.URLError, - ValueError, - ) as exc: - print(f" [ERROR] Failed manifest for {display_name}: {exc}", file=sys.stderr) - url_maps[family] = {} + except ( + json.JSONDecodeError, + OSError, + TimeoutError, + urllib.error.URLError, + ValueError, + ) as exc: + print(f" [ERROR] Failed manifest for {display_name}: {exc}", file=sys.stderr) + url_maps[family] = {} success_count = 0 for family, name in all_needed: @@ -147,8 +148,8 @@ def _install_vector_fonts(force: bool) -> tuple[int, int]: size_mb = os.path.getsize(target) / (1024 * 1024) print(f" \u2713 {name} ({size_mb:.1f} MB)") success_count += 1 - except (OSError, TimeoutError, urllib.error.URLError, ValueError) as exc: - print(f" [ERROR] Failed {name}: {exc}", file=sys.stderr) + except (OSError, TimeoutError, urllib.error.URLError, ValueError) as exc: + print(f" [ERROR] Failed {name}: {exc}", file=sys.stderr) return success_count, len(all_needed) From 80f1b9deebc4b24e51afb076a3e6342857c00181 Mon Sep 17 00:00:00 2001 From: linchbeta Date: Sun, 12 Apr 2026 19:26:27 +0800 Subject: [PATCH 4/6] Add Lora Italic font to configuration --- backend/core/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/core/config.py b/backend/core/config.py index 18526013..12ade810 100644 --- a/backend/core/config.py +++ b/backend/core/config.py @@ -82,6 +82,7 @@ # 英文字体 "lora_regular": "Lora-Regular.ttf", "lora_bold": "Lora-Bold.ttf", + "lora_italic": "Lora-Italic.ttf", "inter_medium": "Inter_24pt-Medium.ttf", } @@ -397,4 +398,4 @@ def get_default_llm_model_for_provider(provider: Optional[str]) -> str: return "deepseek-chat" if p == "moonshot": return "moonshot-v1-8k" - return DEFAULT_LLM_MODEL \ No newline at end of file + return DEFAULT_LLM_MODEL From 67850510612eb19ee38ec6a8b78291becd34df62 Mon Sep 17 00:00:00 2001 From: linchbeta Date: Sun, 12 Apr 2026 19:27:59 +0800 Subject: [PATCH 5/6] Change font from noto_serif_light to lora_regular --- backend/core/modes/builtin/word_of_the_day.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/core/modes/builtin/word_of_the_day.json b/backend/core/modes/builtin/word_of_the_day.json index 7ff0b109..eed5b37f 100644 --- a/backend/core/modes/builtin/word_of_the_day.json +++ b/backend/core/modes/builtin/word_of_the_day.json @@ -36,7 +36,7 @@ { "type": "text", "field": "phonetic", - "font": "noto_serif_light", + "font": "lora_regular", "font_size": 11, "align": "center", "max_lines": 1 From 2d57bf8d293627e801ef533827cd50a0ccf1c3fe Mon Sep 17 00:00:00 2001 From: linchbeta Date: Sun, 12 Apr 2026 19:30:51 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=9F=B3=E6=A0=87?= =?UTF-8?q?=E5=AD=97=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/core/modes/builtin/en/word_of_the_day.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/core/modes/builtin/en/word_of_the_day.json b/backend/core/modes/builtin/en/word_of_the_day.json index 877736d2..45195949 100644 --- a/backend/core/modes/builtin/en/word_of_the_day.json +++ b/backend/core/modes/builtin/en/word_of_the_day.json @@ -74,6 +74,7 @@ { "type": "text", "field": "phonetic", + "font_name": "Lora-Regular.ttf", "font_size": 11, "align": "center", "max_lines": 1 @@ -121,6 +122,7 @@ { "type": "text", "field": "phonetic", + "font_name": "Lora-Regular.ttf", "font_size": 8, "align": "center" }, @@ -160,6 +162,7 @@ { "type": "text", "field": "phonetic", + "font_name": "Lora-Regular.ttf", "font_size": 16, "align": "center", "max_lines": 1