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/
Device/WakeUp_Freescale.cpp@16:f3adba7cf7c4, 2014-09-14 (annotated)
- Committer:
- Sissors
- Date:
- Sun Sep 14 06:45:51 2014 +0000
- Revision:
- 16:f3adba7cf7c4
- Parent:
- Device/WakeUp_KLxxZ.cpp@7:bb411115f814
- Child:
- 18:13aed323e040
Set KLXX code for all Freescale targets (for now).
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Sissors | 16:f3adba7cf7c4 | 1 | #if defined(TARGET_Freescale) |
Sissors | 7:bb411115f814 | 2 | |
Sissors | 7:bb411115f814 | 3 | #include "WakeUp.h" |
Sissors | 7:bb411115f814 | 4 | #include "us_ticker_api.h" |
Sissors | 7:bb411115f814 | 5 | |
Sissors | 7:bb411115f814 | 6 | FunctionPointer WakeUp::callback; |
Sissors | 7:bb411115f814 | 7 | float WakeUp::cycles_per_ms = 1.0; |
Sissors | 7:bb411115f814 | 8 | |
Sissors | 7:bb411115f814 | 9 | static uint16_t remainder_count; |
Sissors | 7:bb411115f814 | 10 | static uint32_t oldvector; |
Sissors | 7:bb411115f814 | 11 | static uint8_t oldPSR; |
Sissors | 7:bb411115f814 | 12 | |
Sissors | 7:bb411115f814 | 13 | void restore(void); |
Sissors | 7:bb411115f814 | 14 | |
Sissors | 7:bb411115f814 | 15 | void WakeUp::set_ms(uint32_t ms) |
Sissors | 7:bb411115f814 | 16 | { |
Sissors | 7:bb411115f814 | 17 | /* Clock the timer */ |
Sissors | 7:bb411115f814 | 18 | SIM->SCGC5 |= 0x1u; |
Sissors | 7:bb411115f814 | 19 | |
Sissors | 7:bb411115f814 | 20 | //Check if it is running, in that case, store current values |
Sissors | 7:bb411115f814 | 21 | remainder_count = 0; |
Sissors | 7:bb411115f814 | 22 | if (NVIC_GetVector(LPTimer_IRQn) != (uint32_t)WakeUp::irq_handler) { |
Sissors | 7:bb411115f814 | 23 | oldvector = NVIC_GetVector(LPTimer_IRQn); |
Sissors | 7:bb411115f814 | 24 | oldPSR = LPTMR0->PSR; |
Sissors | 7:bb411115f814 | 25 | |
Sissors | 7:bb411115f814 | 26 | if (LPTMR0->CSR & LPTMR_CSR_TIE_MASK) { |
Sissors | 7:bb411115f814 | 27 | //Write first to sync value |
Sissors | 7:bb411115f814 | 28 | LPTMR0->CNR = 0; |
Sissors | 7:bb411115f814 | 29 | uint16_t countval = LPTMR0->CNR; |
Sissors | 7:bb411115f814 | 30 | if (countval < LPTMR0->CMR) |
Sissors | 7:bb411115f814 | 31 | remainder_count = countval - LPTMR0->CMR; |
Sissors | 7:bb411115f814 | 32 | } |
Sissors | 7:bb411115f814 | 33 | } |
Sissors | 7:bb411115f814 | 34 | |
Sissors | 7:bb411115f814 | 35 | LPTMR0->CSR = 0; |
Sissors | 7:bb411115f814 | 36 | |
Sissors | 7:bb411115f814 | 37 | if (ms != 0) { |
Sissors | 7:bb411115f814 | 38 | //Clock from the 1kHz LPO |
Sissors | 7:bb411115f814 | 39 | LPTMR0->PSR = LPTMR_PSR_PCS(1); |
Sissors | 7:bb411115f814 | 40 | |
Sissors | 7:bb411115f814 | 41 | /* Set interrupt handler */ |
Sissors | 7:bb411115f814 | 42 | NVIC_SetVector(LPTimer_IRQn, (uint32_t)WakeUp::irq_handler); |
Sissors | 7:bb411115f814 | 43 | NVIC_EnableIRQ(LPTimer_IRQn); |
Sissors | 7:bb411115f814 | 44 | |
Sissors | 7:bb411115f814 | 45 | uint32_t counts = (uint32_t)((float)ms * cycles_per_ms); |
Sissors | 7:bb411115f814 | 46 | |
Sissors | 7:bb411115f814 | 47 | //If no prescaler is needed |
Sissors | 7:bb411115f814 | 48 | if (counts <= 0xFFFF) |
Sissors | 7:bb411115f814 | 49 | LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK; |
Sissors | 7:bb411115f814 | 50 | else { //Otherwise increase prescaler until it fits |
Sissors | 7:bb411115f814 | 51 | counts >>= 1; |
Sissors | 7:bb411115f814 | 52 | uint32_t prescaler = 0; |
Sissors | 7:bb411115f814 | 53 | while (counts > 0xFFFF) { |
Sissors | 7:bb411115f814 | 54 | counts >>= 1; |
Sissors | 7:bb411115f814 | 55 | prescaler++; |
Sissors | 7:bb411115f814 | 56 | } |
Sissors | 7:bb411115f814 | 57 | LPTMR0->PSR |= LPTMR_PSR_PRESCALE(prescaler); |
Sissors | 7:bb411115f814 | 58 | } |
Sissors | 7:bb411115f814 | 59 | LPTMR0->CMR = counts; |
Sissors | 7:bb411115f814 | 60 | |
Sissors | 7:bb411115f814 | 61 | LPTMR0->CSR = LPTMR_CSR_TIE_MASK; |
Sissors | 7:bb411115f814 | 62 | LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; |
Sissors | 7:bb411115f814 | 63 | } else { |
Sissors | 7:bb411115f814 | 64 | restore(); |
Sissors | 7:bb411115f814 | 65 | } |
Sissors | 7:bb411115f814 | 66 | |
Sissors | 7:bb411115f814 | 67 | } |
Sissors | 7:bb411115f814 | 68 | |
Sissors | 7:bb411115f814 | 69 | |
Sissors | 7:bb411115f814 | 70 | void WakeUp::irq_handler(void) |
Sissors | 7:bb411115f814 | 71 | { |
Sissors | 7:bb411115f814 | 72 | // write 1 to TCF to clear the LPT timer compare flag |
Sissors | 7:bb411115f814 | 73 | LPTMR0->CSR |= LPTMR_CSR_TCF_MASK; |
Sissors | 7:bb411115f814 | 74 | restore(); |
Sissors | 7:bb411115f814 | 75 | callback.call(); |
Sissors | 7:bb411115f814 | 76 | } |
Sissors | 7:bb411115f814 | 77 | |
Sissors | 7:bb411115f814 | 78 | void WakeUp::calibrate(void) |
Sissors | 7:bb411115f814 | 79 | { |
Sissors | 7:bb411115f814 | 80 | wait_us(1); //Otherwise next wait might overwrite our settings |
Sissors | 7:bb411115f814 | 81 | cycles_per_ms = 1.0; |
Sissors | 7:bb411115f814 | 82 | set_ms(1100); |
Sissors | 7:bb411115f814 | 83 | wait_ms(100); |
Sissors | 7:bb411115f814 | 84 | |
Sissors | 7:bb411115f814 | 85 | //Write first to sync value |
Sissors | 7:bb411115f814 | 86 | LPTMR0->CNR = 0; |
Sissors | 7:bb411115f814 | 87 | uint32_t ticks = LPTMR0->CNR; |
Sissors | 7:bb411115f814 | 88 | cycles_per_ms = ticks / 100.0; |
Sissors | 7:bb411115f814 | 89 | set_ms(0); |
Sissors | 7:bb411115f814 | 90 | } |
Sissors | 7:bb411115f814 | 91 | |
Sissors | 7:bb411115f814 | 92 | void restore(void){ |
Sissors | 7:bb411115f814 | 93 | /* Reset */ |
Sissors | 7:bb411115f814 | 94 | LPTMR0->CSR = 0; |
Sissors | 7:bb411115f814 | 95 | |
Sissors | 7:bb411115f814 | 96 | /* Set interrupt handler */ |
Sissors | 7:bb411115f814 | 97 | NVIC_SetVector(LPTimer_IRQn, oldvector); |
Sissors | 7:bb411115f814 | 98 | NVIC_EnableIRQ(LPTimer_IRQn); |
Sissors | 7:bb411115f814 | 99 | |
Sissors | 7:bb411115f814 | 100 | /* Clock at (1)MHz -> (1)tick/us */ |
Sissors | 7:bb411115f814 | 101 | LPTMR0->PSR = oldPSR; |
Sissors | 7:bb411115f814 | 102 | |
Sissors | 7:bb411115f814 | 103 | if (remainder_count) { |
Sissors | 7:bb411115f814 | 104 | /* Set the compare register */ |
Sissors | 7:bb411115f814 | 105 | LPTMR0->CMR = remainder_count; |
Sissors | 7:bb411115f814 | 106 | |
Sissors | 7:bb411115f814 | 107 | /* Enable interrupt */ |
Sissors | 7:bb411115f814 | 108 | LPTMR0->CSR |= LPTMR_CSR_TIE_MASK; |
Sissors | 7:bb411115f814 | 109 | |
Sissors | 7:bb411115f814 | 110 | /* Start the timer */ |
Sissors | 7:bb411115f814 | 111 | LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; |
Sissors | 7:bb411115f814 | 112 | } |
Sissors | 7:bb411115f814 | 113 | } |
Sissors | 7:bb411115f814 | 114 | |
Sissors | 7:bb411115f814 | 115 | #endif |