Modified WakeUp program to run on STM32L152RE

Dependencies:   mbed LPC1114_WakeInterruptIn

Fork of WakeUp by Erik -

Files at this revision

API Documentation at this revision

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

Device/WakeUp_KLxxZ.cpp Show annotated file Show diff for this revision Revisions of this file
Device/WakeUp_LPC11u24.cpp Show annotated file Show diff for this revision Revisions of this file
Device/WakeUp_LPC812.cpp Show annotated file Show diff for this revision Revisions of this file
Device/WakeUp_NUCLEO_F030.cpp Show annotated file Show diff for this revision Revisions of this file
WakeUp_KLxxZ.cpp Show diff for this revision Revisions of this file
WakeUp_LPC11u24.cpp Show diff for this revision Revisions of this file
WakeUp_LPC812.cpp Show diff for this revision Revisions of this file
--- /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