🐛 fix: recover JTAG DAP after flash programming with system reset
- Add preemptive rst -system at Step 3 start to clean post-flash DAP state - Replace ineffective SLCR write with targets 1 → rst -system recovery - Exit with clear power-cycle instructions when DAP recovery fails - Show prominent DAP error guidance in GUI for Step 3 and Run All mode Verified: Step 1→2→3 now passes end-to-end (340s) without board power cycle.
This commit is contained in:
+35
-12
@@ -589,14 +589,27 @@ def full_bitstream_program(
|
|||||||
if callback:
|
if callback:
|
||||||
callback("start", "Initializing Zynq via JTAG (FSBL override)...")
|
callback("start", "Initializing Zynq via JTAG (FSBL override)...")
|
||||||
|
|
||||||
# Build TCL with DAP error recovery
|
# Build TCL with preemptive system reset + DAP error recovery
|
||||||
tcl_lines = [
|
tcl_lines = [
|
||||||
'puts "INFO: Starting Zynq initialization via JTAG override..."',
|
'puts "INFO: Starting Zynq initialization via JTAG override..."',
|
||||||
"connect",
|
"connect",
|
||||||
"after 500",
|
"after 500",
|
||||||
]
|
]
|
||||||
|
|
||||||
# DAP error check — if ARM cores not visible, try recovery
|
# Preemptive system reset (safe on clean board; may help after flash)
|
||||||
|
tcl_lines.extend([
|
||||||
|
'# Preemptive system reset to clean up any leftover state',
|
||||||
|
'if {[catch {',
|
||||||
|
' targets -set -nocase -filter {name =~ "arm*#0"}',
|
||||||
|
' rst -system',
|
||||||
|
' after 1000',
|
||||||
|
' stop',
|
||||||
|
' puts "INFO: Preemptive system reset OK"',
|
||||||
|
'}]} { puts "INFO: Preemptive system reset skipped (no ARM target)" }',
|
||||||
|
'',
|
||||||
|
])
|
||||||
|
|
||||||
|
# DAP error check — if ARM cores not visible, try recovery via DAP
|
||||||
tcl_lines.extend([
|
tcl_lines.extend([
|
||||||
'# Check for DAP errors and attempt recovery',
|
'# Check for DAP errors and attempt recovery',
|
||||||
'set target_list [targets]',
|
'set target_list [targets]',
|
||||||
@@ -606,19 +619,29 @@ def full_bitstream_program(
|
|||||||
' puts "WARNING: ARM cores not found — DAP may be in error state"',
|
' puts "WARNING: ARM cores not found — DAP may be in error state"',
|
||||||
' # Show DAP status for logging',
|
' # Show DAP status for logging',
|
||||||
' foreach t $target_list { puts " TARGET: $t" }',
|
' foreach t $target_list { puts " TARGET: $t" }',
|
||||||
' # Attempt to recover by reinitializing via DAP',
|
' # Attempt recovery: select DAP (target 1) and issue system reset',
|
||||||
' catch { targets 1 }',
|
' puts "INFO: Attempting DAP recovery via system reset..."',
|
||||||
' after 500',
|
|
||||||
' # If DAP is accessible, try writing to system reset register',
|
|
||||||
' catch {',
|
' catch {',
|
||||||
' puts "Attempting SLCR system reset..."',
|
' targets 1',
|
||||||
' mwr 0xF8000200 0x00000001',
|
' rst -system',
|
||||||
' after 1000',
|
' after 1000',
|
||||||
' disconnect',
|
' stop',
|
||||||
' after 1000',
|
|
||||||
' connect',
|
|
||||||
' after 500',
|
|
||||||
' }',
|
' }',
|
||||||
|
' # Disconnect and reconnect to refresh JTAG chain',
|
||||||
|
' catch { disconnect; after 1000; connect; after 500 }',
|
||||||
|
' # Check if ARM cores reappeared',
|
||||||
|
' set target_list2 [targets]',
|
||||||
|
' set has_arm2 0',
|
||||||
|
' foreach t $target_list2 {',
|
||||||
|
' puts " AFTER RECOVERY: $t"',
|
||||||
|
' if {[regexp -nocase {arm|cortex} $t]} { set has_arm2 1 }',
|
||||||
|
' }',
|
||||||
|
' if {!$has_arm2} {',
|
||||||
|
' puts "FATAL: DAP recovery failed — board requires power cycle"',
|
||||||
|
' puts "FATAL: Unplug/replug power, then retry Step 3"',
|
||||||
|
' exit 1',
|
||||||
|
' }',
|
||||||
|
' puts "INFO: ARM cores recovered after DAP reset"',
|
||||||
'}',
|
'}',
|
||||||
'',
|
'',
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -871,9 +871,22 @@ class MainWindow(ctk.CTk):
|
|||||||
self._bitstream_callback,
|
self._bitstream_callback,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dap_fail = False
|
||||||
for result in results:
|
for result in results:
|
||||||
status = "✓" if result.success else "✗"
|
status = "✓" if result.success else "✗"
|
||||||
self._log_message(f" {status} {result.step}: {result.message}")
|
self._log_message(f" {status} {result.step}: {result.message}")
|
||||||
|
if "DAP" in result.message and not result.success:
|
||||||
|
dap_fail = True
|
||||||
|
|
||||||
|
if dap_fail:
|
||||||
|
self._log_message("")
|
||||||
|
self._log_message(" ╔══════════════════════════════════════════╗")
|
||||||
|
self._log_message(" ║ DAP ERROR — JTAG debug port hung ║")
|
||||||
|
self._log_message(" ║ This is caused by prior flash programming║")
|
||||||
|
self._log_message(" ║ → Power-cycle the board (unplug/replug) ║")
|
||||||
|
self._log_message(" ║ → Then re-run Step 3 ║")
|
||||||
|
self._log_message(" ╚══════════════════════════════════════════╝")
|
||||||
|
self._log_message("")
|
||||||
|
|
||||||
return all(r.success for r in results)
|
return all(r.success for r in results)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1138,6 +1151,17 @@ class MainWindow(ctk.CTk):
|
|||||||
|
|
||||||
# Stop on first failure when running all steps
|
# Stop on first failure when running all steps
|
||||||
if not single_step and not success:
|
if not single_step and not success:
|
||||||
|
# Special case: Step 2 pass → Step 3 DAP fail = board needs power cycle
|
||||||
|
if i == 2 and results[0] and not success:
|
||||||
|
self._log_message("")
|
||||||
|
self._log_message(" ┌─────────────────────────────────────────┐")
|
||||||
|
self._log_message(" │ Step 3 failed after flash programming. │")
|
||||||
|
self._log_message(" │ This is normal — program_flash leaves │")
|
||||||
|
self._log_message(" │ the JTAG DAP in error state. │")
|
||||||
|
self._log_message(" │ → Power-cycle the board, then re-run │")
|
||||||
|
self._log_message(" │ Step 3 (Load Bootloader) alone. │")
|
||||||
|
self._log_message(" └─────────────────────────────────────────┘")
|
||||||
|
self._log_message("")
|
||||||
break
|
break
|
||||||
|
|
||||||
# Inter-step delay (skip after last step)
|
# Inter-step delay (skip after last step)
|
||||||
|
|||||||
Reference in New Issue
Block a user