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 lp_ticker.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 #include "clocking.h"
sahilmgandhi 18:6a4db94011d3 26 #if DEVICE_LOWPOWERTIMER
sahilmgandhi 18:6a4db94011d3 27
sahilmgandhi 18:6a4db94011d3 28 #include "rtc_api.h"
sahilmgandhi 18:6a4db94011d3 29 #include "rtc_api_HAL.h"
sahilmgandhi 18:6a4db94011d3 30 #include "lp_ticker_api.h"
sahilmgandhi 18:6a4db94011d3 31
sahilmgandhi 18:6a4db94011d3 32 #include "mbed_critical.h"
sahilmgandhi 18:6a4db94011d3 33 #if (defined RTCC_COUNT) && (RTCC_COUNT > 0)
sahilmgandhi 18:6a4db94011d3 34 #include "em_rtcc.h"
sahilmgandhi 18:6a4db94011d3 35 #endif
sahilmgandhi 18:6a4db94011d3 36
sahilmgandhi 18:6a4db94011d3 37 static int rtc_reserved = 0;
sahilmgandhi 18:6a4db94011d3 38
sahilmgandhi 18:6a4db94011d3 39 void lp_ticker_init()
sahilmgandhi 18:6a4db94011d3 40 {
sahilmgandhi 18:6a4db94011d3 41 if(!rtc_reserved) {
sahilmgandhi 18:6a4db94011d3 42 core_util_critical_section_enter();
sahilmgandhi 18:6a4db94011d3 43 rtc_init_real(RTC_INIT_LPTIMER);
sahilmgandhi 18:6a4db94011d3 44 rtc_set_comp0_handler((uint32_t)lp_ticker_irq_handler);
sahilmgandhi 18:6a4db94011d3 45 rtc_reserved = 1;
sahilmgandhi 18:6a4db94011d3 46 core_util_critical_section_exit();
sahilmgandhi 18:6a4db94011d3 47 }
sahilmgandhi 18:6a4db94011d3 48 }
sahilmgandhi 18:6a4db94011d3 49
sahilmgandhi 18:6a4db94011d3 50 void lp_ticker_free()
sahilmgandhi 18:6a4db94011d3 51 {
sahilmgandhi 18:6a4db94011d3 52 if(rtc_reserved) {
sahilmgandhi 18:6a4db94011d3 53 core_util_critical_section_enter();
sahilmgandhi 18:6a4db94011d3 54 rtc_free_real(RTC_INIT_LPTIMER);
sahilmgandhi 18:6a4db94011d3 55 rtc_reserved = 0;
sahilmgandhi 18:6a4db94011d3 56 core_util_critical_section_exit();
sahilmgandhi 18:6a4db94011d3 57 }
sahilmgandhi 18:6a4db94011d3 58 }
sahilmgandhi 18:6a4db94011d3 59
sahilmgandhi 18:6a4db94011d3 60 #ifndef RTCC_COUNT
sahilmgandhi 18:6a4db94011d3 61
sahilmgandhi 18:6a4db94011d3 62 /* RTC API */
sahilmgandhi 18:6a4db94011d3 63
sahilmgandhi 18:6a4db94011d3 64 void lp_ticker_set_interrupt(timestamp_t timestamp)
sahilmgandhi 18:6a4db94011d3 65 {
sahilmgandhi 18:6a4db94011d3 66 uint64_t timestamp_ticks;
sahilmgandhi 18:6a4db94011d3 67 uint64_t current_ticks = RTC_CounterGet();
sahilmgandhi 18:6a4db94011d3 68 timestamp_t current_time = ((uint64_t)(current_ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT));
sahilmgandhi 18:6a4db94011d3 69
sahilmgandhi 18:6a4db94011d3 70 /* Initialize RTC */
sahilmgandhi 18:6a4db94011d3 71 lp_ticker_init();
sahilmgandhi 18:6a4db94011d3 72
sahilmgandhi 18:6a4db94011d3 73 /* calculate offset value */
sahilmgandhi 18:6a4db94011d3 74 timestamp_t offset = timestamp - current_time;
sahilmgandhi 18:6a4db94011d3 75 if(offset > 0xEFFFFFFF) offset = 100;
sahilmgandhi 18:6a4db94011d3 76
sahilmgandhi 18:6a4db94011d3 77 /* map offset to RTC value */
sahilmgandhi 18:6a4db94011d3 78 // ticks = offset * RTC frequency div 1000000
sahilmgandhi 18:6a4db94011d3 79 timestamp_ticks = ((uint64_t)offset * (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT)) / 1000000;
sahilmgandhi 18:6a4db94011d3 80 timestamp_ticks += current_ticks;
sahilmgandhi 18:6a4db94011d3 81
sahilmgandhi 18:6a4db94011d3 82 /* RTC has 24 bit resolution */
sahilmgandhi 18:6a4db94011d3 83 timestamp_ticks &= 0xFFFFFF;
sahilmgandhi 18:6a4db94011d3 84
sahilmgandhi 18:6a4db94011d3 85 /* check for RTC limitation */
sahilmgandhi 18:6a4db94011d3 86 if((timestamp_ticks - RTC_CounterGet()) >= 0x800000) timestamp_ticks = RTC_CounterGet() + 2;
sahilmgandhi 18:6a4db94011d3 87
sahilmgandhi 18:6a4db94011d3 88 /* Set callback */
sahilmgandhi 18:6a4db94011d3 89 RTC_FreezeEnable(true);
sahilmgandhi 18:6a4db94011d3 90 RTC_CompareSet(0, (uint32_t)timestamp_ticks);
sahilmgandhi 18:6a4db94011d3 91 RTC_IntEnable(RTC_IF_COMP0);
sahilmgandhi 18:6a4db94011d3 92 RTC_FreezeEnable(false);
sahilmgandhi 18:6a4db94011d3 93 }
sahilmgandhi 18:6a4db94011d3 94
sahilmgandhi 18:6a4db94011d3 95 inline void lp_ticker_disable_interrupt()
sahilmgandhi 18:6a4db94011d3 96 {
sahilmgandhi 18:6a4db94011d3 97 RTC_IntDisable(RTC_IF_COMP0);
sahilmgandhi 18:6a4db94011d3 98 lp_ticker_free();
sahilmgandhi 18:6a4db94011d3 99 }
sahilmgandhi 18:6a4db94011d3 100
sahilmgandhi 18:6a4db94011d3 101 inline void lp_ticker_clear_interrupt()
sahilmgandhi 18:6a4db94011d3 102 {
sahilmgandhi 18:6a4db94011d3 103 RTC_IntClear(RTC_IF_COMP0);
sahilmgandhi 18:6a4db94011d3 104 }
sahilmgandhi 18:6a4db94011d3 105
sahilmgandhi 18:6a4db94011d3 106 timestamp_t lp_ticker_read()
sahilmgandhi 18:6a4db94011d3 107 {
sahilmgandhi 18:6a4db94011d3 108 lp_ticker_init();
sahilmgandhi 18:6a4db94011d3 109
sahilmgandhi 18:6a4db94011d3 110 uint64_t ticks_temp;
sahilmgandhi 18:6a4db94011d3 111 uint64_t ticks = RTC_CounterGet();
sahilmgandhi 18:6a4db94011d3 112
sahilmgandhi 18:6a4db94011d3 113 /* ticks = counter tick value
sahilmgandhi 18:6a4db94011d3 114 * timestamp = value in microseconds
sahilmgandhi 18:6a4db94011d3 115 * timestamp = ticks * 1.000.000 / RTC frequency
sahilmgandhi 18:6a4db94011d3 116 */
sahilmgandhi 18:6a4db94011d3 117
sahilmgandhi 18:6a4db94011d3 118 ticks_temp = (ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT);
sahilmgandhi 18:6a4db94011d3 119 return (timestamp_t) (ticks_temp & 0xFFFFFFFF);
sahilmgandhi 18:6a4db94011d3 120 }
sahilmgandhi 18:6a4db94011d3 121
sahilmgandhi 18:6a4db94011d3 122 #else
sahilmgandhi 18:6a4db94011d3 123
sahilmgandhi 18:6a4db94011d3 124 /* RTCC API */
sahilmgandhi 18:6a4db94011d3 125
sahilmgandhi 18:6a4db94011d3 126 void lp_ticker_set_interrupt(timestamp_t timestamp)
sahilmgandhi 18:6a4db94011d3 127 {
sahilmgandhi 18:6a4db94011d3 128 uint64_t timestamp_ticks;
sahilmgandhi 18:6a4db94011d3 129 uint64_t current_ticks = RTCC_CounterGet();
sahilmgandhi 18:6a4db94011d3 130 timestamp_t current_time = ((uint64_t)(current_ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT));
sahilmgandhi 18:6a4db94011d3 131
sahilmgandhi 18:6a4db94011d3 132 /* Initialize RTC */
sahilmgandhi 18:6a4db94011d3 133 lp_ticker_init();
sahilmgandhi 18:6a4db94011d3 134
sahilmgandhi 18:6a4db94011d3 135 /* calculate offset value */
sahilmgandhi 18:6a4db94011d3 136 timestamp_t offset = timestamp - current_time;
sahilmgandhi 18:6a4db94011d3 137 if(offset > 0xEFFFFFFF) offset = 100;
sahilmgandhi 18:6a4db94011d3 138
sahilmgandhi 18:6a4db94011d3 139 /* map offset to RTC value */
sahilmgandhi 18:6a4db94011d3 140 // ticks = offset * RTC frequency div 1000000
sahilmgandhi 18:6a4db94011d3 141 timestamp_ticks = ((uint64_t)offset * (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT)) / 1000000;
sahilmgandhi 18:6a4db94011d3 142 // checking the rounding. If timeout is wanted between RTCC ticks, irq should be configured to
sahilmgandhi 18:6a4db94011d3 143 // trigger in the latter RTCC-tick. Otherwise ticker-api fails to send timer event to its client
sahilmgandhi 18:6a4db94011d3 144 if(((timestamp_ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT)) < offset){
sahilmgandhi 18:6a4db94011d3 145 timestamp_ticks++;
sahilmgandhi 18:6a4db94011d3 146 }
sahilmgandhi 18:6a4db94011d3 147
sahilmgandhi 18:6a4db94011d3 148 timestamp_ticks += current_ticks;
sahilmgandhi 18:6a4db94011d3 149
sahilmgandhi 18:6a4db94011d3 150 /* RTCC has 32 bit resolution */
sahilmgandhi 18:6a4db94011d3 151 timestamp_ticks &= 0xFFFFFFFF;
sahilmgandhi 18:6a4db94011d3 152
sahilmgandhi 18:6a4db94011d3 153 /* check for RTCC limitation */
sahilmgandhi 18:6a4db94011d3 154 if((timestamp_ticks - RTCC_CounterGet()) >= 0x80000000) timestamp_ticks = RTCC_CounterGet() + 2;
sahilmgandhi 18:6a4db94011d3 155
sahilmgandhi 18:6a4db94011d3 156 /* init channel */
sahilmgandhi 18:6a4db94011d3 157 RTCC_CCChConf_TypeDef ccchConf = RTCC_CH_INIT_COMPARE_DEFAULT;
sahilmgandhi 18:6a4db94011d3 158 RTCC_ChannelInit(0,&ccchConf);
sahilmgandhi 18:6a4db94011d3 159 /* Set callback */
sahilmgandhi 18:6a4db94011d3 160 RTCC_ChannelCCVSet(0, (uint32_t)timestamp_ticks);
sahilmgandhi 18:6a4db94011d3 161 RTCC_IntEnable(RTCC_IF_CC0);
sahilmgandhi 18:6a4db94011d3 162 }
sahilmgandhi 18:6a4db94011d3 163
sahilmgandhi 18:6a4db94011d3 164 inline void lp_ticker_disable_interrupt()
sahilmgandhi 18:6a4db94011d3 165 {
sahilmgandhi 18:6a4db94011d3 166 RTCC_IntDisable(RTCC_IF_CC0);
sahilmgandhi 18:6a4db94011d3 167 lp_ticker_free();
sahilmgandhi 18:6a4db94011d3 168 }
sahilmgandhi 18:6a4db94011d3 169
sahilmgandhi 18:6a4db94011d3 170 inline void lp_ticker_clear_interrupt()
sahilmgandhi 18:6a4db94011d3 171 {
sahilmgandhi 18:6a4db94011d3 172 RTCC_IntClear(RTCC_IF_CC0);
sahilmgandhi 18:6a4db94011d3 173 }
sahilmgandhi 18:6a4db94011d3 174
sahilmgandhi 18:6a4db94011d3 175 timestamp_t lp_ticker_read()
sahilmgandhi 18:6a4db94011d3 176 {
sahilmgandhi 18:6a4db94011d3 177 lp_ticker_init();
sahilmgandhi 18:6a4db94011d3 178
sahilmgandhi 18:6a4db94011d3 179 uint64_t ticks_temp;
sahilmgandhi 18:6a4db94011d3 180 uint64_t ticks = RTCC_CounterGet();
sahilmgandhi 18:6a4db94011d3 181
sahilmgandhi 18:6a4db94011d3 182 /* ticks = counter tick value
sahilmgandhi 18:6a4db94011d3 183 * timestamp = value in microseconds
sahilmgandhi 18:6a4db94011d3 184 * timestamp = ticks * 1.000.000 / RTC frequency
sahilmgandhi 18:6a4db94011d3 185 */
sahilmgandhi 18:6a4db94011d3 186
sahilmgandhi 18:6a4db94011d3 187 ticks_temp = (ticks * 1000000) / (LOW_ENERGY_CLOCK_FREQUENCY / RTC_CLOCKDIV_INT);
sahilmgandhi 18:6a4db94011d3 188 return (timestamp_t) (ticks_temp & 0xFFFFFFFF);
sahilmgandhi 18:6a4db94011d3 189 }
sahilmgandhi 18:6a4db94011d3 190
sahilmgandhi 18:6a4db94011d3 191 #endif /* RTCC */
sahilmgandhi 18:6a4db94011d3 192
sahilmgandhi 18:6a4db94011d3 193 #endif