Added Restart(by RESET) function from Standby mode only for some Nucleo boards (STM32 series)

Dependencies:   LPC1114_WakeInterruptIn

Dependents:   Check_StandBy

Fork of WakeUp by Erik -

Example program using "Standby function" for Nucleo series is here.
/users/kenjiArai/code/Check_StandBy/

Committer:
Sissors
Date:
Wed Jul 30 15:07:08 2014 +0000
Revision:
12:779d866b8a2d
Parent:
11:72db657fc572
Child:
13:fd24cec76d5a
Added calibrate for LPC1114

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