Harden cortexm_reset() and remove double reset(#601)
Thanks to Dave Marples <dave@marples.net> for input. - Issue only one reset. Start with SRST. Only if not seen, use SYSRESETREQ - Wait for release of DHCSR_S_RESET_ST before issuing more commands - Add timeout to catch reset line stuck low - Remove AP errors
This commit is contained in:
parent
bc84d803ea
commit
effd43ce38
|
@ -598,36 +598,43 @@ static void cortexm_pc_write(target *t, const uint32_t val)
|
||||||
* using the core debug registers in the NVIC. */
|
* using the core debug registers in the NVIC. */
|
||||||
static void cortexm_reset(target *t)
|
static void cortexm_reset(target *t)
|
||||||
{
|
{
|
||||||
|
/* Read DHCSR here to clear S_RESET_ST bit before reset */
|
||||||
|
target_mem_read32(t, CORTEXM_DHCSR);
|
||||||
|
platform_timeout to;
|
||||||
if ((t->target_options & CORTEXM_TOPT_INHIBIT_SRST) == 0) {
|
if ((t->target_options & CORTEXM_TOPT_INHIBIT_SRST) == 0) {
|
||||||
platform_srst_set_val(true);
|
platform_srst_set_val(true);
|
||||||
platform_srst_set_val(false);
|
platform_srst_set_val(false);
|
||||||
|
/* Some NRF52840 users saw invalid SWD transaction with
|
||||||
|
* native/firmware without this delay.*/
|
||||||
|
platform_delay(10);
|
||||||
|
}
|
||||||
|
uint32_t dhcsr = target_mem_read32(t, CORTEXM_DHCSR);
|
||||||
|
if ((dhcsr & CORTEXM_DHCSR_S_RESET_ST) == 0) {
|
||||||
|
/* No reset seen yet, maybe as SRST is not connected, or device has
|
||||||
|
* CORTEXM_TOPT_INHIBIT_SRST set.
|
||||||
|
* Trigger reset by AIRCR.*/
|
||||||
|
target_mem_write32(t, CORTEXM_AIRCR,
|
||||||
|
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read DHCSR here to clear S_RESET_ST bit before reset */
|
|
||||||
target_mem_read32(t, CORTEXM_DHCSR);
|
|
||||||
|
|
||||||
/* Request system reset from NVIC: SRST doesn't work correctly */
|
|
||||||
/* This could be VECTRESET: 0x05FA0001 (reset only core)
|
|
||||||
* or SYSRESETREQ: 0x05FA0004 (system reset)
|
|
||||||
*/
|
|
||||||
target_mem_write32(t, CORTEXM_AIRCR,
|
|
||||||
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
|
|
||||||
|
|
||||||
/* If target needs to do something extra (see Atmel SAM4L for example) */
|
/* If target needs to do something extra (see Atmel SAM4L for example) */
|
||||||
if (t->extended_reset != NULL) {
|
if (t->extended_reset != NULL) {
|
||||||
t->extended_reset(t);
|
t->extended_reset(t);
|
||||||
}
|
}
|
||||||
|
/* Wait for CORTEXM_DHCSR_S_RESET_ST to read 0, meaning reset released.*/
|
||||||
/* Poll for release from reset */
|
platform_timeout_set(&to, 1000);
|
||||||
while (target_mem_read32(t, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
|
while ((target_mem_read32(t, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST) &&
|
||||||
|
!platform_timeout_is_expired(&to));
|
||||||
|
#if defined(PLATFORM_HAS_DEBUG)
|
||||||
|
if (platform_timeout_is_expired(&to))
|
||||||
|
DEBUG("Reset seem to be stuck low!\n");
|
||||||
|
#endif
|
||||||
|
/* 10 ms delay to ensure that things such as the STM32 HSI clock
|
||||||
|
* have started up fully. */
|
||||||
|
platform_delay(10);
|
||||||
/* Reset DFSR flags */
|
/* Reset DFSR flags */
|
||||||
target_mem_write32(t, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
|
target_mem_write32(t, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
|
||||||
|
/* Make sure we ignore any initial DAP error */
|
||||||
/* 1ms delay to ensure that things such as the stm32f1 HSI clock have started
|
target_check_error(t);
|
||||||
* up fully.
|
|
||||||
*/
|
|
||||||
platform_delay(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cortexm_halt_request(target *t)
|
static void cortexm_halt_request(target *t)
|
||||||
|
|
Loading…
Reference in New Issue