mbed library sources

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Thu May 07 09:00:08 2015 +0100
Parent:
535:35ad5cbb2f6a
Child:
537:c61a9ac6f5c2
Commit message:
Synchronized with git revision a1e04f782bf013aeb4122c3ec408e3b011de60ed

Full URL: https://github.com/mbedmicro/mbed/commit/a1e04f782bf013aeb4122c3ec408e3b011de60ed/

MAX32600MBED,MAXWSNENV - Add low-power ticker.

Changed in this revision

targets/hal/TARGET_Maxim/TARGET_MAX32600/device.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Maxim/TARGET_MAX32600/rtc_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Maxim/TARGET_MAX32600/sleep.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Maxim/TARGET_MAX32600/us_ticker.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Maxim/TARGET_MAX32610/device.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Maxim/TARGET_MAX32610/rtc_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Maxim/TARGET_MAX32610/sleep.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_Maxim/TARGET_MAX32610/us_ticker.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32600/device.h	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32600/device.h	Thu May 07 09:00:08 2015 +0100
@@ -64,6 +64,8 @@
 
 #define DEVICE_ERROR_PATTERN    1
 
+#define DEVICE_LOWPOWERTIMER    1
+
 #define DEVICE_CAN              0
 #define DEVICE_ETHERNET         0
 
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32600/rtc_api.c	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32600/rtc_api.c	Thu May 07 09:00:08 2015 +0100
@@ -32,56 +32,51 @@
  */
 
 #include "rtc_api.h"
+#include "lp_ticker_api.h"
 #include "cmsis.h"
 #include "rtc_regs.h"
 #include "pwrseq_regs.h"
 #include "clkman_regs.h"
 
+#define PRESCALE_VAL    MXC_E_RTC_PRESCALE_DIV_2_0    // Set the divider for the 4kHz clock
+#define SHIFT_AMT       (MXC_E_RTC_PRESCALE_DIV_2_12 - PRESCALE_VAL)
+
 static int rtc_inited = 0;
 static volatile uint32_t overflow_cnt = 0;
-static uint32_t overflow_alarm = 0;
+
+static uint64_t rtc_read64(void);
 
 //******************************************************************************
 static void overflow_handler(void)
 {
-    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS;
+    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_OVERFLOW;
     overflow_cnt++;
-
-    if (overflow_cnt == overflow_alarm) {
-        // Enable the comparator interrupt for the alarm
-        MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
-    }
-}
-
-//******************************************************************************
-static void alarm_handler(void)
-{
-    MXC_RTCTMR->inten &= ~MXC_F_RTC_INTEN_COMP0;
-    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS;
 }
 
 //******************************************************************************
 void rtc_init(void)
 {
-    if(rtc_inited) {
+    if (rtc_inited) {
         return;
     }
     rtc_inited = 1;
 
+    overflow_cnt = 0;
+
     // Enable the clock to the synchronizer
     MXC_CLKMAN->clk_ctrl_13_rtc_int_sync = MXC_E_CLKMAN_CLK_SCALE_ENABLED;
 
     // Enable the clock to the RTC
     MXC_PWRSEQ->reg0 |= MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN;
 
-    // Set the divider from the 4kHz clock
-    MXC_RTCTMR->prescale = MXC_E_RTC_PRESCALE_DIV_2_0;
+    // Set the clock divider
+    MXC_RTCTMR->prescale = PRESCALE_VAL;
 
     // Enable the overflow interrupt
     MXC_RTCTMR->inten |= MXC_F_RTC_FLAGS_OVERFLOW;
 
     // Prepare interrupt handlers
-    NVIC_SetVector(RTC0_IRQn, (uint32_t)alarm_handler);
+    NVIC_SetVector(RTC0_IRQn, (uint32_t)lp_ticker_irq_handler);
     NVIC_EnableIRQ(RTC0_IRQn);
     NVIC_SetVector(RTC3_IRQn, (uint32_t)overflow_handler);
     NVIC_EnableIRQ(RTC3_IRQn);
@@ -91,6 +86,12 @@
 }
 
 //******************************************************************************
+void lp_ticker_init(void)
+{
+    rtc_init();
+}
+
+//******************************************************************************
 void rtc_free(void)
 {
     if (MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_ENABLE) {
@@ -118,73 +119,104 @@
 //******************************************************************************
 time_t rtc_read(void)
 {
-    unsigned int shift_amt;
     uint32_t ovf_cnt_1, ovf_cnt_2, timer_cnt;
-
-    // Account for a change in the default prescaler
-    shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
+    uint32_t ovf1, ovf2;
 
     // Ensure coherency between overflow_cnt and timer
     do {
         ovf_cnt_1 = overflow_cnt;
+        ovf1 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         timer_cnt = MXC_RTCTMR->timer;
+        ovf2 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         ovf_cnt_2 = overflow_cnt;
-    } while (ovf_cnt_1 != ovf_cnt_2);
+    } while ((ovf_cnt_1 != ovf_cnt_2) || (ovf1 != ovf2));
 
-    return (timer_cnt >> shift_amt) + (ovf_cnt_1 << (32 - shift_amt));
+    // Account for an unserviced interrupt
+    if (ovf1) {
+        ovf_cnt_1++;
+    }
+
+    return (timer_cnt >> SHIFT_AMT) + (ovf_cnt_1 << (32 - SHIFT_AMT));
 }
 
 //******************************************************************************
-uint64_t rtc_read_us(void)
+static uint64_t rtc_read64(void)
 {
-    unsigned int shift_amt;
     uint32_t ovf_cnt_1, ovf_cnt_2, timer_cnt;
-    uint64_t currentUs;
-
-    // Account for a change in the default prescaler
-    shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
+    uint32_t ovf1, ovf2;
+    uint64_t current_us;
 
     // Ensure coherency between overflow_cnt and timer
     do {
         ovf_cnt_1 = overflow_cnt;
+        ovf1 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         timer_cnt = MXC_RTCTMR->timer;
+        ovf2 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         ovf_cnt_2 = overflow_cnt;
-    } while (ovf_cnt_1 != ovf_cnt_2);
+    } while ((ovf_cnt_1 != ovf_cnt_2) || (ovf1 != ovf2));
 
-    currentUs = (((uint64_t)timer_cnt * 1000000) >> shift_amt) + (((uint64_t)ovf_cnt_1 * 1000000) << (32 - shift_amt));
+    // Account for an unserviced interrupt
+    if (ovf1) {
+        ovf_cnt_1++;
+    }
 
-    return currentUs;
+    current_us = (((uint64_t)timer_cnt * 1000000) >> SHIFT_AMT) + (((uint64_t)ovf_cnt_1 * 1000000) << (32 - SHIFT_AMT));
+
+    return current_us;
 }
 
 //******************************************************************************
 void rtc_write(time_t t)
 {
-    // Account for a change in the default prescaler
-    unsigned int shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
-
     MXC_RTCTMR->ctrl &= ~MXC_F_RTC_CTRL_ENABLE; // disable the timer while updating
-    MXC_RTCTMR->timer = t << shift_amt;
-    overflow_cnt = t >> (32 - shift_amt);
+    MXC_RTCTMR->timer = t << SHIFT_AMT;
+    overflow_cnt = t >> (32 - SHIFT_AMT);
     MXC_RTCTMR->ctrl |= MXC_F_RTC_CTRL_ENABLE;  // enable the timer while updating
 }
 
 //******************************************************************************
-void rtc_set_wakeup(uint64_t wakeupUs)
+void lp_ticker_set_interrupt(timestamp_t timestamp)
 {
-    // Account for a change in the default prescaler
-    unsigned int shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
+    // Note: interrupts are disabled before this function is called.
 
     // Disable the alarm while it is prepared
     MXC_RTCTMR->inten &= ~MXC_F_RTC_INTEN_COMP0;
     MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_COMP0;      // clear interrupt
 
-    overflow_alarm = (wakeupUs >> (32 - shift_amt)) / 1000000;
+    uint64_t curr_ts64 = rtc_read64();
+    uint64_t ts64 = (uint64_t)timestamp | (curr_ts64 & 0xFFFFFFFF00000000ULL);
+    if (ts64 < curr_ts64) {
+        if (ts64 < (curr_ts64 - 1000)) {
+            ts64 += 0x100000000ULL;
+        } else {
+            // This event has already occurred. Set the alarm to expire immediately.
+            MXC_RTCTMR->comp[0] = MXC_RTCTMR->timer + 2;
+            MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
+            return;
+        }
+    }
 
-    if (overflow_alarm == overflow_cnt) {
-        MXC_RTCTMR->comp[0] = (wakeupUs << shift_amt) / 1000000;
-        MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
-    }
+    MXC_RTCTMR->comp[0] = (ts64 << SHIFT_AMT) / 1000000;
+    MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
 
     // Enable wakeup from RTC
     MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_MSK_FLAGS_RTC_ROLLOVER | MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR0);
 }
+
+//******************************************************************************
+inline void lp_ticker_disable_interrupt(void)
+{
+    MXC_RTCTMR->inten &= ~MXC_F_RTC_INTEN_COMP0;
+}
+
+//******************************************************************************
+inline void lp_ticker_clear_interrupt(void)
+{
+    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS;
+}
+
+//******************************************************************************
+inline uint32_t lp_ticker_read(void)
+{
+    return rtc_read64();
+}
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32600/sleep.c	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32600/sleep.c	Thu May 07 09:00:08 2015 +0100
@@ -30,22 +30,14 @@
  * ownership rights.
  *******************************************************************************
  */
- 
+
 #include "sleep_api.h"
-#include "us_ticker_api.h"
 #include "cmsis.h"
 #include "pwrman_regs.h"
 #include "pwrseq_regs.h"
 #include "ioman_regs.h"
 #include "rtc_regs.h"
 
-#define MIN_DEEP_SLEEP_US       500
-
-uint64_t rtc_read_us(void);
-void rtc_set_wakeup(uint64_t wakeupUs);
-void us_ticker_deinit(void);
-void us_ticker_set(timestamp_t timestamp);
-
 static mxc_uart_regs_t *stdio_uart = (mxc_uart_regs_t*)STDIO_UART;
 
 // Normal wait mode
@@ -80,38 +72,11 @@
 // Low-power stop mode
 void deepsleep(void)
 {
-    uint64_t sleepStartRtcUs;
-    uint32_t sleepStartTickerUs;
-    int32_t sleepDurationUs;
-    uint64_t sleepEndRtcUs;
-    uint64_t elapsedUs;
-
     __disable_irq();
 
     // Wait for all STDIO characters to be sent. The UART clock will stop.
     while (stdio_uart->status & MXC_F_UART_STATUS_TX_BUSY);
 
-    // Record the current times
-    sleepStartRtcUs = rtc_read_us();
-    sleepStartTickerUs = us_ticker_read();
-
-    // Get the next mbed timer expiration
-    timestamp_t next_event = 0;
-    us_ticker_get_next_timestamp(&next_event);
-    sleepDurationUs = next_event - sleepStartTickerUs;
-
-    if (sleepDurationUs < MIN_DEEP_SLEEP_US) {
-        /* The next wakeup is too soon. */
-        __enable_irq();
-        return;
-    }
-
-    // Disable the us_ticker. It won't be clocked in DeepSleep
-    us_ticker_deinit();
-
-    // Prepare to wakeup from the RTC
-    rtc_set_wakeup(sleepStartRtcUs + sleepDurationUs);
-
     // Prepare for LP1
     uint32_t reg0 = MXC_PWRSEQ->reg0;
     reg0 &= ~MXC_F_PWRSEQ_REG0_PWR_SVM3EN_SLP;  // disable VDD3 SVM during sleep mode
@@ -151,19 +116,8 @@
     // Woke up from LP1
 
     // The RTC timer does not update until the next tick
-    uint64_t tempUs = rtc_read_us();
-    do {
-        sleepEndRtcUs = rtc_read_us();
-    } while(sleepEndRtcUs == tempUs);
-
-    // Get the elapsed time from the RTC. Wakeup could have been from some other event.
-    elapsedUs = sleepEndRtcUs - sleepStartRtcUs;
-
-    // Update the us_ticker. It was not clocked during DeepSleep
-    us_ticker_init();
-    us_ticker_set(sleepStartTickerUs + elapsedUs);
-    us_ticker_get_next_timestamp(&next_event);
-    us_ticker_set_interrupt(next_event);
+    uint32_t temp = MXC_RTCTMR->timer;
+    while (MXC_RTCTMR->timer == temp);
 
     __enable_irq();
 }
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32600/us_ticker.c	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32600/us_ticker.c	Thu May 07 09:00:08 2015 +0100
@@ -30,7 +30,7 @@
  * ownership rights.
  *******************************************************************************
  */
- 
+
 #include "mbed_error.h"
 #include "us_ticker_api.h"
 #include "PeripheralNames.h"
@@ -53,7 +53,7 @@
 
     // Overflow the ticker when the us ticker overflows
     current_cnt += inc;
-    if(current_cnt > MAX_TICK_VAL) {
+    if (current_cnt > MAX_TICK_VAL) {
         current_cnt -= (MAX_TICK_VAL + 1);
     }
 }
@@ -64,7 +64,7 @@
     // Determine if the event has already happened.
     // If the event is behind the current ticker, within a window,
     // then the event has already happened.
-    if(((current < tick_win) && ((event < current) || 
+    if (((current < tick_win) && ((event < current) || 
         (event > (MAX_TICK_VAL - (tick_win - current))))) || 
         ((event < current) && (event > (current - tick_win)))) {
         return 1;
@@ -169,7 +169,7 @@
 {
     uint64_t current_cnt1, current_cnt2;
     uint32_t term_cnt, tmr_cnt;
-    int intfl1, intfl2;
+    uint32_t intfl1, intfl2;
 
     if (!us_ticker_inited)
         us_ticker_init();
@@ -184,6 +184,7 @@
         current_cnt2 = current_cnt;
     } while ((current_cnt1 != current_cnt2) || (intfl1 != intfl2));
 
+    // Account for an unserviced interrupt
     if (intfl1) {
         current_cnt1 += term_cnt;
     }
@@ -197,6 +198,7 @@
 void us_ticker_set_interrupt(timestamp_t timestamp)
 {
     // Note: interrupts are disabled before this function is called.
+
     US_TIMER->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0;  // disable timer
 
     if (US_TIMER->intfl) {
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32610/device.h	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32610/device.h	Thu May 07 09:00:08 2015 +0100
@@ -64,6 +64,8 @@
 
 #define DEVICE_ERROR_PATTERN    1
 
+#define DEVICE_LOWPOWERTIMER    1
+
 #define DEVICE_CAN              0
 #define DEVICE_ETHERNET         0
 
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32610/rtc_api.c	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32610/rtc_api.c	Thu May 07 09:00:08 2015 +0100
@@ -32,56 +32,51 @@
  */
 
 #include "rtc_api.h"
+#include "lp_ticker_api.h"
 #include "cmsis.h"
 #include "rtc_regs.h"
 #include "pwrseq_regs.h"
 #include "clkman_regs.h"
 
+#define PRESCALE_VAL    MXC_E_RTC_PRESCALE_DIV_2_0    // Set the divider for the 4kHz clock
+#define SHIFT_AMT       (MXC_E_RTC_PRESCALE_DIV_2_12 - PRESCALE_VAL)
+
 static int rtc_inited = 0;
 static volatile uint32_t overflow_cnt = 0;
-static uint32_t overflow_alarm = 0;
+
+static uint64_t rtc_read64(void);
 
 //******************************************************************************
 static void overflow_handler(void)
 {
-    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS;
+    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_OVERFLOW;
     overflow_cnt++;
-
-    if (overflow_cnt == overflow_alarm) {
-        // Enable the comparator interrupt for the alarm
-        MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
-    }
-}
-
-//******************************************************************************
-static void alarm_handler(void)
-{
-    MXC_RTCTMR->inten &= ~MXC_F_RTC_INTEN_COMP0;
-    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS;
 }
 
 //******************************************************************************
 void rtc_init(void)
 {
-    if(rtc_inited) {
+    if (rtc_inited) {
         return;
     }
     rtc_inited = 1;
 
+    overflow_cnt = 0;
+
     // Enable the clock to the synchronizer
     MXC_CLKMAN->clk_ctrl_13_rtc_int_sync = MXC_E_CLKMAN_CLK_SCALE_ENABLED;
 
     // Enable the clock to the RTC
     MXC_PWRSEQ->reg0 |= MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN;
 
-    // Set the divider from the 4kHz clock
-    MXC_RTCTMR->prescale = MXC_E_RTC_PRESCALE_DIV_2_0;
+    // Set the clock divider
+    MXC_RTCTMR->prescale = PRESCALE_VAL;
 
     // Enable the overflow interrupt
     MXC_RTCTMR->inten |= MXC_F_RTC_FLAGS_OVERFLOW;
 
     // Prepare interrupt handlers
-    NVIC_SetVector(RTC0_IRQn, (uint32_t)alarm_handler);
+    NVIC_SetVector(RTC0_IRQn, (uint32_t)lp_ticker_irq_handler);
     NVIC_EnableIRQ(RTC0_IRQn);
     NVIC_SetVector(RTC3_IRQn, (uint32_t)overflow_handler);
     NVIC_EnableIRQ(RTC3_IRQn);
@@ -91,6 +86,12 @@
 }
 
 //******************************************************************************
+void lp_ticker_init(void)
+{
+    rtc_init();
+}
+
+//******************************************************************************
 void rtc_free(void)
 {
     if (MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_ENABLE) {
@@ -118,73 +119,104 @@
 //******************************************************************************
 time_t rtc_read(void)
 {
-    unsigned int shift_amt;
     uint32_t ovf_cnt_1, ovf_cnt_2, timer_cnt;
-
-    // Account for a change in the default prescaler
-    shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
+    uint32_t ovf1, ovf2;
 
     // Ensure coherency between overflow_cnt and timer
     do {
         ovf_cnt_1 = overflow_cnt;
+        ovf1 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         timer_cnt = MXC_RTCTMR->timer;
+        ovf2 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         ovf_cnt_2 = overflow_cnt;
-    } while (ovf_cnt_1 != ovf_cnt_2);
+    } while ((ovf_cnt_1 != ovf_cnt_2) || (ovf1 != ovf2));
 
-    return (timer_cnt >> shift_amt) + (ovf_cnt_1 << (32 - shift_amt));
+    // Account for an unserviced interrupt
+    if (ovf1) {
+        ovf_cnt_1++;
+    }
+
+    return (timer_cnt >> SHIFT_AMT) + (ovf_cnt_1 << (32 - SHIFT_AMT));
 }
 
 //******************************************************************************
-uint64_t rtc_read_us(void)
+static uint64_t rtc_read64(void)
 {
-    unsigned int shift_amt;
     uint32_t ovf_cnt_1, ovf_cnt_2, timer_cnt;
-    uint64_t currentUs;
-
-    // Account for a change in the default prescaler
-    shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
+    uint32_t ovf1, ovf2;
+    uint64_t current_us;
 
     // Ensure coherency between overflow_cnt and timer
     do {
         ovf_cnt_1 = overflow_cnt;
+        ovf1 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         timer_cnt = MXC_RTCTMR->timer;
+        ovf2 = MXC_RTCTMR->flags & MXC_F_RTC_FLAGS_OVERFLOW;
         ovf_cnt_2 = overflow_cnt;
-    } while (ovf_cnt_1 != ovf_cnt_2);
+    } while ((ovf_cnt_1 != ovf_cnt_2) || (ovf1 != ovf2));
 
-    currentUs = (((uint64_t)timer_cnt * 1000000) >> shift_amt) + (((uint64_t)ovf_cnt_1 * 1000000) << (32 - shift_amt));
+    // Account for an unserviced interrupt
+    if (ovf1) {
+        ovf_cnt_1++;
+    }
 
-    return currentUs;
+    current_us = (((uint64_t)timer_cnt * 1000000) >> SHIFT_AMT) + (((uint64_t)ovf_cnt_1 * 1000000) << (32 - SHIFT_AMT));
+
+    return current_us;
 }
 
 //******************************************************************************
 void rtc_write(time_t t)
 {
-    // Account for a change in the default prescaler
-    unsigned int shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
-
     MXC_RTCTMR->ctrl &= ~MXC_F_RTC_CTRL_ENABLE; // disable the timer while updating
-    MXC_RTCTMR->timer = t << shift_amt;
-    overflow_cnt = t >> (32 - shift_amt);
+    MXC_RTCTMR->timer = t << SHIFT_AMT;
+    overflow_cnt = t >> (32 - SHIFT_AMT);
     MXC_RTCTMR->ctrl |= MXC_F_RTC_CTRL_ENABLE;  // enable the timer while updating
 }
 
 //******************************************************************************
-void rtc_set_wakeup(uint64_t wakeupUs)
+void lp_ticker_set_interrupt(timestamp_t timestamp)
 {
-    // Account for a change in the default prescaler
-    unsigned int shift_amt = MXC_E_RTC_PRESCALE_DIV_2_12 - MXC_RTCTMR->prescale;
+    // Note: interrupts are disabled before this function is called.
 
     // Disable the alarm while it is prepared
     MXC_RTCTMR->inten &= ~MXC_F_RTC_INTEN_COMP0;
     MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_COMP0;      // clear interrupt
 
-    overflow_alarm = (wakeupUs >> (32 - shift_amt)) / 1000000;
+    uint64_t curr_ts64 = rtc_read64();
+    uint64_t ts64 = (uint64_t)timestamp | (curr_ts64 & 0xFFFFFFFF00000000ULL);
+    if (ts64 < curr_ts64) {
+        if (ts64 < (curr_ts64 - 1000)) {
+            ts64 += 0x100000000ULL;
+        } else {
+            // This event has already occurred. Set the alarm to expire immediately.
+            MXC_RTCTMR->comp[0] = MXC_RTCTMR->timer + 2;
+            MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
+            return;
+        }
+    }
 
-    if (overflow_alarm == overflow_cnt) {
-        MXC_RTCTMR->comp[0] = (wakeupUs << shift_amt) / 1000000;
-        MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
-    }
+    MXC_RTCTMR->comp[0] = (ts64 << SHIFT_AMT) / 1000000;
+    MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0;
 
     // Enable wakeup from RTC
     MXC_PWRSEQ->msk_flags &= ~(MXC_F_PWRSEQ_MSK_FLAGS_RTC_ROLLOVER | MXC_F_PWRSEQ_MSK_FLAGS_RTC_CMPR0);
 }
+
+//******************************************************************************
+inline void lp_ticker_disable_interrupt(void)
+{
+    MXC_RTCTMR->inten &= ~MXC_F_RTC_INTEN_COMP0;
+}
+
+//******************************************************************************
+inline void lp_ticker_clear_interrupt(void)
+{
+    MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_ASYNC_CLR_FLAGS;
+}
+
+//******************************************************************************
+inline uint32_t lp_ticker_read(void)
+{
+    return rtc_read64();
+}
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32610/sleep.c	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32610/sleep.c	Thu May 07 09:00:08 2015 +0100
@@ -30,22 +30,14 @@
  * ownership rights.
  *******************************************************************************
  */
- 
+
 #include "sleep_api.h"
-#include "us_ticker_api.h"
 #include "cmsis.h"
 #include "pwrman_regs.h"
 #include "pwrseq_regs.h"
 #include "ioman_regs.h"
 #include "rtc_regs.h"
 
-#define MIN_DEEP_SLEEP_US       500
-
-uint64_t rtc_read_us(void);
-void rtc_set_wakeup(uint64_t wakeupUs);
-void us_ticker_deinit(void);
-void us_ticker_set(timestamp_t timestamp);
-
 static mxc_uart_regs_t *stdio_uart = (mxc_uart_regs_t*)STDIO_UART;
 
 // Normal wait mode
@@ -80,38 +72,11 @@
 // Low-power stop mode
 void deepsleep(void)
 {
-    uint64_t sleepStartRtcUs;
-    uint32_t sleepStartTickerUs;
-    int32_t sleepDurationUs;
-    uint64_t sleepEndRtcUs;
-    uint64_t elapsedUs;
-
     __disable_irq();
 
     // Wait for all STDIO characters to be sent. The UART clock will stop.
     while (stdio_uart->status & MXC_F_UART_STATUS_TX_BUSY);
 
-    // Record the current times
-    sleepStartRtcUs = rtc_read_us();
-    sleepStartTickerUs = us_ticker_read();
-
-    // Get the next mbed timer expiration
-    timestamp_t next_event = 0;
-    us_ticker_get_next_timestamp(&next_event);
-    sleepDurationUs = next_event - sleepStartTickerUs;
-
-    if (sleepDurationUs < MIN_DEEP_SLEEP_US) {
-        /* The next wakeup is too soon. */
-        __enable_irq();
-        return;
-    }
-
-    // Disable the us_ticker. It won't be clocked in DeepSleep
-    us_ticker_deinit();
-
-    // Prepare to wakeup from the RTC
-    rtc_set_wakeup(sleepStartRtcUs + sleepDurationUs);
-
     // Prepare for LP1
     uint32_t reg0 = MXC_PWRSEQ->reg0;
     reg0 &= ~MXC_F_PWRSEQ_REG0_PWR_SVM3EN_SLP;  // disable VDD3 SVM during sleep mode
@@ -151,19 +116,8 @@
     // Woke up from LP1
 
     // The RTC timer does not update until the next tick
-    uint64_t tempUs = rtc_read_us();
-    do {
-        sleepEndRtcUs = rtc_read_us();
-    } while(sleepEndRtcUs == tempUs);
-
-    // Get the elapsed time from the RTC. Wakeup could have been from some other event.
-    elapsedUs = sleepEndRtcUs - sleepStartRtcUs;
-
-    // Update the us_ticker. It was not clocked during DeepSleep
-    us_ticker_init();
-    us_ticker_set(sleepStartTickerUs + elapsedUs);
-    us_ticker_get_next_timestamp(&next_event);
-    us_ticker_set_interrupt(next_event);
+    uint32_t temp = MXC_RTCTMR->timer;
+    while (MXC_RTCTMR->timer == temp);
 
     __enable_irq();
 }
--- a/targets/hal/TARGET_Maxim/TARGET_MAX32610/us_ticker.c	Wed May 06 14:15:12 2015 +0100
+++ b/targets/hal/TARGET_Maxim/TARGET_MAX32610/us_ticker.c	Thu May 07 09:00:08 2015 +0100
@@ -30,7 +30,7 @@
  * ownership rights.
  *******************************************************************************
  */
- 
+
 #include "mbed_error.h"
 #include "us_ticker_api.h"
 #include "PeripheralNames.h"
@@ -53,7 +53,7 @@
 
     // Overflow the ticker when the us ticker overflows
     current_cnt += inc;
-    if(current_cnt > MAX_TICK_VAL) {
+    if (current_cnt > MAX_TICK_VAL) {
         current_cnt -= (MAX_TICK_VAL + 1);
     }
 }
@@ -64,7 +64,7 @@
     // Determine if the event has already happened.
     // If the event is behind the current ticker, within a window,
     // then the event has already happened.
-    if(((current < tick_win) && ((event < current) || 
+    if (((current < tick_win) && ((event < current) || 
         (event > (MAX_TICK_VAL - (tick_win - current))))) || 
         ((event < current) && (event > (current - tick_win)))) {
         return 1;
@@ -169,7 +169,7 @@
 {
     uint64_t current_cnt1, current_cnt2;
     uint32_t term_cnt, tmr_cnt;
-    int intfl1, intfl2;
+    uint32_t intfl1, intfl2;
 
     if (!us_ticker_inited)
         us_ticker_init();
@@ -184,6 +184,7 @@
         current_cnt2 = current_cnt;
     } while ((current_cnt1 != current_cnt2) || (intfl1 != intfl2));
 
+    // Account for an unserviced interrupt
     if (intfl1) {
         current_cnt1 += term_cnt;
     }
@@ -197,6 +198,7 @@
 void us_ticker_set_interrupt(timestamp_t timestamp)
 {
     // Note: interrupts are disabled before this function is called.
+
     US_TIMER->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0;  // disable timer
 
     if (US_TIMER->intfl) {