64 bit Timer Class.

Committer:
tedoyle
Date:
Sun Mar 27 20:44:54 2016 +0000
Revision:
2:e89b02820e93
Parent:
1:497fba179833
Child:
3:8396d3e6eb62
Reorganized code to make it easier to read.

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 1:497fba179833 31 Timer64::~Timer64()
tedoyle 0:1e0e79e82839 32 {
tedoyle 1:497fba179833 33 release();
tedoyle 0:1e0e79e82839 34 }
tedoyle 0:1e0e79e82839 35
tedoyle 0:1e0e79e82839 36 int Timer64::init(uint32_t rolloverCheckTimeInMsec)
tedoyle 0:1e0e79e82839 37 {
tedoyle 0:1e0e79e82839 38 if (_timerInitialized)
tedoyle 0:1e0e79e82839 39 {
tedoyle 0:1e0e79e82839 40 return(TIMER64_WARNING_ALREADY_INITIALIZED);
tedoyle 0:1e0e79e82839 41 }
tedoyle 0:1e0e79e82839 42
tedoyle 0:1e0e79e82839 43 if (rolloverCheckTimeInMsec < TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 44 {
tedoyle 0:1e0e79e82839 45 rolloverCheckTimeInMsec = TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS;
tedoyle 0:1e0e79e82839 46 }
tedoyle 0:1e0e79e82839 47 else if (rolloverCheckTimeInMsec > TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS)
tedoyle 0:1e0e79e82839 48 {
tedoyle 0:1e0e79e82839 49 rolloverCheckTimeInMsec = TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS;
tedoyle 0:1e0e79e82839 50 }
tedoyle 0:1e0e79e82839 51
tedoyle 0:1e0e79e82839 52 _timerRunning = false;
tedoyle 0:1e0e79e82839 53 _tickerStartTimeUsec = 0L;
tedoyle 0:1e0e79e82839 54 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 55 _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec;
tedoyle 0:1e0e79e82839 56 _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this);
tedoyle 0:1e0e79e82839 57 _timerInitialized = true;
tedoyle 0:1e0e79e82839 58
tedoyle 0:1e0e79e82839 59 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 60 }
tedoyle 0:1e0e79e82839 61
tedoyle 0:1e0e79e82839 62 int Timer64::release(void)
tedoyle 0:1e0e79e82839 63 {
tedoyle 0:1e0e79e82839 64 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 65 {
tedoyle 2:e89b02820e93 66 return(TIMER64_WARNING_ALREADY_RELEASED);
tedoyle 0:1e0e79e82839 67 }
tedoyle 0:1e0e79e82839 68
tedoyle 0:1e0e79e82839 69 if (_timerRunning)
tedoyle 0:1e0e79e82839 70 {
tedoyle 0:1e0e79e82839 71 stop();
tedoyle 0:1e0e79e82839 72 }
tedoyle 0:1e0e79e82839 73
tedoyle 0:1e0e79e82839 74 _tickerStartTimeUsec = 0L;
tedoyle 0:1e0e79e82839 75 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 76 _timerInitialized = false;
tedoyle 0:1e0e79e82839 77 _rollOverCheckTimer->stop();
tedoyle 0:1e0e79e82839 78 delete _rollOverCheckTimer;
tedoyle 0:1e0e79e82839 79 _rollOverCheckTimer = NULL;
tedoyle 0:1e0e79e82839 80
tedoyle 0:1e0e79e82839 81 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 82 }
tedoyle 0:1e0e79e82839 83 int Timer64::start(void)
tedoyle 0:1e0e79e82839 84 {
tedoyle 0:1e0e79e82839 85 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 86 {
tedoyle 0:1e0e79e82839 87 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 88 }
tedoyle 0:1e0e79e82839 89
tedoyle 2:e89b02820e93 90 if (_timerRunning)
tedoyle 0:1e0e79e82839 91 {
tedoyle 0:1e0e79e82839 92 return(TIMER64_WARNING_ALREADY_RUNNING);
tedoyle 0:1e0e79e82839 93 }
tedoyle 2:e89b02820e93 94
tedoyle 2:e89b02820e93 95 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 2:e89b02820e93 96 _timerRunning = true;
tedoyle 2:e89b02820e93 97 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 98 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 99 }
tedoyle 0:1e0e79e82839 100
tedoyle 0:1e0e79e82839 101 int Timer64::stop(void)
tedoyle 0:1e0e79e82839 102 {
tedoyle 0:1e0e79e82839 103 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 104 {
tedoyle 0:1e0e79e82839 105 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 106 }
tedoyle 0:1e0e79e82839 107
tedoyle 2:e89b02820e93 108 if (!_timerRunning)
tedoyle 0:1e0e79e82839 109 {
tedoyle 0:1e0e79e82839 110 return(TIMER64_WARNING_ALREADY_STOPPED);
tedoyle 0:1e0e79e82839 111 }
tedoyle 2:e89b02820e93 112
tedoyle 2:e89b02820e93 113 read_us();
tedoyle 2:e89b02820e93 114 _timerRunning = false;
tedoyle 2:e89b02820e93 115 _rollOverCheckTimer->stop();
tedoyle 0:1e0e79e82839 116
tedoyle 0:1e0e79e82839 117 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 118 }
tedoyle 0:1e0e79e82839 119
tedoyle 0:1e0e79e82839 120 int Timer64::reset(void)
tedoyle 0:1e0e79e82839 121 {
tedoyle 0:1e0e79e82839 122 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 123 {
tedoyle 0:1e0e79e82839 124 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 125 }
tedoyle 0:1e0e79e82839 126
tedoyle 0:1e0e79e82839 127 if (_timerRunning)
tedoyle 0:1e0e79e82839 128 {
tedoyle 0:1e0e79e82839 129 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 130 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 131 }
tedoyle 0:1e0e79e82839 132
tedoyle 0:1e0e79e82839 133 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 134 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 135 }
tedoyle 0:1e0e79e82839 136
tedoyle 0:1e0e79e82839 137 uint64_t Timer64::read_us(int* status)
tedoyle 0:1e0e79e82839 138 {
tedoyle 0:1e0e79e82839 139 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 140 {
tedoyle 0:1e0e79e82839 141 if (status)
tedoyle 0:1e0e79e82839 142 {
tedoyle 0:1e0e79e82839 143 *status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 0:1e0e79e82839 144 }
tedoyle 0:1e0e79e82839 145
tedoyle 0:1e0e79e82839 146 return(0L);
tedoyle 0:1e0e79e82839 147 }
tedoyle 0:1e0e79e82839 148
tedoyle 0:1e0e79e82839 149 if (_timerRunning)
tedoyle 0:1e0e79e82839 150 {
tedoyle 0:1e0e79e82839 151 timestamp_t ticker_current_timeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 152
tedoyle 0:1e0e79e82839 153 // check for ticker time rollover
tedoyle 0:1e0e79e82839 154
tedoyle 0:1e0e79e82839 155 if (ticker_current_timeUsec >= _tickerStartTimeUsec)
tedoyle 0:1e0e79e82839 156 {
tedoyle 0:1e0e79e82839 157 _totalTimeUsec += (uint64_t)(ticker_current_timeUsec - _tickerStartTimeUsec);
tedoyle 0:1e0e79e82839 158 }
tedoyle 0:1e0e79e82839 159 else
tedoyle 0:1e0e79e82839 160 {
tedoyle 0:1e0e79e82839 161 // rollover!
tedoyle 0:1e0e79e82839 162 _totalTimeUsec += (4294967296L - ((uint64_t)_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec;
tedoyle 0:1e0e79e82839 163
tedoyle 0:1e0e79e82839 164 }
tedoyle 0:1e0e79e82839 165
tedoyle 1:497fba179833 166 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 167 _tickerStartTimeUsec = ticker_current_timeUsec;
tedoyle 0:1e0e79e82839 168 }
tedoyle 0:1e0e79e82839 169
tedoyle 0:1e0e79e82839 170 return(_totalTimeUsec);
tedoyle 0:1e0e79e82839 171 }
tedoyle 0:1e0e79e82839 172
tedoyle 0:1e0e79e82839 173 uint64_t Timer64::read_ms(int* status)
tedoyle 0:1e0e79e82839 174 {
tedoyle 0:1e0e79e82839 175 return(read_us(status) / 1000L);
tedoyle 0:1e0e79e82839 176 }
tedoyle 0:1e0e79e82839 177
tedoyle 0:1e0e79e82839 178 double Timer64::read(int* status)
tedoyle 0:1e0e79e82839 179 {
tedoyle 0:1e0e79e82839 180 return((double)read_us(status) / 1000000.0L);
tedoyle 0:1e0e79e82839 181 }
tedoyle 0:1e0e79e82839 182
tedoyle 0:1e0e79e82839 183 void Timer64::_rollOverCheck(void const* args)
tedoyle 0:1e0e79e82839 184 {
tedoyle 0:1e0e79e82839 185 Timer64* timer = (Timer64*)args;
tedoyle 0:1e0e79e82839 186 timer->read_us();
tedoyle 0:1e0e79e82839 187 return;
tedoyle 0:1e0e79e82839 188 }