64 bit Timer Class.

Committer:
tedoyle
Date:
Sun Mar 27 20:18:44 2016 +0000
Revision:
1:497fba179833
Parent:
0:1e0e79e82839
Child:
2:e89b02820e93
bug fixes and code updates;

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 0:1e0e79e82839 66 return(TIMER64_ERROR_NOT_INITIALIZED);
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 0:1e0e79e82839 90 if (!_timerRunning)
tedoyle 0:1e0e79e82839 91 {
tedoyle 0:1e0e79e82839 92 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 93 _timerRunning = true;
tedoyle 0:1e0e79e82839 94 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 95 }
tedoyle 0:1e0e79e82839 96 else
tedoyle 0:1e0e79e82839 97 {
tedoyle 0:1e0e79e82839 98 return(TIMER64_WARNING_ALREADY_RUNNING);
tedoyle 0:1e0e79e82839 99 }
tedoyle 0:1e0e79e82839 100
tedoyle 0:1e0e79e82839 101 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 102 }
tedoyle 0:1e0e79e82839 103
tedoyle 0:1e0e79e82839 104 int Timer64::stop(void)
tedoyle 0:1e0e79e82839 105 {
tedoyle 0:1e0e79e82839 106 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 107 {
tedoyle 0:1e0e79e82839 108 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 109 }
tedoyle 0:1e0e79e82839 110
tedoyle 0:1e0e79e82839 111 if (_timerRunning)
tedoyle 0:1e0e79e82839 112 {
tedoyle 1:497fba179833 113 read_us();
tedoyle 0:1e0e79e82839 114 _timerRunning = false;
tedoyle 0:1e0e79e82839 115 _rollOverCheckTimer->stop();
tedoyle 0:1e0e79e82839 116 }
tedoyle 0:1e0e79e82839 117 else
tedoyle 0:1e0e79e82839 118 {
tedoyle 0:1e0e79e82839 119 return(TIMER64_WARNING_ALREADY_STOPPED);
tedoyle 0:1e0e79e82839 120 }
tedoyle 0:1e0e79e82839 121
tedoyle 0:1e0e79e82839 122 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 123 }
tedoyle 0:1e0e79e82839 124
tedoyle 0:1e0e79e82839 125 int Timer64::reset(void)
tedoyle 0:1e0e79e82839 126 {
tedoyle 0:1e0e79e82839 127 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 128 {
tedoyle 0:1e0e79e82839 129 return(TIMER64_ERROR_NOT_INITIALIZED);
tedoyle 0:1e0e79e82839 130 }
tedoyle 0:1e0e79e82839 131
tedoyle 0:1e0e79e82839 132 if (_timerRunning)
tedoyle 0:1e0e79e82839 133 {
tedoyle 0:1e0e79e82839 134 _tickerStartTimeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 135 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 136 }
tedoyle 0:1e0e79e82839 137
tedoyle 0:1e0e79e82839 138 _totalTimeUsec = 0L;
tedoyle 0:1e0e79e82839 139 return(TIMER64_OK);
tedoyle 0:1e0e79e82839 140 }
tedoyle 0:1e0e79e82839 141
tedoyle 0:1e0e79e82839 142 uint64_t Timer64::read_us(int* status)
tedoyle 0:1e0e79e82839 143 {
tedoyle 0:1e0e79e82839 144 if (!_timerInitialized)
tedoyle 0:1e0e79e82839 145 {
tedoyle 0:1e0e79e82839 146 if (status)
tedoyle 0:1e0e79e82839 147 {
tedoyle 0:1e0e79e82839 148 *status = TIMER64_ERROR_NOT_INITIALIZED;
tedoyle 0:1e0e79e82839 149 }
tedoyle 0:1e0e79e82839 150
tedoyle 0:1e0e79e82839 151 return(0L);
tedoyle 0:1e0e79e82839 152 }
tedoyle 0:1e0e79e82839 153
tedoyle 0:1e0e79e82839 154 if (_timerRunning)
tedoyle 0:1e0e79e82839 155 {
tedoyle 0:1e0e79e82839 156 timestamp_t ticker_current_timeUsec = ticker_read(_ticker_data);
tedoyle 0:1e0e79e82839 157
tedoyle 0:1e0e79e82839 158 // check for ticker time rollover
tedoyle 0:1e0e79e82839 159
tedoyle 0:1e0e79e82839 160 if (ticker_current_timeUsec >= _tickerStartTimeUsec)
tedoyle 0:1e0e79e82839 161 {
tedoyle 0:1e0e79e82839 162 _totalTimeUsec += (uint64_t)(ticker_current_timeUsec - _tickerStartTimeUsec);
tedoyle 0:1e0e79e82839 163 }
tedoyle 0:1e0e79e82839 164 else
tedoyle 0:1e0e79e82839 165 {
tedoyle 0:1e0e79e82839 166 // rollover!
tedoyle 0:1e0e79e82839 167 _totalTimeUsec += (4294967296L - ((uint64_t)_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec;
tedoyle 0:1e0e79e82839 168
tedoyle 0:1e0e79e82839 169 }
tedoyle 0:1e0e79e82839 170
tedoyle 1:497fba179833 171 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
tedoyle 0:1e0e79e82839 172 _tickerStartTimeUsec = ticker_current_timeUsec;
tedoyle 0:1e0e79e82839 173 }
tedoyle 0:1e0e79e82839 174
tedoyle 0:1e0e79e82839 175 return(_totalTimeUsec);
tedoyle 0:1e0e79e82839 176 }
tedoyle 0:1e0e79e82839 177
tedoyle 0:1e0e79e82839 178 uint64_t Timer64::read_ms(int* status)
tedoyle 0:1e0e79e82839 179 {
tedoyle 0:1e0e79e82839 180 return(read_us(status) / 1000L);
tedoyle 0:1e0e79e82839 181 }
tedoyle 0:1e0e79e82839 182
tedoyle 0:1e0e79e82839 183 double Timer64::read(int* status)
tedoyle 0:1e0e79e82839 184 {
tedoyle 0:1e0e79e82839 185 return((double)read_us(status) / 1000000.0L);
tedoyle 0:1e0e79e82839 186 }
tedoyle 0:1e0e79e82839 187
tedoyle 0:1e0e79e82839 188 void Timer64::_rollOverCheck(void const* args)
tedoyle 0:1e0e79e82839 189 {
tedoyle 0:1e0e79e82839 190 Timer64* timer = (Timer64*)args;
tedoyle 0:1e0e79e82839 191 timer->read_us();
tedoyle 0:1e0e79e82839 192 return;
tedoyle 0:1e0e79e82839 193 }