Flotsam / Wakeup

Dependents:   Full-Project

Fork of WakeUp by Erik -

Committer:
Sissors
Date:
Tue Jan 07 17:41:36 2014 +0000
Revision:
3:2c62a668f265
Child:
5:89dae784c38f
KL46Z included

Who changed what in which revision?

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