64 bit Timer Class.
Diff: Timer64.cpp
- Revision:
- 0:1e0e79e82839
- Child:
- 1:497fba179833
diff -r 000000000000 -r 1e0e79e82839 Timer64.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Timer64.cpp Sat Mar 26 21:44:41 2016 +0000 @@ -0,0 +1,215 @@ + /* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Timer64.h" +#include "ticker_api.h" +#include "us_ticker_api.h" + +Timer64::Timer64() : + _timerInitialized(false), + _timerRunning(false), + _tickerStartTimeUsec(0L), + _totalTimeUsec(0L), + _ticker_data(get_us_ticker_data()), + _rollOverCheckTimer(NULL), + _rollOverCheckTimerPeriodInMsec(TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS) +{ + reset(); +} + +Timer64::Timer64(const ticker_data_t *data) : + _timerInitialized(false), + _timerRunning(false), + _tickerStartTimeUsec(0L), + _totalTimeUsec(0L), + _ticker_data(data), + _rollOverCheckTimer(NULL), + _rollOverCheckTimerPeriodInMsec(TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS) +{ + reset(); +} + +int Timer64::init(uint32_t rolloverCheckTimeInMsec) +{ + if (_timerInitialized) + { + return(TIMER64_WARNING_ALREADY_INITIALIZED); + } + + if (rolloverCheckTimeInMsec < TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS) + { + rolloverCheckTimeInMsec = TIMER64_MIN_ROLLOVER_CHECK_IN_MSECS; + } + else if (rolloverCheckTimeInMsec > TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS) + { + rolloverCheckTimeInMsec = TIMER64_MAX_ROLLOVER_CHECK_IN_MSECS; + } + + _timerRunning = false; + _tickerStartTimeUsec = 0L; + _totalTimeUsec = 0L; + _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec; + _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this); + _timerInitialized = true; + + return(TIMER64_OK); +} + +int Timer64::release(void) +{ + if (!_timerInitialized) + { + return(TIMER64_ERROR_NOT_INITIALIZED); + } + + if (_timerRunning) + { + stop(); + } + + _tickerStartTimeUsec = 0L; + _totalTimeUsec = 0L; + _timerInitialized = false; + _rollOverCheckTimer->stop(); + delete _rollOverCheckTimer; + _rollOverCheckTimer = NULL; + + return(TIMER64_OK); +} +int Timer64::start(void) +{ + if (!_timerInitialized) + { + return(TIMER64_ERROR_NOT_INITIALIZED); + } + + if (!_timerRunning) + { + _tickerStartTimeUsec = ticker_read(_ticker_data); + _timerRunning = true; + _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + } + else + { + return(TIMER64_WARNING_ALREADY_RUNNING); + } + + return(TIMER64_OK); +} + +int Timer64::stop(void) +{ + if (!_timerInitialized) + { + return(TIMER64_ERROR_NOT_INITIALIZED); + } + + if (_timerRunning) + { + _timerRunning = false; + _rollOverCheckTimer->stop(); + } + else + { + return(TIMER64_WARNING_ALREADY_STOPPED); + } + + return(TIMER64_OK); +} + +int Timer64::reset(void) +{ + if (!_timerInitialized) + { + return(TIMER64_ERROR_NOT_INITIALIZED); + } + + if (_timerRunning) + { + _tickerStartTimeUsec = ticker_read(_ticker_data); + _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec); + } + + _totalTimeUsec = 0L; + return(TIMER64_OK); +} + +uint64_t Timer64::read_us(int* status) +{ + if (!_timerInitialized) + { + if (status) + { + *status = TIMER64_ERROR_NOT_INITIALIZED; + } + + return(0L); + } + + if (_timerRunning) + { + timestamp_t ticker_current_timeUsec = ticker_read(_ticker_data); + + // check for ticker time rollover + + if (ticker_current_timeUsec >= _tickerStartTimeUsec) + { + _totalTimeUsec += (uint64_t)(ticker_current_timeUsec - _tickerStartTimeUsec); + } + else + { + // rollover! + _totalTimeUsec += (4294967296L - ((uint64_t)_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec; + + } + + _tickerStartTimeUsec = ticker_current_timeUsec; + } + + return(_totalTimeUsec); +} + +uint64_t Timer64::read_ms(int* status) +{ + return(read_us(status) / 1000L); +} + +double Timer64::read(int* status) +{ + return((double)read_us(status) / 1000000.0L); +} + +#ifdef MBED_OPERATORS +Timer64::operator double() +{ + return read(); +} + +Timer64::operator uint64_t() +{ + return read_us(); +} + +Timer64::operator uint32_t() +{ + return read_us(); +} +#endif + +void Timer64::_rollOverCheck(void const* args) +{ + Timer64* timer = (Timer64*)args; + timer->read_us(); + return; +}