|
16 | 16 |
|
17 | 17 | #include "analogin_api.h"
|
18 | 18 |
|
| 19 | +void WDT_IRQHandler(void) |
| 20 | +{ |
| 21 | + /* Check WDT interrupt flag */ |
| 22 | + if (WDT_GET_TIMEOUT_INT_FLAG()) { |
| 23 | + WDT_CLEAR_TIMEOUT_INT_FLAG(); |
| 24 | + WDT_RESET_COUNTER(); |
| 25 | + } |
| 26 | + |
| 27 | + /* Check WDT wake-up flag */ |
| 28 | + if (WDT_GET_TIMEOUT_WAKEUP_FLAG()) { |
| 29 | + WDT_CLEAR_TIMEOUT_WAKEUP_FLAG(); |
| 30 | + } |
| 31 | +} |
| 32 | + |
19 | 33 | void mbed_sdk_init(void)
|
20 | 34 | {
|
21 | 35 | // NOTE: Support singleton semantics to be called from other init functions
|
@@ -69,4 +83,49 @@ void mbed_sdk_init(void)
|
69 | 83 |
|
70 | 84 | /* Lock protected registers */
|
71 | 85 | SYS_LockReg();
|
| 86 | + |
| 87 | + /* Get around h/w issue with reset from power-down mode |
| 88 | + * |
| 89 | + * When UART interrupt enabled and WDT reset from power-down mode, in the next |
| 90 | + * cycle, UART interrupt keeps breaking in and cannot block unless via NVIC. To |
| 91 | + * get around it, we make up a signal of WDT wake-up from power-down mode in the |
| 92 | + * start of boot process on detecting WDT reset. |
| 93 | + */ |
| 94 | + if (SYS_IS_WDT_RST()) { |
| 95 | + /* Enable IP module clock */ |
| 96 | + CLK_EnableModuleClock(WDT_MODULE); |
| 97 | + |
| 98 | + /* Select IP clock source */ |
| 99 | + CLK_SetModuleClock(WDT_MODULE, CLK_CLKSEL1_WDTSEL_LIRC, 0); |
| 100 | + |
| 101 | + /* The name of symbol WDT_IRQHandler() is mangled in C++ and cannot |
| 102 | + * override that in startup file in C. Note the NVIC_SetVector call |
| 103 | + * cannot be left out when WDT_IRQHandler() is redefined in C++ file. |
| 104 | + * |
| 105 | + * NVIC_SetVector(WDT_IRQn, (uint32_t) WDT_IRQHandler); |
| 106 | + */ |
| 107 | + NVIC_EnableIRQ(WDT_IRQn); |
| 108 | + |
| 109 | + SYS_UnlockReg(); |
| 110 | + |
| 111 | + /* Configure/Enable WDT */ |
| 112 | + WDT->CTL = WDT_TIMEOUT_2POW4 | // Timeout interval of 2^4 LIRC clocks |
| 113 | + WDT_CTL_WDTEN_Msk | // Enable watchdog timer |
| 114 | + WDT_CTL_INTEN_Msk | // Enable interrupt |
| 115 | + WDT_CTL_WKF_Msk | // Clear wake-up flag |
| 116 | + WDT_CTL_WKEN_Msk | // Enable wake-up on timeout |
| 117 | + WDT_CTL_IF_Msk | // Clear interrupt flag |
| 118 | + WDT_CTL_RSTF_Msk | // Clear reset flag |
| 119 | + !WDT_CTL_RSTEN_Msk | // Disable reset |
| 120 | + WDT_CTL_RSTCNT_Msk; // Reset up counter |
| 121 | + |
| 122 | + CLK_PowerDown(); |
| 123 | + |
| 124 | + /* Clear all flags & Disable WDT/INT/WK/RST */ |
| 125 | + WDT->CTL = (WDT_CTL_WKF_Msk | WDT_CTL_IF_Msk | WDT_CTL_RSTF_Msk | WDT_CTL_RSTCNT_Msk); |
| 126 | + |
| 127 | + NVIC_DisableIRQ(WDT_IRQn); |
| 128 | + |
| 129 | + SYS_LockReg(); |
| 130 | + } |
72 | 131 | }
|
0 commit comments