wake library

Dependencies:   LPC1114_WakeInterruptIn

Fork of WakeUp by Erik -

Committer:
Sissors
Date:
Wed Jul 30 09:53:58 2014 +0000
Revision:
11:72db657fc572
Parent:
10:c41bc9154a7c
Child:
12:779d866b8a2d
Rewritten pin selection for LPC1114, now can be changed without modifying WakeUp code

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 #include "WakeUp.h"
Sissors 10:c41bc9154a7c 8 #include "WakeInterruptIn.h"
Sissors 10:c41bc9154a7c 9
Sissors 11:72db657fc572 10 //Pin used, allowed pins = P0_1 (dp24, default), P0_8 (dp1) and P0_9 (dp2)
Sissors 11:72db657fc572 11 //By defining WakeUpPin in for example your main.cpp this can be overridden
Sissors 11:72db657fc572 12 WEAK PinName WakeUpPin = dp24;
Sissors 11:72db657fc572 13 extern PinName WakeUpPin;
Sissors 11:72db657fc572 14
Sissors 11:72db657fc572 15 WakeInterruptIn IRQ_in(WakeUpPin);
Sissors 11:72db657fc572 16 PwmOut pulse_out(WakeUpPin);
Sissors 10:c41bc9154a7c 17
Sissors 10:c41bc9154a7c 18 FunctionPointer WakeUp::callback;
Sissors 10:c41bc9154a7c 19 float WakeUp::cycles_per_ms = 20.0;
Sissors 10:c41bc9154a7c 20
Sissors 10:c41bc9154a7c 21 static uint32_t old_clk_sel = ~0;
Sissors 10:c41bc9154a7c 22 static uint32_t SYSAHBCLKCTRL;
Sissors 10:c41bc9154a7c 23 static uint32_t TCR, PR, MR3;
Sissors 11:72db657fc572 24 static LPC_TMR_TypeDef *WakeUpTimer;
Sissors 11:72db657fc572 25 static uint32_t SYSAHBCLKCTRL_Sleep;
Sissors 11:72db657fc572 26 static uint8_t WakeUpTimer_Match;
Sissors 10:c41bc9154a7c 27
Sissors 10:c41bc9154a7c 28 static inline void restore(void);
Sissors 10:c41bc9154a7c 29
Sissors 10:c41bc9154a7c 30
Sissors 10:c41bc9154a7c 31 void WakeUp::set_ms(uint32_t ms)
Sissors 10:c41bc9154a7c 32 {
Sissors 11:72db657fc572 33 if (old_clk_sel == ~0) { //Only during first run
Sissors 11:72db657fc572 34 old_clk_sel = LPC_SYSCON->MAINCLKSEL;
Sissors 11:72db657fc572 35 SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL;
Sissors 10:c41bc9154a7c 36
Sissors 11:72db657fc572 37 switch(WakeUpPin) {
Sissors 11:72db657fc572 38 case dp24:
Sissors 11:72db657fc572 39 WakeUpTimer = LPC_TMR32B0;
Sissors 11:72db657fc572 40 SYSAHBCLKCTRL_Sleep = 0x15 | (1<<9);
Sissors 11:72db657fc572 41 WakeUpTimer_Match = 2;
Sissors 11:72db657fc572 42 break;
Sissors 11:72db657fc572 43 case dp1:
Sissors 11:72db657fc572 44 WakeUpTimer = LPC_TMR16B0;
Sissors 11:72db657fc572 45 SYSAHBCLKCTRL_Sleep = 0x15 | (1<<7);
Sissors 11:72db657fc572 46 WakeUpTimer_Match = 0;
Sissors 11:72db657fc572 47 break;
Sissors 11:72db657fc572 48 case dp2:
Sissors 11:72db657fc572 49 WakeUpTimer = LPC_TMR16B0;
Sissors 11:72db657fc572 50 SYSAHBCLKCTRL_Sleep = 0x15 | (1<<7);
Sissors 11:72db657fc572 51 WakeUpTimer_Match = 1;
Sissors 11:72db657fc572 52 break;
Sissors 11:72db657fc572 53 default:
Sissors 11:72db657fc572 54 error("Invalid WakeUp pin, choose dp1, dp2 or dp24");
Sissors 11:72db657fc572 55 }
Sissors 11:72db657fc572 56 }
Sissors 11:72db657fc572 57
Sissors 11:72db657fc572 58 if (ms != 0) {
Sissors 11:72db657fc572 59 if (LPC_SYSCON->SYSAHBCLKCTRL != SYSAHBCLKCTRL_Sleep) //Always when it is different from sleep settings
Sissors 10:c41bc9154a7c 60 SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL;
Sissors 10:c41bc9154a7c 61
Sissors 10:c41bc9154a7c 62 LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_WDTOSC_PD;
Sissors 10:c41bc9154a7c 63 LPC_SYSCON->PDSLEEPCFG = 0x000018B7 | (LPC_SYSCON->PDRUNCFG & (PDRUNCFG_WDTOSC_PD | PDRUNCFG_BOD_PD));
Sissors 10:c41bc9154a7c 64
Sissors 10:c41bc9154a7c 65 //Set oscillator for 20kHz
Sissors 10:c41bc9154a7c 66 LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5);
Sissors 10:c41bc9154a7c 67
Sissors 10:c41bc9154a7c 68 //Store old PWM
Sissors 11:72db657fc572 69 TCR = WakeUpTimer->TCR;
Sissors 11:72db657fc572 70 PR = WakeUpTimer->PR;
Sissors 11:72db657fc572 71 MR3 = WakeUpTimer->MR3;
Sissors 10:c41bc9154a7c 72
Sissors 10:c41bc9154a7c 73 //Setup PWM
Sissors 11:72db657fc572 74 WakeUpTimer->TCR = TMR16B0TCR_CRST;
Sissors 10:c41bc9154a7c 75 uint32_t ticks = (float)ms * cycles_per_ms;
Sissors 10:c41bc9154a7c 76
Sissors 10:c41bc9154a7c 77 //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 11:72db657fc572 78 WakeUpTimer->PR = ticks >> 16;
Sissors 11:72db657fc572 79 WakeUpTimer->MR[WakeUpTimer_Match] = ticks / ((ticks >> 16) + 1);
Sissors 11:72db657fc572 80 WakeUpTimer->MR3 = 0xFFFF;
Sissors 10:c41bc9154a7c 81
Sissors 10:c41bc9154a7c 82 IRQ_in.rise(irq_handler);
Sissors 10:c41bc9154a7c 83
Sissors 10:c41bc9154a7c 84 //Disable most peripherals
Sissors 11:72db657fc572 85 LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL_Sleep;
Sissors 10:c41bc9154a7c 86
Sissors 10:c41bc9154a7c 87 //Switch clock to WD OSC
Sissors 10:c41bc9154a7c 88 LPC_SYSCON->MAINCLKSEL = 0x2;
Sissors 10:c41bc9154a7c 89 LPC_SYSCON->MAINCLKUEN = 0;
Sissors 10:c41bc9154a7c 90 LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA;
Sissors 10:c41bc9154a7c 91
Sissors 10:c41bc9154a7c 92 //Enable PWM:
Sissors 11:72db657fc572 93 WakeUpTimer->TCR = TMR16B0TCR_CEN;
Sissors 10:c41bc9154a7c 94 } else {
Sissors 10:c41bc9154a7c 95 //Else restore normal settings
Sissors 10:c41bc9154a7c 96 restore();
Sissors 10:c41bc9154a7c 97 }
Sissors 10:c41bc9154a7c 98
Sissors 10:c41bc9154a7c 99 }
Sissors 10:c41bc9154a7c 100
Sissors 10:c41bc9154a7c 101 void WakeUp::irq_handler(void)
Sissors 10:c41bc9154a7c 102 {
Sissors 10:c41bc9154a7c 103 restore();
Sissors 10:c41bc9154a7c 104 callback.call();
Sissors 10:c41bc9154a7c 105 }
Sissors 10:c41bc9154a7c 106
Sissors 10:c41bc9154a7c 107 void WakeUp::calibrate(void)
Sissors 10:c41bc9154a7c 108 {
Sissors 10:c41bc9154a7c 109 }
Sissors 10:c41bc9154a7c 110
Sissors 10:c41bc9154a7c 111 static inline void restore(void) {
Sissors 10:c41bc9154a7c 112
Sissors 11:72db657fc572 113 WakeUpTimer->MR[WakeUpTimer_Match] = 0xFFFFFFFF;
Sissors 10:c41bc9154a7c 114
Sissors 10:c41bc9154a7c 115 if (old_clk_sel == 3) //Was running on PLL
Sissors 10:c41bc9154a7c 116 while(LPC_SYSCON->SYSPLLSTAT != SYSPLLSTAT_LOCK);
Sissors 10:c41bc9154a7c 117
Sissors 10:c41bc9154a7c 118 if (old_clk_sel < 4) { //If valid setting
Sissors 10:c41bc9154a7c 119 LPC_SYSCON->MAINCLKSEL = old_clk_sel;
Sissors 10:c41bc9154a7c 120 LPC_SYSCON->MAINCLKUEN = 0;
Sissors 10:c41bc9154a7c 121 LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA;
Sissors 10:c41bc9154a7c 122 }
Sissors 10:c41bc9154a7c 123
Sissors 10:c41bc9154a7c 124 IRQ_in.rise(NULL);
Sissors 10:c41bc9154a7c 125
Sissors 10:c41bc9154a7c 126 LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL;
Sissors 10:c41bc9154a7c 127
Sissors 11:72db657fc572 128 WakeUpTimer->MR3 = MR3;
Sissors 11:72db657fc572 129 WakeUpTimer->PR = PR;
Sissors 11:72db657fc572 130 WakeUpTimer->TCR = TCR;
Sissors 10:c41bc9154a7c 131 }
Sissors 10:c41bc9154a7c 132
Sissors 10:c41bc9154a7c 133 #endif