Skip to content

Commit ccde03a

Browse files
authored
Merge pull request ARMmbed#14567 from OpenNuvoton/nvt_m480_wdt_rst
M487: Resolve WDT reset H/W limit
2 parents 99cf33c + e38b691 commit ccde03a

File tree

3 files changed

+28
-59
lines changed

3 files changed

+28
-59
lines changed

targets/TARGET_NUVOTON/TARGET_M480/device/startup_M480.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,7 @@ void Reset_Handler_1(void)
392392
{
393393
/* Disable register write-protection function */
394394
SYS_UnlockReg();
395-
396-
/* Disable Power-on Reset function */
397-
SYS_DISABLE_POR();
398-
395+
399396
/**
400397
* NOTE 1: Some register accesses require unlock.
401398
* NOTE 2: Because EBI (external SRAM) init is done in SystemInit(), SystemInit() must be called at the very start.

targets/TARGET_NUVOTON/TARGET_M480/mbed_overrides.c

Lines changed: 10 additions & 54 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,22 @@ 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
90-
*
91-
* When UART interrupt enabled and WDT reset from power-down mode, in the next
92-
* 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
94-
* start of boot process on detecting WDT reset.
95-
*/
75+
/* Get around h/w limit with WDT reset from PD */
9676
if (SYS_IS_WDT_RST()) {
97-
/* Re-unlock to highlight WDT clock setting is protected */
77+
/* Re-unlock protected clock setting */
9878
SYS_UnlockReg();
9979

100-
/* Enable IP module clock */
101-
CLK_EnableModuleClock(WDT_MODULE);
102-
103-
/* Select IP clock source */
104-
CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0);
80+
/* Set up DPD power down mode */
81+
CLK->PMUSTS |= CLK_PMUSTS_CLRWK_Msk;
82+
CLK->PMUSTS |= CLK_PMUSTS_TMRWK_Msk;
83+
CLK_SetPowerDownMode(CLK_PMUCTL_PDMSEL_DPD);
10584

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
85+
CLK_SET_WKTMR_INTERVAL(CLK_PMUCTL_WKTMRIS_256);
86+
CLK_ENABLE_WKTMR();
12487

12588
CLK_PowerDown();
12689

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-
90+
/* Lock protected registers */
13591
SYS_LockReg();
13692
}
13793
}

targets/TARGET_NUVOTON/TARGET_M480/reset_reason.c

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

42+
/* Get around h/w limit with 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+
4248
if (SYS_IS_POR_RST()) {
4349
reset_reason_cast = RESET_REASON_POWER_ON;
4450
reset_reason_count ++;
@@ -49,7 +55,8 @@ reset_reason_t hal_reset_reason_get(void)
4955
reset_reason_count ++;
5056
}
5157

52-
if (SYS_IS_WDT_RST()) {
58+
/* Get around h/w limit with WDT reset from PD */
59+
if (SYS_IS_WDT_RST() || (CLK->PMUSTS & CLK_PMUSTS_TMRWK_Msk)) {
5360
reset_reason_cast = RESET_REASON_WATCHDOG;
5461
reset_reason_count ++;
5562
}
@@ -103,6 +110,15 @@ uint32_t hal_reset_reason_get_raw(void)
103110
void hal_reset_reason_clear(void)
104111
{
105112
SYS_CLEAR_RST_SOURCE(SYS->RSTSTS);
113+
114+
/* Re-unlock protected clock setting */
115+
SYS_UnlockReg();
116+
117+
/* Get around h/w limit with WDT reset from PD */
118+
CLK->PMUSTS |= (CLK_PMUSTS_CLRWK_Msk | CLK_PMUSTS_TMRWK_Msk);
119+
120+
/* Lock protected registers */
121+
SYS_LockReg();
106122
}
107123

108124
#endif

0 commit comments

Comments
 (0)