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:
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?

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