Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/stlink-lib/common_legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,30 @@ int32_t stlink_exit_debug_mode(stlink_t *sl) {
return 0;
}

if(sl->flash_type != STM32_FLASH_TYPE_UNKNOWN &&
sl->core_stat != TARGET_RESET) {
// stop debugging if the target has been identified
stlink_write_debug32(sl, STM32_REG_DHCSR, STM32_REG_DHCSR_DBGKEY);
if(sl->flash_type != STM32_FLASH_TYPE_UNKNOWN) {
if(sl->core_stat != TARGET_RESET) {
// stop debugging if the target has been identified
stlink_write_debug32(sl, STM32_REG_DHCSR, STM32_REG_DHCSR_DBGKEY);
}

// Disarm vector-catch-on-reset before detaching. --connect-under-reset
// arms DEMCR.VC_CORERESET (halt-on-reset); it lives in the debug power
// domain and survives NRST, so if left armed the core halts on every reset
// -- including NVIC_SystemReset() from firmware -- and the board looks
// bricked until a power cycle. This must run even when core_stat is
// TARGET_RESET, which is exactly the connect-under-reset case that would
// otherwise skip the cleanup. Only the read failing (dead debug link)
// stops us, and we preserve the other DEMCR bits.
uint32_t demcr = 0;
if(!stlink_read_debug32(sl, STM32_REG_CM3_DEMCR, &demcr) &&
(demcr & STM32_REG_CM3_DEMCR_VC_CORERESET)) {
if(stlink_write_debug32(sl, STM32_REG_CM3_DEMCR,
demcr & ~STM32_REG_CM3_DEMCR_VC_CORERESET)) {
WLOG("Could not clear DEMCR.VC_CORERESET; target may halt on reset\n");
}
// clear the stale vector-catch status in DFSR
stlink_write_debug32(sl, STM32_REG_DFSR, STM32_REG_DFSR_VCATCH);
}
}

return (sl->backend->exit_debug_mode(sl));
Expand Down
Loading