Fork of original library to fix mbed 5 deprecation warnings
Dependencies: LPC1114_WakeInterruptIn
Fork of WakeUp by
WakeUp_Freescale.cpp
00001 #if defined(TARGET_Freescale) 00002 00003 #include "WakeUp.h" 00004 #include "us_ticker_api.h" 00005 00006 Callback<void()> WakeUp::cbk; 00007 float WakeUp::cycles_per_ms = 1.0; 00008 00009 static uint16_t remainder_count; 00010 static uint32_t oldvector; 00011 static uint8_t oldPSR; 00012 00013 //See if we have a 32kHz crystal on the clock input 00014 //Check if the DMX32 bit is set, not perfect, but most cases will work 00015 static inline bool is32kXtal(void) { 00016 return (MCG->C4 & MCG_C4_DMX32_MASK); 00017 } 00018 00019 void restore(void); 00020 00021 void WakeUp::set_ms(uint32_t ms) 00022 { 00023 /* Clock the timer */ 00024 SIM->SCGC5 |= 0x1u; 00025 00026 //Check if it is running, in that case, store current values 00027 remainder_count = 0; 00028 if (NVIC_GetVector(LPTimer_IRQn) != (uint32_t)WakeUp::irq_handler) { 00029 oldvector = NVIC_GetVector(LPTimer_IRQn); 00030 oldPSR = LPTMR0->PSR; 00031 00032 if (LPTMR0->CSR & LPTMR_CSR_TIE_MASK) { 00033 //Write first to sync value 00034 LPTMR0->CNR = 0; 00035 uint16_t countval = LPTMR0->CNR; 00036 if (countval < LPTMR0->CMR) 00037 remainder_count = countval - LPTMR0->CMR; 00038 } 00039 } 00040 00041 LPTMR0->CSR = 0; 00042 00043 if (ms != 0) { 00044 /* Set interrupt handler */ 00045 NVIC_SetVector(LPTimer_IRQn, (uint32_t)WakeUp::irq_handler); 00046 NVIC_EnableIRQ(LPTimer_IRQn); 00047 00048 uint32_t counts; 00049 //Set clock 00050 if (is32kXtal()) { 00051 SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK; //Put RTC/LPTMR on 32kHz external. 00052 #ifdef OSC0 00053 OSC0->CR |= OSC_CR_EREFSTEN_MASK; 00054 #else 00055 OSC->CR |= OSC_CR_EREFSTEN_MASK; 00056 #endif 00057 LPTMR0->PSR = LPTMR_PSR_PCS(2); 00058 counts = (uint32_t)((float)ms * 32.768f); 00059 } else { 00060 //Clock from the 1kHz LPO 00061 LPTMR0->PSR = LPTMR_PSR_PCS(1); 00062 counts = (uint32_t)((float)ms * cycles_per_ms); 00063 } 00064 00065 //If no prescaler is needed 00066 if (counts <= 0xFFFF) 00067 LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK; 00068 else { //Otherwise increase prescaler until it fits 00069 counts >>= 1; 00070 uint32_t prescaler = 0; 00071 while (counts > 0xFFFF) { 00072 counts >>= 1; 00073 prescaler++; 00074 } 00075 LPTMR0->PSR |= LPTMR_PSR_PRESCALE(prescaler); 00076 } 00077 LPTMR0->CMR = counts; 00078 00079 LPTMR0->CSR = LPTMR_CSR_TIE_MASK; 00080 LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; 00081 } else { 00082 restore(); 00083 } 00084 00085 } 00086 00087 00088 void WakeUp::irq_handler(void) 00089 { 00090 // write 1 to TCF to clear the LPT timer compare flag 00091 LPTMR0->CSR |= LPTMR_CSR_TCF_MASK; 00092 restore(); 00093 if (cbk) { 00094 cbk.call(); 00095 } 00096 } 00097 00098 void WakeUp::calibrate(void) 00099 { 00100 if (!is32kXtal()) { 00101 wait_us(1); //Otherwise next wait might overwrite our settings 00102 cycles_per_ms = 1.0; 00103 set_ms(1100); 00104 wait_ms(100); 00105 00106 //Write first to sync value 00107 LPTMR0->CNR = 0; 00108 uint32_t ticks = LPTMR0->CNR; 00109 cycles_per_ms = ticks / 100.0; 00110 set_ms(0); 00111 } 00112 } 00113 00114 void restore(void){ 00115 /* Reset */ 00116 LPTMR0->CSR = 0; 00117 00118 /* Set interrupt handler */ 00119 NVIC_SetVector(LPTimer_IRQn, oldvector); 00120 NVIC_EnableIRQ(LPTimer_IRQn); 00121 00122 /* Clock at (1)MHz -> (1)tick/us */ 00123 LPTMR0->PSR = oldPSR; 00124 00125 if (remainder_count) { 00126 /* Set the compare register */ 00127 LPTMR0->CMR = remainder_count; 00128 00129 /* Enable interrupt */ 00130 LPTMR0->CSR |= LPTMR_CSR_TIE_MASK; 00131 00132 /* Start the timer */ 00133 LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; 00134 } 00135 } 00136 00137 #endif
Generated on Tue Jul 12 2022 18:10:46 by 1.7.2