Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

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