Flotsam / Wakeup

Dependents:   Full-Project

Fork of WakeUp by Erik -

Committer:
Sissors
Date:
Sat Jul 12 19:17:51 2014 +0000
Revision:
6:815bef56e136
Parent:
5:89dae784c38f
Added K20D50M support

Who changed what in which revision?

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