diff --git a/CMSIS/Core/Include/core_cm52.h b/CMSIS/Core/Include/core_cm52.h index ed2a5ab5e..2cfc7323d 100644 --- a/CMSIS/Core/Include/core_cm52.h +++ b/CMSIS/Core/Include/core_cm52.h @@ -4112,16 +4112,18 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - - for(;;) /* wait until reset */ + /* SYSRESETREQ needs to be set repeatedly as it is cleared as soon as the CPU's P-channel + * enters WARM_RST state, but another device can deny the transition preventing the + * actual reset. Such denials are usually transient - we need to re-assert SYSRESETREQ + * to retry. + */ + for(;;) { - __NOP(); + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ } } diff --git a/CMSIS/Core/Include/core_cm55.h b/CMSIS/Core/Include/core_cm55.h index f965376cd..3fce4458d 100644 --- a/CMSIS/Core/Include/core_cm55.h +++ b/CMSIS/Core/Include/core_cm55.h @@ -4238,16 +4238,18 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - - for(;;) /* wait until reset */ + /* SYSRESETREQ needs to be set repeatedly as it is cleared as soon as the CPU's P-channel + * enters WARM_RST state, but another device can deny the transition preventing the + * actual reset. Such denials are usually transient - we need to re-assert SYSRESETREQ + * to retry. + */ + for(;;) { - __NOP(); + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ } } diff --git a/CMSIS/Core/Include/core_cm85.h b/CMSIS/Core/Include/core_cm85.h index a0365e3a3..5f0464ca5 100644 --- a/CMSIS/Core/Include/core_cm85.h +++ b/CMSIS/Core/Include/core_cm85.h @@ -4262,16 +4262,18 @@ __STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) */ __NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) { - __DSB(); /* Ensure all outstanding memory accesses included - buffered write are completed before reset */ - SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - - for(;;) /* wait until reset */ + /* SYSRESETREQ needs to be set repeatedly as it is cleared as soon as the CPU's P-channel + * enters WARM_RST state, but another device can deny the transition preventing the + * actual reset. Such denials are usually transient - we need to re-assert SYSRESETREQ + * to retry. + */ + for(;;) { - __NOP(); + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ } }