LPC1768 and LPC11U24 watchdog timer

Dependents:   GSwifi_tsutenkaku barometer-m0 BMAGThrRev

Committer:
okini3939
Date:
Wed May 25 08:52:32 2016 +0000
Revision:
3:b1efde09d8a7
Parent:
2:f6f05e2eafd0
supported LPC8XX

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 1:f7baa89f84bc 1 #include "mbed.h"
okini3939 1:f7baa89f84bc 2 #include "WDT.h"
okini3939 1:f7baa89f84bc 3
okini3939 2:f6f05e2eafd0 4 FunctionPointer Watchdog::_fptr;
okini3939 2:f6f05e2eafd0 5
okini3939 2:f6f05e2eafd0 6 // Simon's Watchdog
okini3939 2:f6f05e2eafd0 7 // see: http://mbed.org/forum/mbed/topic/508/
okini3939 1:f7baa89f84bc 8 void Watchdog::init(float s) {
okini3939 1:f7baa89f84bc 9 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 1:f7baa89f84bc 10 LPC_WDT->WDCLKSEL = 0x01; // Set CLK src to PCLK
okini3939 1:f7baa89f84bc 11 uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK default is /4
okini3939 1:f7baa89f84bc 12 LPC_WDT->WDTC = s * (float)clk;
okini3939 1:f7baa89f84bc 13 LPC_WDT->WDMOD = 0x03; // Enabled and Reset
okini3939 2:f6f05e2eafd0 14 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 3:b1efde09d8a7 15 LPC_WWDT->CLKSEL = 0x01; // Set CLK src to WDOSC
okini3939 3:b1efde09d8a7 16 uint32_t clk = 500000 / 64 / 4; // WD has a fixed /4 prescaler, WDOSC default is /4
okini3939 1:f7baa89f84bc 17 LPC_WWDT->TC = s * (float)clk;
okini3939 1:f7baa89f84bc 18 LPC_WWDT->MOD = 0x03; // Enabled and Reset
okini3939 3:b1efde09d8a7 19 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 20 LPC_SYSCON->WDTOSCCTRL = (0xA << 5); // wdt_osc_clk = Fclkana/2, Fclkana = 3.5MHz
okini3939 3:b1efde09d8a7 21 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 17); // Enable Clock WWDT
okini3939 3:b1efde09d8a7 22 LPC_SYSCON->PDRUNCFG &= ~(1 << 6); // Enable Power WDTOSC_PD
okini3939 3:b1efde09d8a7 23 uint32_t clk = ((3500000 / 2) / 4); // COUNT = wdt_osc_clk/4
okini3939 3:b1efde09d8a7 24 LPC_WWDT->TC = s * (float)clk;
okini3939 3:b1efde09d8a7 25 LPC_WWDT->MOD = 0x3; // Enabled and Reset
okini3939 1:f7baa89f84bc 26 #endif
okini3939 1:f7baa89f84bc 27 kick();
okini3939 1:f7baa89f84bc 28 }
okini3939 1:f7baa89f84bc 29 // "kick" or "feed" the dog - reset the watchdog timer
okini3939 1:f7baa89f84bc 30 // by writing this required bit pattern
okini3939 1:f7baa89f84bc 31 void Watchdog::kick() {
okini3939 1:f7baa89f84bc 32 __disable_irq();
okini3939 1:f7baa89f84bc 33 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 1:f7baa89f84bc 34 LPC_WDT->WDFEED = 0xAA;
okini3939 1:f7baa89f84bc 35 LPC_WDT->WDFEED = 0x55;
okini3939 2:f6f05e2eafd0 36 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 1:f7baa89f84bc 37 LPC_WWDT->FEED = 0xAA;
okini3939 1:f7baa89f84bc 38 LPC_WWDT->FEED = 0x55;
okini3939 3:b1efde09d8a7 39 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 40 LPC_WWDT->FEED = 0xAA;
okini3939 3:b1efde09d8a7 41 LPC_WWDT->FEED = 0x55;
okini3939 1:f7baa89f84bc 42 #endif
okini3939 1:f7baa89f84bc 43 __enable_irq();
okini3939 1:f7baa89f84bc 44 }
okini3939 1:f7baa89f84bc 45
okini3939 1:f7baa89f84bc 46 int Watchdog::getFlg () {
okini3939 1:f7baa89f84bc 47 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 1:f7baa89f84bc 48 return LPC_WDT->WDMOD & (1<<2) ? 1 : 0;
okini3939 2:f6f05e2eafd0 49 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 1:f7baa89f84bc 50 return LPC_WWDT->MOD & (1<<2) ? 1 : 0;
okini3939 3:b1efde09d8a7 51 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 52 return LPC_WWDT->MOD & (1<<2) ? 1 : 0;
okini3939 1:f7baa89f84bc 53 #endif
okini3939 1:f7baa89f84bc 54 }
okini3939 2:f6f05e2eafd0 55
okini3939 2:f6f05e2eafd0 56 void Watchdog::attach (void (*fptr)(void), float s) {
okini3939 2:f6f05e2eafd0 57 if (fptr) {
okini3939 2:f6f05e2eafd0 58 _fptr.attach(fptr);
okini3939 2:f6f05e2eafd0 59 }
okini3939 2:f6f05e2eafd0 60 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 61 LPC_WDT->WDCLKSEL = 0x02; // Set CLK src to RTC
okini3939 2:f6f05e2eafd0 62 uint32_t clk = 32768 / 4; // WD has a fixed /4 prescaler
okini3939 2:f6f05e2eafd0 63 LPC_WDT->WDTC = s * (float)clk;
okini3939 2:f6f05e2eafd0 64 LPC_WDT->WDMOD = 0x01; // Enabled but Reset disable
okini3939 2:f6f05e2eafd0 65 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 66 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15);
okini3939 2:f6f05e2eafd0 67 LPC_SYSCON->PDRUNCFG &= ~(1<<6); // WDT on
okini3939 2:f6f05e2eafd0 68 LPC_SYSCON->WDTOSCCTRL = (1<<5)|(0x1f<<0); // 500kHz / 64
okini3939 2:f6f05e2eafd0 69
okini3939 3:b1efde09d8a7 70 LPC_WWDT->CLKSEL = (1<<0); // Set CLK src to WDOSC
okini3939 3:b1efde09d8a7 71 uint32_t clk = 500000 / 64 / 4; // WD has a fixed /4 prescaler, WDOSC default is /4
okini3939 2:f6f05e2eafd0 72 LPC_WWDT->TC = s * (float)clk;
okini3939 2:f6f05e2eafd0 73 LPC_WWDT->WARNINT = 0;
okini3939 2:f6f05e2eafd0 74 LPC_WWDT->MOD = 0x01; // Enabled but Reset disable
okini3939 2:f6f05e2eafd0 75 kick();
okini3939 2:f6f05e2eafd0 76 LPC_SYSCON->STARTERP1 |= (1<<12);
okini3939 3:b1efde09d8a7 77 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 78 LPC_SYSCON->WDTOSCCTRL = (0xA << 5); // wdt_osc_clk = Fclkana/2, Fclkana = 3.5MHz
okini3939 3:b1efde09d8a7 79 LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 17); // Enable Clock WWDT
okini3939 3:b1efde09d8a7 80 LPC_SYSCON->PDRUNCFG &= ~(1 << 6); // Enable Power WDTOSC_PD
okini3939 3:b1efde09d8a7 81 uint32_t clk = ((3500000 / 2) / 4); // COUNT = wdt_osc_clk/4
okini3939 3:b1efde09d8a7 82 LPC_WWDT->TC = s * (float)clk;
okini3939 3:b1efde09d8a7 83 LPC_WWDT->WARNINT = 0;
okini3939 3:b1efde09d8a7 84 LPC_WWDT->MOD = 0x1; // Enabled and Reset
okini3939 3:b1efde09d8a7 85 kick();
okini3939 3:b1efde09d8a7 86 LPC_SYSCON->STARTERP1 |= (1<<12);
okini3939 2:f6f05e2eafd0 87 #endif
okini3939 2:f6f05e2eafd0 88 NVIC_SetVector(WDT_IRQn, (uint32_t)&Watchdog::isr_wdt);
okini3939 2:f6f05e2eafd0 89 NVIC_ClearPendingIRQ(WDT_IRQn);
okini3939 2:f6f05e2eafd0 90 NVIC_EnableIRQ(WDT_IRQn);
okini3939 2:f6f05e2eafd0 91 }
okini3939 2:f6f05e2eafd0 92
okini3939 2:f6f05e2eafd0 93 template<typename T>
okini3939 2:f6f05e2eafd0 94 void Watchdog::attach (T *object, void (*fptr)(void), float s) {
okini3939 2:f6f05e2eafd0 95 if (fptr) {
okini3939 2:f6f05e2eafd0 96 _fptr.attach(object, fptr);
okini3939 2:f6f05e2eafd0 97 }
okini3939 2:f6f05e2eafd0 98 attach(NULL, s);
okini3939 2:f6f05e2eafd0 99 }
okini3939 2:f6f05e2eafd0 100
okini3939 2:f6f05e2eafd0 101 void Watchdog::isr_wdt(void) {
okini3939 2:f6f05e2eafd0 102 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 103 LPC_WDT->WDMOD |= (1<<3);
okini3939 2:f6f05e2eafd0 104 LPC_WDT->WDMOD &= ~(1<<2);
okini3939 2:f6f05e2eafd0 105 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 106 LPC_WWDT->MOD |= (1<<3);
okini3939 2:f6f05e2eafd0 107 LPC_WWDT->MOD &= ~(1<<2);
okini3939 3:b1efde09d8a7 108 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 109 LPC_WWDT->MOD |= (1<<3);
okini3939 3:b1efde09d8a7 110 LPC_WWDT->MOD &= ~(1<<2);
okini3939 2:f6f05e2eafd0 111 #endif
okini3939 2:f6f05e2eafd0 112 _fptr.call();
okini3939 2:f6f05e2eafd0 113 }
okini3939 2:f6f05e2eafd0 114
okini3939 2:f6f05e2eafd0 115 void Watchdog::sleep () {
okini3939 2:f6f05e2eafd0 116 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 117 LPC_SC->PCON = 0;
okini3939 2:f6f05e2eafd0 118 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 119 LPC_PMU->PCON = 0;
okini3939 3:b1efde09d8a7 120 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 121 LPC_PMU->PCON = 0;
okini3939 2:f6f05e2eafd0 122 #endif
okini3939 2:f6f05e2eafd0 123 SCB->SCR &= ~(1<<2);
okini3939 2:f6f05e2eafd0 124 __WFI();
okini3939 2:f6f05e2eafd0 125 }
okini3939 2:f6f05e2eafd0 126
okini3939 2:f6f05e2eafd0 127 void Watchdog::deepSleep () {
okini3939 2:f6f05e2eafd0 128 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 129 LPC_SC->PCON &= ~(7<<0);
okini3939 2:f6f05e2eafd0 130 LPC_SC->PCON |= (1<<0);
okini3939 2:f6f05e2eafd0 131 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 132 LPC_SYSCON->PDSLEEPCFG &= ~(1<<6); // WDT on
okini3939 2:f6f05e2eafd0 133 LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
okini3939 2:f6f05e2eafd0 134 LPC_PMU->PCON &= ~(7<<0);
okini3939 2:f6f05e2eafd0 135 LPC_PMU->PCON |= (1<<0);
okini3939 3:b1efde09d8a7 136 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 137 LPC_SYSCON->PDSLEEPCFG &= ~(1<<6); // WDT on
okini3939 3:b1efde09d8a7 138 LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
okini3939 3:b1efde09d8a7 139 LPC_PMU->PCON &= ~(7<<0);
okini3939 3:b1efde09d8a7 140 LPC_PMU->PCON |= (1<<0);
okini3939 2:f6f05e2eafd0 141 #endif
okini3939 2:f6f05e2eafd0 142 SCB->SCR |= (1<<2);
okini3939 2:f6f05e2eafd0 143 __WFI();
okini3939 2:f6f05e2eafd0 144 }
okini3939 3:b1efde09d8a7 145
okini3939 3:b1efde09d8a7 146 void Watchdog::powerDown () {
okini3939 3:b1efde09d8a7 147 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 3:b1efde09d8a7 148 LPC_SC->PCON &= ~(7<<0);
okini3939 3:b1efde09d8a7 149 LPC_SC->PCON |= (2<<0);
okini3939 3:b1efde09d8a7 150 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 3:b1efde09d8a7 151 LPC_SYSCON->PDSLEEPCFG &= ~(1<<6); // WDT on
okini3939 3:b1efde09d8a7 152 LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
okini3939 3:b1efde09d8a7 153 LPC_PMU->PCON &= ~(7<<0);
okini3939 3:b1efde09d8a7 154 LPC_PMU->PCON = (2<<0);
okini3939 3:b1efde09d8a7 155 #elif defined(TARGET_LPC81X) || defined(TARGET_LPC82X)
okini3939 3:b1efde09d8a7 156 LPC_SYSCON->PDSLEEPCFG &= ~(1<<6); // WDT on
okini3939 3:b1efde09d8a7 157 LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
okini3939 3:b1efde09d8a7 158 LPC_PMU->PCON &= ~(7<<0);
okini3939 3:b1efde09d8a7 159 LPC_PMU->PCON = (2<<0);
okini3939 3:b1efde09d8a7 160 #endif
okini3939 3:b1efde09d8a7 161 SCB->SCR |= (1<<2);
okini3939 3:b1efde09d8a7 162 __WFI();
okini3939 3:b1efde09d8a7 163 }