Added Restart(by RESET) function from Standby mode only for some Nucleo boards (STM32 series)
Dependencies: LPC1114_WakeInterruptIn
Fork of WakeUp by
Example program using "Standby function" for Nucleo series is here.
/users/kenjiArai/code/Check_StandBy/
Revision 2:648712aa15b4, committed 2013-12-07
- Comitter:
- Sissors
- Date:
- Sat Dec 07 11:21:15 2013 +0000
- Parent:
- 1:92f4c2b52771
- Child:
- 3:2c62a668f265
- Commit message:
- KL25 should now play nicely with mbed
Changed in this revision
WakeUp.h | Show annotated file Show diff for this revision Revisions of this file |
WakeUp_KL25Z.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/WakeUp.h Thu Dec 05 21:32:11 2013 +0000 +++ b/WakeUp.h Sat Dec 07 11:21:15 2013 +0000 @@ -1,17 +1,14 @@ #include "mbed.h" /** -* Class to make use of the LPC81x's low power wake-up timer. +* Class to make use of the LPC81x's and KL25Zs low power wake-up timer. * * One of the methods of waking up from deepsleep/powerdown is using the wake-up timer. -* This is an ultra low-power timer that can run from an always-on 10kHz clock source. +* This is an ultra low-power timer that can run from an always-on clock source. * So while normal timers are shut-down, this one still runs, consuming only roughly 1uA. * If the timer does not need to run everything is shut down again by the library. * -* This class can also be used as general purpose interrupt timer, although just using -* the default Timer library is probably a better idea for that. -* -* Example program: http://mbed.org/users/Sissors/code/LPC812_Sleep_HelloWorld/ +* Example program for the LPC812: http://mbed.org/users/Sissors/code/LPC812_Sleep_HelloWorld/ */ class WakeUp {
--- a/WakeUp_KL25Z.cpp Thu Dec 05 21:32:11 2013 +0000 +++ b/WakeUp_KL25Z.cpp Sat Dec 07 11:21:15 2013 +0000 @@ -1,29 +1,64 @@ #ifdef TARGET_KL25Z #include "WakeUp.h" +#include "us_ticker_api.h" FunctionPointer WakeUp::callback; float WakeUp::cycles_per_ms = 1.0; +static uint16_t remainder_count; +static uint32_t oldvector; + +void restore(void); + void WakeUp::set_ms(uint32_t ms) { /* Clock the timer */ SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK; + + //Check if it is running, in that case, store current values + remainder_count = 0; + if (NVIC_GetVector(LPTimer_IRQn) != (uint32_t)WakeUp::irq_handler) + oldvector = NVIC_GetVector(LPTimer_IRQn); + + if (LPTMR0->CSR & LPTMR_CSR_TIE_MASK) { + //Write first to sync value + LPTMR0->CNR = 0; + uint16_t countval = LPTMR0->CNR; + if (countval < LPTMR0->CMR) + remainder_count = countval - LPTMR0->CMR; + } + LPTMR0->CSR = 0; if (ms != 0) { - //Clock directly from the 1kHz LPO + //Clock from the 1kHz LPO LPTMR0->PSR = LPTMR_PSR_PCS(1); - LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK; /* Set interrupt handler */ NVIC_SetVector(LPTimer_IRQn, (uint32_t)WakeUp::irq_handler); NVIC_EnableIRQ(LPTimer_IRQn); + + uint32_t counts = (uint32_t)((float)ms * cycles_per_ms); - LPTMR0->CMR = (uint32_t)((float)ms * cycles_per_ms); + //If no prescaler is needed + if (counts <= 0xFFFF) + LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK; + else { //Otherwise increase prescaler until it fits + counts >>= 1; + uint32_t prescaler = 0; + while (counts > 0xFFFF) { + counts >>= 1; + prescaler++; + } + LPTMR0->PSR |= LPTMR_PSR_PRESCALE(prescaler); + } + LPTMR0->CMR = counts; LPTMR0->CSR = LPTMR_CSR_TIE_MASK; LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; + } else { + restore(); } } @@ -33,6 +68,7 @@ { // write 1 to TCF to clear the LPT timer compare flag LPTMR0->CSR |= LPTMR_CSR_TCF_MASK; + restore(); callback.call(); } @@ -47,8 +83,31 @@ LPTMR0->CNR = 0; uint32_t ticks = LPTMR0->CNR; cycles_per_ms = ticks / 100.0; + set_ms(0); +} - set_ms(0); +void restore(void){ + /* Reset */ + LPTMR0->CSR = 0; + + /* Set interrupt handler */ + NVIC_SetVector(LPTimer_IRQn, oldvector); + NVIC_EnableIRQ(LPTimer_IRQn); + + /* Clock at (1)MHz -> (1)tick/us */ + LPTMR0->PSR = LPTMR_PSR_PCS(3); // OSCERCLK -> 8MHz + LPTMR0->PSR |= LPTMR_PSR_PRESCALE(2); // divide by 8 + + if (remainder_count) { + /* Set the compare register */ + LPTMR0->CMR = remainder_count; + + /* Enable interrupt */ + LPTMR0->CSR |= LPTMR_CSR_TIE_MASK; + + /* Start the timer */ + LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; + } } @@ -56,5 +115,4 @@ - #endif \ No newline at end of file