Modified WakeUp program to run on STM32L152RE
Dependencies: mbed LPC1114_WakeInterruptIn
Fork of WakeUp by
Device/WakeUp_LPC11XX.cpp
- Committer:
- Sissors
- Date:
- 2014-07-28
- Revision:
- 10:c41bc9154a7c
- Child:
- 11:72db657fc572
File content as of revision 10:c41bc9154a7c:
/** 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