Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Timer64.cpp
00001 /* 00002 * Licensed under the Apache License, Version 2.0 (the "License"); 00003 * you may not use this file except in compliance with the License. 00004 * You may obtain a copy of the License at 00005 * 00006 * http://www.apache.org/licenses/LICENSE-2.0 00007 * 00008 * Unless required by applicable law or agreed to in writing, software 00009 * distributed under the License is distributed on an "AS IS" BASIS, 00010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00011 * See the License for the specific language governing permissions and 00012 * limitations under the License. 00013 */ 00014 00015 #include "Timer64.h" 00016 #include "ticker_api.h" 00017 #include "us_ticker_api.h" 00018 00019 Timer64::Timer64() : 00020 _timerInitialized(false), 00021 _timerRunning(false), 00022 _tickerStartTimeUsec(0u), 00023 _totalTimeUsec(0llu), 00024 _ticker_data(get_us_ticker_data()), 00025 _rollOverCheckTimer(NULL), 00026 _rollOverCheckTimerPeriodInMsec(TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS), 00027 _sem(NULL) 00028 { 00029 ; 00030 } 00031 00032 Timer64::~Timer64() 00033 { 00034 release(); 00035 } 00036 00037 int Timer64::init(uint32_t rolloverCheckTimeInMsec) 00038 { 00039 if (_timerInitialized) 00040 { 00041 return(TIMER64_WARNING_ALREADY_INITIALIZED); 00042 } 00043 00044 if (rolloverCheckTimeInMsec < TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS) 00045 { 00046 rolloverCheckTimeInMsec = TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS; 00047 } 00048 else if (rolloverCheckTimeInMsec > TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS) 00049 { 00050 rolloverCheckTimeInMsec = TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS; 00051 } 00052 00053 _timerRunning = false; 00054 _tickerStartTimeUsec = 0u; 00055 _totalTimeUsec = 0llu; 00056 _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec; 00057 _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this); 00058 _sem = new Semaphore(1); 00059 _timerInitialized = true; 00060 00061 return(TIMER64_OK); 00062 } 00063 00064 int Timer64::release(void) 00065 { 00066 if (!_timerInitialized) 00067 { 00068 return(TIMER64_WARNING_ALREADY_RELEASED); 00069 } 00070 00071 if (_timerRunning) 00072 { 00073 stop(); 00074 } 00075 00076 _tickerStartTimeUsec = 0u; 00077 _totalTimeUsec = 0llu; 00078 _timerInitialized = false; 00079 _rollOverCheckTimer->stop(); 00080 delete _rollOverCheckTimer; 00081 _rollOverCheckTimer = NULL; 00082 delete _sem; 00083 _sem = NULL; 00084 00085 return(TIMER64_OK); 00086 } 00087 00088 int Timer64::start(void) 00089 { 00090 int status = TIMER64_OK; 00091 00092 _sem->wait(); 00093 { 00094 if (!_timerInitialized) 00095 { 00096 status = TIMER64_ERROR_NOT_INITIALIZED; 00097 } 00098 else if (_timerRunning) 00099 { 00100 status = TIMER64_WARNING_ALREADY_RUNNING; 00101 } 00102 else 00103 { 00104 _tickerStartTimeUsec = ticker_read(_ticker_data); 00105 _timerRunning = true; 00106 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); 00107 } 00108 } 00109 _sem->release(); 00110 00111 return(status); 00112 } 00113 00114 int Timer64::stop(void) 00115 { 00116 int status = TIMER64_OK; 00117 00118 _sem->wait(); 00119 { 00120 if (!_timerInitialized) 00121 { 00122 status = TIMER64_ERROR_NOT_INITIALIZED; 00123 } 00124 else if (!_timerRunning) 00125 { 00126 status = TIMER64_WARNING_ALREADY_STOPPED; 00127 } 00128 else 00129 { 00130 _read_us(this); 00131 _timerRunning = false; 00132 _rollOverCheckTimer->stop(); 00133 } 00134 } 00135 _sem->release(); 00136 00137 return(status); 00138 } 00139 00140 int Timer64::reset(void) 00141 { 00142 int status = TIMER64_OK; 00143 00144 _sem->wait(); 00145 { 00146 if (!_timerInitialized) 00147 { 00148 status = TIMER64_ERROR_NOT_INITIALIZED; 00149 } 00150 else 00151 { 00152 if (_timerRunning) 00153 { 00154 _tickerStartTimeUsec = ticker_read(_ticker_data); 00155 _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); 00156 } 00157 00158 _totalTimeUsec = 0llu; 00159 } 00160 } 00161 _sem->release(); 00162 00163 return(status); 00164 } 00165 00166 int Timer64::read_us(uint64_t* timeInUsec) 00167 { 00168 int status = TIMER64_OK; 00169 00170 _sem->wait(); 00171 { 00172 if (!_timerInitialized) 00173 { 00174 status = TIMER64_ERROR_NOT_INITIALIZED; 00175 } 00176 else if (timeInUsec == NULL) 00177 { 00178 status = TIMER64_ERROR_NULL_POINTER; 00179 } 00180 else 00181 { 00182 if (_timerRunning) 00183 { 00184 *timeInUsec = _read_us(this); 00185 } 00186 else 00187 { 00188 *timeInUsec = _totalTimeUsec; 00189 } 00190 } 00191 } 00192 _sem->release(); 00193 00194 return(status); 00195 } 00196 00197 int Timer64::read_ms(uint64_t* timeInMsec) 00198 { 00199 int status = TIMER64_OK; 00200 00201 _sem->wait(); 00202 { 00203 if (!_timerInitialized) 00204 { 00205 status = TIMER64_ERROR_NOT_INITIALIZED; 00206 } 00207 else if (timeInMsec == NULL) 00208 { 00209 status = TIMER64_ERROR_NULL_POINTER; 00210 } 00211 else 00212 { 00213 if (_timerRunning) 00214 { 00215 *timeInMsec = _read_us(this)/1000LU; 00216 } 00217 else 00218 { 00219 *timeInMsec = _totalTimeUsec/1000LU; 00220 } 00221 } 00222 } 00223 _sem->release(); 00224 00225 return(status); 00226 } 00227 00228 int Timer64::read(double* timeInSec) 00229 { 00230 int status = TIMER64_OK; 00231 00232 _sem->wait(); 00233 { 00234 if (!_timerInitialized) 00235 { 00236 status = TIMER64_ERROR_NOT_INITIALIZED; 00237 } 00238 else if (timeInSec == NULL) 00239 { 00240 status = TIMER64_ERROR_NULL_POINTER; 00241 } 00242 else 00243 { 00244 if (_timerRunning) 00245 { 00246 *timeInSec = (double)_read_us(this)/1000000.0L; 00247 } 00248 else 00249 { 00250 *timeInSec = (double)_totalTimeUsec/1000000.0L; 00251 } 00252 } 00253 } 00254 _sem->release(); 00255 00256 return(status); 00257 } 00258 00259 int Timer64::isRunning(bool* running) 00260 { 00261 int status = TIMER64_OK; 00262 00263 _sem->wait(); 00264 { 00265 if (!_timerInitialized) 00266 { 00267 status = TIMER64_ERROR_NOT_INITIALIZED; 00268 } 00269 else 00270 { 00271 *running = _timerRunning; 00272 } 00273 } 00274 _sem->release(); 00275 00276 return(status); 00277 } 00278 00279 void Timer64::_rollOverCheck(void const* args) 00280 { 00281 Timer64* timer = (Timer64*)args; 00282 timer->_read_us(timer); 00283 return; 00284 } 00285 00286 uint64_t Timer64::_read_us(void const* args) 00287 { 00288 Timer64* timer = (Timer64*)args; 00289 timestamp_t ticker_current_timeUsec = ticker_read(timer->_ticker_data); 00290 00291 // check for ticker time rollover 00292 00293 if (ticker_current_timeUsec >= timer->_tickerStartTimeUsec) 00294 { 00295 timer->_totalTimeUsec += (uint64_t)(ticker_current_timeUsec - timer->_tickerStartTimeUsec); 00296 } 00297 else 00298 { 00299 // rollover! 00300 timer->_totalTimeUsec += (uint64_t)(4294967296U - timer->_tickerStartTimeUsec) + (uint64_t)ticker_current_timeUsec; 00301 00302 } 00303 00304 timer->_rollOverCheckTimer->start(timer->_rollOverCheckTimerPeriodInMsec); 00305 timer->_tickerStartTimeUsec = ticker_current_timeUsec; 00306 return(timer->_totalTimeUsec); 00307 } 00308
Generated on Thu Jul 14 2022 11:48:58 by
 1.7.2
 1.7.2