From d4973f633ee12e96a34941dc20e76ccac244930a Mon Sep 17 00:00:00 2001 From: yuquanjun Date: Fri, 4 Sep 2026 12:02:55 +0800 Subject: [PATCH] Include UI0902 bitmaps in release ExtFlash package. Colleague boards showed garbled mode-select when only the tone .res was flashed; ship combined tone+UI0902 image for full external Flash programming. --- tools/publish_k1_release.py | 89 ++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/tools/publish_k1_release.py b/tools/publish_k1_release.py index a633c05..6e22e8c 100644 --- a/tools/publish_k1_release.py +++ b/tools/publish_k1_release.py @@ -1,7 +1,11 @@ # -*- coding: utf-8 -*- -"""Build K1 release zip: MCU .bin + tone .res + SoundWalkerIAP + docs. +"""Build K1 release zip: MCU .bin + ExtFlash resources + SoundWalkerIAP + docs. -No RTT flashing. Version stays Firmware Version[] (currently 0.2.0). +External Flash has TWO regions that must both be present on a blank/erased chip: + 0x00000000 tone pack (logo pad + Charg + 1/2/3.bin) -> *.tone.res / combined + 0x00100000 UI0902 bitmaps (mode rows, boot logo, ...) -> *.ui0902.res / combined + +Prefer flashing the combined *.extflash.res @ 0x0 for colleague upgrades. """ from __future__ import annotations @@ -16,12 +20,14 @@ REPO = Path(r"C:\Users\qjyu\Documents\SoundWalker\一诺国际吉他") PROJ = REPO / "Code" / "YNGJ-GT1-M - AT32F403ARCT7" EXE_BIN = PROJ / "project" / "IAR_V7.4" / "YNGJ-GT1-M" / "Exe" / "YNGJ-GT1-M.bin" TONE_BIN = PROJ / "tools" / "out" / "extflash_tone_0903.bin" +UI0902_BIN = PROJ / "tools" / "out" / "ui0902_res.bin" MAP_TXT = REPO / "Doc" / "音色文件" / "0903" / "FLASH_MAP.txt" IAP_DIR = REPO / "升级" / "MCU主控升级" OUT_ROOT = REPO / "tools" / "out" FW_VER = "0.2.0" TONE_RES_VER = "0903" +UI0902_RES_BASE = 0x00100000 def git_info(cwd: Path) -> tuple[str, str]: @@ -44,11 +50,20 @@ def sha256(path: Path) -> str: return h.hexdigest() +def build_combined_extflash(tone: bytes, ui: bytes) -> bytes: + if len(tone) > UI0902_RES_BASE: + raise SystemExit(f"tone pack {len(tone)} overflows into UI0902 @ 0x{UI0902_RES_BASE:X}") + pad = UI0902_RES_BASE - len(tone) + return tone + (b"\xFF" * pad) + ui + + def main() -> None: if not EXE_BIN.is_file(): raise SystemExit(f"missing MCU bin: {EXE_BIN}") if not TONE_BIN.is_file(): raise SystemExit(f"missing tone pack: {TONE_BIN} (run pack_extflash_tone_0903.py)") + if not UI0902_BIN.is_file(): + raise SystemExit(f"missing UI0902 pack: {UI0902_BIN} (run gen_ui0902_assets.py)") iap = IAP_DIR / "SoundWalkerIAP.exe" guide = IAP_DIR / "升级步骤.docx" @@ -57,7 +72,6 @@ def main() -> None: if not guide.is_file(): raise SystemExit(f"missing guide: {guide}") - # date + commit only (no minutes, no dirty tag) stamp = datetime.now().strftime("%Y%m%d") commit, subject = git_info(PROJ) base = f"K1_MCU_v{FW_VER}_toneRes_v{TONE_RES_VER}_{stamp}_{commit}" @@ -68,48 +82,71 @@ def main() -> None: shutil.rmtree(pkg) pkg.mkdir(parents=True) + tone_data = TONE_BIN.read_bytes() + ui_data = UI0902_BIN.read_bytes() + combined = build_combined_extflash(tone_data, ui_data) + mcu_name = f"YNGJ-GT1-M_MCU_v{FW_VER}_{stamp}.bin" - res_name = f"extflash_toneRes_v{TONE_RES_VER}_{stamp}.res" + tone_name = f"extflash_toneRes_v{TONE_RES_VER}_{stamp}.res" + ui_name = f"extflash_ui0902_{stamp}.res" + comb_name = f"extflash_ALL_tone0903_ui0902_{stamp}.res" + mcu_dst = pkg / mcu_name - res_dst = pkg / res_name + tone_dst = pkg / tone_name + ui_dst = pkg / ui_name + comb_dst = pkg / comb_name + shutil.copy2(EXE_BIN, mcu_dst) - shutil.copy2(TONE_BIN, res_dst) + tone_dst.write_bytes(tone_data) + ui_dst.write_bytes(ui_data) + comb_dst.write_bytes(combined) shutil.copy2(iap, pkg / "SoundWalkerIAP.exe") shutil.copy2(guide, pkg / "升级步骤.docx") if MAP_TXT.is_file(): shutil.copy2(MAP_TXT, pkg / "FLASH_MAP.txt") - # flat convenience copies - shutil.copy2(res_dst, OUT_ROOT / "extflash_tone_0903.res") shutil.copy2(mcu_dst, OUT_ROOT / mcu_name) + shutil.copy2(tone_dst, OUT_ROOT / "extflash_tone_0903.res") + shutil.copy2(ui_dst, OUT_ROOT / "extflash_ui0902.res") + shutil.copy2(comb_dst, OUT_ROOT / "extflash_ALL_tone0903_ui0902.res") readme = pkg / "README.txt" readme.write_text( "\n".join( [ f"K1 release {base}", - f"Built {datetime.now().strftime('%Y-%m-%d %H:%M:%S %z')}", + f"Built {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", f"Git HEAD {commit}", f"Git subject {subject}", - f"FW version {FW_VER} (settings UI Version[])", - f"Tone res toneRes_v{TONE_RES_VER} (no in-bin version; tag in filename)", + f"FW version {FW_VER}", "", - "Contents:", - f" {mcu_name}", - f" size={mcu_dst.stat().st_size} sha256={sha256(mcu_dst)}", - f" flash with SoundWalkerIAP.exe (USB IAP)", - f" {res_name}", - f" size={res_dst.stat().st_size} sha256={sha256(res_dst)}", - " W25Q128 layout: logo@0 + Charg@0xCB70 + 1.bin@0x1B8F0 + 2.bin + 3.bin", - " Must pair with MCU v0.2.0 (address map changed).", - " SoundWalkerIAP.exe", - " 升级步骤.docx", - " FLASH_MAP.txt", + "==== 同事整机升级请优先刷这两项 ====", + f" 1) {mcu_name} -> MCU APP", + f" 2) {comb_name} -> 外部 Flash 从 0x0 起整包", + " (= 音色区 + 填充 + UI0902 图片区)", "", - "Notes:", - " - Boot logo uses UI0902 full-screen asset; packed logo.bin only pads 0x0..0xCB70.", - " - AutoBand legacy 0x9EB5F not remapped in this release.", - " - Flash MCU firmware AND tone .res together.", + "外部 Flash 分区:", + " 0x00000000 音色/充电图 (toneRes)", + " logo pad + Charg@0xCB70 + 1.bin@0x1B8F0 + 2.bin + 3.bin", + " 0x00100000 UI0902 图片 (模式选择大图、全屏开机 Logo、设置/调音台素材等)", + "", + "分文件(仅在工具支持指定偏移时使用):", + f" {tone_name} size={tone_dst.stat().st_size} @ 0x00000000", + f" sha256={sha256(tone_dst)}", + f" {ui_name} size={ui_dst.stat().st_size} @ 0x00100000", + f" sha256={sha256(ui_dst)}", + f" {comb_name} size={comb_dst.stat().st_size} @ 0x00000000 (推荐)", + f" sha256={sha256(comb_dst)}", + "", + f"MCU: {mcu_name} size={mcu_dst.stat().st_size} sha256={sha256(mcu_dst)}", + "", + "说明:", + " - 只刷音色 .res、不刷 UI0902 时,模式选择页会花屏(读图地址在 0x100000)。", + " - 本机开发板若早已刷过 UI0902,只更新音色+MCU 仍可能正常;同事空片/整片擦除会中招。", + " - 开机全屏 Logo 在 UI0902,不在音色包里的 logo.bin 占位。", + " - AutoBand 0x9EB5F 本版未重排。", + "", + "附件: SoundWalkerIAP.exe / 升级步骤.docx / FLASH_MAP.txt", "", ] ),