mbed library sources. Supersedes mbed-src. Edited target satm32f446 for user USART3 pins
Fork of mbed-dev by
Diff: targets/TARGET_Silicon_Labs/TARGET_EFM32/rtcc.c
- Revision:
- 186:707f6e361f3e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/TARGET_Silicon_Labs/TARGET_EFM32/rtcc.c Fri Jun 22 16:45:37 2018 +0100 @@ -0,0 +1,173 @@ +/***************************************************************************//** + * @file rtc_rtcc.c + ******************************************************************************* + * @section License + * <b>(C) Copyright 2018 Silicon Labs, http://www.silabs.com</b> + ******************************************************************************* + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "device.h" +#if DEVICE_RTC || DEVICE_LPTICKER + +/* Use RTCC on devices that have it */ +#if defined(RTCC_PRESENT) + +#include "em_cmu.h" +#include "em_rmu.h" +#include "em_rtcc.h" +#include "rtc_api.h" +#include "lp_ticker_api.h" +#include "clocking.h" + +static bool lptick_inited = false; +static uint32_t lptick_offset = 0; + +void rtc_init(void) +{ + if (BUS_RegBitRead((&RTCC->CTRL), _RTCC_CTRL_ENABLE_SHIFT) != 0) { + /* RTCC already up & running */ + return; + } + + /* Make sure RTCC doesn't get reset (mbed specification) */ + RMU_ResetControl(rmuResetWdog, rmuResetModeLimited); + RMU_ResetControl(rmuResetCoreLockup, rmuResetModeLimited); + RMU_ResetControl(rmuResetSys, rmuResetModeLimited); + RMU_ResetControl(rmuResetPin, rmuResetModeFull); + + /* Set up the RTCC and let it run, Forrest, run */ + RTCC_Reset(); + RTCC_Init_TypeDef rtcc_init = RTCC_INIT_DEFAULT; + rtcc_init.presc = rtccCntPresc_32768; + RTCC_Init(&rtcc_init); + RTCC_Enable(true); +} + +void rtc_free(void) +{ + /* Can't turn off any clock gates here since other parts of the + * system might be using the CORELE clock. */ +} + +int rtc_isenabled(void) +{ + return BUS_RegBitRead((&RTCC->CTRL), _RTCC_CTRL_ENABLE_SHIFT); +} + +time_t rtc_read(void) +{ + return RTCC_CounterGet(); +} + +void rtc_write(time_t t) +{ + core_util_critical_section_enter(); + uint32_t diff = t - RTCC_CounterGet(); + lptick_offset += diff; + + if(RTCC_IntGetEnabled() & RTCC_IF_CC0) { + RTCC->CC[0].CCV += diff << 15; + } + + RTCC_CounterSet(t); + core_util_critical_section_exit(); +} + +/************************* LP_TICKER **************************/ +const ticker_info_t* lp_ticker_get_info(void) +{ + static const ticker_info_t rtc_info = { + LOW_ENERGY_CLOCK_FREQUENCY, + 32 + }; + return &rtc_info; +} + +void RTCC_IRQHandler(void) +{ + uint32_t flags; + flags = RTCC_IntGet(); + if (flags & RTCC_IF_CC0) { + lp_ticker_irq_handler(); + } +} + +void lp_ticker_init() +{ + if (!lptick_inited) { + rtc_init(); + core_util_critical_section_enter(); + lptick_offset = RTCC_CounterGet(); + core_util_critical_section_exit(); + RTCC_CCChConf_TypeDef lp_chan_init = RTCC_CH_INIT_COMPARE_DEFAULT; + lp_chan_init.compBase = rtccCompBasePreCnt; + lp_chan_init.compMask = 0; + RTCC_ChannelInit(0, &lp_chan_init); + lptick_inited = true; + + /* Enable Interrupt from RTCC in NVIC, but don't start generating them */ + RTCC_IntDisable(RTCC_IF_CC0); + RTCC_IntClear(RTCC_IF_CC0); + NVIC_EnableIRQ(RTCC_IRQn); + } else { + RTCC_IntDisable(RTCC_IF_CC0); + RTCC_IntClear(RTCC_IF_CC0); + } +} + +void lp_ticker_free() +{ + if (lptick_inited) { + lp_ticker_disable_interrupt(); + lp_ticker_clear_interrupt(); + lptick_inited = false; + } +} + +void lp_ticker_set_interrupt(timestamp_t timestamp) +{ + RTCC_ChannelCCVSet(0, timestamp + (lptick_offset << 15)); + RTCC_IntEnable(RTCC_IF_CC0); +} + +void lp_ticker_fire_interrupt(void) +{ + RTCC_IntEnable(RTCC_IF_CC0); + RTCC_IntSet(RTCC_IF_CC0); +} + +void lp_ticker_disable_interrupt() +{ + RTCC_IntDisable(RTCC_IF_CC0); +} + +void lp_ticker_clear_interrupt() +{ + RTCC_IntClear(RTCC_IF_CC0); +} + +timestamp_t lp_ticker_read() +{ + core_util_critical_section_enter(); + uint32_t ticks = RTCC_CombinedCounterGet() - (lptick_offset << 15); + core_util_critical_section_exit(); + + return (timestamp_t) (ticks); +} +#endif /* RTCC_PRESENT */ +#endif /* DEVICE_RTC */ \ No newline at end of file