Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: LPC1114_WakeInterruptIn
Fork of WakeUp by
Diff: Device/WakeUp_Freescale.cpp
- Revision:
- 16:f3adba7cf7c4
- Parent:
- 7:bb411115f814
- Child:
- 18:13aed323e040
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Device/WakeUp_Freescale.cpp Sun Sep 14 06:45:51 2014 +0000
@@ -0,0 +1,115 @@
+#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
\ No newline at end of file
