Skip to content

Commit 962c161

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 962c161

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
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: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
/* mbed Microcontroller Library
2-
* Copyright (c) 2017-2018 Nuvoton
1+
/*
2+
* Copyright (c) 2017-2018, 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.
@@ -37,6 +39,12 @@ reset_reason_t hal_reset_reason_get(void)
3739
reset_reason_t reset_reason_cast;
3840
uint32_t reset_reason_count = 0;
3941

42+
/* Resolution of WDT reset/WKT reset cascade to NVIC breaking in on WDT reset from PD */
43+
if (CLK->PMUSTS & CLK_PMUSTS_TMRWK_Msk) {
44+
/* Per test, these reset reason flags will set with WKT reset. Clear them for this resolution. */
45+
SYS_CLEAR_RST_SOURCE(SYS_RSTSTS_PINRF_Msk | SYS_RSTSTS_PORF_Msk);
46+
}
47+
4048
if (SYS_IS_POR_RST()) {
4149
reset_reason_cast = RESET_REASON_POWER_ON;
4250
reset_reason_count ++;
@@ -47,7 +55,8 @@ reset_reason_t hal_reset_reason_get(void)
4755
reset_reason_count ++;
4856
}
4957

50-
if (SYS_IS_WDT_RST()) {
58+
/* Resolution of WDT reset/WKT reset cascade to NVIC breaking in on WDT reset from PD */
59+
if (SYS_IS_WDT_RST() || (CLK->PMUSTS & CLK_PMUSTS_TMRWK_Msk)) {
5160
reset_reason_cast = RESET_REASON_WATCHDOG;
5261
reset_reason_count ++;
5362
}
@@ -101,6 +110,15 @@ uint32_t hal_reset_reason_get_raw(void)
101110
void hal_reset_reason_clear(void)
102111
{
103112
SYS_CLEAR_RST_SOURCE(SYS->RSTSTS);
113+
114+
/* Re-unlock protected clock setting */
115+
SYS_UnlockReg();
116+
117+
/* Resolution of WDT reset/WKT reset cascade to NVIC breaking in on WDT reset from PD */
118+
CLK->PMUSTS |= (CLK_PMUSTS_CLRWK_Msk | CLK_PMUSTS_TMRWK_Msk);
119+
120+
/* Lock protected registers */
121+
SYS_LockReg();
104122
}
105123

106124
#endif

0 commit comments

Comments
 (0)