diff --git a/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c b/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c index ca69b8deb42..119fce578d0 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c @@ -111,9 +111,11 @@ void mbed_sdk_init(void) * and WDT wake-up from PD will. So don't rely on SYS_IS_WDT_RST() to * determine to use or not the workaround. * - * NOTE: To avoid the workaround duplicate run by bootloader (e.g. MCUBoot) - * and application and then crash when bootloader is enabled, the workaround - * is applied only when any H/W reset flag (SYS.RSTSTS) raised. + * NOTE: We may trap in DPD/SPD wake-up reset loop when multi-level + * bootloaders (e.g. LDROM and MCUBoot) and application all integrate + * this workaround. To avoid this, the wake-up flag CLK_PMUSTS_TMRWK_Msk + * is used to guard from duplicate wake-up reset setups by delaying + * its clean-up to hal_watchdog_init (watchdog_api.c). * * NOTE: The workaround will change SYS.RSTSTS and DEVICE_RESET_REASON won't * work as expected. Don't enable MBED_CONF_TARGET_WDT_RESET_WORKAROUND and @@ -133,31 +135,10 @@ MBED_CONF_TARGET_WDT_RESET_WORKAROUND and DEVICE_RESET_REASON \ at the same time." #endif -#define ALL_RESET_FLAGS \ - (SYS_RSTSTS_PORF_Msk | \ - SYS_RSTSTS_PINRF_Msk | \ - SYS_RSTSTS_WDTRF_Msk | \ - SYS_RSTSTS_LVRF_Msk | \ - SYS_RSTSTS_BODRF_Msk | \ - SYS_RSTSTS_SYSRF_Msk | \ - SYS_RSTSTS_CPURF_Msk | \ - SYS_RSTSTS_CPULKRF_Msk) - - /* Apply the workaround only when any H/W reset flag is raised. For - * bootloader enabled application, the workaround must apply either - * by bootloader or by application, but not both. - */ - if (SYS->RSTSTS & ALL_RESET_FLAGS) { + do { /* Re-unlock protected clock setting */ SYS_UnlockReg(); - /* Without this, bootloader enabled application will trap in - * loop of wake-up timer wake-up reset armed here by bootloader - * and application alternately, if both integrate this piece - * of code. - */ - SYS_CLEAR_RST_SOURCE(ALL_RESET_FLAGS); - /* Release I/O hold status */ CLK->IOPDCTL = 1; @@ -174,12 +155,14 @@ at the same time." MBED_UNREACHABLE; } - /* Clean previous wake-up flag */ - CLK->PMUSTS |= (CLK_PMUSTS_CLRWK_Msk | CLK_PMUSTS_TMRWK_Msk); + /* Don't clean wake-up flag here (see above) */ + #if 0 + CLK->PMUSTS |= (CLK_PMUSTS_CLRWK_Msk | CLK_PMUSTS_TMRWK_Msk); + #endif /* Lock protected registers */ SYS_LockReg(); - } + } while (0); #endif } diff --git a/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c b/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c index 4157e30940e..c438d247018 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/watchdog_api.c @@ -88,6 +88,13 @@ watchdog_status_t hal_watchdog_init(const watchdog_config_t *config) SYS_UnlockReg(); + /* See mbed_sdk_init (mbed_override.c) on workaround to + * H/W limit with WDT reset from PD. + */ +#if MBED_CONF_TARGET_WDT_RESET_WORKAROUND + CLK->PMUSTS |= (CLK_PMUSTS_CLRWK_Msk | CLK_PMUSTS_TMRWK_Msk); +#endif + /* Enable IP module clock */ CLK_EnableModuleClock(WDT_MODULE);