Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: LPC1114_WakeInterruptIn
Fork of WakeUp by
Diff: Device/WakeUp_LPC11XX.cpp
- Revision:
- 10:c41bc9154a7c
- Child:
- 11:72db657fc572
diff -r 29bdf5fed21a -r c41bc9154a7c Device/WakeUp_LPC11XX.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Device/WakeUp_LPC11XX.cpp Mon Jul 28 19:46:03 2014 +0000
@@ -0,0 +1,117 @@
+/**
+See homepage of this lib for LPC11xx special treatment
+**/
+
+#ifdef TARGET_LPC11XX_11CXX
+
+//dp1 or dp2 can be chosen
+#define WAKEUP_PIN dp1
+//#define WAKEUP_PIN dp2
+
+#define WAKEUP_MATCH (((WAKEUP_PIN >> PIN_SHIFT) & 0xF) - 8)
+#define WAKEUP_CHANNEL ((WAKEUP_PIN >> PIN_SHIFT) & 0xF)
+
+#define WAKEUP_TIMER LPC_TMR16B0
+#define WAKEUP_TIMER_EN 7
+
+#define SYSAHBCLKCTRL_SLEEP (0x15 | (1<<WAKEUP_TIMER_EN))
+
+#include "WakeUp.h"
+#include "WakeInterruptIn.h"
+
+WakeInterruptIn IRQ_in(WAKEUP_PIN);
+PwmOut pulse_out(WAKEUP_PIN);
+
+FunctionPointer WakeUp::callback;
+float WakeUp::cycles_per_ms = 20.0;
+
+static uint32_t old_clk_sel = ~0;
+static uint32_t SYSAHBCLKCTRL;
+static uint32_t TCR, PR, MR3;
+
+static inline void restore(void);
+
+
+void WakeUp::set_ms(uint32_t ms)
+{
+ if (ms != 0) {
+ if (old_clk_sel == ~0) { //Only during first run
+ old_clk_sel = LPC_SYSCON->MAINCLKSEL;
+ SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL;
+ }
+
+ if (LPC_SYSCON->SYSAHBCLKCTRL != SYSAHBCLKCTRL_SLEEP) //Always when it is different from sleep settings
+ SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL;
+
+ LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_WDTOSC_PD;
+ LPC_SYSCON->PDSLEEPCFG = 0x000018B7 | (LPC_SYSCON->PDRUNCFG & (PDRUNCFG_WDTOSC_PD | PDRUNCFG_BOD_PD));
+
+ //Set oscillator for 20kHz
+ LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5);
+
+ //Store old PWM
+ TCR = WAKEUP_TIMER->TCR;
+ PR = WAKEUP_TIMER->PR;
+ MR3 = WAKEUP_TIMER->MR3;
+
+ //Setup PWM
+ WAKEUP_TIMER->TCR = TMR16B0TCR_CRST;
+ uint32_t ticks = (float)ms * cycles_per_ms;
+
+ //whatever timer it is, we treat it as 16-bit (with PR that is 32-bit still, do the math, it is enough for this)
+ WAKEUP_TIMER->PR = ticks >> 16;
+ WAKEUP_TIMER->MR[WAKEUP_MATCH] = ticks / ((ticks >> 16) + 1);
+ WAKEUP_TIMER->MR3 = 0xFFFF;
+
+ IRQ_in.rise(irq_handler);
+
+ //Disable most peripherals
+ LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL_SLEEP;
+
+ //Switch clock to WD OSC
+ LPC_SYSCON->MAINCLKSEL = 0x2;
+ LPC_SYSCON->MAINCLKUEN = 0;
+ LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA;
+
+ //Enable PWM:
+ WAKEUP_TIMER->TCR = TMR16B0TCR_CEN;
+ } else {
+ //Else restore normal settings
+ restore();
+ }
+
+}
+
+void WakeUp::irq_handler(void)
+{
+ restore();
+ callback.call();
+}
+
+void WakeUp::calibrate(void)
+{
+}
+
+static inline void restore(void) {
+
+ WAKEUP_TIMER->MR[WAKEUP_MATCH] = 0xFFFF;
+
+ if (old_clk_sel == 3) //Was running on PLL
+ while(LPC_SYSCON->SYSPLLSTAT != SYSPLLSTAT_LOCK);
+
+ if (old_clk_sel < 4) { //If valid setting
+ LPC_SYSCON->MAINCLKSEL = old_clk_sel;
+ LPC_SYSCON->MAINCLKUEN = 0;
+ LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA;
+ }
+
+ IRQ_in.rise(NULL);
+
+ LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL;
+
+ WAKEUP_TIMER->MR3 = MR3;
+ WAKEUP_TIMER->PR = PR;
+ WAKEUP_TIMER->TCR = TCR;
+}
+
+#endif
