mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Fri Sep 11 09:30:09 2015 +0100
Revision:
621:9c82b0f79f3d
Parent:
536:c48d7048ab6e
Synchronized with git revision 6c1d63e069ab9bd86de92e8296ca783681257538

Full URL: https://github.com/mbedmicro/mbed/commit/6c1d63e069ab9bd86de92e8296ca783681257538/

ignore target files not supported by the yotta module

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 514:7668256dbe61 1 /*******************************************************************************
mbed_official 514:7668256dbe61 2 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
mbed_official 514:7668256dbe61 3 *
mbed_official 514:7668256dbe61 4 * Permission is hereby granted, free of charge, to any person obtaining a
mbed_official 514:7668256dbe61 5 * copy of this software and associated documentation files (the "Software"),
mbed_official 514:7668256dbe61 6 * to deal in the Software without restriction, including without limitation
mbed_official 514:7668256dbe61 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
mbed_official 514:7668256dbe61 8 * and/or sell copies of the Software, and to permit persons to whom the
mbed_official 514:7668256dbe61 9 * Software is furnished to do so, subject to the following conditions:
mbed_official 514:7668256dbe61 10 *
mbed_official 514:7668256dbe61 11 * The above copyright notice and this permission notice shall be included
mbed_official 514:7668256dbe61 12 * in all copies or substantial portions of the Software.
mbed_official 514:7668256dbe61 13 *
mbed_official 514:7668256dbe61 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
mbed_official 514:7668256dbe61 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
mbed_official 514:7668256dbe61 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
mbed_official 514:7668256dbe61 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
mbed_official 514:7668256dbe61 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
mbed_official 514:7668256dbe61 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
mbed_official 514:7668256dbe61 20 * OTHER DEALINGS IN THE SOFTWARE.
mbed_official 514:7668256dbe61 21 *
mbed_official 514:7668256dbe61 22 * Except as contained in this notice, the name of Maxim Integrated
mbed_official 514:7668256dbe61 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
mbed_official 514:7668256dbe61 24 * Products, Inc. Branding Policy.
mbed_official 514:7668256dbe61 25 *
mbed_official 514:7668256dbe61 26 * The mere transfer of this software does not imply any licenses
mbed_official 514:7668256dbe61 27 * of trade secrets, proprietary technology, copyrights, patents,
mbed_official 514:7668256dbe61 28 * trademarks, maskwork rights, or any other form of intellectual
mbed_official 514:7668256dbe61 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
mbed_official 514:7668256dbe61 30 * ownership rights.
mbed_official 514:7668256dbe61 31 *******************************************************************************
mbed_official 514:7668256dbe61 32 */
mbed_official 536:c48d7048ab6e 33
mbed_official 514:7668256dbe61 34 #include "mbed_error.h"
mbed_official 514:7668256dbe61 35 #include "us_ticker_api.h"
mbed_official 514:7668256dbe61 36 #include "PeripheralNames.h"
mbed_official 514:7668256dbe61 37 #include "tmr_regs.h"
mbed_official 514:7668256dbe61 38
mbed_official 514:7668256dbe61 39 #define US_TIMER MXC_TMR0
mbed_official 514:7668256dbe61 40 #define US_TIMER_IRQn TMR0_IRQn
mbed_official 514:7668256dbe61 41
mbed_official 514:7668256dbe61 42 static int us_ticker_inited = 0;
mbed_official 514:7668256dbe61 43 static uint32_t ticks_per_us;
mbed_official 514:7668256dbe61 44 static uint32_t tick_win;
mbed_official 514:7668256dbe61 45 static volatile uint64_t current_cnt; // Hold the current ticks
mbed_official 514:7668256dbe61 46 static volatile uint64_t event_cnt; // Holds the value of the next event
mbed_official 514:7668256dbe61 47
mbed_official 514:7668256dbe61 48 #define ticks_to_us(ticks) ((ticks) / ticks_per_us);
mbed_official 514:7668256dbe61 49 #define MAX_TICK_VAL ((uint64_t)0xFFFFFFFF * ticks_per_us)
mbed_official 514:7668256dbe61 50
mbed_official 514:7668256dbe61 51 //******************************************************************************
mbed_official 514:7668256dbe61 52 static inline void inc_current_cnt(uint32_t inc) {
mbed_official 514:7668256dbe61 53
mbed_official 514:7668256dbe61 54 // Overflow the ticker when the us ticker overflows
mbed_official 514:7668256dbe61 55 current_cnt += inc;
mbed_official 536:c48d7048ab6e 56 if (current_cnt > MAX_TICK_VAL) {
mbed_official 514:7668256dbe61 57 current_cnt -= (MAX_TICK_VAL + 1);
mbed_official 514:7668256dbe61 58 }
mbed_official 514:7668256dbe61 59 }
mbed_official 514:7668256dbe61 60
mbed_official 514:7668256dbe61 61 //******************************************************************************
mbed_official 514:7668256dbe61 62 static inline int event_passed(uint64_t current, uint64_t event) {
mbed_official 514:7668256dbe61 63
mbed_official 514:7668256dbe61 64 // Determine if the event has already happened.
mbed_official 514:7668256dbe61 65 // If the event is behind the current ticker, within a window,
mbed_official 514:7668256dbe61 66 // then the event has already happened.
mbed_official 536:c48d7048ab6e 67 if (((current < tick_win) && ((event < current) ||
mbed_official 514:7668256dbe61 68 (event > (MAX_TICK_VAL - (tick_win - current))))) ||
mbed_official 514:7668256dbe61 69 ((event < current) && (event > (current - tick_win)))) {
mbed_official 514:7668256dbe61 70 return 1;
mbed_official 514:7668256dbe61 71 }
mbed_official 514:7668256dbe61 72
mbed_official 514:7668256dbe61 73 return 0;
mbed_official 514:7668256dbe61 74 }
mbed_official 514:7668256dbe61 75
mbed_official 514:7668256dbe61 76 //******************************************************************************
mbed_official 514:7668256dbe61 77 static inline uint64_t event_diff(uint64_t current, uint64_t event) {
mbed_official 514:7668256dbe61 78
mbed_official 514:7668256dbe61 79 // Check to see if the ticker will overflow before the event
mbed_official 514:7668256dbe61 80 if(current <= event) {
mbed_official 514:7668256dbe61 81 return (event - current);
mbed_official 514:7668256dbe61 82 }
mbed_official 514:7668256dbe61 83
mbed_official 514:7668256dbe61 84 return ((MAX_TICK_VAL - current) + event);
mbed_official 514:7668256dbe61 85 }
mbed_official 514:7668256dbe61 86
mbed_official 514:7668256dbe61 87 //******************************************************************************
mbed_official 514:7668256dbe61 88 static void tmr_handler(void)
mbed_official 514:7668256dbe61 89 {
mbed_official 514:7668256dbe61 90 uint32_t term_cnt32 = US_TIMER->term_cnt32;
mbed_official 514:7668256dbe61 91 US_TIMER->term_cnt32 = 0xFFFFFFFF; // reset to max value to prevent further interrupts
mbed_official 514:7668256dbe61 92 US_TIMER->intfl = (MXC_F_TMR_INTFL_TIMER0 | MXC_F_TMR_INTFL_TIMER1); // clear interrupt
mbed_official 514:7668256dbe61 93 NVIC_ClearPendingIRQ(US_TIMER_IRQn);
mbed_official 514:7668256dbe61 94
mbed_official 514:7668256dbe61 95 inc_current_cnt(term_cnt32);
mbed_official 514:7668256dbe61 96
mbed_official 514:7668256dbe61 97 if (event_passed(current_cnt + US_TIMER->count32, event_cnt )) {
mbed_official 514:7668256dbe61 98 // the timestamp has expired
mbed_official 515:7467ef1f4ad8 99 event_cnt = 0xFFFFFFFFFFFFFFFFULL; // reset to max value
mbed_official 514:7668256dbe61 100 us_ticker_irq_handler();
mbed_official 514:7668256dbe61 101 } else {
mbed_official 514:7668256dbe61 102
mbed_official 514:7668256dbe61 103 uint64_t diff = event_diff(current_cnt, event_cnt);
mbed_official 514:7668256dbe61 104 if (diff < (uint64_t)0xFFFFFFFF) {
mbed_official 514:7668256dbe61 105 // the event occurs before the next overflow
mbed_official 514:7668256dbe61 106 US_TIMER->term_cnt32 = diff;
mbed_official 514:7668256dbe61 107
mbed_official 514:7668256dbe61 108 // Since the timer keeps counting after the terminal value is reached, it is possible that the new
mbed_official 514:7668256dbe61 109 // terminal value is in the past.
mbed_official 514:7668256dbe61 110 if (US_TIMER->term_cnt32 < US_TIMER->count32) {
mbed_official 514:7668256dbe61 111 // the timestamp has expired
mbed_official 514:7668256dbe61 112 US_TIMER->term_cnt32 = 0xFFFFFFFF; // reset to max value to prevent further interrupts
mbed_official 514:7668256dbe61 113 US_TIMER->intfl = (MXC_F_TMR_INTFL_TIMER0 | MXC_F_TMR_INTFL_TIMER1); // clear interrupt
mbed_official 514:7668256dbe61 114 NVIC_ClearPendingIRQ(US_TIMER_IRQn);
mbed_official 515:7467ef1f4ad8 115 event_cnt = 0xFFFFFFFFFFFFFFFFULL; // reset to max value
mbed_official 514:7668256dbe61 116 us_ticker_irq_handler();
mbed_official 514:7668256dbe61 117 }
mbed_official 514:7668256dbe61 118 }
mbed_official 514:7668256dbe61 119 }
mbed_official 514:7668256dbe61 120 }
mbed_official 514:7668256dbe61 121
mbed_official 514:7668256dbe61 122 //******************************************************************************
mbed_official 514:7668256dbe61 123 void us_ticker_init(void)
mbed_official 514:7668256dbe61 124 {
mbed_official 514:7668256dbe61 125 if (us_ticker_inited)
mbed_official 514:7668256dbe61 126 return;
mbed_official 514:7668256dbe61 127 us_ticker_inited = 1;
mbed_official 514:7668256dbe61 128
mbed_official 514:7668256dbe61 129 current_cnt = 0;
mbed_official 515:7467ef1f4ad8 130 event_cnt = 0xFFFFFFFFFFFFFFFFULL; // reset to max value
mbed_official 514:7668256dbe61 131
mbed_official 514:7668256dbe61 132 if (SystemCoreClock <= 1000000) {
mbed_official 514:7668256dbe61 133 error("us_ticker cannot operate at this SystemCoreClock");
mbed_official 514:7668256dbe61 134 return;
mbed_official 514:7668256dbe61 135 }
mbed_official 514:7668256dbe61 136
mbed_official 514:7668256dbe61 137 // Configure timer for 32-bit continuous mode with /1 prescaler
mbed_official 514:7668256dbe61 138 US_TIMER->ctrl = MXC_E_TMR_MODE_CONTINUOUS << MXC_F_TMR_CTRL_MODE_POS | (0 << MXC_F_TMR_CTRL_PRESCALE_POS);
mbed_official 514:7668256dbe61 139 ticks_per_us = SystemCoreClock / 1000000;
mbed_official 514:7668256dbe61 140
mbed_official 514:7668256dbe61 141 // Set the tick window to 10ms
mbed_official 514:7668256dbe61 142 tick_win = SystemCoreClock/100;
mbed_official 514:7668256dbe61 143
mbed_official 514:7668256dbe61 144 // Set timer overflow to the max
mbed_official 514:7668256dbe61 145 US_TIMER->term_cnt32 = 0xFFFFFFFF;
mbed_official 514:7668256dbe61 146 US_TIMER->pwm_cap32 = 0xFFFFFFFF;
mbed_official 514:7668256dbe61 147 US_TIMER->count32 = 0;
mbed_official 514:7668256dbe61 148
mbed_official 514:7668256dbe61 149 US_TIMER->intfl = (MXC_F_TMR_INTFL_TIMER0 | MXC_F_TMR_INTFL_TIMER1); // clear pending interrupts
mbed_official 514:7668256dbe61 150
mbed_official 514:7668256dbe61 151 NVIC_SetVector(US_TIMER_IRQn, (uint32_t)tmr_handler);
mbed_official 514:7668256dbe61 152 NVIC_EnableIRQ(US_TIMER_IRQn);
mbed_official 514:7668256dbe61 153
mbed_official 514:7668256dbe61 154 US_TIMER->inten |= MXC_F_TMR_INTEN_TIMER0; // enable interrupts
mbed_official 514:7668256dbe61 155 US_TIMER->ctrl |= MXC_F_TMR_CTRL_ENABLE0; // enable timer
mbed_official 514:7668256dbe61 156 }
mbed_official 514:7668256dbe61 157
mbed_official 514:7668256dbe61 158 //******************************************************************************
mbed_official 514:7668256dbe61 159 void us_ticker_deinit(void)
mbed_official 514:7668256dbe61 160 {
mbed_official 514:7668256dbe61 161 US_TIMER->ctrl = 0; // disable timer
mbed_official 514:7668256dbe61 162 US_TIMER->inten = 0; // disable interrupts
mbed_official 514:7668256dbe61 163 US_TIMER->intfl = (MXC_F_TMR_INTFL_TIMER0 | MXC_F_TMR_INTFL_TIMER1); // clear interrupts
mbed_official 514:7668256dbe61 164 us_ticker_inited = 0;
mbed_official 514:7668256dbe61 165 }
mbed_official 514:7668256dbe61 166
mbed_official 514:7668256dbe61 167 //******************************************************************************
mbed_official 514:7668256dbe61 168 uint32_t us_ticker_read(void)
mbed_official 514:7668256dbe61 169 {
mbed_official 514:7668256dbe61 170 uint64_t current_cnt1, current_cnt2;
mbed_official 514:7668256dbe61 171 uint32_t term_cnt, tmr_cnt;
mbed_official 536:c48d7048ab6e 172 uint32_t intfl1, intfl2;
mbed_official 514:7668256dbe61 173
mbed_official 514:7668256dbe61 174 if (!us_ticker_inited)
mbed_official 514:7668256dbe61 175 us_ticker_init();
mbed_official 514:7668256dbe61 176
mbed_official 514:7668256dbe61 177 // Ensure coherency between current_cnt and US_TIMER->count32
mbed_official 514:7668256dbe61 178 do {
mbed_official 514:7668256dbe61 179 current_cnt1 = current_cnt;
mbed_official 514:7668256dbe61 180 intfl1 = US_TIMER->intfl;
mbed_official 514:7668256dbe61 181 term_cnt = US_TIMER->term_cnt32;
mbed_official 514:7668256dbe61 182 tmr_cnt = US_TIMER->count32;
mbed_official 514:7668256dbe61 183 intfl2 = US_TIMER->intfl;
mbed_official 514:7668256dbe61 184 current_cnt2 = current_cnt;
mbed_official 514:7668256dbe61 185 } while ((current_cnt1 != current_cnt2) || (intfl1 != intfl2));
mbed_official 514:7668256dbe61 186
mbed_official 536:c48d7048ab6e 187 // Account for an unserviced interrupt
mbed_official 514:7668256dbe61 188 if (intfl1) {
mbed_official 514:7668256dbe61 189 current_cnt1 += term_cnt;
mbed_official 514:7668256dbe61 190 }
mbed_official 514:7668256dbe61 191
mbed_official 514:7668256dbe61 192 current_cnt1 += tmr_cnt;
mbed_official 514:7668256dbe61 193
mbed_official 514:7668256dbe61 194 return (current_cnt1 / ticks_per_us);
mbed_official 514:7668256dbe61 195 }
mbed_official 514:7668256dbe61 196
mbed_official 514:7668256dbe61 197 //******************************************************************************
mbed_official 514:7668256dbe61 198 void us_ticker_set_interrupt(timestamp_t timestamp)
mbed_official 514:7668256dbe61 199 {
mbed_official 514:7668256dbe61 200 // Note: interrupts are disabled before this function is called.
mbed_official 536:c48d7048ab6e 201
mbed_official 514:7668256dbe61 202 US_TIMER->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0; // disable timer
mbed_official 514:7668256dbe61 203
mbed_official 514:7668256dbe61 204 if (US_TIMER->intfl) {
mbed_official 514:7668256dbe61 205 US_TIMER->intfl = (MXC_F_TMR_INTFL_TIMER0 | MXC_F_TMR_INTFL_TIMER1); // clear interrupt
mbed_official 514:7668256dbe61 206 NVIC_ClearPendingIRQ(US_TIMER_IRQn);
mbed_official 514:7668256dbe61 207 inc_current_cnt(US_TIMER->term_cnt32);
mbed_official 514:7668256dbe61 208 }
mbed_official 514:7668256dbe61 209
mbed_official 514:7668256dbe61 210 // add and reset the current count value
mbed_official 514:7668256dbe61 211 inc_current_cnt(US_TIMER->count32);
mbed_official 514:7668256dbe61 212 US_TIMER->count32 = 0;
mbed_official 514:7668256dbe61 213
mbed_official 514:7668256dbe61 214 // add the number of cycles that the timer is disabled here for
mbed_official 514:7668256dbe61 215 inc_current_cnt(200);
mbed_official 514:7668256dbe61 216
mbed_official 514:7668256dbe61 217 event_cnt = (uint64_t)timestamp * ticks_per_us;
mbed_official 514:7668256dbe61 218
mbed_official 514:7668256dbe61 219 // Check to see if the event has already passed
mbed_official 514:7668256dbe61 220 if (!event_passed(current_cnt, event_cnt)) {
mbed_official 514:7668256dbe61 221 uint64_t diff = event_diff(current_cnt, event_cnt);
mbed_official 514:7668256dbe61 222 if (diff < (uint64_t)0xFFFFFFFF) {
mbed_official 514:7668256dbe61 223 // the event occurs before the next overflow
mbed_official 514:7668256dbe61 224 US_TIMER->term_cnt32 = diff;
mbed_official 514:7668256dbe61 225 } else {
mbed_official 514:7668256dbe61 226 // the event occurs after the next overflow
mbed_official 514:7668256dbe61 227 US_TIMER->term_cnt32 = 0xFFFFFFFF; // set to max
mbed_official 514:7668256dbe61 228 }
mbed_official 514:7668256dbe61 229 } else {
mbed_official 514:7668256dbe61 230 // the requested timestamp occurs in the past
mbed_official 514:7668256dbe61 231 // set the timer up to immediately expire
mbed_official 514:7668256dbe61 232 US_TIMER->term_cnt32 = 1;
mbed_official 514:7668256dbe61 233 }
mbed_official 514:7668256dbe61 234 US_TIMER->ctrl |= MXC_F_TMR_CTRL_ENABLE0; // enable timer
mbed_official 514:7668256dbe61 235 }
mbed_official 514:7668256dbe61 236
mbed_official 514:7668256dbe61 237 //******************************************************************************
mbed_official 514:7668256dbe61 238 void us_ticker_disable_interrupt(void)
mbed_official 514:7668256dbe61 239 {
mbed_official 514:7668256dbe61 240 // There are no more events, set timer overflow to the max
mbed_official 514:7668256dbe61 241 US_TIMER->term_cnt32 = 0xFFFFFFFF;
mbed_official 514:7668256dbe61 242 }
mbed_official 514:7668256dbe61 243
mbed_official 514:7668256dbe61 244 //******************************************************************************
mbed_official 514:7668256dbe61 245 void us_ticker_clear_interrupt(void)
mbed_official 514:7668256dbe61 246 {
mbed_official 514:7668256dbe61 247 // cleared in the local handler
mbed_official 514:7668256dbe61 248 }
mbed_official 514:7668256dbe61 249
mbed_official 514:7668256dbe61 250 //******************************************************************************
mbed_official 514:7668256dbe61 251 void us_ticker_set(timestamp_t timestamp)
mbed_official 514:7668256dbe61 252 {
mbed_official 514:7668256dbe61 253 US_TIMER->ctrl &= ~MXC_F_TMR_CTRL_ENABLE0; // disable timer
mbed_official 514:7668256dbe61 254 current_cnt = (uint64_t)timestamp * ticks_per_us;
mbed_official 514:7668256dbe61 255 US_TIMER->count32 = 0;
mbed_official 514:7668256dbe61 256 US_TIMER->term_cnt32 = 0xFFFFFFFF;
mbed_official 514:7668256dbe61 257 US_TIMER->ctrl |= MXC_F_TMR_CTRL_ENABLE0; // enable timer
mbed_official 514:7668256dbe61 258
mbed_official 514:7668256dbe61 259 if (((uint64_t)timestamp * ticks_per_us) >= event_cnt) {
mbed_official 514:7668256dbe61 260 // The next timestamp has elapsed. Trigger the interrupt to handle it.
mbed_official 514:7668256dbe61 261 NVIC_SetPendingIRQ(US_TIMER_IRQn);
mbed_official 514:7668256dbe61 262 }
mbed_official 514:7668256dbe61 263 }