Modified WakeUp program to run on STM32L152RE

Dependencies:   mbed LPC1114_WakeInterruptIn

Fork of WakeUp by Erik -

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?

UserRevisionLine numberNew 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