Description:
Since v0.42.0, pyocd load --cbuild-run defaults to post-reset: hardware when the cbuild-run YAML has no load-setup section. This causes a SWD communication failure on devices whose DFPs provide no custom ResetHardware debug sequence.
The fallback ResetHardware in _perform_reset() does a plain nRESET toggle, which resets the entire chip including the DAP. The subsequent post_reset_recovery() attempts to reconnect (SWD line reset + DPIDR read), but fails with No ACK.
After the reconnect fails, DebugCoreStop runs as part of board uninit, which also fails.
This is a load operation, not a debug session - debug teardown shouldn't be attempted when SWD is known to be dead.
Programming always succeeds. The failure is exclusively in the post-load reset.
Regression:
- v0.41.0: No post-reset logic in cbuild-run. Load worked fine.
- v0.42.0: Introduced load-setup processing (per v0.42.0 release notes: "Add processing for pre-reset and post-reset options in load-setup configuration"). Hardcoded 'hardware' default at cbuild_run.py:614. Load fails on affected devices.
Root cause:
cbuild_run.py:614:
reset = self.debugger.get('load-setup', {}).get('post-reset', 'hardware')
When the cbuild-run YAML has no load-setup section (which is the case for all DFPs that don't define it), this defaults to 'hardware'.
The default is 'hardware' and there's no way to change it without a command-line override or manual YAML edit.
Affected devices:
Any device whose DFP provides no ResetHardware debug sequence.
Steps to reproduce:
- Use any Microchip SAM Cortex-M device with a DFP that has no debug sequences
- Build a project with CMSIS-Toolbox (csolution) - the generated .cbuild-run.yml will have no load-setup section
- Run: pyocd load --cbuild-run .cbuild-run.yml
- Programming succeeds
- Post-load hardware reset fails with SWD/JTAG communication failure (No ACK)
- DebugCoreStop also fails during board uninit
Debug log (trimmed):
0002314 I Erased 32768 bytes (1 sector), programmed 1024 bytes (1 page), skipped 0 bytes (0 pages) at 2.30 kB/s [loader]
0002314 D reset, core 0, type=HARDWARE [cortex_m]
0002314 D no delegate or debug sequence handled reset; performing HARDWARE reset, core 0 [cortex_m]
0002570 I DAP is not accessible after reset; attempting reconnect [dap]
0002622 D Sending deprecated SWJ sequence to select SWD [swj]
0002628 D DP IDCODE read failed; resending SWJ sequence (use dormant=False) [dap]
0002635 D Sending SWJ sequence to select SWD; using dormant state [swj]
0002643 D DP IDCODE read failed; resending SWJ sequence (use dormant=False) [dap]
0002654 D uninit board [board]
0002654 D Running debug sequence 'DebugCoreStop' (Cortex-M0+) [cbuild_run]
0002656 E Error while running debug sequence 'DebugCoreStop' (core Cortex-M0+): SWD/JTAG communication failure (No ACK) [cbuild_run]
Expected behavior:
pyocd load should program the device and reset it without errors. For a load (non-debug) operation:
- Program flash
- Reset the target (preferably system reset to keep SWD alive, or skip post-reset entirely)
- Disconnect - no debug teardown needed
Suggested fixes:
- Change the default from 'hardware' to 'system' or 'off' at cbuild_run.py:614. System reset (SYSRESETREQ) resets the CPU without killing the DAP and works across vendors.
Workarounds:
- pyocd load -O load.post_reset=sysresetreq --cbuild-run ...
Environment:
- pyOCD: v0.44.0 (regression introduced in v0.42.0)
- Device: Microchip PIC32CM5164JH01100
- DFP: Microchip PIC32CM-JH_DFP 1.6.272
- Probe: On-board CMSIS-DAP (Curiosity Pro)
- OS: Windows 11
- CMSIS-Toolbox: 2.10.0
Description:
Since v0.42.0, pyocd load --cbuild-run defaults to post-reset: hardware when the cbuild-run YAML has no load-setup section. This causes a SWD communication failure on devices whose DFPs provide no custom ResetHardware debug sequence.
The fallback ResetHardware in _perform_reset() does a plain nRESET toggle, which resets the entire chip including the DAP. The subsequent post_reset_recovery() attempts to reconnect (SWD line reset + DPIDR read), but fails with No ACK.
After the reconnect fails, DebugCoreStop runs as part of board uninit, which also fails.
This is a load operation, not a debug session - debug teardown shouldn't be attempted when SWD is known to be dead.
Programming always succeeds. The failure is exclusively in the post-load reset.
Regression:
Root cause:
cbuild_run.py:614:
reset = self.debugger.get('load-setup', {}).get('post-reset', 'hardware')
When the cbuild-run YAML has no load-setup section (which is the case for all DFPs that don't define it), this defaults to 'hardware'.
The default is 'hardware' and there's no way to change it without a command-line override or manual YAML edit.
Affected devices:
Any device whose DFP provides no ResetHardware debug sequence.
Steps to reproduce:
Debug log (trimmed):
0002314 I Erased 32768 bytes (1 sector), programmed 1024 bytes (1 page), skipped 0 bytes (0 pages) at 2.30 kB/s [loader]
0002314 D reset, core 0, type=HARDWARE [cortex_m]
0002314 D no delegate or debug sequence handled reset; performing HARDWARE reset, core 0 [cortex_m]
0002570 I DAP is not accessible after reset; attempting reconnect [dap]
0002622 D Sending deprecated SWJ sequence to select SWD [swj]
0002628 D DP IDCODE read failed; resending SWJ sequence (use dormant=False) [dap]
0002635 D Sending SWJ sequence to select SWD; using dormant state [swj]
0002643 D DP IDCODE read failed; resending SWJ sequence (use dormant=False) [dap]
0002654 D uninit board [board]
0002654 D Running debug sequence 'DebugCoreStop' (Cortex-M0+) [cbuild_run]
0002656 E Error while running debug sequence 'DebugCoreStop' (core Cortex-M0+): SWD/JTAG communication failure (No ACK) [cbuild_run]
Expected behavior:
pyocd load should program the device and reset it without errors. For a load (non-debug) operation:
Suggested fixes:
Workarounds:
Environment: