Modified WakeUp program to run on STM32L152RE

Dependencies:   mbed LPC1114_WakeInterruptIn

Fork of WakeUp by Erik -

Revision:
10:c41bc9154a7c
Child:
11:72db657fc572
--- /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