mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_Silicon_Labs/TARGET_EFM32/lp_ticker.c@187:0387e8f68319, 2018-09-06 (annotated)
- Committer:
- AnnaBridge
- Date:
- Thu Sep 06 13:40:20 2018 +0100
- Revision:
- 187:0387e8f68319
- Parent:
- 186:707f6e361f3e
mbed-dev library. Release version 163
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
<> | 144:ef7eb2e8f9f7 | 1 | /***************************************************************************//** |
<> | 144:ef7eb2e8f9f7 | 2 | * @file lp_ticker.c |
<> | 144:ef7eb2e8f9f7 | 3 | ******************************************************************************* |
<> | 144:ef7eb2e8f9f7 | 4 | * @section License |
<> | 144:ef7eb2e8f9f7 | 5 | * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b> |
<> | 144:ef7eb2e8f9f7 | 6 | ******************************************************************************* |
<> | 144:ef7eb2e8f9f7 | 7 | * |
<> | 144:ef7eb2e8f9f7 | 8 | * SPDX-License-Identifier: Apache-2.0 |
<> | 144:ef7eb2e8f9f7 | 9 | * |
<> | 144:ef7eb2e8f9f7 | 10 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
<> | 144:ef7eb2e8f9f7 | 11 | * not use this file except in compliance with the License. |
<> | 144:ef7eb2e8f9f7 | 12 | * You may obtain a copy of the License at |
<> | 144:ef7eb2e8f9f7 | 13 | * |
<> | 144:ef7eb2e8f9f7 | 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
<> | 144:ef7eb2e8f9f7 | 15 | * |
<> | 144:ef7eb2e8f9f7 | 16 | * Unless required by applicable law or agreed to in writing, software |
<> | 144:ef7eb2e8f9f7 | 17 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
<> | 144:ef7eb2e8f9f7 | 18 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
<> | 144:ef7eb2e8f9f7 | 19 | * See the License for the specific language governing permissions and |
<> | 144:ef7eb2e8f9f7 | 20 | * limitations under the License. |
<> | 144:ef7eb2e8f9f7 | 21 | * |
<> | 144:ef7eb2e8f9f7 | 22 | ******************************************************************************/ |
<> | 144:ef7eb2e8f9f7 | 23 | |
<> | 144:ef7eb2e8f9f7 | 24 | #include "device.h" |
<> | 150:02e0a0aed4ec | 25 | #include "clocking.h" |
Anna Bridge |
186:707f6e361f3e | 26 | #if DEVICE_LPTICKER |
<> | 144:ef7eb2e8f9f7 | 27 | |
AnnaBridge | 181:57724642e740 | 28 | /******************************************************************************* |
AnnaBridge | 181:57724642e740 | 29 | * The Silicon Labs lp_ticker implementation is mapped on top of an extended RTC |
AnnaBridge | 181:57724642e740 | 30 | * API, since the RTC is available in the lowest energy modes. By default, the |
AnnaBridge | 181:57724642e740 | 31 | * RTC counter is configured to run at 4kHz, giving us a quarter-ms resolution |
AnnaBridge | 181:57724642e740 | 32 | * for the low power timer, which should be good enough for a low power use |
AnnaBridge | 181:57724642e740 | 33 | * case. |
AnnaBridge | 181:57724642e740 | 34 | * |
Anna Bridge |
186:707f6e361f3e | 35 | * Mapping of mbed APIs to Silicon Labs peripherals: |
Anna Bridge |
186:707f6e361f3e | 36 | * ---: Does not meet mbed API requirements |
Anna Bridge |
186:707f6e361f3e | 37 | * X : Implemented to provide mbed API functionality |
Anna Bridge |
186:707f6e361f3e | 38 | * |
Anna Bridge |
186:707f6e361f3e | 39 | * -------------------------------------------- |
Anna Bridge |
186:707f6e361f3e | 40 | * | ------------- | RTCC | BURTC | RTC | TIMER | |
Anna Bridge |
186:707f6e361f3e | 41 | * | rtc_api | X | X | --- | ----- | |
Anna Bridge |
186:707f6e361f3e | 42 | * | lp_ticker_api | X | | X | ----- | |
Anna Bridge |
186:707f6e361f3e | 43 | * | us_ticker_api | --- | ----- | --- | X | |
Anna Bridge |
186:707f6e361f3e | 44 | * -------------------------------------------- |
Anna Bridge |
186:707f6e361f3e | 45 | * |
AnnaBridge | 181:57724642e740 | 46 | * On Silicon Labs devices, the lowest width RTC implementation has a 24-bit |
AnnaBridge | 181:57724642e740 | 47 | * counter, which gets extended with a further 32-bit software counter. This |
AnnaBridge | 181:57724642e740 | 48 | * gives 56 bits of actual width, which with the default speed maps to |
AnnaBridge | 181:57724642e740 | 49 | * 557462 years before the extended RTC counter wraps around. We are pretty |
AnnaBridge | 181:57724642e740 | 50 | * certain no device is going to have that amount of uptime. |
AnnaBridge | 181:57724642e740 | 51 | * (At max speed the wraparound is at 69730 years, which is unlikely as well) |
AnnaBridge | 181:57724642e740 | 52 | ******************************************************************************/ |
AnnaBridge | 181:57724642e740 | 53 | |
AnnaBridge | 187:0387e8f68319 | 54 | #if defined(RTC_PRESENT) && !defined(RTCC_PRESENT) |
Anna Bridge |
186:707f6e361f3e | 55 | #include "em_rtc.h" |
Anna Bridge |
186:707f6e361f3e | 56 | #include "em_cmu.h" |
<> | 144:ef7eb2e8f9f7 | 57 | #include "lp_ticker_api.h" |
<> | 160:d5399cc887bb | 58 | #include "mbed_critical.h" |
<> | 144:ef7eb2e8f9f7 | 59 | |
Anna Bridge |
186:707f6e361f3e | 60 | #if RTC_CLOCKDIV_INT > 16 |
Anna Bridge |
186:707f6e361f3e | 61 | #error invalid prescaler value RTC_CLOCKDIV_INT, since LP ticker resolution will exceed 1ms. |
Anna Bridge |
186:707f6e361f3e | 62 | #endif |
Anna Bridge |
186:707f6e361f3e | 63 | |
Anna Bridge |
186:707f6e361f3e | 64 | #define RTC_BITS (24U) |
Anna Bridge |
186:707f6e361f3e | 65 | #define RTC_MAX_VALUE (0xFFFFFFUL) |
Anna Bridge |
186:707f6e361f3e | 66 | |
Anna Bridge |
186:707f6e361f3e | 67 | static bool rtc_inited = false; |
Anna Bridge |
186:707f6e361f3e | 68 | |
Anna Bridge |
186:707f6e361f3e | 69 | const ticker_info_t* lp_ticker_get_info(void) |
Anna Bridge |
186:707f6e361f3e | 70 | { |
Anna Bridge |
186:707f6e361f3e | 71 | static const ticker_info_t rtc_info = { |
Anna Bridge |
186:707f6e361f3e | 72 | LOW_ENERGY_CLOCK_FREQUENCY, |
Anna Bridge |
186:707f6e361f3e | 73 | RTC_BITS |
Anna Bridge |
186:707f6e361f3e | 74 | }; |
Anna Bridge |
186:707f6e361f3e | 75 | return &rtc_info; |
Anna Bridge |
186:707f6e361f3e | 76 | } |
Anna Bridge |
186:707f6e361f3e | 77 | |
Anna Bridge |
186:707f6e361f3e | 78 | void RTC_IRQHandler(void) |
Anna Bridge |
186:707f6e361f3e | 79 | { |
Anna Bridge |
186:707f6e361f3e | 80 | uint32_t flags; |
Anna Bridge |
186:707f6e361f3e | 81 | flags = RTC_IntGet(); |
Anna Bridge |
186:707f6e361f3e | 82 | if ((flags & RTC_IF_COMP0) && rtc_inited) { |
Anna Bridge |
186:707f6e361f3e | 83 | RTC_IntClear(RTC_IF_COMP0); |
Anna Bridge |
186:707f6e361f3e | 84 | lp_ticker_irq_handler(); |
Anna Bridge |
186:707f6e361f3e | 85 | } |
Anna Bridge |
186:707f6e361f3e | 86 | } |
<> | 144:ef7eb2e8f9f7 | 87 | |
<> | 144:ef7eb2e8f9f7 | 88 | void lp_ticker_init() |
<> | 144:ef7eb2e8f9f7 | 89 | { |
Anna Bridge |
186:707f6e361f3e | 90 | core_util_critical_section_enter(); |
Anna Bridge |
186:707f6e361f3e | 91 | if (!rtc_inited) { |
Anna Bridge |
186:707f6e361f3e | 92 | CMU_ClockEnable(cmuClock_RTC, true); |
Anna Bridge |
186:707f6e361f3e | 93 | |
Anna Bridge |
186:707f6e361f3e | 94 | /* Initialize RTC */ |
Anna Bridge |
186:707f6e361f3e | 95 | RTC_Init_TypeDef init = RTC_INIT_DEFAULT; |
Anna Bridge |
186:707f6e361f3e | 96 | init.enable = 1; |
Anna Bridge |
186:707f6e361f3e | 97 | /* Don't use compare register 0 as top value */ |
Anna Bridge |
186:707f6e361f3e | 98 | init.comp0Top = 0; |
Anna Bridge |
186:707f6e361f3e | 99 | |
Anna Bridge |
186:707f6e361f3e | 100 | /* Initialize */ |
Anna Bridge |
186:707f6e361f3e | 101 | RTC_Init(&init); |
Anna Bridge |
186:707f6e361f3e | 102 | RTC_CounterSet(20); |
Anna Bridge |
186:707f6e361f3e | 103 | |
Anna Bridge |
186:707f6e361f3e | 104 | /* Enable Interrupt from RTC */ |
Anna Bridge |
186:707f6e361f3e | 105 | RTC_IntDisable(RTC_IF_COMP0); |
Anna Bridge |
186:707f6e361f3e | 106 | RTC_IntClear(RTC_IF_COMP0); |
Anna Bridge |
186:707f6e361f3e | 107 | NVIC_SetVector(RTC_IRQn, (uint32_t)RTC_IRQHandler); |
Anna Bridge |
186:707f6e361f3e | 108 | NVIC_EnableIRQ(RTC_IRQn); |
Anna Bridge |
186:707f6e361f3e | 109 | |
Anna Bridge |
186:707f6e361f3e | 110 | rtc_inited = true; |
Anna Bridge |
186:707f6e361f3e | 111 | } else { |
Anna Bridge |
186:707f6e361f3e | 112 | /* Cancel current interrupt by virtue of calling init again */ |
Anna Bridge |
186:707f6e361f3e | 113 | RTC_IntDisable(RTC_IF_COMP0); |
Anna Bridge |
186:707f6e361f3e | 114 | RTC_IntClear(RTC_IF_COMP0); |
<> | 144:ef7eb2e8f9f7 | 115 | } |
Anna Bridge |
186:707f6e361f3e | 116 | core_util_critical_section_exit(); |
<> | 144:ef7eb2e8f9f7 | 117 | } |
<> | 144:ef7eb2e8f9f7 | 118 | |
<> | 144:ef7eb2e8f9f7 | 119 | void lp_ticker_free() |
<> | 144:ef7eb2e8f9f7 | 120 | { |
Anna Bridge |
186:707f6e361f3e | 121 | /* Disable the RTC if it was inited and is no longer in use by anyone. */ |
Anna Bridge |
186:707f6e361f3e | 122 | if (rtc_inited) { |
Anna Bridge |
186:707f6e361f3e | 123 | NVIC_DisableIRQ(RTC_IRQn); |
Anna Bridge |
186:707f6e361f3e | 124 | RTC_Reset(); |
Anna Bridge |
186:707f6e361f3e | 125 | CMU_ClockEnable(cmuClock_RTC, false); |
Anna Bridge |
186:707f6e361f3e | 126 | rtc_inited = false; |
<> | 144:ef7eb2e8f9f7 | 127 | } |
Anna Bridge |
186:707f6e361f3e | 128 | RTC_FreezeEnable(false); |
<> | 144:ef7eb2e8f9f7 | 129 | } |
<> | 144:ef7eb2e8f9f7 | 130 | |
<> | 144:ef7eb2e8f9f7 | 131 | void lp_ticker_set_interrupt(timestamp_t timestamp) |
<> | 144:ef7eb2e8f9f7 | 132 | { |
Anna Bridge |
186:707f6e361f3e | 133 | RTC_IntDisable(RTC_IF_COMP0); |
Anna Bridge |
186:707f6e361f3e | 134 | RTC_IntClear(RTC_IF_COMP0); |
Anna Bridge |
186:707f6e361f3e | 135 | RTC_FreezeEnable(true); |
Anna Bridge |
186:707f6e361f3e | 136 | RTC_CompareSet(0, (uint32_t) (timestamp & RTC_MAX_VALUE)); |
Anna Bridge |
186:707f6e361f3e | 137 | RTC_FreezeEnable(false); |
Anna Bridge |
186:707f6e361f3e | 138 | RTC_IntEnable(RTC_IF_COMP0); |
<> | 144:ef7eb2e8f9f7 | 139 | } |
<> | 144:ef7eb2e8f9f7 | 140 | |
Anna Bridge |
186:707f6e361f3e | 141 | void lp_ticker_fire_interrupt(void) |
AnnaBridge | 174:b96e65c34a4d | 142 | { |
Anna Bridge |
186:707f6e361f3e | 143 | RTC_IntEnable(RTC_IF_COMP0); |
Anna Bridge |
186:707f6e361f3e | 144 | RTC_IntSet(RTC_IF_COMP0); |
AnnaBridge | 174:b96e65c34a4d | 145 | } |
AnnaBridge | 174:b96e65c34a4d | 146 | |
Anna Bridge |
186:707f6e361f3e | 147 | void lp_ticker_disable_interrupt() |
<> | 144:ef7eb2e8f9f7 | 148 | { |
Anna Bridge |
186:707f6e361f3e | 149 | RTC_IntDisable(RTC_IF_COMP0); |
<> | 144:ef7eb2e8f9f7 | 150 | } |
<> | 144:ef7eb2e8f9f7 | 151 | |
Anna Bridge |
186:707f6e361f3e | 152 | void lp_ticker_clear_interrupt() |
<> | 144:ef7eb2e8f9f7 | 153 | { |
Anna Bridge |
186:707f6e361f3e | 154 | RTC_IntClear(RTC_IF_COMP0); |
<> | 144:ef7eb2e8f9f7 | 155 | } |
<> | 144:ef7eb2e8f9f7 | 156 | |
<> | 144:ef7eb2e8f9f7 | 157 | timestamp_t lp_ticker_read() |
<> | 144:ef7eb2e8f9f7 | 158 | { |
Anna Bridge |
186:707f6e361f3e | 159 | return (timestamp_t) RTC_CounterGet(); |
<> | 144:ef7eb2e8f9f7 | 160 | } |
<> | 144:ef7eb2e8f9f7 | 161 | |
Anna Bridge |
186:707f6e361f3e | 162 | #elif defined(RTCC_PRESENT) |
Anna Bridge |
186:707f6e361f3e | 163 | /* lp_ticker api is implemented in rtc_rtcc.c */ |
Anna Bridge |
186:707f6e361f3e | 164 | #endif /* RTC_PRESENT */ |
Anna Bridge |
186:707f6e361f3e | 165 | #endif /* DEVICE_LPTICKER */ |