K1Guitar/tools/flash_app_cspy.py

94 lines
3.3 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""Flash APP via cspybat (AT32F403AC) then J-Link reset."""
from __future__ import annotations
import shutil
import subprocess
import time
from pathlib import Path
BASE = Path(r"C:\Users\qjyu\Documents\SoundWalker\一诺国际吉他\Code\YNGJ-GT1-M - AT32F403ARCT7")
STAGE = Path(r"C:\Temp\k1flash_boot")
CSPY = Path(r"C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.3\common\bin\cspybat.exe")
JLINK = Path(r"C:\Program Files\SEGGER\JLink_V818\JLink.exe")
APP_OUT = BASE / "project" / "IAR_V7.4" / "YNGJ-GT1-M" / "Exe" / "YNGJ-GT1-M.out"
GEN_TMPL = BASE / "project" / "IAR_V7.4" / "settings" / "YNGJ-GT1-M.YNGJ-GT1-M.general.xcl"
DRV_TMPL = BASE / "project" / "IAR_V7.4" / "settings" / "YNGJ-GT1-M.YNGJ-GT1-M.driver.xcl"
RESET_JLINK = BASE / "tools" / "reset_run.jlink"
def kill_debuggers() -> None:
for n in (
"cspybat.exe", "CSpyBat.exe", "JLink.exe", "IarIdePm.exe",
"JLinkGUIServer.exe", "JLinkRTTClient.exe", "JFlash.exe",
):
subprocess.run(["taskkill", "/F", "/IM", n], capture_output=True)
time.sleep(1.0)
def stage_xcl(out_file: Path):
STAGE.mkdir(parents=True, exist_ok=True)
staged_out = STAGE / out_file.name
shutil.copy2(out_file, staged_out)
gen_lines = GEN_TMPL.read_text(encoding="utf-8", errors="replace").splitlines()
new_gen = []
for ln in gen_lines:
if ".out" in ln and ("YNGJ" in ln or "BOOT" in ln or "AT32" in ln):
new_gen.append(f'"{staged_out}" ')
else:
new_gen.append(ln)
gen_path = STAGE / "general.xcl"
gen_path.write_text("\n".join(new_gen) + "\n", encoding="utf-8", newline="\n")
drv_lines = DRV_TMPL.read_text(encoding="utf-8", errors="replace").splitlines()
forced = [ln for ln in drv_lines if not ln.strip().startswith("--jlink_device")]
forced.append("--jlink_device=AT32F403AC")
drv_path = STAGE / "driver.xcl"
drv_path.write_text("\n".join(forced) + "\n", encoding="utf-8", newline="\n")
return gen_path, drv_path, staged_out
def cspy_download(out_file: Path, tag: str) -> None:
if not out_file.is_file():
raise SystemExit(f"missing {out_file}")
gen_path, drv_path, staged_out = stage_xcl(out_file)
logp = STAGE / f"cspy_{tag}.log"
cmd = [
str(CSPY), "-f", str(gen_path),
f"--debug_file={staged_out}",
"--download_only", "--backend", "-f", str(drv_path),
]
print(f"cspybat download {tag}: {staged_out.name}", flush=True)
with logp.open("w", encoding="utf-8", errors="replace") as log:
r = subprocess.run(cmd, stdout=log, stderr=subprocess.STDOUT, timeout=240)
text = logp.read_text(encoding="utf-8", errors="replace")
print(text[-1500:], flush=True)
if r.returncode != 0:
raise SystemExit(f"cspybat {tag} failed rc={r.returncode}")
def jlink_reset() -> None:
print("J-Link reset/run...", flush=True)
subprocess.run(
[
str(JLINK), "-Device", "AT32F403AC", "-If", "SWD",
"-Speed", "4000", "-AutoConnect", "1",
"-CommandFile", str(RESET_JLINK),
],
capture_output=True, timeout=45,
)
time.sleep(2.5)
def main() -> None:
kill_debuggers()
cspy_download(APP_OUT, "app")
jlink_reset()
print("FLASH OK", flush=True)
if __name__ == "__main__":
main()