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:
mx300
Date:
Fri Nov 24 00:04:03 2017 +0000
Parent:
24:65c04a02ad45
Commit message:
Modified for use on STM32L152RE

Changed in this revision

Device/WakeUp_Freescale.cpp Show diff for this revision Revisions of this file
Device/WakeUp_LPC11XX.cpp Show diff for this revision Revisions of this file
Device/WakeUp_LPC11u24.cpp Show diff for this revision Revisions of this file
Device/WakeUp_LPC812.cpp Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 65c04a02ad45 -r 5147cde086fd Device/WakeUp_Freescale.cpp
--- a/Device/WakeUp_Freescale.cpp	Tue Jul 04 07:59:06 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-#if defined(TARGET_Freescale)
-
-#include "WakeUp.h"
-#include "us_ticker_api.h"
-
-Callback<void()> WakeUp::callback;
-float WakeUp::cycles_per_ms = 1.0;
-
-static uint16_t remainder_count;
-static uint32_t oldvector;
-static uint8_t oldPSR;
-
-//See if we have a 32kHz crystal on the clock input
-//Check if the DMX32 bit is set, not perfect, but most cases will work
-static inline bool is32kXtal(void) {
-    return (MCG->C4 & MCG_C4_DMX32_MASK);
-}
-
-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) {
-        /* Set interrupt handler */
-        NVIC_SetVector(LPTimer_IRQn, (uint32_t)WakeUp::irq_handler);
-        NVIC_EnableIRQ(LPTimer_IRQn);
-        
-        uint32_t counts;
-        //Set clock
-        if (is32kXtal()) {
-            SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK;    //Put RTC/LPTMR on 32kHz external. 
-            #ifdef OSC0
-            OSC0->CR |= OSC_CR_EREFSTEN_MASK;
-            #else
-            OSC->CR |= OSC_CR_EREFSTEN_MASK;
-            #endif
-            LPTMR0->PSR = LPTMR_PSR_PCS(2);
-            counts = (uint32_t)((float)ms * 32.768f);
-        } else {
-            //Clock from the 1kHz LPO
-            LPTMR0->PSR = LPTMR_PSR_PCS(1);
-            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)
-{
-    if (!is32kXtal()) {
-        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
diff -r 65c04a02ad45 -r 5147cde086fd Device/WakeUp_LPC11XX.cpp
--- a/Device/WakeUp_LPC11XX.cpp	Tue Jul 04 07:59:06 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/**
-See homepage of this lib for LPC11xx special treatment
-**/
-
-#ifdef TARGET_LPC11XX_11CXX
-
-#include "WakeUp.h"
-#include "WakeInterruptIn.h"
-#include "pinmap.h"
-#include "toolchain.h"
-
-//Pin used, allowed pins = P0_1 (dp24, default), P0_8 (dp1) and P0_9 (dp2)
-//By defining WakeUpPin in for example your main.cpp this can be overridden
-WEAK PinName WakeUpPin = dp24;
-extern PinName WakeUpPin;
-
-WakeInterruptIn IRQ_in(WakeUpPin);
-PwmOut pulse_out(WakeUpPin);
-
-Callback<void()> WakeUp::callback;
-float WakeUp::cycles_per_ms = 20.0;
-
-static uint32_t old_clk_sel = ~0;
-static uint32_t SYSAHBCLKCTRL;
-static uint32_t TCR, PR, MR3;
-static LPC_TMR_TypeDef *WakeUpTimer;
-static uint32_t SYSAHBCLKCTRL_Sleep;
-static uint8_t WakeUpTimer_Match;
-
-static inline void restore(void);
-
-
-void WakeUp::set_ms(uint32_t ms)
-{
-    if (old_clk_sel == ~0) {                                //Only during first run
-        old_clk_sel = LPC_SYSCON->MAINCLKSEL;
-        SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL;
-        
-        switch(WakeUpPin) {
-            case dp24:
-                WakeUpTimer = LPC_TMR32B0;
-                SYSAHBCLKCTRL_Sleep = 0x15 | (1<<9);
-                WakeUpTimer_Match = 2;
-                break;
-            case dp1:
-                WakeUpTimer = LPC_TMR16B0;
-                SYSAHBCLKCTRL_Sleep = 0x15 | (1<<7);
-                WakeUpTimer_Match = 0;
-                break;
-            case dp2:
-                WakeUpTimer = LPC_TMR16B0;
-                SYSAHBCLKCTRL_Sleep = 0x15 | (1<<7);
-                WakeUpTimer_Match = 1;
-                break;
-            default:
-                error("Invalid WakeUp pin, choose dp1, dp2 or dp24");
-        }            
-    }
-        
-    if (ms != 0) {        
-        if (LPC_SYSCON->SYSAHBCLKCTRL != SYSAHBCLKCTRL_Sleep)    //Always when it is different from sleep settings
-            SYSAHBCLKCTRL = LPC_SYSCON->SYSAHBCLKCTRL;
-
-        LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_WDTOSC_PD;
-        LPC_SYSCON->PDSLEEPCFG = 0x000018B7 | (LPC_SYSCON->PDRUNCFG & (PDRUNCFG_WDTOSC_PD | PDRUNCFG_BOD_PD)); 
-        
-        //Set oscillator for 20kHz
-        LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5);
-        
-        //Store old PWM
-        TCR = WakeUpTimer->TCR;
-        PR = WakeUpTimer->PR;
-        MR3 = WakeUpTimer->MR3;
-        
-        //Setup PWM
-        WakeUpTimer->TCR = TMR16B0TCR_CRST;
-        uint32_t ticks = (float)ms * cycles_per_ms;
-        
-        //whatever timer it is, we treat it as 16-bit (with PR that is 32-bit still, do the math, it is enough for this)
-        WakeUpTimer->PR = ticks >> 16;
-        WakeUpTimer->MR[WakeUpTimer_Match] = ticks / ((ticks >> 16) + 1);
-        WakeUpTimer->MR3 = 0xFFFF;
-                
-        IRQ_in.rise(irq_handler);
-        
-        //Disable most peripherals
-        LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL_Sleep;
-        
-        //Switch clock to WD OSC
-        LPC_SYSCON->MAINCLKSEL = 0x2;
-        LPC_SYSCON->MAINCLKUEN = 0;
-        LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA;
-        
-        //Enable PWM:
-        WakeUpTimer->TCR = TMR16B0TCR_CEN;
-    } else {
-        //Else restore normal settings
-        restore();
-    }
-    
-}
-
-void WakeUp::irq_handler(void)
-{    
-    restore();    
-    callback.call();
-}
-
-void WakeUp::calibrate(void)
-{
-    //Save current pin function
-    __IO uint32_t *reg = (__IO uint32_t*)(LPC_IOCON_BASE + (dp24 & 0xFF));
-    uint32_t old_pinfun = *reg;
-    
-    //Set oscillator for 20kHz
-    LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_WDTOSC_PD;
-    LPC_SYSCON->WDTOSCCTRL = 14 | (1<<5);
-    
-    //Direct WDT to the CLKOUT pin (dp24), sample it back
-    DigitalIn din(dp24);
-    Timer timer;
-    
-    LPC_SYSCON->CLKOUTDIV = 1;
-    LPC_SYSCON->CLKOUTCLKSEL = 0x2;
-    LPC_SYSCON->CLKOUTUEN = 0;
-    LPC_SYSCON->CLKOUTUEN = CLKOUTUEN_ENA;
-    pin_function(dp24, 1);
-    
-    int count = 0;
-    timer.start();
-    while (timer.read_ms() < 100) {
-        while (din.read() == 0);
-        while (din.read() == 1);
-        count++;
-    }
-    cycles_per_ms = (float)count / 100.0f;
-    
-    //Set old pin function back, disable CLKOUT
-    *reg = old_pinfun;
-    LPC_SYSCON->CLKOUTDIV = 0;
-}
-
-static inline void restore(void) {
-        
-    WakeUpTimer->MR[WakeUpTimer_Match] = 0xFFFFFFFF;
-
-    if (old_clk_sel == 3)                           //Was running on PLL
-        while(LPC_SYSCON->SYSPLLSTAT != SYSPLLSTAT_LOCK);
-    
-    if (old_clk_sel < 4) {  //If valid setting
-        LPC_SYSCON->MAINCLKSEL = old_clk_sel;
-        LPC_SYSCON->MAINCLKUEN = 0;
-        LPC_SYSCON->MAINCLKUEN = MAINCLKUEN_ENA;
-    }
-    
-    IRQ_in.rise(NULL);
-    
-    LPC_SYSCON->SYSAHBCLKCTRL = SYSAHBCLKCTRL; 
-    
-    WakeUpTimer->MR3 = MR3;
-    WakeUpTimer->PR = PR;
-    WakeUpTimer->TCR = TCR;
-}
-
-#endif
diff -r 65c04a02ad45 -r 5147cde086fd Device/WakeUp_LPC11u24.cpp
--- a/Device/WakeUp_LPC11u24.cpp	Tue Jul 04 07:59:06 2017 +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"
-
-Callback<void()> 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
diff -r 65c04a02ad45 -r 5147cde086fd Device/WakeUp_LPC812.cpp
--- a/Device/WakeUp_LPC812.cpp	Tue Jul 04 07:59:06 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#ifdef TARGET_LPC812
-
-#include "WakeUp.h"
-
-Callback<void()> 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
diff -r 65c04a02ad45 -r 5147cde086fd main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Nov 24 00:04:03 2017 +0000
@@ -0,0 +1,29 @@
+
+// Depending on the LED connections either the LED is off the 2 seconds
+// the target spends in deepsleep(), and on for the other second. Or it is inverted 
+ 
+#include "mbed.h"
+#include "WakeUp.h"
+ 
+DigitalOut myled(LED1);
+ 
+int main() {
+    //The low-power oscillator can be quite inaccurate on some targets
+    //this function calibrates it against the main clock
+    WakeUp::calibrate();
+   
+    while(1) {
+        //Set LED to zero
+        myled = 0;
+        
+        //Set wakeup time for 2 seconds
+        WakeUp::set_ms(2000);
+        
+        //Enter deepsleep, the program won't go beyond this point until it is woken up
+        sleep();
+  
+        //Set LED for 1 second to one
+        myled = 1;
+        wait(1);
+    }
+}
\ No newline at end of file
diff -r 65c04a02ad45 -r 5147cde086fd mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Nov 24 00:04:03 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/235179ab3f27
\ No newline at end of file