Skip to content

Commit 08dc5c5

Browse files
committed
M487: Get around h/w issue with WDT reset from power-down mode
On WDT reset from power-down mode with NVIC interrupt enabled, in the next reset cycle, NVIC interrupt keeps breaking in abnormally when NVIC interrupt is enabled. To get around it, we deliberately enter the sequence of wake-up timer wake-up reset from deep power-down mode in the start of boot process when WDT reset is detected.
1 parent 0be7685 commit 08dc5c5

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
/* mbed Microcontroller Library
2-
* Copyright (c) 2015-2016 Nuvoton
1+
/*
2+
* Copyright (c) 2015-2016, Nuvoton Technology Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
35
*
46
* Licensed under the Apache License, Version 2.0 (the "License");
57
* you may not use this file except in compliance with the License.
@@ -57,7 +59,7 @@ void mbed_sdk_init(void)
5759

5860
/* Set PCLK0/PCLK1 to HCLK/2 */
5961
CLK->PCLKDIV = (CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2); // PCLK divider set 2
60-
62+
6163
#if DEVICE_ANALOGIN
6264
/* Vref connect to internal */
6365
SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_3_0V;
@@ -69,4 +71,34 @@ void mbed_sdk_init(void)
6971

7072
/* Lock protected registers */
7173
SYS_LockReg();
74+
75+
/* Get around h/w issue with reset from power-down mode
76+
*
77+
* On WDT reset from power-down mode with NVIC interrupt enabled, in the next reset
78+
* cycle, NVIC interrupt keeps breaking in abnormally when NVIC interrupt is enabled.
79+
* To get around it, we deliberately enter the sequence of wake-up timer wake-up reset
80+
* from deep power-down mode in the start of boot process when WDT reset is detected.
81+
*/
82+
if (SYS_IS_WDT_RST()) {
83+
/* Re-unlock protected clock setting */
84+
SYS_UnlockReg();
85+
86+
/* Set up DPD power down mode */
87+
CLK->PMUSTS |= CLK_PMUSTS_CLRWK_Msk;
88+
CLK->PMUSTS |= CLK_PMUSTS_TMRWK_Msk;
89+
CLK_SetPowerDownMode(CLK_PMUCTL_PDMSEL_DPD);
90+
91+
/* Set up PMU wakeup timer, wakeup interval must be WKTMRIS_512 51.2 ms at least */
92+
CLK_SET_WKTMR_INTERVAL(CLK_PMUCTL_WKTMRIS_512);
93+
CLK_ENABLE_WKTMR();
94+
95+
CLK_PowerDown();
96+
97+
/* We must clear WDT reset reason to avoid re-enter the sequence in the current cycle
98+
* and recover PD mode to NPD in the re-reset cycle. Per test, these are done with the
99+
* re-reset, so no need to configure them explicitly. */
100+
101+
/* Wait for re-reset to happen */
102+
while(1);
103+
}
72104
}

targets/TARGET_NUVOTON/TARGET_M480/reset_reason.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ reset_reason_t hal_reset_reason_get(void)
3737
reset_reason_t reset_reason_cast;
3838
uint32_t reset_reason_count = 0;
3939

40+
/* Resolution of WDT reset/WKT reset cascade to NVIC breaking in on WDT reset from PD */
41+
if (CLK->PMUSTS & CLK_PMUSTS_TMRWK_Msk) {
42+
/* Per test, these reset reason flags will set with WKT reset. Clear them for this resolution. */
43+
SYS_CLEAR_RST_SOURCE(SYS_RSTSTS_PINRF_Msk | SYS_RSTSTS_PORF_Msk);
44+
}
45+
4046
if (SYS_IS_POR_RST()) {
4147
reset_reason_cast = RESET_REASON_POWER_ON;
4248
reset_reason_count ++;
@@ -47,7 +53,8 @@ reset_reason_t hal_reset_reason_get(void)
4753
reset_reason_count ++;
4854
}
4955

50-
if (SYS_IS_WDT_RST()) {
56+
/* Resolution of WDT reset/WKT reset cascade to NVIC breaking in on WDT reset from PD */
57+
if (SYS_IS_WDT_RST() || (CLK->PMUSTS & CLK_PMUSTS_TMRWK_Msk)) {
5158
reset_reason_cast = RESET_REASON_WATCHDOG;
5259
reset_reason_count ++;
5360
}
@@ -101,6 +108,15 @@ uint32_t hal_reset_reason_get_raw(void)
101108
void hal_reset_reason_clear(void)
102109
{
103110
SYS_CLEAR_RST_SOURCE(SYS->RSTSTS);
111+
112+
/* Re-unlock protected clock setting */
113+
SYS_UnlockReg();
114+
115+
/* Resolution of WDT reset/WKT reset cascade to NVIC breaking in on WDT reset from PD */
116+
CLK->PMUSTS |= (CLK_PMUSTS_CLRWK_Msk | CLK_PMUSTS_TMRWK_Msk);
117+
118+
/* Lock protected registers */
119+
SYS_LockReg();
104120
}
105121

106122
#endif

0 commit comments

Comments
 (0)