Skip to content

Commit b26fd71

Browse files
committed
Resolve M480 WDT reset H/W limit by reset from deep power-down
1 parent 9738b27 commit b26fd71

File tree

1 file changed

+12
-49
lines changed

1 file changed

+12
-49
lines changed

targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c

Lines changed: 12 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,6 @@
1818

1919
#include "analogin_api.h"
2020

21-
void WDT_IRQHandler(void)
22-
{
23-
/* Check WDT interrupt flag */
24-
if (WDT_GET_TIMEOUT_INT_FLAG()) {
25-
WDT_CLEAR_TIMEOUT_INT_FLAG();
26-
WDT_RESET_COUNTER();
27-
}
28-
29-
/* Check WDT wake-up flag */
30-
if (WDT_GET_TIMEOUT_WAKEUP_FLAG()) {
31-
WDT_CLEAR_TIMEOUT_WAKEUP_FLAG();
32-
}
33-
}
34-
3521
void mbed_sdk_init(void)
3622
{
3723
// NOTE: Support singleton semantics to be called from other init functions
@@ -73,7 +59,7 @@ void mbed_sdk_init(void)
7359

7460
/* Set PCLK0/PCLK1 to HCLK/2 */
7561
CLK->PCLKDIV = (CLK_PCLKDIV_PCLK0DIV2 | CLK_PCLKDIV_PCLK1DIV2); // PCLK divider set 2
76-
62+
7763
#if DEVICE_ANALOGIN
7864
/* Vref connect to internal */
7965
SYS->VREFCTL = (SYS->VREFCTL & ~SYS_VREFCTL_VREFCTL_Msk) | SYS_VREFCTL_VREF_3_0V;
@@ -86,52 +72,29 @@ void mbed_sdk_init(void)
8672
/* Lock protected registers */
8773
SYS_LockReg();
8874

89-
/* Get around h/w issue with reset from power-down mode
75+
/* Get around h/w issue with reset from deep power-down mode
9076
*
9177
* When UART interrupt enabled and WDT reset from power-down mode, in the next
9278
* cycle, UART interrupt keeps breaking in and cannot block unless via NVIC. To
93-
* get around it, we make up a signal of WDT wake-up from power-down mode in the
79+
* get around it, we make up a signal of wake-up from deep power-down mode in the
9480
* start of boot process on detecting WDT reset.
9581
*/
9682
if (SYS_IS_WDT_RST()) {
97-
/* Re-unlock to highlight WDT clock setting is protected */
83+
/* Re-unlock protected clock setting */
9884
SYS_UnlockReg();
9985

100-
/* Enable IP module clock */
101-
CLK_EnableModuleClock(WDT_MODULE);
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);
10290

103-
/* Select IP clock source */
104-
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
105-
106-
/* The name of symbol WDT_IRQHandler() is mangled in C++ and cannot
107-
* override that in startup file in C. Note the NVIC_SetVector call
108-
* cannot be left out when WDT_IRQHandler() is redefined in C++ file.
109-
*
110-
* NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler);
111-
*/
112-
NVIC_EnableIRQ(WDT_IRQn);
113-
114-
/* Configure/Enable WDT */
115-
WDT->CTL = WDT_TIMEOUT_2POW4 | // Timeout interval of 2^4 LIRC clocks
116-
WDT_CTL_WDTEN_Msk | // Enable watchdog timer
117-
WDT_CTL_INTEN_Msk | // Enable interrupt
118-
WDT_CTL_WKF_Msk | // Clear wake-up flag
119-
WDT_CTL_WKEN_Msk | // Enable wake-up on timeout
120-
WDT_CTL_IF_Msk | // Clear interrupt flag
121-
WDT_CTL_RSTF_Msk | // Clear reset flag
122-
!WDT_CTL_RSTEN_Msk | // Disable reset
123-
WDT_CTL_RSTCNT_Msk; // Reset up counter
91+
/* Set up PMU wakeup timer, wakeup interval must be WKTMRIS_256 25.6 ms at least */
92+
CLK_SET_WKTMR_INTERVAL(CLK_PMUCTL_WKTMRIS_256);
93+
CLK_ENABLE_WKTMR();
12494

12595
CLK_PowerDown();
12696

127-
/* Re-unlock for safe */
128-
SYS_UnlockReg();
129-
130-
/* Clear all flags & Disable WDT/INT/WK/RST */
131-
WDT->CTL = (WDT_CTL_WKF_Msk | WDT_CTL_IF_Msk | WDT_CTL_RSTF_Msk | WDT_CTL_RSTCNT_Msk);
132-
133-
NVIC_DisableIRQ(WDT_IRQn);
134-
13597
SYS_LockReg();
13698
}
99+
137100
}

0 commit comments

Comments
 (0)