64 bit Timer Class.

Committer:
tedoyle
Date:
Tue Apr 05 19:07:09 2016 +0000
Revision:
8:5d17ff4f9c23
Parent:
4:9ca673a83acb
Updated constants to accurately reflect unsigned values

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 8:5d17ff4f9c23 22 _tickerStartTimeUsec(0u),
tedoyle 8:5d17ff4f9c23 23 _totalTimeUsec(0llu),
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 8:5d17ff4f9c23 54 _tickerStartTimeUsec = 0u;
tedoyle 8:5d17ff4f9c23 55 _totalTimeUsec = 0llu;
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 8:5d17ff4f9c23 76 _tickerStartTimeUsec = 0u;
tedoyle 8:5d17ff4f9c23 77 _totalTimeUsec = 0llu;
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 8:5d17ff4f9c23 158 _totalTimeUsec = 0llu;
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 4:9ca673a83acb 176 else if (timeInUsec == NULL)
tedoyle 4:9ca673a83acb 177 {
tedoyle 4:9ca673a83acb 178 status = TIMER64_ERROR_NULL_POINTER;
tedoyle 4:9ca673a83acb 179 }
tedoyle 0:1e0e79e82839 180 else
tedoyle 0:1e0e79e82839 181 {
tedoyle 3:8396d3e6eb62 182 if (_timerRunning)
tedoyle 3:8396d3e6eb62 183 {
tedoyle 3:8396d3e6eb62 184 *timeInUsec = _read_us(this);
tedoyle 3:8396d3e6eb62 185 }
tedoyle 3:8396d3e6eb62 186 else
tedoyle 3:8396d3e6eb62 187 {
tedoyle 3:8396d3e6eb62 188 *timeInUsec = _totalTimeUsec;
tedoyle 3:8396d3e6eb62 189 }
tedoyle 0:1e0e79e82839 190 }
tedoyle 3:8396d3e6eb62 191 }
tedoyle 3:8396d3e6eb62 192 _sem->release();
tedoyle 3:8396d3e6eb62 193
tedoyle 3:8396d3e6eb62 194 return(status);
tedoyle 0:1e0e79e82839 195 }
tedoyle 0:1e0e79e82839 196
tedoyle 3:8396d3e6eb62 197 int Timer64::read_ms(uint64_t* timeInMsec)
tedoyle 0:1e0e79e82839 198 {
tedoyle 3:8396d3e6eb62 199 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 200
tedoyle 3:8396d3e6eb62 201 _sem->wait();
tedoyle 3:8396d3e6eb62 202 {
tedoyle 3:8396d3e6eb62 203 if (!_timerInitialized)
tedoyle 3:8396d3e6eb62 204 {
tedoyle 3:8396d3e6eb62 205 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 3:8396d3e6eb62 206 }
tedoyle 4:9ca673a83acb 207 else if (timeInMsec == NULL)
tedoyle 4:9ca673a83acb 208 {
tedoyle 4:9ca673a83acb 209 status = TIMER64_ERROR_NULL_POINTER;
tedoyle 4:9ca673a83acb 210 }
tedoyle 3:8396d3e6eb62 211 else
tedoyle 3:8396d3e6eb62 212 {
tedoyle 3:8396d3e6eb62 213 if (_timerRunning)
tedoyle 3:8396d3e6eb62 214 {
tedoyle 8:5d17ff4f9c23 215 *timeInMsec = _read_us(this)/1000LU;
tedoyle 3:8396d3e6eb62 216 }
tedoyle 3:8396d3e6eb62 217 else
tedoyle 3:8396d3e6eb62 218 {
tedoyle 8:5d17ff4f9c23 219 *timeInMsec = _totalTimeUsec/1000LU;
tedoyle 3:8396d3e6eb62 220 }
tedoyle 3:8396d3e6eb62 221 }
tedoyle 3:8396d3e6eb62 222 }
tedoyle 3:8396d3e6eb62 223 _sem->release();
tedoyle 3:8396d3e6eb62 224
tedoyle 3:8396d3e6eb62 225 return(status);
tedoyle 0:1e0e79e82839 226 }
tedoyle 0:1e0e79e82839 227
tedoyle 3:8396d3e6eb62 228 int Timer64::read(double* timeInSec)
tedoyle 0:1e0e79e82839 229 {
tedoyle 3:8396d3e6eb62 230 int status = TIMER64_OK;
tedoyle 3:8396d3e6eb62 231
tedoyle 3:8396d3e6eb62 232 _sem->wait();
tedoyle 3:8396d3e6eb62 233 {
tedoyle 3:8396d3e6eb62 234 if (!_timerInitialized)
tedoyle 3:8396d3e6eb62 235 {
tedoyle 3:8396d3e6eb62 236 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 3:8396d3e6eb62 237 }
tedoyle 4:9ca673a83acb 238 else if (timeInSec == NULL)
tedoyle 4:9ca673a83acb 239 {
tedoyle 4:9ca673a83acb 240 status = TIMER64_ERROR_NULL_POINTER;
tedoyle 4:9ca673a83acb 241 }
tedoyle 3:8396d3e6eb62 242 else
tedoyle 3:8396d3e6eb62 243 {
tedoyle 3:8396d3e6eb62 244 if (_timerRunning)
tedoyle 3:8396d3e6eb62 245 {
tedoyle 3:8396d3e6eb62 246 *timeInSec = (double)_read_us(this)/1000000.0L;
tedoyle 3:8396d3e6eb62 247 }
tedoyle 3:8396d3e6eb62 248 else
tedoyle 3:8396d3e6eb62 249 {
tedoyle 3:8396d3e6eb62 250 *timeInSec = (double)_totalTimeUsec/1000000.0L;
tedoyle 3:8396d3e6eb62 251 }
tedoyle 3:8396d3e6eb62 252 }
tedoyle 3:8396d3e6eb62 253 }
tedoyle 3:8396d3e6eb62 254 _sem->release();
tedoyle 3:8396d3e6eb62 255
tedoyle 3:8396d3e6eb62 256 return(status);
tedoyle 0:1e0e79e82839 257 }
tedoyle 0:1e0e79e82839 258
tedoyle 4:9ca673a83acb 259 int Timer64::isRunning(bool* running)
tedoyle 4:9ca673a83acb 260 {
tedoyle 4:9ca673a83acb 261 int status = TIMER64_OK;
tedoyle 4:9ca673a83acb 262
tedoyle 4:9ca673a83acb 263 _sem->wait();
tedoyle 4:9ca673a83acb 264 {
tedoyle 4:9ca673a83acb 265 if (!_timerInitialized)
tedoyle 4:9ca673a83acb 266 {
tedoyle 4:9ca673a83acb 267 status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 4:9ca673a83acb 268 }
tedoyle 4:9ca673a83acb 269 else
tedoyle 4:9ca673a83acb 270 {
tedoyle 4:9ca673a83acb 271 *running = _timerRunning;
tedoyle 4:9ca673a83acb 272 }
tedoyle 4:9ca673a83acb 273 }
tedoyle 4:9ca673a83acb 274 _sem->release();
tedoyle 4:9ca673a83acb 275
tedoyle 4:9ca673a83acb 276 return(status);
tedoyle 4:9ca673a83acb 277 }
tedoyle 4:9ca673a83acb 278
tedoyle 0:1e0e79e82839 279 void Timer64::_rollOverCheck(void const* args)
tedoyle 0:1e0e79e82839 280 {
tedoyle 0:1e0e79e82839 281 Timer64* timer = (Timer64*)args;
tedoyle 3:8396d3e6eb62 282 timer->_read_us(timer);
tedoyle 0:1e0e79e82839 283 return;
tedoyle 0:1e0e79e82839 284 }
tedoyle 3:8396d3e6eb62 285
tedoyle 3:8396d3e6eb62 286 uint64_t Timer64::_read_us(void const* args)
tedoyle 3:8396d3e6eb62 287 {
tedoyle 3:8396d3e6eb62 288 Timer64* timer = (Timer64*)args;
tedoyle 3:8396d3e6eb62 289 timestamp_t ticker_current_timeUsec = ticker_read(timer->_ticker_data);
tedoyle 3:8396d3e6eb62 290
tedoyle 3:8396d3e6eb62 291 // check for ticker time rollover
tedoyle 3:8396d3e6eb62 292
tedoyle 3:8396d3e6eb62 293 if (ticker_current_timeUsec >= timer->_tickerStartTimeUsec)
tedoyle 3:8396d3e6eb62 294 {
tedoyle 3:8396d3e6eb62 295 timer->_totalTimeUsec += (uint64_t)(ticker_current_timeUsec - timer->_tickerStartTimeUsec);
tedoyle 3:8396d3e6eb62 296 }
tedoyle 3:8396d3e6eb62 297 else
tedoyle 3:8396d3e6eb62 298 {
tedoyle 3:8396d3e6eb62 299 // rollover!
tedoyle 8:5d17ff4f9c23 300 timer->_totalTimeUsec += (uint64_t)(4294967296U - timer->_tickerStartTimeUsec) + (uint64_t)ticker_current_timeUsec;
tedoyle 3:8396d3e6eb62 301
tedoyle 3:8396d3e6eb62 302 }
tedoyle 3:8396d3e6eb62 303
tedoyle 3:8396d3e6eb62 304 timer->_rollOverCheckTimer->start(timer->_rollOverCheckTimerPeriodInMsec);
tedoyle 3:8396d3e6eb62 305 timer->_tickerStartTimeUsec = ticker_current_timeUsec;
tedoyle 3:8396d3e6eb62 306 return(timer->_totalTimeUsec);
tedoyle 3:8396d3e6eb62 307 }
tedoyle 3:8396d3e6eb62 308