mbed library sources. Supersedes mbed-src. Edited target satm32f446 for user USART3 pins
Fork of mbed-dev by
Diff: targets/TARGET_Maxim/TARGET_MAX32620C/rtc_api.c
- Revision:
- 186:707f6e361f3e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/TARGET_Maxim/TARGET_MAX32620C/rtc_api.c Fri Jun 22 16:45:37 2018 +0100 @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (C) 2016,2018 Maxim Integrated Products, Inc., All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + ******************************************************************************* + */ + +#include <string.h> +#include "rtc_api.h" +#include "lp_ticker_api.h" +#include "rtc.h" +#include "lp.h" +#include <string.h> + +// LOG2 for 32-bit powers of 2 +#define LOG2_1(n) (((n) >= (1 << 1)) ? 1 : 0) +#define LOG2_2(n) (((n) >= (1 << 2)) ? ( 2 + (LOG2_1((n) >> 2))) : LOG2_1(n)) +#define LOG2_4(n) (((n) >= (1 << 4)) ? ( 4 + (LOG2_2((n) >> 4))) : LOG2_2(n)) +#define LOG2_8(n) (((n) >= (1 << 8)) ? ( 8 + (LOG2_4((n) >> 8))) : LOG2_4(n)) +#define LOG2(n) (((n) >= (1 << 16)) ? (16 + (LOG2_8((n) >> 16))) : LOG2_8(n)) + +#define LP_TIMER_FREQ_HZ 4096 +#define LP_TIMER_PRESCALE RTC_PRESCALE_DIV_2_0 +#define LP_TIMER_RATE_HZ (LP_TIMER_FREQ_HZ >> LP_TIMER_PRESCALE) +#define LP_TIMER_WIDTH 32 + +static volatile int rtc_inited = 0; +static volatile int lp_ticker_inited = 0; + +//****************************************************************************** +static void init_rtc(void) +{ + /* Enable power for RTC for all LPx states */ + MXC_PWRSEQ->reg0 |= (MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | + MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP); + + /* Enable clock to synchronizers */ + CLKMAN_SetClkScale(CLKMAN_CLK_SYNC, CLKMAN_SCALE_DIV_1); + + /* RTC registers are only reset on a power cycle. Do not reconfigure the RTC + * if it is already running. + */ + if (!RTC_IsActive()) { + rtc_cfg_t cfg; + memset(&cfg, 0, sizeof(rtc_cfg_t)); + cfg.prescaler = LP_TIMER_PRESCALE; + cfg.snoozeMode = RTC_SNOOZE_DISABLE; + + int retval = RTC_Init(&cfg); + MBED_ASSERT(retval == E_NO_ERROR); + + RTC_EnableINT(MXC_F_RTC_FLAGS_OVERFLOW); + RTC_Start(); + } +} + +//****************************************************************************** +static void overflow_handler(void) +{ + MXC_RTCTMR->comp[1] += ((UINT32_MAX >> LOG2(LP_TIMER_RATE_HZ)) + 1); + RTC_ClearFlags(MXC_F_RTC_FLAGS_OVERFLOW); +} + +//****************************************************************************** +void rtc_init(void) +{ + NVIC_SetVector(RTC3_IRQn, (uint32_t)overflow_handler); + NVIC_EnableIRQ(RTC3_IRQn); + + // Enable as LP wakeup source + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_FLAGS_RTC_ROLLOVER; + + init_rtc(); +} + +//****************************************************************************** +void rtc_free(void) +{ + while (MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +//****************************************************************************** +int rtc_isenabled(void) +{ + return !!RTC_IsActive(); +} + +//****************************************************************************** +void rtc_write(time_t t) +{ + MXC_RTCTMR->comp[1] = t - (MXC_RTCTMR->timer >> LOG2(LP_TIMER_RATE_HZ)); + while (MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +//****************************************************************************** +time_t rtc_read(void) +{ + return (MXC_RTCTMR->timer >> LOG2(LP_TIMER_RATE_HZ)) + MXC_RTCTMR->comp[1]; +} + +//****************************************************************************** +void lp_ticker_init(void) +{ + RTC_DisableINT(MXC_F_RTC_INTEN_COMP0); + NVIC_SetVector(RTC0_IRQn, (uint32_t)lp_ticker_irq_handler); + NVIC_EnableIRQ(RTC0_IRQn); + init_rtc(); +} + +//****************************************************************************** +void lp_ticker_free(void) +{ + // Disable interrupt associated with LPTICKER API + RTC_DisableINT(MXC_F_RTC_INTEN_COMP0); + + // RTC hardware is shared by LPTICKER and RTC APIs. + // Prior initialization of the RTC API gates disabling the RTC hardware. + if (!(MXC_RTCTMR->inten & MXC_F_RTC_INTEN_OVERFLOW)) { + RTC_Stop(); + } +} + +//****************************************************************************** +uint32_t lp_ticker_read(void) +{ + return MXC_RTCTMR->timer; +} + +//****************************************************************************** +void lp_ticker_set_interrupt(timestamp_t timestamp) +{ + MXC_RTCTMR->comp[0] = timestamp; + MXC_RTCTMR->flags = MXC_F_RTC_FLAGS_COMP0; + RTC_EnableINT(MXC_F_RTC_INTEN_COMP0); + + // Enable as LP wakeup source + MXC_PWRSEQ->msk_flags |= MXC_F_PWRSEQ_FLAGS_RTC_CMPR0; + + // Postponed write pending wait for comp0 and flags + while (MXC_RTCTMR->ctrl & MXC_F_RTC_CTRL_PENDING); +} + +//****************************************************************************** +void lp_ticker_disable_interrupt(void) +{ + RTC_DisableINT(MXC_F_RTC_INTEN_COMP0); +} + +//****************************************************************************** +void lp_ticker_clear_interrupt(void) +{ + RTC_ClearFlags(MXC_F_RTC_FLAGS_COMP0); +} + +//****************************************************************************** +void lp_ticker_fire_interrupt(void) +{ + NVIC_SetPendingIRQ(RTC0_IRQn); +} + +//****************************************************************************** +const ticker_info_t *lp_ticker_get_info(void) +{ + static const ticker_info_t info = { + LP_TIMER_RATE_HZ, + LP_TIMER_WIDTH + }; + + return &info; +}