64 bit Timer Class.

Revision:
3:8396d3e6eb62
Parent:
2:e89b02820e93
Child:
4:9ca673a83acb
Child:
6:100cf27b43aa
diff -r e89b02820e93 -r 8396d3e6eb62 Timer64.cpp
--- a/Timer64.cpp	Sun Mar 27 20:44:54 2016 +0000
+++ b/Timer64.cpp	Mon Mar 28 16:31:42 2016 +0000
@@ -23,9 +23,10 @@
     _totalTimeUsec(0L), 
     _ticker_data(get_us_ticker_data()),
     _rollOverCheckTimer(NULL),
-    _rollOverCheckTimerPeriodInMsec(TIMER64_15MINUTE_ROLLOVER_CHECK_IN_MSECS)
+    _rollOverCheckTimerPeriodInMsec(TIMER64_DEFAULT_ROLLOVER_CHECK_IN_MSECS),
+    _sem(NULL)
 {
-    reset();
+    ;
 }
 
 Timer64::~Timer64()
@@ -54,6 +55,7 @@
     _totalTimeUsec = 0L; 
     _rollOverCheckTimerPeriodInMsec = rolloverCheckTimeInMsec;
     _rollOverCheckTimer = new RtosTimer(_rollOverCheck, osTimerPeriodic, this);
+    _sem = new Semaphore(1);
     _timerInitialized = true;
     
     return(TIMER64_OK);
@@ -77,112 +79,198 @@
     _rollOverCheckTimer->stop();
     delete _rollOverCheckTimer;
     _rollOverCheckTimer = NULL;
+    delete _sem;
+    _sem = NULL;
     
     return(TIMER64_OK);
 }
+
 int Timer64::start(void)
 {
-    if (!_timerInitialized)
-    {
-        return(TIMER64_ERROR_NOT_INITIALIZED);
-    }
-    
-    if (_timerRunning)
+    int status = TIMER64_OK;
+
+    _sem->wait();
     {
-        return(TIMER64_WARNING_ALREADY_RUNNING);
+        if (!_timerInitialized)
+        {
+            status = TIMER64_ERROR_NOT_INITIALIZED;
+        }
+        else if (_timerRunning)
+        {
+            status = TIMER64_WARNING_ALREADY_RUNNING;
+        }
+        else
+        {
+            _tickerStartTimeUsec = ticker_read(_ticker_data);
+            _timerRunning = true;
+            _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
+        }
     }
-
-    _tickerStartTimeUsec = ticker_read(_ticker_data);
-    _timerRunning = true;
-    _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
-    return(TIMER64_OK);
+    _sem->release();
+    
+    return(status);
 }
 
 int Timer64::stop(void)
 {
-    if (!_timerInitialized)
-    {
-        return(TIMER64_ERROR_NOT_INITIALIZED);
-    }
-    
-    if (!_timerRunning)
+    int status = TIMER64_OK;
+
+    _sem->wait();
     {
-        return(TIMER64_WARNING_ALREADY_STOPPED);
+        if (!_timerInitialized)
+        {
+            status = TIMER64_ERROR_NOT_INITIALIZED;
+        }
+        else if (!_timerRunning)
+        {
+            status = TIMER64_WARNING_ALREADY_STOPPED;
+        }
+        else
+        {
+            _read_us(this);
+            _timerRunning = false;
+            _rollOverCheckTimer->stop();
+        }
     }
-
-    read_us();
-    _timerRunning = false;
-    _rollOverCheckTimer->stop();
+    _sem->release();
     
-    return(TIMER64_OK);
+    return(status);
 }
 
 int Timer64::reset(void)
 {
-    if (!_timerInitialized)
-    {
-        return(TIMER64_ERROR_NOT_INITIALIZED);
-    }
-    
-    if (_timerRunning)
+    int status = TIMER64_OK;
+
+    _sem->wait();
     {
-        _tickerStartTimeUsec = ticker_read(_ticker_data);
-        _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
+        if (!_timerInitialized)
+        {
+            status = TIMER64_ERROR_NOT_INITIALIZED;
+        }
+        else
+        {
+            if (_timerRunning)
+            {
+                _tickerStartTimeUsec = ticker_read(_ticker_data);
+                _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
+            }
+            
+            _totalTimeUsec = 0L;
+        }
     }
+    _sem->release();
     
-    _totalTimeUsec = 0L;
-    return(TIMER64_OK);
+    return(status);
 }
 
-uint64_t Timer64::read_us(int* status)
+int Timer64::read_us(uint64_t* timeInUsec)
 {
-    if (!_timerInitialized)
+    int status = TIMER64_OK;
+
+    _sem->wait();
     {
-        if (status)
+        if (!_timerInitialized)
         {
-            *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);
+            status = TIMER64_ERROR_NOT_INITIALIZED;
         }
         else
         {
-            // rollover!
-            _totalTimeUsec += (4294967296L - ((uint64_t)_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec;
-            
+            if (_timerRunning)
+            {
+                *timeInUsec = _read_us(this);
+            }
+            else
+            {
+                *timeInUsec = _totalTimeUsec;
+            }
         }
-        
-        _rollOverCheckTimer->start(_rollOverCheckTimerPeriodInMsec);
-        _tickerStartTimeUsec = ticker_current_timeUsec;
-    }    
-
-    return(_totalTimeUsec);
+    }
+    _sem->release();
+    
+    return(status);
 }
 
-uint64_t Timer64::read_ms(int* status)
+int Timer64::read_ms(uint64_t* timeInMsec)
 {
-    return(read_us(status) / 1000L);
+    int status = TIMER64_OK;
+
+    _sem->wait();
+    {
+        if (!_timerInitialized)
+        {
+            status = TIMER64_ERROR_NOT_INITIALIZED;
+        }
+        else
+        {
+            if (_timerRunning)
+            {
+                *timeInMsec = _read_us(this)/1000L;
+            }
+            else
+            {
+                *timeInMsec = _totalTimeUsec/1000L;
+            }
+        }
+    }
+    _sem->release();
+    
+    return(status);
 }
 
-double Timer64::read(int* status)
+int Timer64::read(double* timeInSec)
 {
-    return((double)read_us(status) / 1000000.0L);
+    int status = TIMER64_OK;
+
+    _sem->wait();
+    {
+        if (!_timerInitialized)
+        {
+            status = TIMER64_ERROR_NOT_INITIALIZED;
+        }
+        else
+        {
+            if (_timerRunning)
+            {
+                *timeInSec = (double)_read_us(this)/1000000.0L;
+            }
+            else
+            {
+                *timeInSec = (double)_totalTimeUsec/1000000.0L;
+            }
+        }
+    }
+    _sem->release();
+    
+    return(status);
 }
 
 void Timer64::_rollOverCheck(void const* args)
 {
     Timer64* timer = (Timer64*)args;
-    timer->read_us();
+    timer->_read_us(timer);
     return;
 }
+
+uint64_t Timer64::_read_us(void const* args)
+{
+    Timer64* timer = (Timer64*)args;
+    timestamp_t ticker_current_timeUsec = ticker_read(timer->_ticker_data);
+    
+    // check for ticker time rollover
+    
+    if (ticker_current_timeUsec >= timer->_tickerStartTimeUsec)
+    {
+        timer->_totalTimeUsec += (uint64_t)(ticker_current_timeUsec - timer->_tickerStartTimeUsec);
+    }
+    else
+    {
+        // rollover!
+        timer->_totalTimeUsec += (4294967296L - ((uint64_t)timer->_tickerStartTimeUsec)) + (uint64_t)ticker_current_timeUsec;
+        
+    }
+    
+    timer->_rollOverCheckTimer->start(timer->_rollOverCheckTimerPeriodInMsec);
+    timer->_tickerStartTimeUsec = ticker_current_timeUsec;
+    return(timer->_totalTimeUsec);
+}
+