LPC1768 and LPC11U24 watchdog timer

Dependents:   GSwifi_tsutenkaku barometer-m0 BMAGThrRev

Committer:
okini3939
Date:
Fri Jul 11 00:53:14 2014 +0000
Revision:
2:f6f05e2eafd0
Parent:
1:f7baa89f84bc
Child:
3:b1efde09d8a7
supported WDT interrupt and deep-sleep;

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 1:f7baa89f84bc 15 LPC_WWDT->CLKSEL = 0x01; // Set CLK src to PCLK
okini3939 1:f7baa89f84bc 16 uint32_t clk = SystemCoreClock / 16; // WD has a fixed /4 prescaler, PCLK 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 1:f7baa89f84bc 19 #endif
okini3939 1:f7baa89f84bc 20 kick();
okini3939 1:f7baa89f84bc 21 }
okini3939 1:f7baa89f84bc 22 // "kick" or "feed" the dog - reset the watchdog timer
okini3939 1:f7baa89f84bc 23 // by writing this required bit pattern
okini3939 1:f7baa89f84bc 24 void Watchdog::kick() {
okini3939 1:f7baa89f84bc 25 __disable_irq();
okini3939 1:f7baa89f84bc 26 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 1:f7baa89f84bc 27 LPC_WDT->WDFEED = 0xAA;
okini3939 1:f7baa89f84bc 28 LPC_WDT->WDFEED = 0x55;
okini3939 2:f6f05e2eafd0 29 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 1:f7baa89f84bc 30 LPC_WWDT->FEED = 0xAA;
okini3939 1:f7baa89f84bc 31 LPC_WWDT->FEED = 0x55;
okini3939 1:f7baa89f84bc 32 #endif
okini3939 1:f7baa89f84bc 33 __enable_irq();
okini3939 1:f7baa89f84bc 34 }
okini3939 1:f7baa89f84bc 35
okini3939 1:f7baa89f84bc 36 int Watchdog::getFlg () {
okini3939 1:f7baa89f84bc 37 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 1:f7baa89f84bc 38 return LPC_WDT->WDMOD & (1<<2) ? 1 : 0;
okini3939 2:f6f05e2eafd0 39 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 1:f7baa89f84bc 40 return LPC_WWDT->MOD & (1<<2) ? 1 : 0;
okini3939 1:f7baa89f84bc 41 #endif
okini3939 1:f7baa89f84bc 42 }
okini3939 2:f6f05e2eafd0 43
okini3939 2:f6f05e2eafd0 44 void Watchdog::attach (void (*fptr)(void), float s) {
okini3939 2:f6f05e2eafd0 45 if (fptr) {
okini3939 2:f6f05e2eafd0 46 _fptr.attach(fptr);
okini3939 2:f6f05e2eafd0 47 }
okini3939 2:f6f05e2eafd0 48 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 49 LPC_WDT->WDCLKSEL = 0x02; // Set CLK src to RTC
okini3939 2:f6f05e2eafd0 50 uint32_t clk = 32768 / 4; // WD has a fixed /4 prescaler
okini3939 2:f6f05e2eafd0 51 LPC_WDT->WDTC = s * (float)clk;
okini3939 2:f6f05e2eafd0 52 LPC_WDT->WDMOD = 0x01; // Enabled but Reset disable
okini3939 2:f6f05e2eafd0 53 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 54 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<15);
okini3939 2:f6f05e2eafd0 55 LPC_SYSCON->PDRUNCFG &= ~(1<<6); // WDT on
okini3939 2:f6f05e2eafd0 56 LPC_SYSCON->WDTOSCCTRL = (1<<5)|(0x1f<<0); // 500kHz / 64
okini3939 2:f6f05e2eafd0 57
okini3939 2:f6f05e2eafd0 58 LPC_WWDT->CLKSEL = (1<<0); // Set CLK src to PCLK
okini3939 2:f6f05e2eafd0 59 uint32_t clk = 500000 / 64 / 4; // WD has a fixed /4 prescaler, PCLK default is /4
okini3939 2:f6f05e2eafd0 60 LPC_WWDT->TC = s * (float)clk;
okini3939 2:f6f05e2eafd0 61 LPC_WWDT->WARNINT = 0;
okini3939 2:f6f05e2eafd0 62 LPC_WWDT->MOD = 0x01; // Enabled but Reset disable
okini3939 2:f6f05e2eafd0 63 kick();
okini3939 2:f6f05e2eafd0 64 LPC_SYSCON->STARTERP1 |= (1<<12);
okini3939 2:f6f05e2eafd0 65 #endif
okini3939 2:f6f05e2eafd0 66 NVIC_SetVector(WDT_IRQn, (uint32_t)&Watchdog::isr_wdt);
okini3939 2:f6f05e2eafd0 67 NVIC_ClearPendingIRQ(WDT_IRQn);
okini3939 2:f6f05e2eafd0 68 NVIC_EnableIRQ(WDT_IRQn);
okini3939 2:f6f05e2eafd0 69 }
okini3939 2:f6f05e2eafd0 70
okini3939 2:f6f05e2eafd0 71 template<typename T>
okini3939 2:f6f05e2eafd0 72 void Watchdog::attach (T *object, void (*fptr)(void), float s) {
okini3939 2:f6f05e2eafd0 73 if (fptr) {
okini3939 2:f6f05e2eafd0 74 _fptr.attach(object, fptr);
okini3939 2:f6f05e2eafd0 75 }
okini3939 2:f6f05e2eafd0 76 attach(NULL, s);
okini3939 2:f6f05e2eafd0 77 }
okini3939 2:f6f05e2eafd0 78
okini3939 2:f6f05e2eafd0 79 void Watchdog::isr_wdt(void) {
okini3939 2:f6f05e2eafd0 80 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 81 LPC_WDT->WDMOD |= (1<<3);
okini3939 2:f6f05e2eafd0 82 LPC_WDT->WDMOD &= ~(1<<2);
okini3939 2:f6f05e2eafd0 83 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 84 LPC_WWDT->MOD |= (1<<3);
okini3939 2:f6f05e2eafd0 85 LPC_WWDT->MOD &= ~(1<<2);
okini3939 2:f6f05e2eafd0 86 #endif
okini3939 2:f6f05e2eafd0 87 _fptr.call();
okini3939 2:f6f05e2eafd0 88 }
okini3939 2:f6f05e2eafd0 89
okini3939 2:f6f05e2eafd0 90 void Watchdog::sleep () {
okini3939 2:f6f05e2eafd0 91 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 92 LPC_SC->PCON = 0;
okini3939 2:f6f05e2eafd0 93 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 94 LPC_PMU->PCON = 0;
okini3939 2:f6f05e2eafd0 95 #endif
okini3939 2:f6f05e2eafd0 96 SCB->SCR &= ~(1<<2);
okini3939 2:f6f05e2eafd0 97 __WFI();
okini3939 2:f6f05e2eafd0 98 }
okini3939 2:f6f05e2eafd0 99
okini3939 2:f6f05e2eafd0 100 void Watchdog::deepSleep () {
okini3939 2:f6f05e2eafd0 101 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
okini3939 2:f6f05e2eafd0 102 LPC_SC->PCON &= ~(7<<0);
okini3939 2:f6f05e2eafd0 103 LPC_SC->PCON |= (1<<0);
okini3939 2:f6f05e2eafd0 104 #elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11UXX)
okini3939 2:f6f05e2eafd0 105 LPC_SYSCON->PDSLEEPCFG &= ~(1<<6); // WDT on
okini3939 2:f6f05e2eafd0 106 LPC_SYSCON->PDAWAKECFG = LPC_SYSCON->PDRUNCFG;
okini3939 2:f6f05e2eafd0 107 LPC_PMU->PCON &= ~(7<<0);
okini3939 2:f6f05e2eafd0 108 LPC_PMU->PCON |= (1<<0);
okini3939 2:f6f05e2eafd0 109 #endif
okini3939 2:f6f05e2eafd0 110 SCB->SCR |= (1<<2);
okini3939 2:f6f05e2eafd0 111 __WFI();
okini3939 2:f6f05e2eafd0 112 }