diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/sleep.c b/targets/TARGET_NUVOTON/TARGET_NUC472/sleep.c index ae41314636..321377702a 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/sleep.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/sleep.c @@ -40,7 +40,14 @@ void hal_sleep(void) /** * Enter power-down mode, in which HXT/HIRC are halted. + * + * \note On NUC472, on wake-up from power-down mode, we may meet hard fault or + * some other unknown error. Before its cause is found, we enter idle mode + * instead for a workaround. To simulate power-down mode with idle mode, we + * also disable us_ticker during power-down period. */ +#include "nu_modutil.h" +const struct nu_modinit_s *nu_us_ticker_modinit(void); void hal_deepsleep(void) { #if DEVICE_SERIAL @@ -49,9 +56,11 @@ void hal_deepsleep(void) } #endif + CLK_DisableModuleClock(nu_us_ticker_modinit()->clkidx); SYS_UnlockReg(); - CLK_PowerDown(); + CLK_Idle(); SYS_LockReg(); + CLK_EnableModuleClock(nu_us_ticker_modinit()->clkidx); } #endif diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c b/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c index 78997c68a9..4a3bca7886 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/us_ticker.c @@ -38,6 +38,13 @@ static void tmr0_vec(void); static const struct nu_modinit_s timer0_modinit = {TIMER_0, TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_PCLK, 0, TMR0_RST, TMR0_IRQn, (void *) tmr0_vec}; +/* Externalize this function for hal_deepsleep() to get around unknown error + * with power-down. */ +const struct nu_modinit_s *nu_us_ticker_modinit(void) +{ + return &timer0_modinit; +} + #define TIMER_MODINIT timer0_modinit /* Track ticker status */