✨ feat: flash phase tracking, erase checkbox, flash_model config
Step 2 UI now shows real-time flash operation phases parsed from program_flash output: - Erase: "Performing Erase Operation..." → sf erase → Erased: OK - Program: "Performing Program Operation..." → write blocks 0%→100% - Verify: "Performing Verify Operation..." → read+cmp 0%→100% Configuration additions: - erase_before_program checkbox: controls whether to pre-erase before programming - flash_model: chip type for capacity reference (s25fl256s1 = 32 MiB) subprocess_utils.py now emits 'phase' callbacks (erase/program/verify/done) detected from program_flash output transitions.
This commit is contained in:
+41
-4
@@ -80,6 +80,7 @@ class MainWindow(ctk.CTk):
|
||||
self._zynq_jtag_present: bool = False
|
||||
self._zynq_jtag_info = None
|
||||
self._uart_monitor: UartMonitor | None = None
|
||||
self._flash_phase: str = ""
|
||||
|
||||
# StringVar references for config sync
|
||||
self._ip_string_var: ctk.StringVar | None = None
|
||||
@@ -186,6 +187,7 @@ class MainWindow(ctk.CTk):
|
||||
self._config.bootloader_elf_path = files["bootloader_elf_path"]
|
||||
self._config.bootloader_bin_path = files["bootloader_bin_path"]
|
||||
self._config.fsbl_elf_path = files["fsbl_elf_path"]
|
||||
self._config.erase_before_program = self._erase_cb_var.get()
|
||||
self._config.firmware_bin_path = files["firmware_bin_path"]
|
||||
|
||||
def _save_config(self) -> None:
|
||||
@@ -398,7 +400,7 @@ class MainWindow(ctk.CTk):
|
||||
row=0, column=0, sticky="nsew",
|
||||
padx=PADDING, pady=PADDING,
|
||||
)
|
||||
panel.grid_rowconfigure(6, weight=1)
|
||||
panel.grid_rowconfigure(7, weight=1)
|
||||
|
||||
title = ctk.CTkLabel(
|
||||
panel,
|
||||
@@ -461,6 +463,27 @@ class MainWindow(ctk.CTk):
|
||||
self._fsbl_selector.set_path(str(resolved))
|
||||
self._fsbl_selector.grid(row=5, column=0, sticky="nsew", padx=PADDING, pady=PADDING_SMALL)
|
||||
|
||||
# Flash options
|
||||
flash_frame = ctk.CTkFrame(panel)
|
||||
flash_frame.grid(row=6, column=0, sticky="nsew", padx=PADDING, pady=PADDING_SMALL)
|
||||
flash_frame.grid_columnconfigure(0, weight=1)
|
||||
|
||||
self._erase_cb_var = ctk.BooleanVar(value=self._config.erase_before_program)
|
||||
self._erase_cb = ctk.CTkCheckBox(
|
||||
flash_frame,
|
||||
text="Erase flash before programming",
|
||||
variable=self._erase_cb_var,
|
||||
font=FONT_SMALL,
|
||||
)
|
||||
self._erase_cb.grid(row=0, column=0, sticky="w", padx=PADDING_SMALL)
|
||||
|
||||
flash_model_label = ctk.CTkLabel(
|
||||
flash_frame,
|
||||
text=f"Flash: {self._config.flash_model} (32 MiB)",
|
||||
font=FONT_SMALL,
|
||||
)
|
||||
flash_model_label.grid(row=1, column=0, sticky="w", padx=PADDING_SMALL, pady=(2, 0))
|
||||
|
||||
# Firmware BIN path (TFTP upload)
|
||||
self._firmware_bin_selector = FileSelector(
|
||||
panel,
|
||||
@@ -470,7 +493,7 @@ class MainWindow(ctk.CTk):
|
||||
if self._config.firmware_bin_path:
|
||||
resolved = self._config.resolve_path(self._config.firmware_bin_path)
|
||||
self._firmware_bin_selector.set_path(str(resolved))
|
||||
self._firmware_bin_selector.grid(row=6, column=0, sticky="nsew", padx=PADDING, pady=PADDING_SMALL)
|
||||
self._firmware_bin_selector.grid(row=7, column=0, sticky="nsew", padx=PADDING, pady=PADDING_SMALL)
|
||||
|
||||
# Save button
|
||||
save_btn = ctk.CTkButton(
|
||||
@@ -479,7 +502,7 @@ class MainWindow(ctk.CTk):
|
||||
font=FONT_SMALL,
|
||||
command=self._save_config,
|
||||
)
|
||||
save_btn.grid(row=7, column=0, padx=PADDING, pady=PADDING)
|
||||
save_btn.grid(row=8, column=0, padx=PADDING, pady=PADDING)
|
||||
|
||||
def _build_serial_panel(self, parent: ctk.CTkFrame) -> None:
|
||||
"""Build the serial monitor panel."""
|
||||
@@ -725,7 +748,21 @@ class MainWindow(ctk.CTk):
|
||||
return False
|
||||
|
||||
def _flash_callback(self, status: str, message: str) -> None:
|
||||
"""Callback for flash programming progress."""
|
||||
"""Callback for flash programming progress — tracks phases."""
|
||||
if status == "phase":
|
||||
# Track current flash phase for UI
|
||||
self._flash_phase = message # 'erase', 'program', 'verify', 'done'
|
||||
phase_names = {"erase": "Erasing", "program": "Programming", "verify": "Verifying", "done": "Done"}
|
||||
label = phase_names.get(message, message)
|
||||
self._log_message(f" ▸ {label}")
|
||||
return
|
||||
if status == "progress":
|
||||
pct = message.rstrip('%')
|
||||
# Show progress within current phase
|
||||
phase_label = {"erase": "Erase", "program": "Program", "verify": "Verify"}.get(
|
||||
self._flash_phase, "Flash")
|
||||
self._log_message(f" [{phase_label}] {pct}%")
|
||||
return
|
||||
self._log_message(f" [{status}] {message}")
|
||||
|
||||
def _jtag_callback(self, status: str, message: str) -> None:
|
||||
|
||||
Reference in New Issue
Block a user