Modified WakeUp program to run on STM32L152RE
Dependencies: mbed LPC1114_WakeInterruptIn
Fork of WakeUp by
Device/WakeUp_LPC11XX.cpp@10:c41bc9154a7c, 2014-07-28 (annotated)
- Committer:
- Sissors
- Date:
- Mon Jul 28 19:46:03 2014 +0000
- Revision:
- 10:c41bc9154a7c
- Child:
- 11:72db657fc572
Added initial LPC11xx support (LPC1114). Might need another commit :)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Sissors | 10:c41bc9154a7c | 1 | /** |
Sissors | 10:c41bc9154a7c | 2 | See homepage of this lib for LPC11xx special treatment |
Sissors | 10:c41bc9154a7c | 3 | **/ |
Sissors | 10:c41bc9154a7c | 4 | |
Sissors | 10:c41bc9154a7c | 5 | #ifdef TARGET_LPC11XX_11CXX |
Sissors | 10:c41bc9154a7c | 6 | |
Sissors | 10:c41bc9154a7c | 7 | //dp1 or dp2 can be chosen |
Sissors | 10:c41bc9154a7c | 8 | #define WAKEUP_PIN dp1 |
Sissors | 10:c41bc9154a7c | 9 | //#define WAKEUP_PIN dp2 |
Sissors | 10:c41bc9154a7c | 10 | |
Sissors | 10:c41bc9154a7c | 11 | #define WAKEUP_MATCH (((WAKEUP_PIN >> PIN_SHIFT) & 0xF) - 8) |
Sissors | 10:c41bc9154a7c | 12 | #define WAKEUP_CHANNEL ((WAKEUP_PIN >> PIN_SHIFT) & 0xF) |
Sissors | 10:c41bc9154a7c | 13 | |
Sissors | 10:c41bc9154a7c | 14 | #define WAKEUP_TIMER LPC_TMR16B0 |
Sissors | 10:c41bc9154a7c | 15 | #define WAKEUP_TIMER_EN 7 |
Sissors | 10:c41bc9154a7c | 16 | |
Sissors | 10:c41bc9154a7c | 17 | #define SYSAHBCLKCTRL_SLEEP (0x15 | (1<<WAKEUP_TIMER_EN)) |
Sissors | 10:c41bc9154a7c | 18 | |
Sissors | 10:c41bc9154a7c | 19 | #include "WakeUp.h" |
Sissors | 10:c41bc9154a7c | 20 | #include "WakeInterruptIn.h" |
Sissors | 10:c41bc9154a7c | 21 | |
Sissors | 10:c41bc9154a7c | 22 | WakeInterruptIn IRQ_in(WAKEUP_PIN); |
Sissors | 10:c41bc9154a7c | 23 | PwmOut pulse_out(WAKEUP_PIN); |
Sissors | 10:c41bc9154a7c | 24 | |
Sissors | 10:c41bc9154a7c | 25 | FunctionPointer WakeUp::callback; |
Sissors | 10:c41bc9154a7c | 26 | float WakeUp::cycles_per_ms = 20.0; |
Sissors | 10:c41bc9154a7c | 27 | |
Sissors | 10:c41bc9154a7c | 28 | static uint32_t old_clk_sel = ~0; |
Sissors | 10:c41bc9154a7c | 29 | static uint32_t SYSAHBCLKCTRL; |
Sissors | 10:c41bc9154a7c | 30 | static uint32_t TCR, PR, MR3; |
Sissors | 10:c41bc9154a7c | 31 | |
Sissors | 10:c41bc9154a7c | 32 | static inline void restore(void); |
Sissors | 10:c41bc9154a7c | 33 | |
Sissors | 10:c41bc9154a7c | 34 | |
Sissors | 10:c41bc9154a7c | 35 | void WakeUp::set_ms(uint32_t ms) |
Sissors | 10:c41bc9154a7c | 36 | { |
Sissors | 10:c41bc9154a7c | 37 | if (ms != 0) { |
Sissors | 10:c41bc9154a7c | 38 | if (old_clk_sel == ~0) { //Only during first run |
Sissors | 10:c41bc9154a7c | 39 | old_clk_sel = LPC_SYSCON->MAINCLKSEL; |
Sissors | 10:c41bc9154a7c | 40 | SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL; |
Sissors | 10:c41bc9154a7c | 41 | } |
Sissors | 10:c41bc9154a7c | 42 | |
Sissors | 10:c41bc9154a7c | 43 | if (LPC_SYSCON->SYSAHBCLKCTRL != SYSAHBCLKCTRL_SLEEP) //Always when it is different from sleep settings |
Sissors | 10:c41bc9154a7c | 44 | SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL; |
Sissors | 10:c41bc9154a7c | 45 | |
Sissors | 10:c41bc9154a7c | 46 | LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_WDTOSC_PD; |
Sissors | 10:c41bc9154a7c | 47 | LPC_SYSCON->PDSLEEPCFG = 0x000018B7 | (LPC_SYSCON->PDRUNCFG & (PDRUNCFG_WDTOSC_PD | PDRUNCFG_BOD_PD)); |
Sissors | 10:c41bc9154a7c | 48 | |
Sissors | 10:c41bc9154a7c | 49 | //Set oscillator for 20kHz |
Sissors | 10:c41bc9154a7c | 50 | LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5); |
Sissors | 10:c41bc9154a7c | 51 | |
Sissors | 10:c41bc9154a7c | 52 | //Store old PWM |
Sissors | 10:c41bc9154a7c | 53 | TCR = WAKEUP_TIMER->TCR; |
Sissors | 10:c41bc9154a7c | 54 | PR = WAKEUP_TIMER->PR; |
Sissors | 10:c41bc9154a7c | 55 | MR3 = WAKEUP_TIMER->MR3; |
Sissors | 10:c41bc9154a7c | 56 | |
Sissors | 10:c41bc9154a7c | 57 | //Setup PWM |
Sissors | 10:c41bc9154a7c | 58 | WAKEUP_TIMER->TCR = TMR16B0TCR_CRST; |
Sissors | 10:c41bc9154a7c | 59 | uint32_t ticks = (float)ms * cycles_per_ms; |
Sissors | 10:c41bc9154a7c | 60 | |
Sissors | 10:c41bc9154a7c | 61 | //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) |
Sissors | 10:c41bc9154a7c | 62 | WAKEUP_TIMER->PR = ticks >> 16; |
Sissors | 10:c41bc9154a7c | 63 | WAKEUP_TIMER->MR[WAKEUP_MATCH] = ticks / ((ticks >> 16) + 1); |
Sissors | 10:c41bc9154a7c | 64 | WAKEUP_TIMER->MR3 = 0xFFFF; |
Sissors | 10:c41bc9154a7c | 65 | |
Sissors | 10:c41bc9154a7c | 66 | IRQ_in.rise(irq_handler); |
Sissors | 10:c41bc9154a7c | 67 | |
Sissors | 10:c41bc9154a7c | 68 | //Disable most peripherals |
Sissors | 10:c41bc9154a7c | 69 | LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL_SLEEP; |
Sissors | 10:c41bc9154a7c | 70 | |
Sissors | 10:c41bc9154a7c | 71 | //Switch clock to WD OSC |
Sissors | 10:c41bc9154a7c | 72 | LPC_SYSCON->MAINCLKSEL = 0x2; |
Sissors | 10:c41bc9154a7c | 73 | LPC_SYSCON->MAINCLKUEN = 0; |
Sissors | 10:c41bc9154a7c | 74 | LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA; |
Sissors | 10:c41bc9154a7c | 75 | |
Sissors | 10:c41bc9154a7c | 76 | //Enable PWM: |
Sissors | 10:c41bc9154a7c | 77 | WAKEUP_TIMER->TCR = TMR16B0TCR_CEN; |
Sissors | 10:c41bc9154a7c | 78 | } else { |
Sissors | 10:c41bc9154a7c | 79 | //Else restore normal settings |
Sissors | 10:c41bc9154a7c | 80 | restore(); |
Sissors | 10:c41bc9154a7c | 81 | } |
Sissors | 10:c41bc9154a7c | 82 | |
Sissors | 10:c41bc9154a7c | 83 | } |
Sissors | 10:c41bc9154a7c | 84 | |
Sissors | 10:c41bc9154a7c | 85 | void WakeUp::irq_handler(void) |
Sissors | 10:c41bc9154a7c | 86 | { |
Sissors | 10:c41bc9154a7c | 87 | restore(); |
Sissors | 10:c41bc9154a7c | 88 | callback.call(); |
Sissors | 10:c41bc9154a7c | 89 | } |
Sissors | 10:c41bc9154a7c | 90 | |
Sissors | 10:c41bc9154a7c | 91 | void WakeUp::calibrate(void) |
Sissors | 10:c41bc9154a7c | 92 | { |
Sissors | 10:c41bc9154a7c | 93 | } |
Sissors | 10:c41bc9154a7c | 94 | |
Sissors | 10:c41bc9154a7c | 95 | static inline void restore(void) { |
Sissors | 10:c41bc9154a7c | 96 | |
Sissors | 10:c41bc9154a7c | 97 | WAKEUP_TIMER->MR[WAKEUP_MATCH] = 0xFFFF; |
Sissors | 10:c41bc9154a7c | 98 | |
Sissors | 10:c41bc9154a7c | 99 | if (old_clk_sel == 3) //Was running on PLL |
Sissors | 10:c41bc9154a7c | 100 | while(LPC_SYSCON->SYSPLLSTAT != SYSPLLSTAT_LOCK); |
Sissors | 10:c41bc9154a7c | 101 | |
Sissors | 10:c41bc9154a7c | 102 | if (old_clk_sel < 4) { //If valid setting |
Sissors | 10:c41bc9154a7c | 103 | LPC_SYSCON->MAINCLKSEL = old_clk_sel; |
Sissors | 10:c41bc9154a7c | 104 | LPC_SYSCON->MAINCLKUEN = 0; |
Sissors | 10:c41bc9154a7c | 105 | LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA; |
Sissors | 10:c41bc9154a7c | 106 | } |
Sissors | 10:c41bc9154a7c | 107 | |
Sissors | 10:c41bc9154a7c | 108 | IRQ_in.rise(NULL); |
Sissors | 10:c41bc9154a7c | 109 | |
Sissors | 10:c41bc9154a7c | 110 | LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL; |
Sissors | 10:c41bc9154a7c | 111 | |
Sissors | 10:c41bc9154a7c | 112 | WAKEUP_TIMER->MR3 = MR3; |
Sissors | 10:c41bc9154a7c | 113 | WAKEUP_TIMER->PR = PR; |
Sissors | 10:c41bc9154a7c | 114 | WAKEUP_TIMER->TCR = TCR; |
Sissors | 10:c41bc9154a7c | 115 | } |
Sissors | 10:c41bc9154a7c | 116 | |
Sissors | 10:c41bc9154a7c | 117 | #endif |