Map tone Flash banks for pack 0903 and bump firmware to 0.2.0.
Point normal/expert/universal ADDRESS at 1.bin/3.bin bases, add ExtFlash_Tone_Addr.h plus pack/publish helpers for paired MCU+.res releases.
This commit is contained in:
parent
8f0d0a3a52
commit
c05301d8b9
|
|
@ -100,7 +100,7 @@ int16_t MIC_VOL_MAP[10]= {-9000,-7000,-5000,-3000,-1000,1000,3000,5000,7000,9000
|
|||
|
||||
uint8_t TOUCH_AREA_NUM = (sizeof(Touch_Areas)/sizeof(Touch_AreaTypeDef));
|
||||
|
||||
const uint8_t Version[3] = {0,1,11};
|
||||
const uint8_t Version[3] = {0,2,0}; /* major.minor.patch — 0.2.0: tone pack 0903 addr remap */
|
||||
|
||||
uint8_t Led = 8;
|
||||
bool PressFlag = 0;
|
||||
|
|
@ -304,8 +304,7 @@ void Power_Key_Scan()
|
|||
void (*CurrUIProcress)(DisplayTaskMessage_Type xEvent);
|
||||
|
||||
/* UI 公共全局变量 */
|
||||
//volatile uint32_t ADDRESS = 0x0001b8F0;
|
||||
volatile uint32_t ADDRESS = 0x00000000;
|
||||
volatile uint32_t ADDRESS = FLASH_ADDR_MODE_UNIVERSAL;
|
||||
uint8_t KEY_ID_1629 = 0;
|
||||
bool StartFlag = false;
|
||||
bool InModeFlag = false;
|
||||
|
|
|
|||
19
UI/UI_Idle.c
19
UI/UI_Idle.c
|
|
@ -150,22 +150,22 @@ void Touch_Mode_Select_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex)
|
|||
|
||||
switch (ID)
|
||||
{
|
||||
case 0: /* 万能 */
|
||||
case 0: /* 万能 → 3.bin */
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
ADDRESS = 0x0009EB5F;
|
||||
ADDRESS = FLASH_ADDR_AUTOBAND_LEGACY;
|
||||
else
|
||||
ADDRESS = 0x0001B8F0;
|
||||
ADDRESS = FLASH_ADDR_MODE_UNIVERSAL;
|
||||
MenuPage_SongMode_Proc();
|
||||
break;
|
||||
case 1: /* 专业 */
|
||||
case 1: /* 专业 → 1.bin */
|
||||
if (mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
ADDRESS = 0x0009EB5F;
|
||||
ADDRESS = FLASH_ADDR_AUTOBAND_LEGACY;
|
||||
else
|
||||
ADDRESS = 0x00000000;
|
||||
ADDRESS = FLASH_ADDR_MODE_EXPERT;
|
||||
MenuPage_ExpertMode_Proc();
|
||||
break;
|
||||
case 2: /* 普通 */
|
||||
ADDRESS = 0x0009598F;
|
||||
case 2: /* 普通 → 1.bin */
|
||||
ADDRESS = FLASH_ADDR_MODE_NORMAL;
|
||||
MenuPage_FreeMode_Proc();
|
||||
break;
|
||||
default:
|
||||
|
|
@ -266,7 +266,8 @@ void IdleProcess(DisplayTaskMessage_Type msg)
|
|||
BSP_MainPowerEnable(1);
|
||||
LCD_WR_REG(0x29); //Display on
|
||||
|
||||
LCD_WR_PIC_FROM_FLASH(40, 50, 160, 190, 0x0000CB70);
|
||||
LCD_WR_PIC_FROM_FLASH(40, 50, EXTFLASH_CHARGING_W, EXTFLASH_CHARGING_H,
|
||||
EXTFLASH_CHARGING_ADDR);
|
||||
LCD_BLK_Set();
|
||||
flag = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,10 +225,16 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
|
|||
|
||||
if(mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
{
|
||||
ADDRESS = 0x0009EB5B;
|
||||
ADDRESS = FLASH_ADDR_AUTOBAND_LEGACY;
|
||||
}else
|
||||
{
|
||||
ADDRESS = 0x00000000;
|
||||
{
|
||||
/* 关闭 AutoBand:回到当前 TAB 对应音色库 */
|
||||
switch (mGuiData[GUI_TAB_INDEX].Current)
|
||||
{
|
||||
case 1: ADDRESS = FLASH_ADDR_MODE_EXPERT; break;
|
||||
case 2: ADDRESS = FLASH_ADDR_MODE_NORMAL; break;
|
||||
default: ADDRESS = FLASH_ADDR_MODE_UNIVERSAL; break;
|
||||
}
|
||||
}
|
||||
if (!UI_SetFocus(GUI_MODE_PARAM))
|
||||
label_ModeSelece_ui(&UI_Label[GUI_MODE_PARAM],&mGuiData[GUI_MODE_PARAM]);
|
||||
|
|
@ -263,42 +269,34 @@ void Touch_Action(int8_t FLAG, uint8_t ID, uint8_t areaIndex,uint8_t value)
|
|||
app_tm1629_all_on(LED_COLOR_G);
|
||||
switch(mGuiData[ID].Current)
|
||||
{
|
||||
case 0:
|
||||
case 0: /* 万能 → 3.bin */
|
||||
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[ID].Current)
|
||||
break;
|
||||
StartFlag = 0;
|
||||
AutoBandTop1_Stop();
|
||||
if(mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
{
|
||||
ADDRESS = 0x0009EB5F;
|
||||
}
|
||||
ADDRESS = FLASH_ADDR_AUTOBAND_LEGACY;
|
||||
else
|
||||
{
|
||||
ADDRESS = 0x00000000;
|
||||
}
|
||||
ADDRESS = FLASH_ADDR_MODE_UNIVERSAL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 1: /* 专业 → 1.bin */
|
||||
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[ID].Current)
|
||||
break;
|
||||
StartFlag = 0;
|
||||
AutoBandTop1_Stop();
|
||||
if(mGuiData[GUI_AUTOBAND_SW].Current)
|
||||
{
|
||||
ADDRESS = 0x0009EB5F;
|
||||
}
|
||||
ADDRESS = FLASH_ADDR_AUTOBAND_LEGACY;
|
||||
else
|
||||
{
|
||||
ADDRESS = 0x00000000;
|
||||
}
|
||||
ADDRESS = FLASH_ADDR_MODE_EXPERT;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 2: /* 普通 → 1.bin */
|
||||
if(mGuiData[GUI_TAB_LAST_INDEX].Current == mGuiData[ID].Current)
|
||||
break;
|
||||
StartFlag = 0;
|
||||
AutoBandTop1_Stop();
|
||||
ADDRESS = 0x0009598F;
|
||||
ADDRESS = FLASH_ADDR_MODE_NORMAL;
|
||||
break;
|
||||
}
|
||||
Refresh_TabSelect_ui(&UI_Label[ID], &mGuiData[ID]);
|
||||
|
|
|
|||
|
|
@ -236,15 +236,19 @@ void UI_GotoCurrentModePage(void)
|
|||
switch (mGuiData[GUI_TAB_INDEX].Current)
|
||||
{
|
||||
case 0:
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current ? 0x0009EB5F : 0x0001B8F0;
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current
|
||||
? FLASH_ADDR_AUTOBAND_LEGACY
|
||||
: FLASH_ADDR_MODE_UNIVERSAL;
|
||||
MenuPage_SongMode_Proc();
|
||||
break;
|
||||
case 1:
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current ? 0x0009EB5F : 0x00000000;
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current
|
||||
? FLASH_ADDR_AUTOBAND_LEGACY
|
||||
: FLASH_ADDR_MODE_EXPERT;
|
||||
MenuPage_ExpertMode_Proc();
|
||||
break;
|
||||
case 2:
|
||||
ADDRESS = 0x0009598F;
|
||||
ADDRESS = FLASH_ADDR_MODE_NORMAL;
|
||||
MenuPage_FreeMode_Proc();
|
||||
break;
|
||||
default:
|
||||
|
|
@ -803,15 +807,19 @@ void UI_NavBar_Action(uint8_t value)
|
|||
switch (value)
|
||||
{
|
||||
case UI0902_NAV_UNIVERSAL:
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current ? 0x0009EB5F : 0x0001B8F0;
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current
|
||||
? FLASH_ADDR_AUTOBAND_LEGACY
|
||||
: FLASH_ADDR_MODE_UNIVERSAL;
|
||||
MenuPage_SongMode_Proc();
|
||||
break;
|
||||
case UI0902_NAV_NORMAL:
|
||||
ADDRESS = 0x0009598F;
|
||||
ADDRESS = FLASH_ADDR_MODE_NORMAL;
|
||||
MenuPage_FreeMode_Proc();
|
||||
break;
|
||||
case UI0902_NAV_EXPERT:
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current ? 0x0009EB5F : 0x00000000;
|
||||
ADDRESS = mGuiData[GUI_AUTOBAND_SW].Current
|
||||
? FLASH_ADDR_AUTOBAND_LEGACY
|
||||
: FLASH_ADDR_MODE_EXPERT;
|
||||
MenuPage_ExpertMode_Proc();
|
||||
break;
|
||||
case UI0902_NAV_SETTING:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef __EXTFLASH_TONE_ADDR_H
|
||||
#define __EXTFLASH_TONE_ADDR_H
|
||||
|
||||
/* Auto-generated by tools/pack_extflash_tone_0903.py — do not hand-edit. */
|
||||
/* W25Q128 absolute offsets. Boot logo display uses UI0902_BOOT_LOGO_ADDR. */
|
||||
/* Tone resource pack has no in-bin version field; release tag = EXTFLASH_TONE_RES_VER. */
|
||||
#define EXTFLASH_TONE_RES_VER "0903"
|
||||
#define EXTFLASH_TONE_RES_VER_MAJOR 0
|
||||
#define EXTFLASH_TONE_RES_VER_MINOR 9
|
||||
#define EXTFLASH_TONE_RES_VER_PATCH 3
|
||||
|
||||
#define EXTFLASH_LOGO_ADDR 0x00000000UL
|
||||
#define EXTFLASH_LOGO_SIZE 52080UL
|
||||
|
||||
#define EXTFLASH_CHARGING_ADDR 0x0000CB70UL
|
||||
#define EXTFLASH_CHARGING_SIZE 60800UL
|
||||
#define EXTFLASH_CHARGING_W 160
|
||||
#define EXTFLASH_CHARGING_H 190
|
||||
|
||||
#define EXTFLASH_BIN1_RHYTHM_ADDR 0x0001B8F0UL
|
||||
#define EXTFLASH_BIN1_RHYTHM_SIZE 530317UL
|
||||
|
||||
#define EXTFLASH_BIN2_SONG_HAITIAN_ADDR 0x0009D07DUL
|
||||
#define EXTFLASH_BIN2_SONG_HAITIAN_SIZE 46474UL
|
||||
|
||||
#define EXTFLASH_BIN3_UNIVERSAL_ADDR 0x000A8607UL
|
||||
#define EXTFLASH_BIN3_UNIVERSAL_SIZE 31854UL
|
||||
|
||||
/* Convenience aliases used by UI ADDRESS */
|
||||
#define FLASH_ADDR_MODE_NORMAL EXTFLASH_BIN1_RHYTHM_ADDR /* 普通 */
|
||||
#define FLASH_ADDR_MODE_EXPERT EXTFLASH_BIN1_RHYTHM_ADDR /* 专业 */
|
||||
#define FLASH_ADDR_SONG_HAITIAN EXTFLASH_BIN2_SONG_HAITIAN_ADDR
|
||||
#define FLASH_ADDR_MODE_UNIVERSAL EXTFLASH_BIN3_UNIVERSAL_ADDR /* 万能 */
|
||||
|
||||
/* Legacy AutoBand bank — not repacked in 0903; left unchanged in firmware */
|
||||
#define FLASH_ADDR_AUTOBAND_LEGACY 0x0009EB5FUL
|
||||
|
||||
#define EXTFLASH_TONE_PACK_END 0x000B0275UL
|
||||
#define EXTFLASH_TONE_PACK_SIZE 721525UL
|
||||
#define UI0902_RES_BASE_SAFE_GAP (0x00100000UL - EXTFLASH_TONE_PACK_END)
|
||||
|
||||
#endif
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
#include "Drv_ILI9341_Lcd_Image.h"
|
||||
#include "Drv_ILI9341_Lcd_Image_UI0902.h"
|
||||
#include "UI0902_Res_Addr.h"
|
||||
#include "ExtFlash_Tone_Addr.h"
|
||||
#include "Drv_ILI9341_Lcd_Dump.h"
|
||||
#include "Drv_XPT2046_Touch.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,152 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Pack external W25Q128 tone/logo image for K1 (0903).
|
||||
|
||||
Layout (absolute W25Q128 offsets):
|
||||
0x00000000 logo.bin (legacy pad; boot UI uses UI0902 full-screen logo)
|
||||
0x0000CB70 Charg.bin (160x190 RGB565 charging art)
|
||||
0x0001B8F0 1.bin 普通/专业 31 rhythms
|
||||
0x0009D07D 2.bin 海阔天空
|
||||
0x000A8607 3.bin 万能模式
|
||||
|
||||
Outputs:
|
||||
tools/out/extflash_tone_0903.bin
|
||||
project/inc/ExtFlash_Tone_Addr.h
|
||||
Doc/音色文件/0903/FLASH_MAP.txt
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1] # firmware project root
|
||||
REPO = ROOT.parent.parent # 一诺国际吉他
|
||||
OUT_DIR = ROOT / "tools" / "out"
|
||||
OUT_BIN = OUT_DIR / "extflash_tone_0903.bin"
|
||||
OUT_HDR = ROOT / "project" / "inc" / "ExtFlash_Tone_Addr.h"
|
||||
OUT_MAP = REPO / "Doc" / "音色文件" / "0903" / "FLASH_MAP.txt"
|
||||
|
||||
TONE_DIR = REPO / "Doc" / "音色文件" / "0903"
|
||||
|
||||
|
||||
def find_ziliao() -> Path:
|
||||
for p in REPO.iterdir():
|
||||
if p.is_dir() and (p / "logo.bin").is_file() and (p / "Charg.bin").is_file():
|
||||
return p
|
||||
raise FileNotFoundError("资料/logo.bin + Charg.bin not found under repo")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
ziliao = find_ziliao()
|
||||
parts = [
|
||||
("LOGO", ziliao / "logo.bin", 0x00000000, "legacy pad; boot uses UI0902_BOOT_LOGO"),
|
||||
("CHARGING", ziliao / "Charg.bin", 0x0000CB70, "160x190 RGB565"),
|
||||
("BIN1_RHYTHM", TONE_DIR / "1.bin", 0x0001B8F0, "普通/专业 31 条节奏"),
|
||||
("BIN2_SONG_HAITIAN", TONE_DIR / "2.bin", None, "本地曲目 海阔天空"),
|
||||
("BIN3_UNIVERSAL", TONE_DIR / "3.bin", None, "万能模式"),
|
||||
]
|
||||
|
||||
blobs = []
|
||||
cursor = 0
|
||||
rows = []
|
||||
for name, path, force_off, note in parts:
|
||||
data = path.read_bytes()
|
||||
if force_off is not None:
|
||||
if cursor > force_off:
|
||||
raise SystemExit(f"{name}: cursor 0x{cursor:X} past forced 0x{force_off:X}")
|
||||
if cursor < force_off:
|
||||
pad = force_off - cursor
|
||||
blobs.append(b"\xFF" * pad)
|
||||
cursor = force_off
|
||||
rows.append((f"(pad)", force_off - pad, pad, "gap fill 0xFF"))
|
||||
off = cursor
|
||||
blobs.append(data)
|
||||
cursor += len(data)
|
||||
rows.append((name, off, len(data), f"{note} <- {path.name}"))
|
||||
|
||||
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
packed = b"".join(blobs)
|
||||
OUT_BIN.write_bytes(packed)
|
||||
|
||||
# named lookup
|
||||
by_name = {r[0]: r for r in rows if not r[0].startswith("(")}
|
||||
|
||||
hdr = f"""#ifndef __EXTFLASH_TONE_ADDR_H
|
||||
#define __EXTFLASH_TONE_ADDR_H
|
||||
|
||||
/* Auto-generated by tools/pack_extflash_tone_0903.py — do not hand-edit. */
|
||||
/* W25Q128 absolute offsets. Boot logo display uses UI0902_BOOT_LOGO_ADDR. */
|
||||
/* Tone resource pack has no in-bin version field; release tag = EXTFLASH_TONE_RES_VER. */
|
||||
#define EXTFLASH_TONE_RES_VER "0903"
|
||||
#define EXTFLASH_TONE_RES_VER_MAJOR 0
|
||||
#define EXTFLASH_TONE_RES_VER_MINOR 9
|
||||
#define EXTFLASH_TONE_RES_VER_PATCH 3
|
||||
|
||||
#define EXTFLASH_LOGO_ADDR 0x{by_name['LOGO'][1]:08X}UL
|
||||
#define EXTFLASH_LOGO_SIZE {by_name['LOGO'][2]}UL
|
||||
|
||||
#define EXTFLASH_CHARGING_ADDR 0x{by_name['CHARGING'][1]:08X}UL
|
||||
#define EXTFLASH_CHARGING_SIZE {by_name['CHARGING'][2]}UL
|
||||
#define EXTFLASH_CHARGING_W 160
|
||||
#define EXTFLASH_CHARGING_H 190
|
||||
|
||||
#define EXTFLASH_BIN1_RHYTHM_ADDR 0x{by_name['BIN1_RHYTHM'][1]:08X}UL
|
||||
#define EXTFLASH_BIN1_RHYTHM_SIZE {by_name['BIN1_RHYTHM'][2]}UL
|
||||
|
||||
#define EXTFLASH_BIN2_SONG_HAITIAN_ADDR 0x{by_name['BIN2_SONG_HAITIAN'][1]:08X}UL
|
||||
#define EXTFLASH_BIN2_SONG_HAITIAN_SIZE {by_name['BIN2_SONG_HAITIAN'][2]}UL
|
||||
|
||||
#define EXTFLASH_BIN3_UNIVERSAL_ADDR 0x{by_name['BIN3_UNIVERSAL'][1]:08X}UL
|
||||
#define EXTFLASH_BIN3_UNIVERSAL_SIZE {by_name['BIN3_UNIVERSAL'][2]}UL
|
||||
|
||||
/* Convenience aliases used by UI ADDRESS */
|
||||
#define FLASH_ADDR_MODE_NORMAL EXTFLASH_BIN1_RHYTHM_ADDR /* 普通 */
|
||||
#define FLASH_ADDR_MODE_EXPERT EXTFLASH_BIN1_RHYTHM_ADDR /* 专业 */
|
||||
#define FLASH_ADDR_SONG_HAITIAN EXTFLASH_BIN2_SONG_HAITIAN_ADDR
|
||||
#define FLASH_ADDR_MODE_UNIVERSAL EXTFLASH_BIN3_UNIVERSAL_ADDR /* 万能 */
|
||||
|
||||
/* Legacy AutoBand bank — not repacked in 0903; left unchanged in firmware */
|
||||
#define FLASH_ADDR_AUTOBAND_LEGACY 0x0009EB5FUL
|
||||
|
||||
#define EXTFLASH_TONE_PACK_END 0x{cursor:08X}UL
|
||||
#define EXTFLASH_TONE_PACK_SIZE {cursor}UL
|
||||
#define UI0902_RES_BASE_SAFE_GAP (0x00100000UL - EXTFLASH_TONE_PACK_END)
|
||||
|
||||
#endif
|
||||
"""
|
||||
OUT_HDR.write_text(hdr, encoding="utf-8", newline="\n")
|
||||
|
||||
map_lines = [
|
||||
"K1 external Flash map — tone pack 0903",
|
||||
f"Packed file: Code/.../tools/out/{OUT_BIN.name} ({len(packed)} bytes)",
|
||||
f"Ends at 0x{cursor:X}; UI0902_RES_BASE=0x00100000; free gap={0x100000 - cursor} bytes",
|
||||
"",
|
||||
f"{'Name':<22} {'Offset':>10} {'Size':>10} Note",
|
||||
"-" * 72,
|
||||
]
|
||||
for name, off, size, note in rows:
|
||||
map_lines.append(f"{name:<22} 0x{off:08X} {size:10d} {note}")
|
||||
map_lines += [
|
||||
"",
|
||||
"Firmware ADDRESS mapping:",
|
||||
" 普通/专业 -> FLASH_ADDR_MODE_NORMAL/EXPERT (1.bin)",
|
||||
" 海阔天空 -> FLASH_ADDR_SONG_HAITIAN (2.bin)",
|
||||
" 万能 -> FLASH_ADDR_MODE_UNIVERSAL (3.bin)",
|
||||
" AutoBand -> FLASH_ADDR_AUTOBAND_LEGACY 0x9EB5F (unchanged; overlaps 2.bin region — do not enable until remapped)",
|
||||
" Boot logo -> UI0902_BOOT_LOGO_ADDR (full-screen); packed logo.bin only pads 0x0..0xCB70",
|
||||
" Charging -> EXTFLASH_CHARGING_ADDR",
|
||||
]
|
||||
OUT_MAP.write_text("\n".join(map_lines) + "\n", encoding="utf-8", newline="\n")
|
||||
|
||||
print(f"Wrote {OUT_BIN} ({len(packed)} bytes)")
|
||||
print(f"Wrote {OUT_HDR}")
|
||||
print(f"Wrote {OUT_MAP}")
|
||||
for name, off, size, note in rows:
|
||||
print(f" 0x{off:08X} {size:8d} {name} {note}")
|
||||
if cursor > 0x00100000:
|
||||
raise SystemExit("ERROR: pack overflows into UI0902_RES_BASE")
|
||||
print(f"OK: {0x00100000 - cursor} bytes free before UI0902 @ 0x00100000")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Build K1 release zip: MCU .bin + tone .res + SoundWalkerIAP + docs.
|
||||
|
||||
No RTT flashing. Version stays Firmware Version[] (currently 0.2.0).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
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"
|
||||
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"
|
||||
|
||||
|
||||
def git_info(cwd: Path) -> tuple[str, str]:
|
||||
def run(args: list[str]) -> str:
|
||||
r = subprocess.run(
|
||||
args, cwd=str(cwd), capture_output=True, text=True, encoding="utf-8", errors="replace"
|
||||
)
|
||||
return (r.stdout or "").strip()
|
||||
|
||||
commit = run(["git", "rev-parse", "--short=7", "HEAD"]) or "nogit"
|
||||
subject = run(["git", "log", "-1", "--pretty=%s"]) or ""
|
||||
return commit, subject
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
h = hashlib.sha256()
|
||||
with path.open("rb") as f:
|
||||
for chunk in iter(lambda: f.read(1 << 20), b""):
|
||||
h.update(chunk)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
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)")
|
||||
|
||||
iap = IAP_DIR / "SoundWalkerIAP.exe"
|
||||
guide = IAP_DIR / "升级步骤.docx"
|
||||
if not iap.is_file():
|
||||
raise SystemExit(f"missing IAP tool: {iap}")
|
||||
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}"
|
||||
|
||||
OUT_ROOT.mkdir(parents=True, exist_ok=True)
|
||||
pkg = OUT_ROOT / base
|
||||
if pkg.exists():
|
||||
shutil.rmtree(pkg)
|
||||
pkg.mkdir(parents=True)
|
||||
|
||||
mcu_name = f"YNGJ-GT1-M_MCU_v{FW_VER}_{stamp}.bin"
|
||||
res_name = f"extflash_toneRes_v{TONE_RES_VER}_{stamp}.res"
|
||||
mcu_dst = pkg / mcu_name
|
||||
res_dst = pkg / res_name
|
||||
shutil.copy2(EXE_BIN, mcu_dst)
|
||||
shutil.copy2(TONE_BIN, res_dst)
|
||||
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)
|
||||
|
||||
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"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)",
|
||||
"",
|
||||
"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",
|
||||
"",
|
||||
"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.",
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
newline="\n",
|
||||
)
|
||||
|
||||
zip_path = OUT_ROOT / f"{base}.zip"
|
||||
if zip_path.exists():
|
||||
zip_path.unlink()
|
||||
with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
|
||||
for f in sorted(pkg.rglob("*")):
|
||||
if f.is_file():
|
||||
zf.write(f, arcname=f"{base}/{f.relative_to(pkg).as_posix()}")
|
||||
|
||||
print(f"PKG {pkg}")
|
||||
print(f"ZIP {zip_path} ({zip_path.stat().st_size} bytes)")
|
||||
for f in sorted(pkg.iterdir()):
|
||||
print(f" {f.name} {f.stat().st_size}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in New Issue