diff --git a/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.s b/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.s index ede95180f5..8e32b53a73 100644 --- a/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.s +++ b/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_ARM_MICRO/startup_efm32zg.s @@ -29,7 +29,7 @@ ; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ; -Stack_Size EQU 0x00000400 +Stack_Size EQU 0x00000200 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size diff --git a/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_GCC_ARM/startup_efm32zg.S b/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_GCC_ARM/startup_efm32zg.S index 2ae76f121c..466de1d800 100644 --- a/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_GCC_ARM/startup_efm32zg.S +++ b/libraries/mbed/targets/cmsis/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/TOOLCHAIN_GCC_ARM/startup_efm32zg.S @@ -37,7 +37,7 @@ #ifdef __STACK_SIZE .equ Stack_Size, __STACK_SIZE #else - .equ Stack_Size, 0x400 + .equ Stack_Size, 0x200 #endif .globl __StackTop .globl __StackLimit diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/device.h b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/device.h index 59ff712fe9..3b8d9841db 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/device.h +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/device.h @@ -64,6 +64,8 @@ #define DEVICE_ERROR_PATTERN 1 +#define DEVICE_LOWPOWERTIMER 1 + #define DEVICE_CAN 0 #define DEVICE_ETHERNET 0 diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/rtc_api.c b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/rtc_api.c index 033420d4ad..807a15e31e 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/rtc_api.c +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/rtc_api.c @@ -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); @@ -90,6 +85,12 @@ void rtc_init(void) MXC_RTCTMR->ctrl |= MXC_F_RTC_CTRL_ENABLE; } +//****************************************************************************** +void lp_ticker_init(void) +{ + rtc_init(); +} + //****************************************************************************** void rtc_free(void) { @@ -118,73 +119,104 @@ int rtc_isenabled(void) //****************************************************************************** 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; - - if (overflow_alarm == overflow_cnt) { - MXC_RTCTMR->comp[0] = (wakeupUs << shift_amt) / 1000000; - MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0; + 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; + } } + 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(); +} diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/sleep.c b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/sleep.c index 3eb9154f03..4d26c53573 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/sleep.c +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/sleep.c @@ -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 @@ static void clearAllGPIOWUD(void) // 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 @@ void deepsleep(void) // 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(); } diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/us_ticker.c b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/us_ticker.c index 17690d5da4..05381a43cf 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/us_ticker.c +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32600/us_ticker.c @@ -30,7 +30,7 @@ * ownership rights. ******************************************************************************* */ - + #include "mbed_error.h" #include "us_ticker_api.h" #include "PeripheralNames.h" @@ -53,7 +53,7 @@ static inline void inc_current_cnt(uint32_t inc) { // 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 @@ static inline int event_passed(uint64_t current, uint64_t event) { // 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 @@ uint32_t us_ticker_read(void) { 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 @@ uint32_t us_ticker_read(void) 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 @@ uint32_t us_ticker_read(void) 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) { diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/device.h b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/device.h index 59ff712fe9..3b8d9841db 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/device.h +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/device.h @@ -64,6 +64,8 @@ #define DEVICE_ERROR_PATTERN 1 +#define DEVICE_LOWPOWERTIMER 1 + #define DEVICE_CAN 0 #define DEVICE_ETHERNET 0 diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/rtc_api.c b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/rtc_api.c index 033420d4ad..807a15e31e 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/rtc_api.c +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/rtc_api.c @@ -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); @@ -90,6 +85,12 @@ void rtc_init(void) MXC_RTCTMR->ctrl |= MXC_F_RTC_CTRL_ENABLE; } +//****************************************************************************** +void lp_ticker_init(void) +{ + rtc_init(); +} + //****************************************************************************** void rtc_free(void) { @@ -118,73 +119,104 @@ int rtc_isenabled(void) //****************************************************************************** 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; - - if (overflow_alarm == overflow_cnt) { - MXC_RTCTMR->comp[0] = (wakeupUs << shift_amt) / 1000000; - MXC_RTCTMR->inten |= MXC_F_RTC_INTEN_COMP0; + 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; + } } + 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(); +} diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/sleep.c b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/sleep.c index 3eb9154f03..4d26c53573 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/sleep.c +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/sleep.c @@ -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 @@ static void clearAllGPIOWUD(void) // 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 @@ void deepsleep(void) // 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(); } diff --git a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/us_ticker.c b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/us_ticker.c index 17690d5da4..05381a43cf 100644 --- a/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/us_ticker.c +++ b/libraries/mbed/targets/hal/TARGET_Maxim/TARGET_MAX32610/us_ticker.c @@ -30,7 +30,7 @@ * ownership rights. ******************************************************************************* */ - + #include "mbed_error.h" #include "us_ticker_api.h" #include "PeripheralNames.h" @@ -53,7 +53,7 @@ static inline void inc_current_cnt(uint32_t inc) { // 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 @@ static inline int event_passed(uint64_t current, uint64_t event) { // 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 @@ uint32_t us_ticker_read(void) { 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 @@ uint32_t us_ticker_read(void) 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 @@ uint32_t us_ticker_read(void) 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) { diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F1/pinmap.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F1/pinmap.c index d311a0c3c8..a5bcd84130 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F1/pinmap.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F1/pinmap.c @@ -177,12 +177,21 @@ void pin_mode(PinName pin, PinMode mode) if (pin_index < 8) { if ((gpio->CRL & (0x03 << (pin_index * 4))) == 0) { // MODE bits = Input mode gpio->CRL |= (0x08 << (pin_index * 4)); // Set pull-up / pull-down + gpio->CRL &= ~(0x08 << ((pin_index * 4)-1)); // ENSURES GPIOx_CRL.CNFx.bit0 = 0 } } else { if ((gpio->CRH & (0x03 << ((pin_index % 8) * 4))) == 0) { // MODE bits = Input mode gpio->CRH |= (0x08 << ((pin_index % 8) * 4)); // Set pull-up / pull-down + gpio->CRH &= ~(0x08 << (((pin_index % 8) * 4)-1)); // ENSURES GPIOx_CRH.CNFx.bit0 = 0 } } + // Now it's time to setup properly if pullup or pulldown. This is done in ODR register: + // set pull-up => bit=1, set pull-down => bit = 0 + if (mode == PullUp) { + gpio->ODR |= (0x01 << (pin_index)); // Set pull-up + } else{ + gpio->ODR &= ~(0x01 << (pin_index)); // Set pull-down + } break; case OpenDrain: // Set open-drain for Output mode (General Purpose or Alternate Function) diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/device.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/device.h index 0ef7e6deb3..d1873076f9 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/device.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32HG_STK3400/device.h @@ -50,6 +50,11 @@ #define DEVICE_LOWPOWERTIMER 1 +// Redefine OPEN_MAX from sys_limits.h to save on RAM. +// Effect: maximum amount of file handlers = OPEN_MAX +// This is not going to have an impact, since this is a RAM-limited part anyway. +#define OPEN_MAX 24 + #include "objects.h" #include "Modules.h" #include "device_peripherals.h" diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/device.h b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/device.h index 0ef7e6deb3..d7b54e2aaf 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/device.h +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/TARGET_EFM32ZG_STK3200/device.h @@ -50,6 +50,11 @@ #define DEVICE_LOWPOWERTIMER 1 +// Redefine OPEN_MAX from sys_limits.h to save on RAM. +// Effect: maximum amount of file handlers = OPEN_MAX +// This is not going to have an impact, since this is a RAM-limited part anyway. +#define OPEN_MAX 8 + #include "objects.h" #include "Modules.h" #include "device_peripherals.h" diff --git a/workspace_tools/export/gcc_arm_efm32gg_stk3700.tmpl b/workspace_tools/export/gcc_arm_efm32gg_stk3700.tmpl index d248ebfc81..5a3920aabe 100644 --- a/workspace_tools/export/gcc_arm_efm32gg_stk3700.tmpl +++ b/workspace_tools/export/gcc_arm_efm32gg_stk3700.tmpl @@ -23,7 +23,7 @@ OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump SIZE = $(GCC_BIN)arm-none-eabi-size CPU = -mcpu=cortex-m3 -mthumb -CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections +CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -fno-common -fomit-frame-pointer CC_FLAGS += -MMD -MP ifeq ($(DEBUG), 1) @@ -53,7 +53,7 @@ clean: $(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $< .cpp.o: - $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< + $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -fno-rtti -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< $(OBJ_FOLDER)$(PROJECT).axf: $(OBJECTS) $(SYS_OBJECTS) diff --git a/workspace_tools/export/gcc_arm_efm32hg_stk3400.tmpl b/workspace_tools/export/gcc_arm_efm32hg_stk3400.tmpl index 65d85dfd8a..b45dc6469e 100644 --- a/workspace_tools/export/gcc_arm_efm32hg_stk3400.tmpl +++ b/workspace_tools/export/gcc_arm_efm32hg_stk3400.tmpl @@ -23,7 +23,7 @@ OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump SIZE = $(GCC_BIN)arm-none-eabi-size CPU = -mcpu=cortex-m0plus -mthumb -CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections +CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -fno-common -fomit-frame-pointer CC_FLAGS += -MMD -MP ifeq ($(DEBUG), 1) @@ -53,7 +53,7 @@ clean: $(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $< .cpp.o: - $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< + $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -fno-rtti -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< $(OBJ_FOLDER)$(PROJECT).axf: $(OBJECTS) $(SYS_OBJECTS) diff --git a/workspace_tools/export/gcc_arm_efm32lg_stk3600.tmpl b/workspace_tools/export/gcc_arm_efm32lg_stk3600.tmpl index d248ebfc81..5a3920aabe 100644 --- a/workspace_tools/export/gcc_arm_efm32lg_stk3600.tmpl +++ b/workspace_tools/export/gcc_arm_efm32lg_stk3600.tmpl @@ -23,7 +23,7 @@ OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump SIZE = $(GCC_BIN)arm-none-eabi-size CPU = -mcpu=cortex-m3 -mthumb -CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections +CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -fno-common -fomit-frame-pointer CC_FLAGS += -MMD -MP ifeq ($(DEBUG), 1) @@ -53,7 +53,7 @@ clean: $(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $< .cpp.o: - $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< + $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -fno-rtti -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< $(OBJ_FOLDER)$(PROJECT).axf: $(OBJECTS) $(SYS_OBJECTS) diff --git a/workspace_tools/export/gcc_arm_efm32wg_stk3800.tmpl b/workspace_tools/export/gcc_arm_efm32wg_stk3800.tmpl index d248ebfc81..5a3920aabe 100644 --- a/workspace_tools/export/gcc_arm_efm32wg_stk3800.tmpl +++ b/workspace_tools/export/gcc_arm_efm32wg_stk3800.tmpl @@ -23,7 +23,7 @@ OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump SIZE = $(GCC_BIN)arm-none-eabi-size CPU = -mcpu=cortex-m3 -mthumb -CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections +CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -fno-common -fomit-frame-pointer CC_FLAGS += -MMD -MP ifeq ($(DEBUG), 1) @@ -53,7 +53,7 @@ clean: $(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $< .cpp.o: - $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< + $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -fno-rtti -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< $(OBJ_FOLDER)$(PROJECT).axf: $(OBJECTS) $(SYS_OBJECTS) diff --git a/workspace_tools/export/gcc_arm_efm32zg_stk3200.tmpl b/workspace_tools/export/gcc_arm_efm32zg_stk3200.tmpl index 65d85dfd8a..b45dc6469e 100644 --- a/workspace_tools/export/gcc_arm_efm32zg_stk3200.tmpl +++ b/workspace_tools/export/gcc_arm_efm32zg_stk3200.tmpl @@ -23,7 +23,7 @@ OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump SIZE = $(GCC_BIN)arm-none-eabi-size CPU = -mcpu=cortex-m0plus -mthumb -CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections +CC_FLAGS = $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections -fno-common -fomit-frame-pointer CC_FLAGS += -MMD -MP ifeq ($(DEBUG), 1) @@ -53,7 +53,7 @@ clean: $(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $< .cpp.o: - $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< + $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -fno-rtti -std=gnu++98 $(INCLUDE_PATHS) -o $@ $< $(OBJ_FOLDER)$(PROJECT).axf: $(OBJECTS) $(SYS_OBJECTS) diff --git a/workspace_tools/export/simplicityv3_slsproj.tmpl b/workspace_tools/export/simplicityv3_slsproj.tmpl index 00535b5fa3..ac4d35519f 100644 --- a/workspace_tools/export/simplicityv3_slsproj.tmpl +++ b/workspace_tools/export/simplicityv3_slsproj.tmpl @@ -62,8 +62,10 @@ {# For debug build, don't apply optimizations #} + + - + @@ -105,8 +107,10 @@ {# Use optimize for size on release build #} + + - +