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.
Fork of WakeUp by
Revision 7:bb411115f814, committed 2014-07-23
- Comitter:
- Sissors
- Date:
- Wed Jul 23 19:54:52 2014 +0000
- Parent:
- 6:815bef56e136
- Child:
- 8:8d9a6ac0fba8
- Commit message:
- Added NUCLEO F030R8
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Device/WakeUp_KLxxZ.cpp Wed Jul 23 19:54:52 2014 +0000
@@ -0,0 +1,115 @@
+#if defined(TARGET_KLXX) || defined(TARGET_K20D5M)
+
+#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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Device/WakeUp_LPC11u24.cpp Wed Jul 23 19:54:52 2014 +0000
@@ -0,0 +1,63 @@
+/**
+Due to lack of another option for the LPC11u24 the watchdog timer is used as wakeup source.
+Since if the reset on watchdog event bit is set, I cannot remove it again, this means if you also got watchdog code running
+the most likely result is that it just resets your board.
+**/
+
+
+#ifdef TARGET_LPC11U24
+
+#include "WakeUp.h"
+
+FunctionPointer WakeUp::callback;
+float WakeUp::cycles_per_ms = 5.0;
+
+void WakeUp::set_ms(uint32_t ms)
+{
+ if (ms != 0) {
+ LPC_SYSCON->SYSAHBCLKCTRL |= 0x8000;
+ LPC_SYSCON->PDRUNCFG &= ~(1<<6);
+ LPC_SYSCON->PDSLEEPCFG &= ~(1<<6);
+ LPC_SYSCON->STARTERP1 |= 1<<12;
+
+ //Set oscillator for 20kHz = 5kHz after divide by 4 in WDT
+ LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5);
+
+ LPC_WWDT->MOD = 1; //Enable WDT
+ LPC_WWDT->TC = (uint32_t)((float)ms * cycles_per_ms);
+ LPC_WWDT->CLKSEL = 1; //WDTOSC
+ LPC_WWDT->WARNINT = 0;
+
+ NVIC_SetVector(WDT_IRQn, (uint32_t)WakeUp::irq_handler);
+
+ //Feeeeeed me
+ LPC_WWDT->FEED = 0xAA;
+ LPC_WWDT->FEED = 0x55;
+
+ NVIC_EnableIRQ(WDT_IRQn);
+ } else
+ NVIC_DisableIRQ(WDT_IRQn);
+
+}
+
+void WakeUp::irq_handler(void)
+{
+ LPC_WWDT->MOD = 1<<3;
+ callback.call();
+}
+
+void WakeUp::calibrate(void)
+{
+ cycles_per_ms = 5.0;
+ set_ms(1100);
+ wait_ms(10); //Give time to sync
+ uint32_t count1 = LPC_WWDT->TV;
+ wait_ms(100);
+ uint32_t count2 = LPC_WWDT->TV;
+ set_ms(0);
+ count1 = count1 - count2;
+
+ cycles_per_ms = count1 / 100.0;
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Device/WakeUp_LPC812.cpp Wed Jul 23 19:54:52 2014 +0000
@@ -0,0 +1,74 @@
+#ifdef TARGET_LPC812
+
+#include "WakeUp.h"
+
+FunctionPointer WakeUp::callback;
+float WakeUp::cycles_per_ms = 10.0;
+
+void WakeUp::set_ms(uint32_t ms)
+{
+ //Enable clock to register interface:
+ LPC_SYSCON->SYSAHBCLKCTRL |= 1<<9;
+
+ //Clear the counter:
+ LPC_WKT->CTRL |= 1<<2;
+ if (ms != 0) {
+ //Enable clock to register interface:
+ LPC_SYSCON->SYSAHBCLKCTRL |= 1<<9;
+
+ //Set 10kHz timer as source, and just to be sure clear status bit
+ LPC_WKT->CTRL = 3;
+
+ //Enable the 10kHz timer
+ LPC_PMU->DPDCTRL |= (1<<2) | (1<<3);
+
+ //Set interrupts
+ NVIC_SetVector(WKT_IRQn, (uint32_t)WakeUp::irq_handler);
+ NVIC_EnableIRQ(WKT_IRQn);
+
+ //Load the timer
+ LPC_WKT->COUNT = (uint32_t)((float)ms * cycles_per_ms);
+
+ } else {
+ //Disable clock to register interface:
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<9);
+
+ //Disable the 10kHz timer
+ LPC_PMU->DPDCTRL &= ~((1<<2) | (1<<3));
+ }
+}
+
+void WakeUp::irq_handler(void)
+{
+ //Clear status
+ LPC_WKT->CTRL |= 2;
+
+ //Disable clock to register interface:
+ LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<9);
+
+ //Disable the 10kHz timer
+ LPC_PMU->DPDCTRL &= ~((1<<2) | (1<<3));
+
+ callback.call();
+}
+
+void WakeUp::calibrate(void)
+{
+ cycles_per_ms = 10.0;
+ set_ms(1100);
+ wait_ms(100);
+
+ uint32_t prevread = LPC_WKT->COUNT;
+ uint32_t read = LPC_WKT->COUNT;
+ while( read != prevread) {
+ prevread = read;
+ read = LPC_WKT->COUNT;
+ }
+
+ uint32_t ticks = 11000 - read;
+
+ cycles_per_ms = ticks / 100.0;
+ set_ms(0);
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Device/WakeUp_NUCLEO_F030.cpp Wed Jul 23 19:54:52 2014 +0000
@@ -0,0 +1,91 @@
+#ifdef TARGET_NUCLEO_F030R8
+
+#include "WakeUp.h"
+#include "rtc_api.h"
+#include "stm32f0xx_rtc.h"
+
+FunctionPointer WakeUp::callback;
+
+void WakeUp::set_ms(uint32_t ms)
+{
+ if (!rtc_isenabled()) //Make sure RTC is running
+ rtc_init();
+
+ //Alarm must be disabled to change anything
+ PWR_BackupAccessCmd(ENABLE);
+ RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
+
+ if (ms == 0) { //Just disable alarm
+ PWR_BackupAccessCmd(DISABLE);
+ return;
+ }
+
+ //RTC prescaler + calculate how many sub-seconds should be added
+ uint32_t prescaler = (RTC->PRER & 0x7FFF) + 1;
+ uint32_t subsecsadd = ((ms % 1000) * prescaler) / 1000;
+
+ if ((ms < 1000) && (subsecsadd < 2))
+ subsecsadd = 2; //At least 2 subsecs delay to be sure interrupt is called
+
+ //Get current time
+ uint32_t subsecs = RTC->SSR;
+ time_t secs = rtc_read();
+
+ //Calculate alarm values
+ //Subseconds is countdown, so substract the 'added' sub-seconds and prevent underflow
+ if (subsecs < subsecsadd) {
+ subsecs += prescaler;
+ secs++;
+ }
+ subsecs -= subsecsadd;
+
+ //Set seconds correctly
+ secs += ms / 1000;
+ struct tm *timeinfo = localtime(&secs);
+
+ RTC_AlarmTypeDef alarmStruct;
+ alarmStruct.RTC_AlarmTime.RTC_Hours = timeinfo->tm_hour;
+ alarmStruct.RTC_AlarmTime.RTC_Minutes = timeinfo->tm_min;
+ alarmStruct.RTC_AlarmTime.RTC_Seconds = timeinfo->tm_sec;
+ alarmStruct.RTC_AlarmTime.RTC_H12 = RTC_HourFormat_24;
+ alarmStruct.RTC_AlarmMask = RTC_AlarmMask_None;
+ alarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
+ alarmStruct.RTC_AlarmDateWeekDay = timeinfo->tm_mday;
+
+ //Enable EXTI interrupt of the RTC
+ EXTI_InitTypeDef extiStruct;
+ extiStruct.EXTI_Line = EXTI_Line17;
+ extiStruct.EXTI_Mode = EXTI_Mode_Interrupt;
+ extiStruct.EXTI_Trigger = EXTI_Trigger_Rising;
+ extiStruct.EXTI_LineCmd = ENABLE;
+
+ //Enable RTC interrupt
+ RTC_AlarmSubSecondConfig(RTC_Alarm_A, subsecs, RTC_AlarmSubSecondMask_None);
+ RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &alarmStruct);
+ RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
+ RTC_ITConfig(RTC_IT_ALRA, ENABLE);
+ PWR_BackupAccessCmd(DISABLE);
+
+ //Enable everything else
+ EXTI_Init(&extiStruct);
+ NVIC_SetVector(RTC_IRQn, (uint32_t)WakeUp::irq_handler);
+ NVIC_EnableIRQ(RTC_IRQn);
+}
+
+
+void WakeUp::irq_handler(void)
+{
+ //Clear RTC + EXTI interrupt flags
+ PWR_BackupAccessCmd(ENABLE);
+ RTC_ClearFlag(RTC_FLAG_ALRAF);
+ EXTI_ClearFlag(EXTI_Line17);
+ PWR_BackupAccessCmd(DISABLE);
+ callback.call();
+}
+
+void WakeUp::calibrate(void)
+{
+ //RTC, we assume it is accurate enough without calibration
+}
+
+#endif
--- a/WakeUp_KLxxZ.cpp Sat Jul 12 19:17:51 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-#if defined(TARGET_KLXX) || defined(TARGET_K20D50M)
-
-#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
--- a/WakeUp_LPC11u24.cpp Sat Jul 12 19:17:51 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/**
-Due to lack of another option for the LPC11u24 the watchdog timer is used as wakeup source.
-Since if the reset on watchdog event bit is set, I cannot remove it again, this means if you also got watchdog code running
-the most likely result is that it just resets your board.
-**/
-
-
-#ifdef TARGET_LPC11U24
-
-#include "WakeUp.h"
-
-FunctionPointer WakeUp::callback;
-float WakeUp::cycles_per_ms = 5.0;
-
-void WakeUp::set_ms(uint32_t ms)
-{
- if (ms != 0) {
- LPC_SYSCON->SYSAHBCLKCTRL |= 0x8000;
- LPC_SYSCON->PDRUNCFG &= ~(1<<6);
- LPC_SYSCON->PDSLEEPCFG &= ~(1<<6);
- LPC_SYSCON->STARTERP1 |= 1<<12;
-
- //Set oscillator for 20kHz = 5kHz after divide by 4 in WDT
- LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5);
-
- LPC_WWDT->MOD = 1; //Enable WDT
- LPC_WWDT->TC = (uint32_t)((float)ms * cycles_per_ms);
- LPC_WWDT->CLKSEL = 1; //WDTOSC
- LPC_WWDT->WARNINT = 0;
-
- NVIC_SetVector(WDT_IRQn, (uint32_t)WakeUp::irq_handler);
-
- //Feeeeeed me
- LPC_WWDT->FEED = 0xAA;
- LPC_WWDT->FEED = 0x55;
-
- NVIC_EnableIRQ(WDT_IRQn);
- } else
- NVIC_DisableIRQ(WDT_IRQn);
-
-}
-
-void WakeUp::irq_handler(void)
-{
- LPC_WWDT->MOD = 1<<3;
- callback.call();
-}
-
-void WakeUp::calibrate(void)
-{
- cycles_per_ms = 5.0;
- set_ms(1100);
- wait_ms(10); //Give time to sync
- uint32_t count1 = LPC_WWDT->TV;
- wait_ms(100);
- uint32_t count2 = LPC_WWDT->TV;
- set_ms(0);
- count1 = count1 - count2;
-
- cycles_per_ms = count1 / 100.0;
-}
-
-#endif
--- a/WakeUp_LPC812.cpp Sat Jul 12 19:17:51 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#ifdef TARGET_LPC812
-
-#include "WakeUp.h"
-
-FunctionPointer WakeUp::callback;
-float WakeUp::cycles_per_ms = 10.0;
-
-void WakeUp::set_ms(uint32_t ms)
-{
- //Enable clock to register interface:
- LPC_SYSCON->SYSAHBCLKCTRL |= 1<<9;
-
- //Clear the counter:
- LPC_WKT->CTRL |= 1<<2;
- if (ms != 0) {
- //Enable clock to register interface:
- LPC_SYSCON->SYSAHBCLKCTRL |= 1<<9;
-
- //Set 10kHz timer as source, and just to be sure clear status bit
- LPC_WKT->CTRL = 3;
-
- //Enable the 10kHz timer
- LPC_PMU->DPDCTRL |= (1<<2) | (1<<3);
-
- //Set interrupts
- NVIC_SetVector(WKT_IRQn, (uint32_t)WakeUp::irq_handler);
- NVIC_EnableIRQ(WKT_IRQn);
-
- //Load the timer
- LPC_WKT->COUNT = (uint32_t)((float)ms * cycles_per_ms);
-
- } else {
- //Disable clock to register interface:
- LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<9);
-
- //Disable the 10kHz timer
- LPC_PMU->DPDCTRL &= ~((1<<2) | (1<<3));
- }
-}
-
-void WakeUp::irq_handler(void)
-{
- //Clear status
- LPC_WKT->CTRL |= 2;
-
- //Disable clock to register interface:
- LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<9);
-
- //Disable the 10kHz timer
- LPC_PMU->DPDCTRL &= ~((1<<2) | (1<<3));
-
- callback.call();
-}
-
-void WakeUp::calibrate(void)
-{
- cycles_per_ms = 10.0;
- set_ms(1100);
- wait_ms(100);
-
- uint32_t prevread = LPC_WKT->COUNT;
- uint32_t read = LPC_WKT->COUNT;
- while( read != prevread) {
- prevread = read;
- read = LPC_WKT->COUNT;
- }
-
- uint32_t ticks = 11000 - read;
-
- cycles_per_ms = ticks / 100.0;
- set_ms(0);
-}
-
-#endif
