64 bit Timer Class.

Committer:
tedoyle
Date:
Sat Mar 26 21:44:41 2016 +0000
Revision:
0:1e0e79e82839
Child:
1:497fba179833
Updated;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tedoyle 0:1e0e79e82839 1 /*
tedoyle 0:1e0e79e82839 2 * Licensed under the Apache License, Version 2.0 (the "License");
tedoyle 0:1e0e79e82839 3 * you may not use this file except in compliance with the License.
tedoyle 0:1e0e79e82839 4 * You may obtain a copy of the License at
tedoyle 0:1e0e79e82839 5 *
tedoyle 0:1e0e79e82839 6 * http://www.apache.org/licenses/LICENSE-2.0
tedoyle 0:1e0e79e82839 7 *
tedoyle 0:1e0e79e82839 8 * Unless required by applicable law or agreed to in writing, software
tedoyle 0:1e0e79e82839 9 * distributed under the License is distributed on an "AS IS" BASIS,
tedoyle 0:1e0e79e82839 10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
tedoyle 0:1e0e79e82839 11 * See the License for the specific language governing permissions and
tedoyle 0:1e0e79e82839 12 * limitations under the License.
tedoyle 0:1e0e79e82839 13 */
tedoyle 0:1e0e79e82839 14
tedoyle 0:1e0e79e82839 15 #include "Timer64.h"
tedoyle 0:1e0e79e82839 16 #include "ticker_api.h"
tedoyle 0:1e0e79e82839 17 #include "us_ticker_api.h"
tedoyle 0:1e0e79e82839 18
tedoyle 0:1e0e79e82839 19 Timer64::Timer64() :
tedoyle 0:1e0e79e82839 20 _timerInitialized(false),
tedoyle 0:1e0e79e82839 21 _timerRunning(false),
tedoyle 0:1e0e79e82839 22 _tickerStartTimeUsec(0L),
tedoyle 0:1e0e79e82839 23 _totalTimeUsec(0L),
tedoyle 0:1e0e79e82839 24 _ticker_data(get_us_ticker_data()),
tedoyle 0:1e0e79e82839 25 _rollOverCheckTimer(NULL),
tedoyle 0:1e0e79e82839 26 _rollOverCheckTimerPeriodInMsec(TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 27 {
tedoyle 0:1e0e79e82839 28 reset();
tedoyle 0:1e0e79e82839 29 }
tedoyle 0:1e0e79e82839 30
tedoyle 0:1e0e79e82839 31 Timer64::Timer64(const ticker_data_t *data) :
tedoyle 0:1e0e79e82839 32 _timerInitialized(false),
tedoyle 0:1e0e79e82839 33 _timerRunning(false),
tedoyle 0:1e0e79e82839 34 _tickerStartTimeUsec(0L),
tedoyle 0:1e0e79e82839 35 _totalTimeUsec(0L),
tedoyle 0:1e0e79e82839 36 _ticker_data(data),
tedoyle 0:1e0e79e82839 37 _rollOverCheckTimer(NULL),
tedoyle 0:1e0e79e82839 38 _rollOverCheckTimerPeriodInMsec(TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 39 {
tedoyle 0:1e0e79e82839 40 reset();
tedoyle 0:1e0e79e82839 41 }
tedoyle 0:1e0e79e82839 42
tedoyle 0:1e0e79e82839 43 int Timer64::init(uint32_t rolloverCheckTimeInMsec)
tedoyle 0:1e0e79e82839 44 {
tedoyle 0:1e0e79e82839 45 if (_timerInitialized)
tedoyle 0:1e0e79e82839 46 {
tedoyle 0:1e0e79e82839 47 return(TIMER64_WARNING_ALREADY_INITIALIZED);
tedoyle 0:1e0e79e82839 48 }
tedoyle 0:1e0e79e82839 49
tedoyle 0:1e0e79e82839 50 if (rolloverCheckTimeInMsec < TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 51 {
tedoyle 0:1e0e79e82839 52 rolloverCheckTimeInMsec = TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS;
tedoyle 0:1e0e79e82839 53 }
tedoyle 0:1e0e79e82839 54 else if (rolloverCheckTimeInMsec > TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 55 {
tedoyle 0:1e0e79e82839 56 rolloverCheckTimeInMsec = TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS;
tedoyle 0:1e0e79e82839 57 }
tedoyle 0:1e0e79e82839 58
tedoyle 0:1e0e79e82839 59 _timerRunning = false;
tedoyle 0:1e0e79e82839 60 _tickerStartTimeUsec = 0L;
tedoyle 0:1e0e79e82839 61 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 62 _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec;
tedoyle 0:1e0e79e82839 63 _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this);
tedoyle 0:1e0e79e82839 64 _timerInitialized = true;
tedoyle 0:1e0e79e82839 65
tedoyle 0:1e0e79e82839 66 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 67 }
tedoyle 0:1e0e79e82839 68
tedoyle 0:1e0e79e82839 69 int Timer64::release(void)
tedoyle 0:1e0e79e82839 70 {
tedoyle 0:1e0e79e82839 71 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 72 {
tedoyle 0:1e0e79e82839 73 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 74 }
tedoyle 0:1e0e79e82839 75
tedoyle 0:1e0e79e82839 76 if (_timerRunning)
tedoyle 0:1e0e79e82839 77 {
tedoyle 0:1e0e79e82839 78 stop();
tedoyle 0:1e0e79e82839 79 }
tedoyle 0:1e0e79e82839 80
tedoyle 0:1e0e79e82839 81 _tickerStartTimeUsec = 0L;
tedoyle 0:1e0e79e82839 82 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 83 _timerInitialized = false;
tedoyle 0:1e0e79e82839 84 _rollOverCheckTimer->stop();
tedoyle 0:1e0e79e82839 85 delete _rollOverCheckTimer;
tedoyle 0:1e0e79e82839 86 _rollOverCheckTimer = NULL;
tedoyle 0:1e0e79e82839 87
tedoyle 0:1e0e79e82839 88 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 89 }
tedoyle 0:1e0e79e82839 90 int Timer64::start(void)
tedoyle 0:1e0e79e82839 91 {
tedoyle 0:1e0e79e82839 92 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 93 {
tedoyle 0:1e0e79e82839 94 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 95 }
tedoyle 0:1e0e79e82839 96
tedoyle 0:1e0e79e82839 97 if (!_timerRunning)
tedoyle 0:1e0e79e82839 98 {
tedoyle 0:1e0e79e82839 99 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 100 _timerRunning = true;
tedoyle 0:1e0e79e82839 101 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 102 }
tedoyle 0:1e0e79e82839 103 else
tedoyle 0:1e0e79e82839 104 {
tedoyle 0:1e0e79e82839 105 return(TIMER64_WARNING_ALREADY_RUNNING);
tedoyle 0:1e0e79e82839 106 }
tedoyle 0:1e0e79e82839 107
tedoyle 0:1e0e79e82839 108 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 109 }
tedoyle 0:1e0e79e82839 110
tedoyle 0:1e0e79e82839 111 int Timer64::stop(void)
tedoyle 0:1e0e79e82839 112 {
tedoyle 0:1e0e79e82839 113 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 114 {
tedoyle 0:1e0e79e82839 115 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 116 }
tedoyle 0:1e0e79e82839 117
tedoyle 0:1e0e79e82839 118 if (_timerRunning)
tedoyle 0:1e0e79e82839 119 {
tedoyle 0:1e0e79e82839 120 _timerRunning = false;
tedoyle 0:1e0e79e82839 121 _rollOverCheckTimer->stop();
tedoyle 0:1e0e79e82839 122 }
tedoyle 0:1e0e79e82839 123 else
tedoyle 0:1e0e79e82839 124 {
tedoyle 0:1e0e79e82839 125 return(TIMER64_WARNING_ALREADY_STOPPED);
tedoyle 0:1e0e79e82839 126 }
tedoyle 0:1e0e79e82839 127
tedoyle 0:1e0e79e82839 128 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 129 }
tedoyle 0:1e0e79e82839 130
tedoyle 0:1e0e79e82839 131 int Timer64::reset(void)
tedoyle 0:1e0e79e82839 132 {
tedoyle 0:1e0e79e82839 133 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 134 {
tedoyle 0:1e0e79e82839 135 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 136 }
tedoyle 0:1e0e79e82839 137
tedoyle 0:1e0e79e82839 138 if (_timerRunning)
tedoyle 0:1e0e79e82839 139 {
tedoyle 0:1e0e79e82839 140 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 141 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 142 }
tedoyle 0:1e0e79e82839 143
tedoyle 0:1e0e79e82839 144 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 145 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 146 }
tedoyle 0:1e0e79e82839 147
tedoyle 0:1e0e79e82839 148 uint64_t Timer64::read_us(int* status)
tedoyle 0:1e0e79e82839 149 {
tedoyle 0:1e0e79e82839 150 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 151 {
tedoyle 0:1e0e79e82839 152 if (status)
tedoyle 0:1e0e79e82839 153 {
tedoyle 0:1e0e79e82839 154 *status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 0:1e0e79e82839 155 }
tedoyle 0:1e0e79e82839 156
tedoyle 0:1e0e79e82839 157 return(0L);
tedoyle 0:1e0e79e82839 158 }
tedoyle 0:1e0e79e82839 159
tedoyle 0:1e0e79e82839 160 if (_timerRunning)
tedoyle 0:1e0e79e82839 161 {
tedoyle 0:1e0e79e82839 162 timestamp_t ticker_current_timeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 163
tedoyle 0:1e0e79e82839 164 // check for ticker time rollover
tedoyle 0:1e0e79e82839 165
tedoyle 0:1e0e79e82839 166 if (ticker_current_timeUsec >= _tickerStartTimeUsec)
tedoyle 0:1e0e79e82839 167 {
tedoyle 0:1e0e79e82839 168 _totalTimeUsec += (uint64_t)(ticker_current_timeUsec - _tickerStartTimeUsec);
tedoyle 0:1e0e79e82839 169 }
tedoyle 0:1e0e79e82839 170 else
tedoyle 0:1e0e79e82839 171 {
tedoyle 0:1e0e79e82839 172 // rollover!
tedoyle 0:1e0e79e82839 173 _totalTimeUsec += (4294967296L - ((uint64_t)_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec;
tedoyle 0:1e0e79e82839 174
tedoyle 0:1e0e79e82839 175 }
tedoyle 0:1e0e79e82839 176
tedoyle 0:1e0e79e82839 177 _tickerStartTimeUsec = ticker_current_timeUsec;
tedoyle 0:1e0e79e82839 178 }
tedoyle 0:1e0e79e82839 179
tedoyle 0:1e0e79e82839 180 return(_totalTimeUsec);
tedoyle 0:1e0e79e82839 181 }
tedoyle 0:1e0e79e82839 182
tedoyle 0:1e0e79e82839 183 uint64_t Timer64::read_ms(int* status)
tedoyle 0:1e0e79e82839 184 {
tedoyle 0:1e0e79e82839 185 return(read_us(status) / 1000L);
tedoyle 0:1e0e79e82839 186 }
tedoyle 0:1e0e79e82839 187
tedoyle 0:1e0e79e82839 188 double Timer64::read(int* status)
tedoyle 0:1e0e79e82839 189 {
tedoyle 0:1e0e79e82839 190 return((double)read_us(status) / 1000000.0L);
tedoyle 0:1e0e79e82839 191 }
tedoyle 0:1e0e79e82839 192
tedoyle 0:1e0e79e82839 193 #ifdef MBED_OPERATORS
tedoyle 0:1e0e79e82839 194 Timer64::operator double()
tedoyle 0:1e0e79e82839 195 {
tedoyle 0:1e0e79e82839 196 return read();
tedoyle 0:1e0e79e82839 197 }
tedoyle 0:1e0e79e82839 198
tedoyle 0:1e0e79e82839 199 Timer64::operator uint64_t()
tedoyle 0:1e0e79e82839 200 {
tedoyle 0:1e0e79e82839 201 return read_us();
tedoyle 0:1e0e79e82839 202 }
tedoyle 0:1e0e79e82839 203
tedoyle 0:1e0e79e82839 204 Timer64::operator uint32_t()
tedoyle 0:1e0e79e82839 205 {
tedoyle 0:1e0e79e82839 206 return read_us();
tedoyle 0:1e0e79e82839 207 }
tedoyle 0:1e0e79e82839 208 #endif
tedoyle 0:1e0e79e82839 209
tedoyle 0:1e0e79e82839 210 void Timer64::_rollOverCheck(void const* args)
tedoyle 0:1e0e79e82839 211 {
tedoyle 0:1e0e79e82839 212 Timer64* timer = (Timer64*)args;
tedoyle 0:1e0e79e82839 213 timer->read_us();
tedoyle 0:1e0e79e82839 214 return;
tedoyle 0:1e0e79e82839 215 }