mbed library sources. Supersedes mbed-src.

Dependents:   Hobbyking_Cheetah_Compact Hobbyking_Cheetah_Compact_DRV8323_14bit Hobbyking_Cheetah_Compact_DRV8323_V51_201907 HKC_MiniCheetah ... more

Fork of mbed-dev by mbed official

Committer:
benkatz
Date:
Mon Jul 30 20:31:44 2018 +0000
Revision:
181:36facd806e4a
Parent:
149:156823d33999
going on the robot.  fixed a dumb bug in float_to_uint

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file rtc_api.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"
<> 144:ef7eb2e8f9f7 25 #if DEVICE_RTC
<> 144:ef7eb2e8f9f7 26
<> 144:ef7eb2e8f9f7 27 #include "rtc_api.h"
<> 144:ef7eb2e8f9f7 28 #include "rtc_api_HAL.h"
<> 144:ef7eb2e8f9f7 29 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 30 #include "sleep_api.h"
<> 144:ef7eb2e8f9f7 31 #include "sleepmodes.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #if (defined RTC_COUNT) && (RTC_COUNT > 0)
<> 144:ef7eb2e8f9f7 34 #include "em_rtc.h"
<> 144:ef7eb2e8f9f7 35 #endif
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 #if (defined RTCC_COUNT) && (RTCC_COUNT > 0)
<> 144:ef7eb2e8f9f7 38 #include "em_rtcc.h"
<> 144:ef7eb2e8f9f7 39 #endif
<> 144:ef7eb2e8f9f7 40
<> 144:ef7eb2e8f9f7 41 static bool rtc_inited = false;
<> 144:ef7eb2e8f9f7 42 static time_t time_base = 0;
<> 144:ef7eb2e8f9f7 43 static uint32_t useflags = 0;
<> 144:ef7eb2e8f9f7 44 static uint32_t time_extend = 0;
<> 144:ef7eb2e8f9f7 45
<> 144:ef7eb2e8f9f7 46 static void (*comp0_handler)(void) = NULL;
<> 144:ef7eb2e8f9f7 47
<> 144:ef7eb2e8f9f7 48 #ifndef RTCC_COUNT
<> 144:ef7eb2e8f9f7 49
<> 144:ef7eb2e8f9f7 50 /* Using RTC API */
<> 144:ef7eb2e8f9f7 51
<> 144:ef7eb2e8f9f7 52 #define RTC_LEAST_ACTIVE_SLEEPMODE EM2
<> 144:ef7eb2e8f9f7 53 #define RTC_NUM_BITS (24)
<> 144:ef7eb2e8f9f7 54
<> 144:ef7eb2e8f9f7 55 void RTC_IRQHandler(void)
<> 144:ef7eb2e8f9f7 56 {
<> 144:ef7eb2e8f9f7 57 uint32_t flags;
<> 144:ef7eb2e8f9f7 58 flags = RTC_IntGet();
<> 144:ef7eb2e8f9f7 59 if (flags & RTC_IF_OF) {
<> 144:ef7eb2e8f9f7 60 RTC_IntClear(RTC_IF_OF);
<> 144:ef7eb2e8f9f7 61 /* RTC has overflowed (24 bits). Use time_extend as software counter for 32 more bits. */
<> 144:ef7eb2e8f9f7 62 time_extend += 1;
<> 144:ef7eb2e8f9f7 63 }
<> 144:ef7eb2e8f9f7 64 if (flags & RTC_IF_COMP0) {
<> 144:ef7eb2e8f9f7 65 RTC_IntClear(RTC_IF_COMP0);
<> 144:ef7eb2e8f9f7 66 if (comp0_handler != NULL) {
<> 144:ef7eb2e8f9f7 67 comp0_handler();
<> 144:ef7eb2e8f9f7 68 }
<> 144:ef7eb2e8f9f7 69 }
<> 144:ef7eb2e8f9f7 70 }
<> 144:ef7eb2e8f9f7 71
<> 144:ef7eb2e8f9f7 72 uint32_t rtc_get_32bit(void)
<> 144:ef7eb2e8f9f7 73 {
<> 144:ef7eb2e8f9f7 74 uint32_t pending = (RTC_IntGet() & RTC_IF_OF) ? 1 : 0;
<> 144:ef7eb2e8f9f7 75 return (RTC_CounterGet() + ((time_extend + pending) << RTC_NUM_BITS));
<> 144:ef7eb2e8f9f7 76 }
<> 144:ef7eb2e8f9f7 77
<> 144:ef7eb2e8f9f7 78 uint64_t rtc_get_full(void)
<> 144:ef7eb2e8f9f7 79 {
<> 144:ef7eb2e8f9f7 80 uint64_t ticks = 0;
<> 144:ef7eb2e8f9f7 81 ticks += time_extend;
<> 144:ef7eb2e8f9f7 82 ticks = ticks << RTC_NUM_BITS;
<> 144:ef7eb2e8f9f7 83 ticks += RTC_CounterGet();
<> 144:ef7eb2e8f9f7 84 return ticks;
<> 144:ef7eb2e8f9f7 85 }
<> 144:ef7eb2e8f9f7 86
<> 144:ef7eb2e8f9f7 87 void rtc_init_real(uint32_t flags)
<> 144:ef7eb2e8f9f7 88 {
<> 144:ef7eb2e8f9f7 89 useflags |= flags;
<> 144:ef7eb2e8f9f7 90
<> 144:ef7eb2e8f9f7 91 if (!rtc_inited) {
<> 144:ef7eb2e8f9f7 92 CMU_ClockEnable(cmuClock_RTC, true);
<> 144:ef7eb2e8f9f7 93
<> 144:ef7eb2e8f9f7 94 /* Enable clock to the interface of the low energy modules */
<> 144:ef7eb2e8f9f7 95 CMU_ClockEnable(cmuClock_CORELE, true);
<> 144:ef7eb2e8f9f7 96
<> 144:ef7eb2e8f9f7 97 /* Scale clock to save power */
<> 144:ef7eb2e8f9f7 98 CMU_ClockDivSet(cmuClock_RTC, RTC_CLOCKDIV);
<> 144:ef7eb2e8f9f7 99
<> 144:ef7eb2e8f9f7 100 /* Initialize RTC */
<> 144:ef7eb2e8f9f7 101 RTC_Init_TypeDef init = RTC_INIT_DEFAULT;
<> 144:ef7eb2e8f9f7 102 init.enable = 1;
<> 144:ef7eb2e8f9f7 103 /* Don't use compare register 0 as top value */
<> 144:ef7eb2e8f9f7 104 init.comp0Top = 0;
<> 144:ef7eb2e8f9f7 105
<> 144:ef7eb2e8f9f7 106 /* Enable Interrupt from RTC */
<> 144:ef7eb2e8f9f7 107 RTC_IntEnable(RTC_IEN_OF);
<> 144:ef7eb2e8f9f7 108 NVIC_SetVector(RTC_IRQn, (uint32_t)RTC_IRQHandler);
<> 144:ef7eb2e8f9f7 109 NVIC_EnableIRQ(RTC_IRQn);
<> 144:ef7eb2e8f9f7 110
<> 144:ef7eb2e8f9f7 111 /* Initialize */
<> 144:ef7eb2e8f9f7 112 RTC_Init(&init);
<> 144:ef7eb2e8f9f7 113
<> 144:ef7eb2e8f9f7 114 blockSleepMode(RTC_LEAST_ACTIVE_SLEEPMODE);
<> 144:ef7eb2e8f9f7 115 rtc_inited = true;
<> 144:ef7eb2e8f9f7 116 }
<> 144:ef7eb2e8f9f7 117 }
<> 144:ef7eb2e8f9f7 118
<> 144:ef7eb2e8f9f7 119 void rtc_free(void)
<> 144:ef7eb2e8f9f7 120 {
<> 144:ef7eb2e8f9f7 121 rtc_free_real(RTC_INIT_RTC);
<> 144:ef7eb2e8f9f7 122 }
<> 144:ef7eb2e8f9f7 123
<> 144:ef7eb2e8f9f7 124 void rtc_free_real(uint32_t flags)
<> 144:ef7eb2e8f9f7 125 {
<> 144:ef7eb2e8f9f7 126 /* Clear use flag */
<> 144:ef7eb2e8f9f7 127 useflags &= ~flags;
<> 144:ef7eb2e8f9f7 128
<> 144:ef7eb2e8f9f7 129 /* Disable the RTC if it was inited and is no longer in use by anyone. */
<> 144:ef7eb2e8f9f7 130 if (rtc_inited && (useflags == 0)) {
<> 144:ef7eb2e8f9f7 131 NVIC_DisableIRQ(RTC_IRQn);
<> 144:ef7eb2e8f9f7 132 RTC_Reset();
<> 144:ef7eb2e8f9f7 133 CMU_ClockEnable(cmuClock_RTC, false);
<> 144:ef7eb2e8f9f7 134 unblockSleepMode(RTC_LEAST_ACTIVE_SLEEPMODE);
<> 144:ef7eb2e8f9f7 135 rtc_inited = false;
<> 144:ef7eb2e8f9f7 136 }
<> 144:ef7eb2e8f9f7 137 }
<> 144:ef7eb2e8f9f7 138
<> 144:ef7eb2e8f9f7 139 #else
<> 144:ef7eb2e8f9f7 140
<> 144:ef7eb2e8f9f7 141 /* Using RTCC API */
<> 144:ef7eb2e8f9f7 142
<> 144:ef7eb2e8f9f7 143 #define RTCC_LEAST_ACTIVE_SLEEPMODE EM2
<> 144:ef7eb2e8f9f7 144 #define RTCC_NUM_BITS (32)
<> 144:ef7eb2e8f9f7 145
<> 144:ef7eb2e8f9f7 146 void RTCC_IRQHandler(void)
<> 144:ef7eb2e8f9f7 147 {
<> 144:ef7eb2e8f9f7 148 uint32_t flags;
<> 144:ef7eb2e8f9f7 149 flags = RTCC_IntGet();
<> 144:ef7eb2e8f9f7 150
<> 144:ef7eb2e8f9f7 151 if (flags & RTCC_IF_OF) {
<> 144:ef7eb2e8f9f7 152 RTCC_IntClear(RTCC_IF_OF);
<> 144:ef7eb2e8f9f7 153 /* RTC has overflowed (32 bits). Use time_extend as software counter for 32 more bits. */
<> 144:ef7eb2e8f9f7 154 time_extend += 1;
<> 144:ef7eb2e8f9f7 155 }
<> 144:ef7eb2e8f9f7 156
<> 144:ef7eb2e8f9f7 157 if (flags & RTCC_IF_CC0) {
<> 144:ef7eb2e8f9f7 158 RTCC_IntClear(RTCC_IF_CC0);
<> 144:ef7eb2e8f9f7 159 if (comp0_handler != NULL) {
<> 144:ef7eb2e8f9f7 160 comp0_handler();
<> 144:ef7eb2e8f9f7 161 }
<> 144:ef7eb2e8f9f7 162 }
<> 144:ef7eb2e8f9f7 163 }
<> 144:ef7eb2e8f9f7 164
<> 144:ef7eb2e8f9f7 165 uint32_t rtc_get_32bit(void)
<> 144:ef7eb2e8f9f7 166 {
<> 144:ef7eb2e8f9f7 167 return RTCC_CounterGet();
<> 144:ef7eb2e8f9f7 168 }
<> 144:ef7eb2e8f9f7 169
<> 144:ef7eb2e8f9f7 170 uint64_t rtc_get_full(void)
<> 144:ef7eb2e8f9f7 171 {
<> 144:ef7eb2e8f9f7 172 uint64_t ticks = 0;
<> 144:ef7eb2e8f9f7 173 ticks += time_extend;
<> 144:ef7eb2e8f9f7 174 ticks = ticks << RTCC_NUM_BITS;
<> 144:ef7eb2e8f9f7 175 ticks += RTCC_CounterGet();
<> 144:ef7eb2e8f9f7 176 return ticks;
<> 144:ef7eb2e8f9f7 177 }
<> 144:ef7eb2e8f9f7 178
<> 144:ef7eb2e8f9f7 179 void rtc_init_real(uint32_t flags)
<> 144:ef7eb2e8f9f7 180 {
<> 144:ef7eb2e8f9f7 181 useflags |= flags;
<> 144:ef7eb2e8f9f7 182
<> 144:ef7eb2e8f9f7 183 if (!rtc_inited) {
<> 144:ef7eb2e8f9f7 184 CMU_ClockEnable(cmuClock_RTCC, true);
<> 144:ef7eb2e8f9f7 185
<> 144:ef7eb2e8f9f7 186 /* Enable clock to the interface of the low energy modules */
<> 144:ef7eb2e8f9f7 187 CMU_ClockEnable(cmuClock_CORELE, true);
<> 144:ef7eb2e8f9f7 188
<> 144:ef7eb2e8f9f7 189 /* Initialize RTC */
<> 144:ef7eb2e8f9f7 190 RTCC_Init_TypeDef init = RTCC_INIT_DEFAULT;
<> 144:ef7eb2e8f9f7 191 init.enable = 1;
<> 144:ef7eb2e8f9f7 192 init.precntWrapOnCCV0 = false;
<> 144:ef7eb2e8f9f7 193 init.cntWrapOnCCV1 = false;
<> 144:ef7eb2e8f9f7 194 #if RTC_CLOCKDIV_INT == 8
<> 144:ef7eb2e8f9f7 195 init.presc = rtccCntPresc_8;
<> 144:ef7eb2e8f9f7 196 #else
<> 144:ef7eb2e8f9f7 197 #error invalid prescaler value RTC_CLOCKDIV_INT
<> 144:ef7eb2e8f9f7 198 #endif
<> 144:ef7eb2e8f9f7 199
<> 144:ef7eb2e8f9f7 200 /* Enable Interrupt from RTC */
<> 144:ef7eb2e8f9f7 201 RTCC_IntEnable(RTCC_IEN_OF);
<> 144:ef7eb2e8f9f7 202 NVIC_SetVector(RTCC_IRQn, (uint32_t)RTCC_IRQHandler);
<> 144:ef7eb2e8f9f7 203 NVIC_EnableIRQ(RTCC_IRQn);
<> 144:ef7eb2e8f9f7 204
<> 144:ef7eb2e8f9f7 205 /* Initialize */
<> 144:ef7eb2e8f9f7 206 RTCC_Init(&init);
<> 144:ef7eb2e8f9f7 207
<> 144:ef7eb2e8f9f7 208 blockSleepMode(RTCC_LEAST_ACTIVE_SLEEPMODE);
<> 144:ef7eb2e8f9f7 209 rtc_inited = true;
<> 144:ef7eb2e8f9f7 210 }
<> 144:ef7eb2e8f9f7 211 }
<> 144:ef7eb2e8f9f7 212
<> 144:ef7eb2e8f9f7 213 void rtc_free(void)
<> 144:ef7eb2e8f9f7 214 {
<> 144:ef7eb2e8f9f7 215 rtc_free_real(RTC_INIT_RTC);
<> 144:ef7eb2e8f9f7 216 }
<> 144:ef7eb2e8f9f7 217
<> 144:ef7eb2e8f9f7 218 void rtc_free_real(uint32_t flags)
<> 144:ef7eb2e8f9f7 219 {
<> 144:ef7eb2e8f9f7 220 /* Clear use flag */
<> 144:ef7eb2e8f9f7 221 useflags &= ~flags;
<> 144:ef7eb2e8f9f7 222
<> 144:ef7eb2e8f9f7 223 /* Disable the RTC if it was inited and is no longer in use by anyone. */
<> 144:ef7eb2e8f9f7 224 if (rtc_inited && (useflags == 0)) {
<> 144:ef7eb2e8f9f7 225 NVIC_DisableIRQ(RTCC_IRQn);
<> 144:ef7eb2e8f9f7 226 RTCC_Reset();
<> 144:ef7eb2e8f9f7 227 CMU_ClockEnable(cmuClock_RTCC, false);
<> 144:ef7eb2e8f9f7 228 unblockSleepMode(RTCC_LEAST_ACTIVE_SLEEPMODE);
<> 144:ef7eb2e8f9f7 229 rtc_inited = false;
<> 144:ef7eb2e8f9f7 230 }
<> 144:ef7eb2e8f9f7 231 }
<> 144:ef7eb2e8f9f7 232
<> 144:ef7eb2e8f9f7 233 #endif /* RTCC_COUNT */
<> 144:ef7eb2e8f9f7 234
<> 144:ef7eb2e8f9f7 235 void rtc_set_comp0_handler(uint32_t handler)
<> 144:ef7eb2e8f9f7 236 {
<> 144:ef7eb2e8f9f7 237 comp0_handler = (void (*)(void)) handler;
<> 144:ef7eb2e8f9f7 238 }
<> 144:ef7eb2e8f9f7 239
<> 144:ef7eb2e8f9f7 240 void rtc_init(void)
<> 144:ef7eb2e8f9f7 241 {
<> 144:ef7eb2e8f9f7 242 /* Register that the RTC is used for timekeeping. */
<> 144:ef7eb2e8f9f7 243 rtc_init_real(RTC_INIT_RTC);
<> 144:ef7eb2e8f9f7 244 }
<> 144:ef7eb2e8f9f7 245
<> 144:ef7eb2e8f9f7 246 int rtc_isenabled(void)
<> 144:ef7eb2e8f9f7 247 {
<> 144:ef7eb2e8f9f7 248 return rtc_inited;
<> 144:ef7eb2e8f9f7 249 }
<> 144:ef7eb2e8f9f7 250
<> 144:ef7eb2e8f9f7 251 time_t rtc_read(void)
<> 144:ef7eb2e8f9f7 252 {
<> 144:ef7eb2e8f9f7 253 return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT) + time_base;
<> 144:ef7eb2e8f9f7 254 }
<> 144:ef7eb2e8f9f7 255
<> 144:ef7eb2e8f9f7 256 time_t rtc_read_uncompensated(void)
<> 144:ef7eb2e8f9f7 257 {
<> 144:ef7eb2e8f9f7 258 return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT);
<> 144:ef7eb2e8f9f7 259 }
<> 144:ef7eb2e8f9f7 260
<> 144:ef7eb2e8f9f7 261 void rtc_write(time_t t)
<> 144:ef7eb2e8f9f7 262 {
<> 144:ef7eb2e8f9f7 263 /* We have to check that the RTC did not tick while doing this. */
<> 144:ef7eb2e8f9f7 264 /* If the RTC ticks we just redo this. */
<> 144:ef7eb2e8f9f7 265 uint32_t time;
<> 144:ef7eb2e8f9f7 266 do {
<> 144:ef7eb2e8f9f7 267 time = rtc_read_uncompensated();
<> 144:ef7eb2e8f9f7 268 time_base = t - time;
<> 144:ef7eb2e8f9f7 269 } while (time != (uint32_t)rtc_read_uncompensated());
<> 144:ef7eb2e8f9f7 270 }
<> 144:ef7eb2e8f9f7 271
<> 144:ef7eb2e8f9f7 272 #endif