✨ 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:
+27
-2
@@ -1,7 +1,8 @@
|
||||
"""Non-blocking subprocess execution with real-time output parsing.
|
||||
|
||||
Provides run_streaming() which streams stdout/stderr to callbacks
|
||||
in real time, parsing for warnings, errors, and progress indicators.
|
||||
in real time, parsing for warnings, errors, progress indicators,
|
||||
and flash operation phase transitions (erase/program/verify).
|
||||
Used by flash_programmer and bitstream_programmer.
|
||||
"""
|
||||
|
||||
@@ -15,7 +16,7 @@ from typing import Callable
|
||||
|
||||
StreamCallback = Callable[[str, str], None] | None
|
||||
"""Callback type: (category, message) where category is one of:
|
||||
'out', 'err', 'warn', 'error', 'progress', 'done'"""
|
||||
'out', 'err', 'warn', 'error', 'progress', 'phase', 'done'"""
|
||||
|
||||
# Regex patterns for parsing tool output
|
||||
_WARNING_RE = re.compile(r"WARNING\s*[:\[].*", re.IGNORECASE)
|
||||
@@ -24,6 +25,12 @@ _PROGRESS_RE = re.compile(r"(\d{1,3})\s*%")
|
||||
_INFO_KEYWORDS = ["connected", "downloading", "running", "initialization",
|
||||
"verif", "write", "erase", "flash operation"]
|
||||
|
||||
# Phase transition patterns for program_flash output
|
||||
_PHASE_ERASE_RE = re.compile(r"Performing Erase Operation", re.IGNORECASE)
|
||||
_PHASE_PROGRAM_RE = re.compile(r"Performing Program Operation", re.IGNORECASE)
|
||||
_PHASE_VERIFY_RE = re.compile(r"Performing Verify Operation", re.IGNORECASE)
|
||||
_PHASE_DONE_RE = re.compile(r"(Erase|Program|Verify) Operation successful", re.IGNORECASE)
|
||||
|
||||
|
||||
def run_streaming(
|
||||
cmd: list[str],
|
||||
@@ -133,6 +140,24 @@ def _parse_and_callback(
|
||||
callback("warn", line)
|
||||
return
|
||||
|
||||
# Check for phase transitions (program_flash output)
|
||||
if _PHASE_ERASE_RE.search(line):
|
||||
callback("phase", "erase")
|
||||
callback("out", line)
|
||||
return
|
||||
if _PHASE_PROGRAM_RE.search(line):
|
||||
callback("phase", "program")
|
||||
callback("out", line)
|
||||
return
|
||||
if _PHASE_VERIFY_RE.search(line):
|
||||
callback("phase", "verify")
|
||||
callback("out", line)
|
||||
return
|
||||
if _PHASE_DONE_RE.search(line):
|
||||
callback("phase", "done")
|
||||
callback("out", line)
|
||||
return
|
||||
|
||||
# Check for progress percentage
|
||||
m = _PROGRESS_RE.search(line)
|
||||
if m:
|
||||
|
||||
Reference in New Issue
Block a user