64 bit Timer Class.

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;
+}