mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

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