The common example for running a watchdog timer on mbed processors doesn't work for the LPC1114, a common and easily-breadboardable ARM chip. My program provides a watchdog class that works on the LPC1114 but which is also similar to the common example found in https://mbed.org/forum/mbed/topic/508/
main.cpp@0:1c1e04c41063, 2014-08-10 (annotated)
- Committer:
- ThatcherC
- Date:
- Sun Aug 10 02:58:11 2014 +0000
- Revision:
- 0:1c1e04c41063
First commit of Watchdog implementation for LPC1114 on the mbed platform.; ; Seems to work.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ThatcherC | 0:1c1e04c41063 | 1 | #include "mbed.h" |
ThatcherC | 0:1c1e04c41063 | 2 | |
ThatcherC | 0:1c1e04c41063 | 3 | /* |
ThatcherC | 0:1c1e04c41063 | 4 | Main code copied from: http://mbed.org/cookbook/WatchDog-Timer |
ThatcherC | 0:1c1e04c41063 | 5 | Modified for use with LPC1114 with source code found here: |
ThatcherC | 0:1c1e04c41063 | 6 | https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11XX_11CXX/LPC11xx.h |
ThatcherC | 0:1c1e04c41063 | 7 | With some inspiration from: |
ThatcherC | 0:1c1e04c41063 | 8 | https://github.com/Mrjohns42/RSL/blob/master/LPC1114/nRF24L01/wdt.c |
ThatcherC | 0:1c1e04c41063 | 9 | */ |
ThatcherC | 0:1c1e04c41063 | 10 | |
ThatcherC | 0:1c1e04c41063 | 11 | // LEDs used to indicate code activity and reset source |
ThatcherC | 0:1c1e04c41063 | 12 | DigitalOut led1(dp1); |
ThatcherC | 0:1c1e04c41063 | 13 | DigitalOut led2(dp4); |
ThatcherC | 0:1c1e04c41063 | 14 | |
ThatcherC | 0:1c1e04c41063 | 15 | // Simon's Watchdog code from |
ThatcherC | 0:1c1e04c41063 | 16 | // http://mbed.org/forum/mbed/topic/508/ |
ThatcherC | 0:1c1e04c41063 | 17 | class Watchdog { |
ThatcherC | 0:1c1e04c41063 | 18 | public: |
ThatcherC | 0:1c1e04c41063 | 19 | // Load timeout value in watchdog timer and enable |
ThatcherC | 0:1c1e04c41063 | 20 | void kick(float s) { |
ThatcherC | 0:1c1e04c41063 | 21 | LPC_SYSCON->SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL|(1<<15); |
ThatcherC | 0:1c1e04c41063 | 22 | LPC_SYSCON->WDTCLKSEL = 0x1; // Set CLK src to Main Clock |
ThatcherC | 0:1c1e04c41063 | 23 | LPC_SYSCON->WDTCLKUEN = 0x01; /* Update clock */ |
ThatcherC | 0:1c1e04c41063 | 24 | LPC_SYSCON->WDTCLKUEN = 0x00; /* Toggle update register once */ |
ThatcherC | 0:1c1e04c41063 | 25 | LPC_SYSCON->WDTCLKUEN = 0x01; |
ThatcherC | 0:1c1e04c41063 | 26 | LPC_SYSCON->WDTCLKDIV = 0x10; |
ThatcherC | 0:1c1e04c41063 | 27 | uint32_t clk = SystemCoreClock/16; // WD has a fixed /4 prescaler, PCLK default is /4 |
ThatcherC | 0:1c1e04c41063 | 28 | LPC_WDT->TC = s * (float)clk; |
ThatcherC | 0:1c1e04c41063 | 29 | LPC_WDT->MOD = 0x3; // Enabled and Reset |
ThatcherC | 0:1c1e04c41063 | 30 | kick(); |
ThatcherC | 0:1c1e04c41063 | 31 | } |
ThatcherC | 0:1c1e04c41063 | 32 | // "kick" or "feed" the dog - reset the watchdog timer |
ThatcherC | 0:1c1e04c41063 | 33 | // by writing this required bit pattern |
ThatcherC | 0:1c1e04c41063 | 34 | void kick() { |
ThatcherC | 0:1c1e04c41063 | 35 | LPC_WDT->FEED = 0xAA; |
ThatcherC | 0:1c1e04c41063 | 36 | LPC_WDT->FEED = 0x55; |
ThatcherC | 0:1c1e04c41063 | 37 | } |
ThatcherC | 0:1c1e04c41063 | 38 | }; |
ThatcherC | 0:1c1e04c41063 | 39 | |
ThatcherC | 0:1c1e04c41063 | 40 | // Setup the watchdog timer |
ThatcherC | 0:1c1e04c41063 | 41 | Watchdog wdt; |
ThatcherC | 0:1c1e04c41063 | 42 | |
ThatcherC | 0:1c1e04c41063 | 43 | int main() { |
ThatcherC | 0:1c1e04c41063 | 44 | int count = 0; |
ThatcherC | 0:1c1e04c41063 | 45 | // On reset, indicate a watchdog reset or a pushbutton reset on LED 4 or 3 |
ThatcherC | 0:1c1e04c41063 | 46 | if ((LPC_WDT->MOD >> 2) & 1) |
ThatcherC | 0:1c1e04c41063 | 47 | led1 = 1; else led1 = 0; |
ThatcherC | 0:1c1e04c41063 | 48 | |
ThatcherC | 0:1c1e04c41063 | 49 | // setup a 10 second timeout on watchdog timer hardware |
ThatcherC | 0:1c1e04c41063 | 50 | // needs to be longer than worst case main loop exection time |
ThatcherC | 0:1c1e04c41063 | 51 | wdt.kick(10.0); |
ThatcherC | 0:1c1e04c41063 | 52 | |
ThatcherC | 0:1c1e04c41063 | 53 | // Main program loop - resets watchdog once each loop iteration |
ThatcherC | 0:1c1e04c41063 | 54 | // Would typically have a lot of code in loop with many calls |
ThatcherC | 0:1c1e04c41063 | 55 | while (1) { |
ThatcherC | 0:1c1e04c41063 | 56 | wait(.1); |
ThatcherC | 0:1c1e04c41063 | 57 | led2 = 1; |
ThatcherC | 0:1c1e04c41063 | 58 | wait(.1); |
ThatcherC | 0:1c1e04c41063 | 59 | // Simulate a fault lock up with an infinite while loop, but only after 25 loop iterations |
ThatcherC | 0:1c1e04c41063 | 60 | if (count == 25) while (1) {}; |
ThatcherC | 0:1c1e04c41063 | 61 | |
ThatcherC | 0:1c1e04c41063 | 62 | // LED 2 will stay on during the fault |
ThatcherC | 0:1c1e04c41063 | 63 | led2 = 0; |
ThatcherC | 0:1c1e04c41063 | 64 | count ++; |
ThatcherC | 0:1c1e04c41063 | 65 | // End of main loop so "kick" to reset watchdog timer and avoid a reset |
ThatcherC | 0:1c1e04c41063 | 66 | wdt.kick(); |
ThatcherC | 0:1c1e04c41063 | 67 | } |
ThatcherC | 0:1c1e04c41063 | 68 | } |