Wake-up timer library to wake from deepsleep/power-down
Dependencies: LPC1114_WakeInterruptIn
Fork of WakeUp by
Device/WakeUp_Freescale.cpp
- Committer:
- Sissors
- Date:
- 2014-09-14
- Revision:
- 16:f3adba7cf7c4
- Parent:
- Device/WakeUp_KLxxZ.cpp@ 7:bb411115f814
- Child:
- 18:13aed323e040
File content as of revision 16:f3adba7cf7c4:
#if defined(TARGET_Freescale) #include "WakeUp.h" #include "us_ticker_api.h" FunctionPointer WakeUp::callback; float WakeUp::cycles_per_ms = 1.0; static uint16_t remainder_count; static uint32_t oldvector; static uint8_t oldPSR; void restore(void); void WakeUp::set_ms(uint32_t ms) { /* Clock the timer */ SIM->SCGC5 |= 0x1u; //Check if it is running, in that case, store current values remainder_count = 0; if (NVIC_GetVector(LPTimer_IRQn) != (uint32_t)WakeUp::irq_handler) { oldvector = NVIC_GetVector(LPTimer_IRQn); oldPSR = LPTMR0->PSR; if (LPTMR0->CSR & LPTMR_CSR_TIE_MASK) { //Write first to sync value LPTMR0->CNR = 0; uint16_t countval = LPTMR0->CNR; if (countval < LPTMR0->CMR) remainder_count = countval - LPTMR0->CMR; } } LPTMR0->CSR = 0; if (ms != 0) { //Clock from the 1kHz LPO LPTMR0->PSR = LPTMR_PSR_PCS(1); /* Set interrupt handler */ NVIC_SetVector(LPTimer_IRQn, (uint32_t)WakeUp::irq_handler); NVIC_EnableIRQ(LPTimer_IRQn); uint32_t counts = (uint32_t)((float)ms * cycles_per_ms); //If no prescaler is needed if (counts <= 0xFFFF) LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK; else { //Otherwise increase prescaler until it fits counts >>= 1; uint32_t prescaler = 0; while (counts > 0xFFFF) { counts >>= 1; prescaler++; } LPTMR0->PSR |= LPTMR_PSR_PRESCALE(prescaler); } LPTMR0->CMR = counts; LPTMR0->CSR = LPTMR_CSR_TIE_MASK; LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; } else { restore(); } } void WakeUp::irq_handler(void) { // write 1 to TCF to clear the LPT timer compare flag LPTMR0->CSR |= LPTMR_CSR_TCF_MASK; restore(); callback.call(); } void WakeUp::calibrate(void) { wait_us(1); //Otherwise next wait might overwrite our settings cycles_per_ms = 1.0; set_ms(1100); wait_ms(100); //Write first to sync value LPTMR0->CNR = 0; uint32_t ticks = LPTMR0->CNR; cycles_per_ms = ticks / 100.0; set_ms(0); } void restore(void){ /* Reset */ LPTMR0->CSR = 0; /* Set interrupt handler */ NVIC_SetVector(LPTimer_IRQn, oldvector); NVIC_EnableIRQ(LPTimer_IRQn); /* Clock at (1)MHz -> (1)tick/us */ LPTMR0->PSR = oldPSR; if (remainder_count) { /* Set the compare register */ LPTMR0->CMR = remainder_count; /* Enable interrupt */ LPTMR0->CSR |= LPTMR_CSR_TIE_MASK; /* Start the timer */ LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; } } #endif