64 bit Timer Class.

Committer:
tedoyle
Date:
Fri Apr 01 16:26:49 2016 +0000
Revision:
6:100cf27b43aa
Parent:
3:8396d3e6eb62
?

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 3:8396d3e6eb62 26 _rollOverCheckTimerPeriodInMsec(TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS),
tedoyle 3:8396d3e6eb62 27 _sem(NULL)
tedoyle 0:1e0e79e82839 28 {
tedoyle 3:8396d3e6eb62 29 ;
tedoyle 0:1e0e79e82839 30 }
tedoyle 0:1e0e79e82839 31
tedoyle 1:497fba179833 32 Timer64::~Timer64()
tedoyle 0:1e0e79e82839 33 {
tedoyle 1:497fba179833 34 release();
tedoyle 0:1e0e79e82839 35 }
tedoyle 0:1e0e79e82839 36
tedoyle 0:1e0e79e82839 37 int Timer64::init(uint32_t rolloverCheckTimeInMsec)
tedoyle 0:1e0e79e82839 38 {
tedoyle 0:1e0e79e82839 39 if (_timerInitialized)
tedoyle 0:1e0e79e82839 40 {
tedoyle 0:1e0e79e82839 41 return(TIMER64_WARNING_ALREADY_INITIALIZED);
tedoyle 0:1e0e79e82839 42 }
tedoyle 0:1e0e79e82839 43
tedoyle 0:1e0e79e82839 44 if (rolloverCheckTimeInMsec < TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 45 {
tedoyle 0:1e0e79e82839 46 rolloverCheckTimeInMsec = TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS;
tedoyle 0:1e0e79e82839 47 }
tedoyle 0:1e0e79e82839 48 else if (rolloverCheckTimeInMsec > TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 49 {
tedoyle 0:1e0e79e82839 50 rolloverCheckTimeInMsec = TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS;
tedoyle 0:1e0e79e82839 51 }
tedoyle 0:1e0e79e82839 52
tedoyle 0:1e0e79e82839 53 _timerRunning = false;
tedoyle 0:1e0e79e82839 54 _tickerStartTimeUsec = 0L;
tedoyle 0:1e0e79e82839 55 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 56 _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec;
tedoyle 0:1e0e79e82839 57 _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this);
tedoyle 3:8396d3e6eb62 58 _sem = new Semaphore(1);
tedoyle 0:1e0e79e82839 59 _timerInitialized = true;
tedoyle 0:1e0e79e82839 60
tedoyle 0:1e0e79e82839 61 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 62 }
tedoyle 0:1e0e79e82839 63
tedoyle 0:1e0e79e82839 64 int Timer64::release(void)
tedoyle 0:1e0e79e82839 65 {
tedoyle 0:1e0e79e82839 66 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 67 {
tedoyle 2:e89b02820e93 68 return(TIMER64_WARNING_ALREADY_RELEASED);
tedoyle 0:1e0e79e82839 69 }
tedoyle 0:1e0e79e82839 70
tedoyle 0:1e0e79e82839 71 if (_timerRunning)
tedoyle 0:1e0e79e82839 72 {
tedoyle 0:1e0e79e82839 73 stop();
tedoyle 0:1e0e79e82839 74 }
tedoyle 0:1e0e79e82839 75
tedoyle 0:1e0e79e82839 76 _tickerStartTimeUsec = 0L;
tedoyle 0:1e0e79e82839 77 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 78 _timerInitialized = false;
tedoyle 0:1e0e79e82839 79 _rollOverCheckTimer->stop();
tedoyle 0:1e0e79e82839 80 delete _rollOverCheckTimer;
tedoyle 0:1e0e79e82839 81 _rollOverCheckTimer = NULL;
tedoyle 3:8396d3e6eb62 82 delete _sem;
tedoyle 3:8396d3e6eb62 83 _sem = NULL;
tedoyle 0:1e0e79e82839 84
tedoyle 0:1e0e79e82839 85 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 86 }
tedoyle 3:8396d3e6eb62 87
tedoyle 0:1e0e79e82839 88 int Timer64::start(void)
tedoyle 0:1e0e79e82839 89 {
tedoyle 3:8396d3e6eb62 90 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 91
tedoyle 3:8396d3e6eb62 92 _sem->wait();
tedoyle 0:1e0e79e82839 93 {
tedoyle 3:8396d3e6eb62 94 if (!_timerInitialized)
tedoyle 3:8396d3e6eb62 95 {
tedoyle 3:8396d3e6eb62 96 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 3:8396d3e6eb62 97 }
tedoyle 3:8396d3e6eb62 98 else if (_timerRunning)
tedoyle 3:8396d3e6eb62 99 {
tedoyle 3:8396d3e6eb62 100 status = TIMER64_WARNING_ALREADY_RUNNING;
tedoyle 3:8396d3e6eb62 101 }
tedoyle 3:8396d3e6eb62 102 else
tedoyle 3:8396d3e6eb62 103 {
tedoyle 3:8396d3e6eb62 104 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 3:8396d3e6eb62 105 _timerRunning = true;
tedoyle 3:8396d3e6eb62 106 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 3:8396d3e6eb62 107 }
tedoyle 0:1e0e79e82839 108 }
tedoyle 3:8396d3e6eb62 109 _sem->release();
tedoyle 3:8396d3e6eb62 110
tedoyle 3:8396d3e6eb62 111 return(status);
tedoyle 0:1e0e79e82839 112 }
tedoyle 0:1e0e79e82839 113
tedoyle 0:1e0e79e82839 114 int Timer64::stop(void)
tedoyle 0:1e0e79e82839 115 {
tedoyle 3:8396d3e6eb62 116 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 117
tedoyle 3:8396d3e6eb62 118 _sem->wait();
tedoyle 0:1e0e79e82839 119 {
tedoyle 3:8396d3e6eb62 120 if (!_timerInitialized)
tedoyle 3:8396d3e6eb62 121 {
tedoyle 3:8396d3e6eb62 122 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 3:8396d3e6eb62 123 }
tedoyle 3:8396d3e6eb62 124 else if (!_timerRunning)
tedoyle 3:8396d3e6eb62 125 {
tedoyle 3:8396d3e6eb62 126 status = TIMER64_WARNING_ALREADY_STOPPED;
tedoyle 3:8396d3e6eb62 127 }
tedoyle 3:8396d3e6eb62 128 else
tedoyle 3:8396d3e6eb62 129 {
tedoyle 3:8396d3e6eb62 130 _read_us(this);
tedoyle 3:8396d3e6eb62 131 _timerRunning = false;
tedoyle 3:8396d3e6eb62 132 _rollOverCheckTimer->stop();
tedoyle 3:8396d3e6eb62 133 }
tedoyle 0:1e0e79e82839 134 }
tedoyle 3:8396d3e6eb62 135 _sem->release();
tedoyle 0:1e0e79e82839 136
tedoyle 3:8396d3e6eb62 137 return(status);
tedoyle 0:1e0e79e82839 138 }
tedoyle 0:1e0e79e82839 139
tedoyle 0:1e0e79e82839 140 int Timer64::reset(void)
tedoyle 0:1e0e79e82839 141 {
tedoyle 3:8396d3e6eb62 142 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 143
tedoyle 3:8396d3e6eb62 144 _sem->wait();
tedoyle 0:1e0e79e82839 145 {
tedoyle 3:8396d3e6eb62 146 if (!_timerInitialized)
tedoyle 3:8396d3e6eb62 147 {
tedoyle 3:8396d3e6eb62 148 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 3:8396d3e6eb62 149 }
tedoyle 3:8396d3e6eb62 150 else
tedoyle 3:8396d3e6eb62 151 {
tedoyle 3:8396d3e6eb62 152 if (_timerRunning)
tedoyle 3:8396d3e6eb62 153 {
tedoyle 3:8396d3e6eb62 154 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 3:8396d3e6eb62 155 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 3:8396d3e6eb62 156 }
tedoyle 3:8396d3e6eb62 157
tedoyle 3:8396d3e6eb62 158 _totalTimeUsec = 0L;
tedoyle 3:8396d3e6eb62 159 }
tedoyle 0:1e0e79e82839 160 }
tedoyle 3:8396d3e6eb62 161 _sem->release();
tedoyle 0:1e0e79e82839 162
tedoyle 3:8396d3e6eb62 163 return(status);
tedoyle 0:1e0e79e82839 164 }
tedoyle 0:1e0e79e82839 165
tedoyle 3:8396d3e6eb62 166 int Timer64::read_us(uint64_t* timeInUsec)
tedoyle 0:1e0e79e82839 167 {
tedoyle 3:8396d3e6eb62 168 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 169
tedoyle 3:8396d3e6eb62 170 _sem->wait();
tedoyle 0:1e0e79e82839 171 {
tedoyle 3:8396d3e6eb62 172 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 173 {
tedoyle 3:8396d3e6eb62 174 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 0:1e0e79e82839 175 }
tedoyle 0:1e0e79e82839 176 else
tedoyle 0:1e0e79e82839 177 {
tedoyle 3:8396d3e6eb62 178 if (_timerRunning)
tedoyle 3:8396d3e6eb62 179 {
tedoyle 3:8396d3e6eb62 180 *timeInUsec = _read_us(this);
tedoyle 3:8396d3e6eb62 181 }
tedoyle 3:8396d3e6eb62 182 else
tedoyle 3:8396d3e6eb62 183 {
tedoyle 3:8396d3e6eb62 184 *timeInUsec = _totalTimeUsec;
tedoyle 3:8396d3e6eb62 185 }
tedoyle 0:1e0e79e82839 186 }
tedoyle 3:8396d3e6eb62 187 }
tedoyle 3:8396d3e6eb62 188 _sem->release();
tedoyle 3:8396d3e6eb62 189
tedoyle 3:8396d3e6eb62 190 return(status);
tedoyle 0:1e0e79e82839 191 }
tedoyle 0:1e0e79e82839 192
tedoyle 3:8396d3e6eb62 193 int Timer64::read_ms(uint64_t* timeInMsec)
tedoyle 0:1e0e79e82839 194 {
tedoyle 3:8396d3e6eb62 195 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 196
tedoyle 3:8396d3e6eb62 197 _sem->wait();
tedoyle 3:8396d3e6eb62 198 {
tedoyle 3:8396d3e6eb62 199 if (!_timerInitialized)
tedoyle 3:8396d3e6eb62 200 {
tedoyle 3:8396d3e6eb62 201 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 3:8396d3e6eb62 202 }
tedoyle 3:8396d3e6eb62 203 else
tedoyle 3:8396d3e6eb62 204 {
tedoyle 3:8396d3e6eb62 205 if (_timerRunning)
tedoyle 3:8396d3e6eb62 206 {
tedoyle 3:8396d3e6eb62 207 *timeInMsec = _read_us(this)/1000L;
tedoyle 3:8396d3e6eb62 208 }
tedoyle 3:8396d3e6eb62 209 else
tedoyle 3:8396d3e6eb62 210 {
tedoyle 3:8396d3e6eb62 211 *timeInMsec = _totalTimeUsec/1000L;
tedoyle 3:8396d3e6eb62 212 }
tedoyle 3:8396d3e6eb62 213 }
tedoyle 3:8396d3e6eb62 214 }
tedoyle 3:8396d3e6eb62 215 _sem->release();
tedoyle 3:8396d3e6eb62 216
tedoyle 3:8396d3e6eb62 217 return(status);
tedoyle 0:1e0e79e82839 218 }
tedoyle 0:1e0e79e82839 219
tedoyle 3:8396d3e6eb62 220 int Timer64::read(double* timeInSec)
tedoyle 0:1e0e79e82839 221 {
tedoyle 3:8396d3e6eb62 222 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 223
tedoyle 3:8396d3e6eb62 224 _sem->wait();
tedoyle 3:8396d3e6eb62 225 {
tedoyle 3:8396d3e6eb62 226 if (!_timerInitialized)
tedoyle 3:8396d3e6eb62 227 {
tedoyle 3:8396d3e6eb62 228 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 3:8396d3e6eb62 229 }
tedoyle 3:8396d3e6eb62 230 else
tedoyle 3:8396d3e6eb62 231 {
tedoyle 3:8396d3e6eb62 232 if (_timerRunning)
tedoyle 3:8396d3e6eb62 233 {
tedoyle 3:8396d3e6eb62 234 *timeInSec = (double)_read_us(this)/1000000.0L;
tedoyle 3:8396d3e6eb62 235 }
tedoyle 3:8396d3e6eb62 236 else
tedoyle 3:8396d3e6eb62 237 {
tedoyle 3:8396d3e6eb62 238 *timeInSec = (double)_totalTimeUsec/1000000.0L;
tedoyle 3:8396d3e6eb62 239 }
tedoyle 3:8396d3e6eb62 240 }
tedoyle 3:8396d3e6eb62 241 }
tedoyle 3:8396d3e6eb62 242 _sem->release();
tedoyle 3:8396d3e6eb62 243
tedoyle 3:8396d3e6eb62 244 return(status);
tedoyle 0:1e0e79e82839 245 }
tedoyle 0:1e0e79e82839 246
tedoyle 6:100cf27b43aa 247 int Timer64::isRunning(bool* running)
tedoyle 6:100cf27b43aa 248 {
tedoyle 6:100cf27b43aa 249 int status = TIMER64_OK;
tedoyle 6:100cf27b43aa 250
tedoyle 6:100cf27b43aa 251 _sem->wait();
tedoyle 6:100cf27b43aa 252 {
tedoyle 6:100cf27b43aa 253 if (!_timerInitialized)
tedoyle 6:100cf27b43aa 254 {
tedoyle 6:100cf27b43aa 255 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 6:100cf27b43aa 256 }
tedoyle 6:100cf27b43aa 257 else
tedoyle 6:100cf27b43aa 258 {
tedoyle 6:100cf27b43aa 259 *running = _timerRunning;
tedoyle 6:100cf27b43aa 260 }
tedoyle 6:100cf27b43aa 261 }
tedoyle 6:100cf27b43aa 262 _sem->release();
tedoyle 6:100cf27b43aa 263
tedoyle 6:100cf27b43aa 264 return(status);
tedoyle 6:100cf27b43aa 265 }
tedoyle 6:100cf27b43aa 266
tedoyle 0:1e0e79e82839 267 void Timer64::_rollOverCheck(void const* args)
tedoyle 0:1e0e79e82839 268 {
tedoyle 0:1e0e79e82839 269 Timer64* timer = (Timer64*)args;
tedoyle 3:8396d3e6eb62 270 timer->_read_us(timer);
tedoyle 0:1e0e79e82839 271 return;
tedoyle 0:1e0e79e82839 272 }
tedoyle 3:8396d3e6eb62 273
tedoyle 3:8396d3e6eb62 274 uint64_t Timer64::_read_us(void const* args)
tedoyle 3:8396d3e6eb62 275 {
tedoyle 3:8396d3e6eb62 276 Timer64* timer = (Timer64*)args;
tedoyle 3:8396d3e6eb62 277 timestamp_t ticker_current_timeUsec = ticker_read(timer->_ticker_data);
tedoyle 3:8396d3e6eb62 278
tedoyle 3:8396d3e6eb62 279 // check for ticker time rollover
tedoyle 3:8396d3e6eb62 280
tedoyle 3:8396d3e6eb62 281 if (ticker_current_timeUsec >= timer->_tickerStartTimeUsec)
tedoyle 3:8396d3e6eb62 282 {
tedoyle 3:8396d3e6eb62 283 timer->_totalTimeUsec += (uint64_t)(ticker_current_timeUsec - timer->_tickerStartTimeUsec);
tedoyle 3:8396d3e6eb62 284 }
tedoyle 3:8396d3e6eb62 285 else
tedoyle 3:8396d3e6eb62 286 {
tedoyle 3:8396d3e6eb62 287 // rollover!
tedoyle 3:8396d3e6eb62 288 timer->_totalTimeUsec += (4294967296L - ((uint64_t)timer->_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec;
tedoyle 3:8396d3e6eb62 289
tedoyle 3:8396d3e6eb62 290 }
tedoyle 3:8396d3e6eb62 291
tedoyle 3:8396d3e6eb62 292 timer->_rollOverCheckTimer->start(timer->_rollOverCheckTimerPeriodInMsec);
tedoyle 3:8396d3e6eb62 293 timer->_tickerStartTimeUsec = ticker_current_timeUsec;
tedoyle 3:8396d3e6eb62 294 return(timer->_totalTimeUsec);
tedoyle 3:8396d3e6eb62 295 }
tedoyle 3:8396d3e6eb62 296