Wake-up timer library to wake from deepsleep/power-down
Dependencies: LPC1114_WakeInterruptIn
Fork of WakeUp by
Revision 0:fc439458a359, committed 2013-11-23
- Comitter:
- Sissors
- Date:
- Sat Nov 23 11:35:14 2013 +0000
- Child:
- 1:92f4c2b52771
- Commit message:
- v1.0
;
Changed in this revision
WakeUp.cpp | Show annotated file Show diff for this revision Revisions of this file |
WakeUp.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WakeUp.cpp Sat Nov 23 11:35:14 2013 +0000 @@ -0,0 +1,72 @@ +#include "WakeUp.h" + +FunctionPointer WakeUp::callback; +float WakeUp::cycles_per_ms = 10.0; + +void WakeUp::set_ms(uint32_t ms) +{ + //Enable clock to register interface: + LPC_SYSCON->SYSAHBCLKCTRL |= 1<<9; + + //Clear the counter: + LPC_WKT->CTRL |= 1<<2; + if (ms != 0) { + //Enable clock to register interface: + LPC_SYSCON->SYSAHBCLKCTRL |= 1<<9; + + //Set 10kHz timer as source, and just to be sure clear status bit + LPC_WKT->CTRL = 3; + + //Enable the 10kHz timer + LPC_PMU->DPDCTRL |= (1<<2) | (1<<3); + + //Set interrupts + NVIC_SetVector(WKT_IRQn, (uint32_t)WakeUp::irq_handler); + NVIC_EnableIRQ(WKT_IRQn); + + //Load the timer + LPC_WKT->COUNT = (uint32_t)((float)ms * cycles_per_ms); + + } else { + //Disable clock to register interface: + LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<9); + + //Disable the 10kHz timer + LPC_PMU->DPDCTRL &= ~((1<<2) | (1<<3)); + } +} + +void WakeUp::irq_handler(void) +{ + //Clear status + LPC_WKT->CTRL |= 2; + + //Disable clock to register interface: + LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<9); + + //Disable the 10kHz timer + LPC_PMU->DPDCTRL &= ~((1<<2) | (1<<3)); + + callback.call(); +} + +void WakeUp::calibrate(void) +{ + cycles_per_ms = 10.0; + set_ms(1100); + wait_ms(100); + + uint32_t prevread = LPC_WKT->COUNT; + uint32_t read = LPC_WKT->COUNT; + while( read != prevread) { + prevread = read; + read = LPC_WKT->COUNT; + } + + uint32_t ticks = 11000 - read; + + cycles_per_ms = ticks / 100.0; + set_ms(0); +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WakeUp.h Sat Nov 23 11:35:14 2013 +0000 @@ -0,0 +1,71 @@ +#include "mbed.h" + +/** +* Class to make use of the LPC81x's low power wake-up timer. +* +* One of the methods of waking up from deepsleep/powerdown is using the wake-up timer. +* This is an ultra low-power timer that can run from an always-on 10kHz clock source. +* So while normal timers are shut-down, this one still runs, consuming only roughly 1uA. +* If the timer does not need to run everything is shut down again by the library. +* +* This class can also be used as general purpose interrupt timer, although just using +* the default Timer library is probably a better idea for that. +* +* Example program: http://mbed.org/users/Sissors/code/LPC812_Sleep_HelloWorld/ +*/ +class WakeUp +{ +public: + /** + * Set the timeout + * + * @param s - required time in seconds + */ + static void set(uint32_t s) { + set_ms(1000 * s); + } + + /** + * Set the timeout + * + * @param ms - required time in milliseconds + */ + static void set_ms(uint32_t ms); + + /** + * Attach a function to be called after timeout + * + * This is optional, if you just want to wake up you + * do not need to attach a function. + * + * Also supports normal way to attach member functions + * (not documented for simplicity) + * + * @param *function - function to call + */ + static void attach(void (*function)(void)) { + callback.attach(function); + } + + template<typename T> + static void attach(T *object, void (T::*member)(void)) { + callback.attach(object, member); + } + + /** + * Calibrate the timer + * + * The 10kHz timer has a very bad accuracy: +/- 45%. + * This function calibrates it for 100ms against the main clock. + * So you get almost that accuracy by calling this function. + * + * Warning: Blocks for 100ms! + */ + static void calibrate(void); + + +private: + static FunctionPointer callback; + static void irq_handler(void); + static float cycles_per_ms; +}; \ No newline at end of file