add the implementation of LP1768 wakeup based on the old WakeUp library

Dependencies:   LPC1114_WakeInterruptIn

Fork of WakeUp by steven niu

Committer:
Sissors
Date:
Wed Jul 30 20:39:57 2014 +0000
Revision:
15:6bf547e1e62d
Parent:
8:bb411115f814
Calibrate on LPC1114 now restores pin function settings afterwards (previously this broke wakeups were dp24 was used).
;
; Moved WakeInterruptIn to Device folder.

Who changed what in which revision?

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