mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
188:bcfe06ba3d64
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 178:79309dc6340a 1 /*******************************************************************************
AnnaBridge 184:08ed48f1de7f 2 * Copyright (c) 2010-2018 Analog Devices, Inc.
AnnaBridge 178:79309dc6340a 3 *
AnnaBridge 178:79309dc6340a 4 * All rights reserved.
AnnaBridge 178:79309dc6340a 5 *
AnnaBridge 178:79309dc6340a 6 * Redistribution and use in source and binary forms, with or without modification,
AnnaBridge 178:79309dc6340a 7 * are permitted provided that the following conditions are met:
AnnaBridge 178:79309dc6340a 8 * - Redistributions of source code must retain the above copyright notice,
AnnaBridge 178:79309dc6340a 9 * this list of conditions and the following disclaimer.
AnnaBridge 178:79309dc6340a 10 * - Redistributions in binary form must reproduce the above copyright notice,
AnnaBridge 178:79309dc6340a 11 * this list of conditions and the following disclaimer in the documentation
AnnaBridge 178:79309dc6340a 12 * and/or other materials provided with the distribution.
AnnaBridge 178:79309dc6340a 13 * - Modified versions of the software must be conspicuously marked as such.
AnnaBridge 178:79309dc6340a 14 * - This software is licensed solely and exclusively for use with processors
AnnaBridge 178:79309dc6340a 15 * manufactured by or for Analog Devices, Inc.
AnnaBridge 178:79309dc6340a 16 * - This software may not be combined or merged with other code in any manner
AnnaBridge 178:79309dc6340a 17 * that would cause the software to become subject to terms and conditions
AnnaBridge 178:79309dc6340a 18 * which differ from those listed here.
AnnaBridge 178:79309dc6340a 19 * - Neither the name of Analog Devices, Inc. nor the names of its
AnnaBridge 178:79309dc6340a 20 * contributors may be used to endorse or promote products derived
AnnaBridge 178:79309dc6340a 21 * from this software without specific prior written permission.
AnnaBridge 178:79309dc6340a 22 * - The use of this software may or may not infringe the patent rights of one
AnnaBridge 178:79309dc6340a 23 * or more patent holders. This license does not release you from the
AnnaBridge 178:79309dc6340a 24 * requirement that you obtain separate licenses from these patent holders
AnnaBridge 178:79309dc6340a 25 * to use this software.
AnnaBridge 178:79309dc6340a 26 *
AnnaBridge 178:79309dc6340a 27 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS"
AnnaBridge 178:79309dc6340a 28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-
AnnaBridge 178:79309dc6340a 29 * INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
AnnaBridge 178:79309dc6340a 30 * DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE
AnnaBridge 178:79309dc6340a 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR
AnnaBridge 178:79309dc6340a 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF
AnnaBridge 178:79309dc6340a 33 * CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF
AnnaBridge 178:79309dc6340a 34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
AnnaBridge 178:79309dc6340a 35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
AnnaBridge 178:79309dc6340a 36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
AnnaBridge 178:79309dc6340a 37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
AnnaBridge 178:79309dc6340a 38 * POSSIBILITY OF SUCH DAMAGE.
AnnaBridge 178:79309dc6340a 39 ******************************************************************************/
AnnaBridge 178:79309dc6340a 40
AnnaBridge 178:79309dc6340a 41 #include <stdint.h>
AnnaBridge 178:79309dc6340a 42 #include <stdio.h>
AnnaBridge 178:79309dc6340a 43 #include <drivers/tmr/adi_tmr.h>
AnnaBridge 178:79309dc6340a 44 #include <drivers/pwr/adi_pwr.h>
AnnaBridge 178:79309dc6340a 45 #include <drivers/gpio/adi_gpio.h>
AnnaBridge 178:79309dc6340a 46
AnnaBridge 178:79309dc6340a 47 #ifndef BITM_TMR_RGB_CTL_EN
AnnaBridge 178:79309dc6340a 48 #define BITM_TMR_RGB_CTL_EN BITM_TMR_CTL_EN
AnnaBridge 178:79309dc6340a 49 #endif
AnnaBridge 178:79309dc6340a 50
AnnaBridge 178:79309dc6340a 51 typedef uint32_t timestamp_t;
AnnaBridge 178:79309dc6340a 52
AnnaBridge 178:79309dc6340a 53 // defined in mbed_us_ticker_api.c which calls the ticker_irq_handler() routine
AnnaBridge 178:79309dc6340a 54 // defined in mbed_ticker_api.c
AnnaBridge 178:79309dc6340a 55 void us_ticker_irq_handler(void);
AnnaBridge 178:79309dc6340a 56
AnnaBridge 178:79309dc6340a 57 static int us_ticker_inited = 0;
AnnaBridge 178:79309dc6340a 58
Anna Bridge 186:707f6e361f3e 59 static ADI_TMR_CONFIG tmrConfig;
AnnaBridge 178:79309dc6340a 60
AnnaBridge 178:79309dc6340a 61 static volatile uint32_t Upper_count = 0, largecnt = 0;
AnnaBridge 178:79309dc6340a 62
AnnaBridge 178:79309dc6340a 63 static ADI_TMR_TypeDef * adi_tmr_registers[ADI_TMR_DEVICE_NUM] = {pADI_TMR0, pADI_TMR1, pADI_TMR2};
AnnaBridge 178:79309dc6340a 64
AnnaBridge 178:79309dc6340a 65 #if defined(__ADUCM302x__)
AnnaBridge 178:79309dc6340a 66 static const IRQn_Type adi_tmr_interrupt[ADI_TMR_DEVICE_NUM] = {TMR0_EVT_IRQn, TMR1_EVT_IRQn, TMR2_EVT_IRQn};
AnnaBridge 178:79309dc6340a 67 #elif defined(__ADUCM4x50__)
AnnaBridge 178:79309dc6340a 68 static const IRQn_Type adi_tmr_interrupt[ADI_TMR_DEVICE_NUM] = {TMR0_EVT_IRQn, TMR1_EVT_IRQn, TMR2_EVT_IRQn, TMR_RGB_EVT_IRQn};
AnnaBridge 178:79309dc6340a 69 #else
AnnaBridge 178:79309dc6340a 70 #error TMR is not ported for this processor
AnnaBridge 178:79309dc6340a 71 #endif
AnnaBridge 178:79309dc6340a 72
AnnaBridge 178:79309dc6340a 73
AnnaBridge 178:79309dc6340a 74 /*---------------------------------------------------------------------------*
AnnaBridge 178:79309dc6340a 75 Local functions
AnnaBridge 178:79309dc6340a 76 *---------------------------------------------------------------------------*/
AnnaBridge 178:79309dc6340a 77 static void GP1CallbackFunction(void *pCBParam, uint32_t Event, void * pArg)
AnnaBridge 178:79309dc6340a 78 {
AnnaBridge 178:79309dc6340a 79 Upper_count++;
AnnaBridge 178:79309dc6340a 80 }
AnnaBridge 178:79309dc6340a 81
AnnaBridge 178:79309dc6340a 82
AnnaBridge 178:79309dc6340a 83 static uint32_t get_current_time(void)
AnnaBridge 178:79309dc6340a 84 {
AnnaBridge 178:79309dc6340a 85 uint16_t tmrcnt0, tmrcnt1;
AnnaBridge 178:79309dc6340a 86 uint32_t totaltmr0, totaltmr1;
AnnaBridge 178:79309dc6340a 87 uint32_t uc1, tmrpend0, tmrpend1;
AnnaBridge 178:79309dc6340a 88
AnnaBridge 178:79309dc6340a 89 do {
AnnaBridge 178:79309dc6340a 90 volatile uint32_t *ucptr = &Upper_count;
AnnaBridge 178:79309dc6340a 91
AnnaBridge 178:79309dc6340a 92 /*
AnnaBridge 178:79309dc6340a 93 * Carefully coded to prevent race conditions. Do not make changes unless you understand all the
AnnaBridge 178:79309dc6340a 94 * implications.
AnnaBridge 178:79309dc6340a 95 *
AnnaBridge 178:79309dc6340a 96 * Note this function can be called with interrupts globally disabled or enabled. It has been coded to work in both cases.
AnnaBridge 178:79309dc6340a 97 *
AnnaBridge 178:79309dc6340a 98 * TMR0 and TMR1 both run from the same synchronous clock. TMR0 runs at 26MHz and TMR1 runs at 26/256MHz.
AnnaBridge 178:79309dc6340a 99 * TMR1 generates an interrupt every time it overflows its 16 bit counter. TMR0 runs faster and provides
AnnaBridge 178:79309dc6340a 100 * the lowest 8 bits of the current time count. When TMR0 and TMR1 are combined, they provide 24 bits of
AnnaBridge 178:79309dc6340a 101 * timer precision. i.e. (TMR0.CURCNT & 0xff) + (TMR1.CURCNT << 8)
AnnaBridge 178:79309dc6340a 102 *
AnnaBridge 178:79309dc6340a 103 * There are several race conditions protected against:
AnnaBridge 178:79309dc6340a 104 * 1. TMR0 and TMR1 are both read at the same time, however, on rare occasions, one will have incremented before the other.
AnnaBridge 178:79309dc6340a 105 * Therefore we read both timer counters, and check if the middle 8 bits match, if they don't then read the counts again
AnnaBridge 178:79309dc6340a 106 * until they do. This ensures that one or the other counters are stable with respect to each other.
AnnaBridge 178:79309dc6340a 107 *
AnnaBridge 178:79309dc6340a 108 * 2. TMR1.CURCNT and Upper_count racing. Prevent this by disabling the TMR1 interrupt, which stops Upper_count increment interrupt (GP1CallbackFunction).
AnnaBridge 178:79309dc6340a 109 * Then check pending bit of TMR1 to see if we missed Upper_count interrupt, and add it manually later.
AnnaBridge 178:79309dc6340a 110 *
AnnaBridge 178:79309dc6340a 111 * 3. Race between the TMR1 pend, and the TMR1.CURCNT read. Even with TMR1 interrupt disabled, the pend bit
AnnaBridge 178:79309dc6340a 112 * may be set while TMR1.CURCNT is being read. We don't know if the pend bit matches the TMR1 state.
AnnaBridge 178:79309dc6340a 113 * To prevent this, the pending bit is read twice, and we see if it matches; if it doesn't, loop around again.
AnnaBridge 178:79309dc6340a 114 *
AnnaBridge 178:79309dc6340a 115 * Note the TMR1 interrupt is enabled on each iteration of the loop to flush out any pending TMR1 interrupt,
AnnaBridge 178:79309dc6340a 116 * thereby clearing any TMR1 pend's. This have no effect if this routine is called with interrupts globally disabled.
AnnaBridge 178:79309dc6340a 117 */
AnnaBridge 178:79309dc6340a 118
AnnaBridge 178:79309dc6340a 119 NVIC_DisableIRQ(adi_tmr_interrupt[ADI_TMR_DEVICE_GP1]); // Prevent Upper_count increment
AnnaBridge 178:79309dc6340a 120 tmrpend0 = NVIC_GetPendingIRQ(adi_tmr_interrupt[ADI_TMR_DEVICE_GP1]);
AnnaBridge 178:79309dc6340a 121 // Check if there is a pending interrupt for timer 1
AnnaBridge 178:79309dc6340a 122
AnnaBridge 178:79309dc6340a 123 __DMB(); // memory barrier: read GP0 before GP1
AnnaBridge 178:79309dc6340a 124
AnnaBridge 178:79309dc6340a 125 tmrcnt0 = adi_tmr_registers[ADI_TMR_DEVICE_GP0]->CURCNT; // to minimize skew, read both timers manually
AnnaBridge 178:79309dc6340a 126
AnnaBridge 178:79309dc6340a 127 __DMB(); // memory barrier: read GP0 before GP1
AnnaBridge 178:79309dc6340a 128
AnnaBridge 178:79309dc6340a 129 tmrcnt1 = adi_tmr_registers[ADI_TMR_DEVICE_GP1]->CURCNT; // read both timers manually
AnnaBridge 178:79309dc6340a 130
AnnaBridge 178:79309dc6340a 131 totaltmr0 = tmrcnt0; // expand to u32 bits
AnnaBridge 178:79309dc6340a 132 totaltmr1 = tmrcnt1; // expand to u32 bits
AnnaBridge 178:79309dc6340a 133
AnnaBridge 178:79309dc6340a 134 tmrcnt0 &= 0xff00u;
AnnaBridge 178:79309dc6340a 135 tmrcnt1 <<= 8;
AnnaBridge 178:79309dc6340a 136
AnnaBridge 178:79309dc6340a 137 __DMB();
AnnaBridge 178:79309dc6340a 138
AnnaBridge 178:79309dc6340a 139 uc1 = *ucptr; // Read Upper_count
AnnaBridge 178:79309dc6340a 140
AnnaBridge 178:79309dc6340a 141 tmrpend1 = NVIC_GetPendingIRQ(adi_tmr_interrupt[ADI_TMR_DEVICE_GP1]);
AnnaBridge 178:79309dc6340a 142 // Check for a pending interrupt again. Only leave loop if they match
AnnaBridge 178:79309dc6340a 143
AnnaBridge 178:79309dc6340a 144 NVIC_EnableIRQ(adi_tmr_interrupt[ADI_TMR_DEVICE_GP1]); // enable interrupt on every loop to allow TMR1 interrupt to run
AnnaBridge 178:79309dc6340a 145 } while ((tmrcnt0 != tmrcnt1) || (tmrpend0 != tmrpend1));
AnnaBridge 178:79309dc6340a 146
AnnaBridge 178:79309dc6340a 147 totaltmr1 <<= 8; // Timer1 runs 256x slower
AnnaBridge 178:79309dc6340a 148 totaltmr1 += totaltmr0 & 0xffu; // Use last 8 bits of Timer0 as it runs faster
AnnaBridge 178:79309dc6340a 149 // totaltmr1 now contain 24 bits of significance
AnnaBridge 178:79309dc6340a 150
AnnaBridge 178:79309dc6340a 151 if (tmrpend0) { // If an interrupt is pending, then increment local copy of upper count
AnnaBridge 178:79309dc6340a 152 uc1++;
AnnaBridge 178:79309dc6340a 153 }
AnnaBridge 178:79309dc6340a 154
AnnaBridge 178:79309dc6340a 155 uint64_t Uc = totaltmr1; // expand out to 64 bits unsigned
AnnaBridge 178:79309dc6340a 156 Uc += ((uint64_t) uc1) << 24; // Add on the upper count to get the full precision count
AnnaBridge 178:79309dc6340a 157
AnnaBridge 178:79309dc6340a 158 // Divide Uc by 26 (26MHz converted to 1MHz) todo scale for other clock freqs
AnnaBridge 178:79309dc6340a 159
AnnaBridge 178:79309dc6340a 160 Uc *= 1290555u; // Divide total(1/26) << 25
AnnaBridge 178:79309dc6340a 161 Uc >>= 25; // shift back. Fixed point avoid use of floating point divide.
AnnaBridge 178:79309dc6340a 162 // Compiler does this inline using shifts and adds.
AnnaBridge 178:79309dc6340a 163
AnnaBridge 178:79309dc6340a 164 return Uc;
AnnaBridge 178:79309dc6340a 165 }
AnnaBridge 178:79309dc6340a 166
AnnaBridge 178:79309dc6340a 167
AnnaBridge 178:79309dc6340a 168 static void calc_event_counts(uint32_t timestamp)
AnnaBridge 178:79309dc6340a 169 {
AnnaBridge 178:79309dc6340a 170 uint32_t calc_time, blocks, offset;
AnnaBridge 178:79309dc6340a 171 uint64_t aa;
AnnaBridge 178:79309dc6340a 172
AnnaBridge 178:79309dc6340a 173 calc_time = get_current_time();
AnnaBridge 178:79309dc6340a 174 offset = timestamp - calc_time; // offset in useconds
AnnaBridge 178:79309dc6340a 175
AnnaBridge 178:79309dc6340a 176 if (offset > 0xf0000000u) // if offset is a really big number, assume that timer has already expired (i.e. negative)
AnnaBridge 178:79309dc6340a 177 offset = 0u;
AnnaBridge 178:79309dc6340a 178
AnnaBridge 178:79309dc6340a 179 if (offset > 10u) { // it takes 10us to user timer routine after interrupt. Offset timer to account for that.
AnnaBridge 178:79309dc6340a 180 offset -= 10u;
AnnaBridge 178:79309dc6340a 181 } else
AnnaBridge 178:79309dc6340a 182 offset = 0u;
AnnaBridge 178:79309dc6340a 183
AnnaBridge 178:79309dc6340a 184 aa = (uint64_t) offset;
AnnaBridge 178:79309dc6340a 185 aa *= 26u; // convert from 1MHz to 26MHz clock. todo scale for other clock freqs
AnnaBridge 178:79309dc6340a 186
AnnaBridge 178:79309dc6340a 187 blocks = aa >> 7;
AnnaBridge 178:79309dc6340a 188 blocks++; // round
AnnaBridge 178:79309dc6340a 189
AnnaBridge 178:79309dc6340a 190 largecnt = blocks>>1; // communicate to event_timer() routine
AnnaBridge 178:79309dc6340a 191 }
AnnaBridge 178:79309dc6340a 192
AnnaBridge 178:79309dc6340a 193 static void event_timer()
AnnaBridge 178:79309dc6340a 194 {
AnnaBridge 178:79309dc6340a 195 if (largecnt) {
AnnaBridge 178:79309dc6340a 196 uint32_t cnt = largecnt;
AnnaBridge 178:79309dc6340a 197
AnnaBridge 178:79309dc6340a 198 if (cnt > 65535u) {
AnnaBridge 178:79309dc6340a 199 cnt = 0u;
AnnaBridge 178:79309dc6340a 200 } else {
AnnaBridge 178:79309dc6340a 201 cnt = 65536u - cnt;
AnnaBridge 178:79309dc6340a 202 }
AnnaBridge 178:79309dc6340a 203
Anna Bridge 186:707f6e361f3e 204 tmrConfig.nLoad = cnt;
Anna Bridge 186:707f6e361f3e 205 tmrConfig.nAsyncLoad = cnt;
Anna Bridge 186:707f6e361f3e 206 adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, &tmrConfig);
AnnaBridge 178:79309dc6340a 207 adi_tmr_Enable(ADI_TMR_DEVICE_GP2, true);
AnnaBridge 178:79309dc6340a 208 } else {
Anna Bridge 186:707f6e361f3e 209 tmrConfig.nLoad = 65535u;
Anna Bridge 186:707f6e361f3e 210 tmrConfig.nAsyncLoad = 65535u;
Anna Bridge 186:707f6e361f3e 211 adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, &tmrConfig);
AnnaBridge 184:08ed48f1de7f 212 adi_tmr_Enable(ADI_TMR_DEVICE_GP2, true);
AnnaBridge 178:79309dc6340a 213 }
AnnaBridge 178:79309dc6340a 214 }
AnnaBridge 178:79309dc6340a 215
AnnaBridge 178:79309dc6340a 216
AnnaBridge 178:79309dc6340a 217 /*
AnnaBridge 178:79309dc6340a 218 * Interrupt routine for timer 2
AnnaBridge 178:79309dc6340a 219 *
AnnaBridge 178:79309dc6340a 220 * largecnt counts how many timer ticks should be counted to reach timer event.
AnnaBridge 178:79309dc6340a 221 * Each interrupt happens every 65536 timer ticks, unless there are less than 65536 ticks to count.
AnnaBridge 178:79309dc6340a 222 * In that case do the remaining timers ticks.
AnnaBridge 178:79309dc6340a 223 *
AnnaBridge 178:79309dc6340a 224 * largecnt is a global that is used to communicate between event_timer and the interrupt routine
AnnaBridge 178:79309dc6340a 225 * On entry, largecnt will be any value larger than 0.
AnnaBridge 178:79309dc6340a 226 */
AnnaBridge 178:79309dc6340a 227 static void GP2CallbackFunction(void *pCBParam, uint32_t Event, void * pArg)
AnnaBridge 178:79309dc6340a 228 {
AnnaBridge 178:79309dc6340a 229 if (largecnt >= 65536u) {
AnnaBridge 178:79309dc6340a 230 largecnt -= 65536u;
AnnaBridge 178:79309dc6340a 231 } else {
AnnaBridge 178:79309dc6340a 232 largecnt = 0;
AnnaBridge 178:79309dc6340a 233 }
AnnaBridge 178:79309dc6340a 234
AnnaBridge 178:79309dc6340a 235 if (largecnt < 65536u) {
AnnaBridge 178:79309dc6340a 236 adi_tmr_Enable(ADI_TMR_DEVICE_GP2, false);
AnnaBridge 184:08ed48f1de7f 237 if (largecnt) {
AnnaBridge 184:08ed48f1de7f 238 event_timer();
AnnaBridge 184:08ed48f1de7f 239 } else {
AnnaBridge 184:08ed48f1de7f 240 us_ticker_irq_handler();
AnnaBridge 184:08ed48f1de7f 241 }
AnnaBridge 178:79309dc6340a 242 }
AnnaBridge 178:79309dc6340a 243 }
AnnaBridge 178:79309dc6340a 244
AnnaBridge 178:79309dc6340a 245
AnnaBridge 178:79309dc6340a 246 /*---------------------------------------------------------------------------*
AnnaBridge 178:79309dc6340a 247 us_ticker HAL APIs
AnnaBridge 178:79309dc6340a 248 *---------------------------------------------------------------------------*/
AnnaBridge 178:79309dc6340a 249 void us_ticker_init(void)
AnnaBridge 178:79309dc6340a 250 {
AnnaBridge 178:79309dc6340a 251 if (us_ticker_inited) {
Anna Bridge 186:707f6e361f3e 252 // Disable ticker interrupt on reinitialization
Anna Bridge 186:707f6e361f3e 253 adi_tmr_Enable(ADI_TMR_DEVICE_GP2, false);
AnnaBridge 178:79309dc6340a 254 return;
AnnaBridge 178:79309dc6340a 255 }
AnnaBridge 178:79309dc6340a 256
AnnaBridge 178:79309dc6340a 257 us_ticker_inited = 1;
AnnaBridge 178:79309dc6340a 258
AnnaBridge 178:79309dc6340a 259 /*--------------------- GP TIMER INITIALIZATION --------------------------*/
AnnaBridge 178:79309dc6340a 260
AnnaBridge 178:79309dc6340a 261 /* Set up GP0 callback function */
AnnaBridge 178:79309dc6340a 262 adi_tmr_Init(ADI_TMR_DEVICE_GP0, NULL, NULL, false);
AnnaBridge 178:79309dc6340a 263
AnnaBridge 178:79309dc6340a 264 /* Set up GP1 callback function */
AnnaBridge 178:79309dc6340a 265 adi_tmr_Init(ADI_TMR_DEVICE_GP1, GP1CallbackFunction, NULL, true);
AnnaBridge 178:79309dc6340a 266
AnnaBridge 178:79309dc6340a 267 /* Set up GP1 callback function */
AnnaBridge 178:79309dc6340a 268 adi_tmr_Init(ADI_TMR_DEVICE_GP2, GP2CallbackFunction, NULL, true);
AnnaBridge 178:79309dc6340a 269
AnnaBridge 178:79309dc6340a 270 /* Configure GP0 to run at 26MHz */
AnnaBridge 178:79309dc6340a 271 tmrConfig.bCountingUp = true;
AnnaBridge 178:79309dc6340a 272 tmrConfig.bPeriodic = true;
AnnaBridge 178:79309dc6340a 273 tmrConfig.ePrescaler = ADI_TMR_PRESCALER_1; // TMR0 at 26MHz
AnnaBridge 178:79309dc6340a 274 tmrConfig.eClockSource = ADI_TMR_CLOCK_PCLK; // TMR source is PCLK (most examples use HFOSC)
AnnaBridge 178:79309dc6340a 275 tmrConfig.nLoad = 0;
AnnaBridge 178:79309dc6340a 276 tmrConfig.nAsyncLoad = 0;
AnnaBridge 178:79309dc6340a 277 tmrConfig.bReloading = false;
AnnaBridge 178:79309dc6340a 278 tmrConfig.bSyncBypass = true; // Allow x1 prescale: requires PCLK as a clk
AnnaBridge 178:79309dc6340a 279 adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP0, &tmrConfig);
AnnaBridge 178:79309dc6340a 280
AnnaBridge 178:79309dc6340a 281 /* Configure GP1 to have a period 256 times longer than GP0 */
AnnaBridge 178:79309dc6340a 282 tmrConfig.nLoad = 0;
AnnaBridge 178:79309dc6340a 283 tmrConfig.nAsyncLoad = 0;
AnnaBridge 178:79309dc6340a 284 tmrConfig.ePrescaler = ADI_TMR_PRESCALER_256; // TMR1 = 26MHz/256
AnnaBridge 178:79309dc6340a 285 adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP1, &tmrConfig);
AnnaBridge 178:79309dc6340a 286
AnnaBridge 178:79309dc6340a 287 /* Configure GP2 for doing event counts */
Anna Bridge 186:707f6e361f3e 288 tmrConfig.bCountingUp = true;
Anna Bridge 186:707f6e361f3e 289 tmrConfig.bPeriodic = true;
Anna Bridge 186:707f6e361f3e 290 tmrConfig.ePrescaler = ADI_TMR_PRESCALER_256; // TMR2 at 26MHz/256
Anna Bridge 186:707f6e361f3e 291 tmrConfig.eClockSource = ADI_TMR_CLOCK_PCLK; // TMR source is PCLK (most examples use HFOSC)
Anna Bridge 186:707f6e361f3e 292 tmrConfig.nLoad = 0;
Anna Bridge 186:707f6e361f3e 293 tmrConfig.nAsyncLoad = 0;
Anna Bridge 186:707f6e361f3e 294 tmrConfig.bReloading = false;
Anna Bridge 186:707f6e361f3e 295 tmrConfig.bSyncBypass = true; // Allow x1 prescale
Anna Bridge 186:707f6e361f3e 296 adi_tmr_ConfigTimer(ADI_TMR_DEVICE_GP2, &tmrConfig);
AnnaBridge 178:79309dc6340a 297
AnnaBridge 178:79309dc6340a 298
AnnaBridge 178:79309dc6340a 299 /*------------------------- GP TIMER ENABLE ------------------------------*/
AnnaBridge 178:79309dc6340a 300
AnnaBridge 178:79309dc6340a 301 /* Manually enable both timers to get them started at the same time
AnnaBridge 178:79309dc6340a 302 *
AnnaBridge 178:79309dc6340a 303 */
AnnaBridge 178:79309dc6340a 304 adi_tmr_registers[ADI_TMR_DEVICE_GP0]->CTL |= (uint16_t) BITM_TMR_RGB_CTL_EN;
AnnaBridge 178:79309dc6340a 305 adi_tmr_registers[ADI_TMR_DEVICE_GP1]->CTL |= (uint16_t) BITM_TMR_RGB_CTL_EN;
AnnaBridge 178:79309dc6340a 306 }
AnnaBridge 178:79309dc6340a 307
AnnaBridge 178:79309dc6340a 308 uint32_t us_ticker_read()
AnnaBridge 178:79309dc6340a 309 {
AnnaBridge 178:79309dc6340a 310 uint32_t curr_time;
AnnaBridge 178:79309dc6340a 311
AnnaBridge 178:79309dc6340a 312 if (!us_ticker_inited) {
AnnaBridge 178:79309dc6340a 313 us_ticker_init();
AnnaBridge 178:79309dc6340a 314 }
AnnaBridge 178:79309dc6340a 315
AnnaBridge 178:79309dc6340a 316 curr_time = get_current_time();
AnnaBridge 178:79309dc6340a 317
AnnaBridge 178:79309dc6340a 318 return curr_time;
AnnaBridge 178:79309dc6340a 319 }
AnnaBridge 178:79309dc6340a 320
AnnaBridge 178:79309dc6340a 321 void us_ticker_disable_interrupt(void)
AnnaBridge 178:79309dc6340a 322 {
AnnaBridge 178:79309dc6340a 323 adi_tmr_Enable(ADI_TMR_DEVICE_GP2, false);
AnnaBridge 178:79309dc6340a 324 }
AnnaBridge 178:79309dc6340a 325
AnnaBridge 178:79309dc6340a 326 void us_ticker_clear_interrupt(void)
AnnaBridge 178:79309dc6340a 327 {
AnnaBridge 178:79309dc6340a 328 NVIC_ClearPendingIRQ(TMR2_EVT_IRQn);
AnnaBridge 178:79309dc6340a 329 }
AnnaBridge 178:79309dc6340a 330
AnnaBridge 178:79309dc6340a 331 void us_ticker_set_interrupt(timestamp_t timestamp)
AnnaBridge 178:79309dc6340a 332 {
Anna Bridge 186:707f6e361f3e 333 // if timestamp is already past, do not set interrupt
Anna Bridge 186:707f6e361f3e 334 if ((timestamp + 10) <= us_ticker_read()) return;
AnnaBridge 178:79309dc6340a 335 /* timestamp is when interrupt should fire.
AnnaBridge 178:79309dc6340a 336 *
AnnaBridge 178:79309dc6340a 337 * This MUST not be called if another timer event is currently enabled.
AnnaBridge 178:79309dc6340a 338 *
AnnaBridge 178:79309dc6340a 339 */
AnnaBridge 178:79309dc6340a 340 calc_event_counts(timestamp); // use timestamp to calculate largecnt to control number of timer interrupts
Anna Bridge 186:707f6e361f3e 341 tmrConfig.ePrescaler = ADI_TMR_PRESCALER_256; // TMR2 at 26MHz/256
AnnaBridge 178:79309dc6340a 342 event_timer(); // uses largecnt to initiate timer interrupts
AnnaBridge 178:79309dc6340a 343 }
AnnaBridge 178:79309dc6340a 344
AnnaBridge 178:79309dc6340a 345 /** Set pending interrupt that should be fired right away.
AnnaBridge 178:79309dc6340a 346 *
AnnaBridge 178:79309dc6340a 347 * The ticker should be initialized prior calling this function.
AnnaBridge 178:79309dc6340a 348 *
AnnaBridge 178:79309dc6340a 349 * This MUST not be called if another timer event is currently enabled.
AnnaBridge 178:79309dc6340a 350 */
AnnaBridge 178:79309dc6340a 351 void us_ticker_fire_interrupt(void)
AnnaBridge 178:79309dc6340a 352 {
AnnaBridge 184:08ed48f1de7f 353 largecnt = 1; // set a minimal interval so interrupt fire immediately
Anna Bridge 186:707f6e361f3e 354 tmrConfig.ePrescaler = ADI_TMR_PRESCALER_1; // TMR2 at 26MHz/1
AnnaBridge 184:08ed48f1de7f 355 event_timer(); // enable the timer and interrupt
AnnaBridge 178:79309dc6340a 356 }
AnnaBridge 178:79309dc6340a 357
AnnaBridge 188:bcfe06ba3d64 358 void us_ticker_free(void)
AnnaBridge 188:bcfe06ba3d64 359 {
AnnaBridge 188:bcfe06ba3d64 360 adi_tmr_Enable(ADI_TMR_DEVICE_GP2, false);
AnnaBridge 188:bcfe06ba3d64 361 }
AnnaBridge 178:79309dc6340a 362
AnnaBridge 178:79309dc6340a 363 /*
AnnaBridge 178:79309dc6340a 364 ** EOF
AnnaBridge 178:79309dc6340a 365 */