mbed library sources. Supersedes mbed-src. Edited target satm32f446 for user USART3 pins
Fork of mbed-dev by
targets/TARGET_Silicon_Labs/TARGET_EFM32/rtcc.c@186:707f6e361f3e, 2018-06-22 (annotated)
- Committer:
- Anna Bridge
- Date:
- Fri Jun 22 16:45:37 2018 +0100
- Revision:
- 186:707f6e361f3e
mbed-dev library. Release version 162
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Anna Bridge |
186:707f6e361f3e | 1 | /***************************************************************************//** |
Anna Bridge |
186:707f6e361f3e | 2 | * @file rtc_rtcc.c |
Anna Bridge |
186:707f6e361f3e | 3 | ******************************************************************************* |
Anna Bridge |
186:707f6e361f3e | 4 | * @section License |
Anna Bridge |
186:707f6e361f3e | 5 | * <b>(C) Copyright 2018 Silicon Labs, http://www.silabs.com</b> |
Anna Bridge |
186:707f6e361f3e | 6 | ******************************************************************************* |
Anna Bridge |
186:707f6e361f3e | 7 | * |
Anna Bridge |
186:707f6e361f3e | 8 | * SPDX-License-Identifier: Apache-2.0 |
Anna Bridge |
186:707f6e361f3e | 9 | * |
Anna Bridge |
186:707f6e361f3e | 10 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
Anna Bridge |
186:707f6e361f3e | 11 | * not use this file except in compliance with the License. |
Anna Bridge |
186:707f6e361f3e | 12 | * You may obtain a copy of the License at |
Anna Bridge |
186:707f6e361f3e | 13 | * |
Anna Bridge |
186:707f6e361f3e | 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
Anna Bridge |
186:707f6e361f3e | 15 | * |
Anna Bridge |
186:707f6e361f3e | 16 | * Unless required by applicable law or agreed to in writing, software |
Anna Bridge |
186:707f6e361f3e | 17 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
Anna Bridge |
186:707f6e361f3e | 18 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
Anna Bridge |
186:707f6e361f3e | 19 | * See the License for the specific language governing permissions and |
Anna Bridge |
186:707f6e361f3e | 20 | * limitations under the License. |
Anna Bridge |
186:707f6e361f3e | 21 | * |
Anna Bridge |
186:707f6e361f3e | 22 | ******************************************************************************/ |
Anna Bridge |
186:707f6e361f3e | 23 | |
Anna Bridge |
186:707f6e361f3e | 24 | #include "device.h" |
Anna Bridge |
186:707f6e361f3e | 25 | #if DEVICE_RTC || DEVICE_LPTICKER |
Anna Bridge |
186:707f6e361f3e | 26 | |
Anna Bridge |
186:707f6e361f3e | 27 | /* Use RTCC on devices that have it */ |
Anna Bridge |
186:707f6e361f3e | 28 | #if defined(RTCC_PRESENT) |
Anna Bridge |
186:707f6e361f3e | 29 | |
Anna Bridge |
186:707f6e361f3e | 30 | #include "em_cmu.h" |
Anna Bridge |
186:707f6e361f3e | 31 | #include "em_rmu.h" |
Anna Bridge |
186:707f6e361f3e | 32 | #include "em_rtcc.h" |
Anna Bridge |
186:707f6e361f3e | 33 | #include "rtc_api.h" |
Anna Bridge |
186:707f6e361f3e | 34 | #include "lp_ticker_api.h" |
Anna Bridge |
186:707f6e361f3e | 35 | #include "clocking.h" |
Anna Bridge |
186:707f6e361f3e | 36 | |
Anna Bridge |
186:707f6e361f3e | 37 | static bool lptick_inited = false; |
Anna Bridge |
186:707f6e361f3e | 38 | static uint32_t lptick_offset = 0; |
Anna Bridge |
186:707f6e361f3e | 39 | |
Anna Bridge |
186:707f6e361f3e | 40 | void rtc_init(void) |
Anna Bridge |
186:707f6e361f3e | 41 | { |
Anna Bridge |
186:707f6e361f3e | 42 | if (BUS_RegBitRead((&RTCC->CTRL), _RTCC_CTRL_ENABLE_SHIFT) != 0) { |
Anna Bridge |
186:707f6e361f3e | 43 | /* RTCC already up & running */ |
Anna Bridge |
186:707f6e361f3e | 44 | return; |
Anna Bridge |
186:707f6e361f3e | 45 | } |
Anna Bridge |
186:707f6e361f3e | 46 | |
Anna Bridge |
186:707f6e361f3e | 47 | /* Make sure RTCC doesn't get reset (mbed specification) */ |
Anna Bridge |
186:707f6e361f3e | 48 | RMU_ResetControl(rmuResetWdog, rmuResetModeLimited); |
Anna Bridge |
186:707f6e361f3e | 49 | RMU_ResetControl(rmuResetCoreLockup, rmuResetModeLimited); |
Anna Bridge |
186:707f6e361f3e | 50 | RMU_ResetControl(rmuResetSys, rmuResetModeLimited); |
Anna Bridge |
186:707f6e361f3e | 51 | RMU_ResetControl(rmuResetPin, rmuResetModeFull); |
Anna Bridge |
186:707f6e361f3e | 52 | |
Anna Bridge |
186:707f6e361f3e | 53 | /* Set up the RTCC and let it run, Forrest, run */ |
Anna Bridge |
186:707f6e361f3e | 54 | RTCC_Reset(); |
Anna Bridge |
186:707f6e361f3e | 55 | RTCC_Init_TypeDef rtcc_init = RTCC_INIT_DEFAULT; |
Anna Bridge |
186:707f6e361f3e | 56 | rtcc_init.presc = rtccCntPresc_32768; |
Anna Bridge |
186:707f6e361f3e | 57 | RTCC_Init(&rtcc_init); |
Anna Bridge |
186:707f6e361f3e | 58 | RTCC_Enable(true); |
Anna Bridge |
186:707f6e361f3e | 59 | } |
Anna Bridge |
186:707f6e361f3e | 60 | |
Anna Bridge |
186:707f6e361f3e | 61 | void rtc_free(void) |
Anna Bridge |
186:707f6e361f3e | 62 | { |
Anna Bridge |
186:707f6e361f3e | 63 | /* Can't turn off any clock gates here since other parts of the |
Anna Bridge |
186:707f6e361f3e | 64 | * system might be using the CORELE clock. */ |
Anna Bridge |
186:707f6e361f3e | 65 | } |
Anna Bridge |
186:707f6e361f3e | 66 | |
Anna Bridge |
186:707f6e361f3e | 67 | int rtc_isenabled(void) |
Anna Bridge |
186:707f6e361f3e | 68 | { |
Anna Bridge |
186:707f6e361f3e | 69 | return BUS_RegBitRead((&RTCC->CTRL), _RTCC_CTRL_ENABLE_SHIFT); |
Anna Bridge |
186:707f6e361f3e | 70 | } |
Anna Bridge |
186:707f6e361f3e | 71 | |
Anna Bridge |
186:707f6e361f3e | 72 | time_t rtc_read(void) |
Anna Bridge |
186:707f6e361f3e | 73 | { |
Anna Bridge |
186:707f6e361f3e | 74 | return RTCC_CounterGet(); |
Anna Bridge |
186:707f6e361f3e | 75 | } |
Anna Bridge |
186:707f6e361f3e | 76 | |
Anna Bridge |
186:707f6e361f3e | 77 | void rtc_write(time_t t) |
Anna Bridge |
186:707f6e361f3e | 78 | { |
Anna Bridge |
186:707f6e361f3e | 79 | core_util_critical_section_enter(); |
Anna Bridge |
186:707f6e361f3e | 80 | uint32_t diff = t - RTCC_CounterGet(); |
Anna Bridge |
186:707f6e361f3e | 81 | lptick_offset += diff; |
Anna Bridge |
186:707f6e361f3e | 82 | |
Anna Bridge |
186:707f6e361f3e | 83 | if(RTCC_IntGetEnabled() & RTCC_IF_CC0) { |
Anna Bridge |
186:707f6e361f3e | 84 | RTCC->CC[0].CCV += diff << 15; |
Anna Bridge |
186:707f6e361f3e | 85 | } |
Anna Bridge |
186:707f6e361f3e | 86 | |
Anna Bridge |
186:707f6e361f3e | 87 | RTCC_CounterSet(t); |
Anna Bridge |
186:707f6e361f3e | 88 | core_util_critical_section_exit(); |
Anna Bridge |
186:707f6e361f3e | 89 | } |
Anna Bridge |
186:707f6e361f3e | 90 | |
Anna Bridge |
186:707f6e361f3e | 91 | /************************* LP_TICKER **************************/ |
Anna Bridge |
186:707f6e361f3e | 92 | const ticker_info_t* lp_ticker_get_info(void) |
Anna Bridge |
186:707f6e361f3e | 93 | { |
Anna Bridge |
186:707f6e361f3e | 94 | static const ticker_info_t rtc_info = { |
Anna Bridge |
186:707f6e361f3e | 95 | LOW_ENERGY_CLOCK_FREQUENCY, |
Anna Bridge |
186:707f6e361f3e | 96 | 32 |
Anna Bridge |
186:707f6e361f3e | 97 | }; |
Anna Bridge |
186:707f6e361f3e | 98 | return &rtc_info; |
Anna Bridge |
186:707f6e361f3e | 99 | } |
Anna Bridge |
186:707f6e361f3e | 100 | |
Anna Bridge |
186:707f6e361f3e | 101 | void RTCC_IRQHandler(void) |
Anna Bridge |
186:707f6e361f3e | 102 | { |
Anna Bridge |
186:707f6e361f3e | 103 | uint32_t flags; |
Anna Bridge |
186:707f6e361f3e | 104 | flags = RTCC_IntGet(); |
Anna Bridge |
186:707f6e361f3e | 105 | if (flags & RTCC_IF_CC0) { |
Anna Bridge |
186:707f6e361f3e | 106 | lp_ticker_irq_handler(); |
Anna Bridge |
186:707f6e361f3e | 107 | } |
Anna Bridge |
186:707f6e361f3e | 108 | } |
Anna Bridge |
186:707f6e361f3e | 109 | |
Anna Bridge |
186:707f6e361f3e | 110 | void lp_ticker_init() |
Anna Bridge |
186:707f6e361f3e | 111 | { |
Anna Bridge |
186:707f6e361f3e | 112 | if (!lptick_inited) { |
Anna Bridge |
186:707f6e361f3e | 113 | rtc_init(); |
Anna Bridge |
186:707f6e361f3e | 114 | core_util_critical_section_enter(); |
Anna Bridge |
186:707f6e361f3e | 115 | lptick_offset = RTCC_CounterGet(); |
Anna Bridge |
186:707f6e361f3e | 116 | core_util_critical_section_exit(); |
Anna Bridge |
186:707f6e361f3e | 117 | RTCC_CCChConf_TypeDef lp_chan_init = RTCC_CH_INIT_COMPARE_DEFAULT; |
Anna Bridge |
186:707f6e361f3e | 118 | lp_chan_init.compBase = rtccCompBasePreCnt; |
Anna Bridge |
186:707f6e361f3e | 119 | lp_chan_init.compMask = 0; |
Anna Bridge |
186:707f6e361f3e | 120 | RTCC_ChannelInit(0, &lp_chan_init); |
Anna Bridge |
186:707f6e361f3e | 121 | lptick_inited = true; |
Anna Bridge |
186:707f6e361f3e | 122 | |
Anna Bridge |
186:707f6e361f3e | 123 | /* Enable Interrupt from RTCC in NVIC, but don't start generating them */ |
Anna Bridge |
186:707f6e361f3e | 124 | RTCC_IntDisable(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 125 | RTCC_IntClear(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 126 | NVIC_EnableIRQ(RTCC_IRQn); |
Anna Bridge |
186:707f6e361f3e | 127 | } else { |
Anna Bridge |
186:707f6e361f3e | 128 | RTCC_IntDisable(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 129 | RTCC_IntClear(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 130 | } |
Anna Bridge |
186:707f6e361f3e | 131 | } |
Anna Bridge |
186:707f6e361f3e | 132 | |
Anna Bridge |
186:707f6e361f3e | 133 | void lp_ticker_free() |
Anna Bridge |
186:707f6e361f3e | 134 | { |
Anna Bridge |
186:707f6e361f3e | 135 | if (lptick_inited) { |
Anna Bridge |
186:707f6e361f3e | 136 | lp_ticker_disable_interrupt(); |
Anna Bridge |
186:707f6e361f3e | 137 | lp_ticker_clear_interrupt(); |
Anna Bridge |
186:707f6e361f3e | 138 | lptick_inited = false; |
Anna Bridge |
186:707f6e361f3e | 139 | } |
Anna Bridge |
186:707f6e361f3e | 140 | } |
Anna Bridge |
186:707f6e361f3e | 141 | |
Anna Bridge |
186:707f6e361f3e | 142 | void lp_ticker_set_interrupt(timestamp_t timestamp) |
Anna Bridge |
186:707f6e361f3e | 143 | { |
Anna Bridge |
186:707f6e361f3e | 144 | RTCC_ChannelCCVSet(0, timestamp + (lptick_offset << 15)); |
Anna Bridge |
186:707f6e361f3e | 145 | RTCC_IntEnable(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 146 | } |
Anna Bridge |
186:707f6e361f3e | 147 | |
Anna Bridge |
186:707f6e361f3e | 148 | void lp_ticker_fire_interrupt(void) |
Anna Bridge |
186:707f6e361f3e | 149 | { |
Anna Bridge |
186:707f6e361f3e | 150 | RTCC_IntEnable(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 151 | RTCC_IntSet(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 152 | } |
Anna Bridge |
186:707f6e361f3e | 153 | |
Anna Bridge |
186:707f6e361f3e | 154 | void lp_ticker_disable_interrupt() |
Anna Bridge |
186:707f6e361f3e | 155 | { |
Anna Bridge |
186:707f6e361f3e | 156 | RTCC_IntDisable(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 157 | } |
Anna Bridge |
186:707f6e361f3e | 158 | |
Anna Bridge |
186:707f6e361f3e | 159 | void lp_ticker_clear_interrupt() |
Anna Bridge |
186:707f6e361f3e | 160 | { |
Anna Bridge |
186:707f6e361f3e | 161 | RTCC_IntClear(RTCC_IF_CC0); |
Anna Bridge |
186:707f6e361f3e | 162 | } |
Anna Bridge |
186:707f6e361f3e | 163 | |
Anna Bridge |
186:707f6e361f3e | 164 | timestamp_t lp_ticker_read() |
Anna Bridge |
186:707f6e361f3e | 165 | { |
Anna Bridge |
186:707f6e361f3e | 166 | core_util_critical_section_enter(); |
Anna Bridge |
186:707f6e361f3e | 167 | uint32_t ticks = RTCC_CombinedCounterGet() - (lptick_offset << 15); |
Anna Bridge |
186:707f6e361f3e | 168 | core_util_critical_section_exit(); |
Anna Bridge |
186:707f6e361f3e | 169 | |
Anna Bridge |
186:707f6e361f3e | 170 | return (timestamp_t) (ticks); |
Anna Bridge |
186:707f6e361f3e | 171 | } |
Anna Bridge |
186:707f6e361f3e | 172 | #endif /* RTCC_PRESENT */ |
Anna Bridge |
186:707f6e361f3e | 173 | #endif /* DEVICE_RTC */ |