Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Revision:
20:62e0760cae13
Parent:
19:e537bacd1478
Child:
21:48fe75bcde84
diff -r e537bacd1478 -r 62e0760cae13 tick.c
--- a/tick.c	Wed Jan 17 20:42:14 2018 +0000
+++ b/tick.c	Thu Jan 18 18:07:30 2018 +0000
@@ -13,16 +13,8 @@
 static volatile int64_t nsTickCount;
 static volatile int64_t nsFreqCount;
 static volatile int64_t nsTimeCount;
-
 static bool nsCountIsSet = false;
 bool  TickIsSet() { return nsCountIsSet; }
-void TickSet(int64_t extClock)
-{
-    nsTickCount  = 0;
-    nsFreqCount  = 0;
-    nsTimeCount  = extClock - LPC_TIM1->TC;
-    nsCountIsSet = true;
-}
 
 static volatile int32_t slew = 0; //ns     - up to +/- 2.147s of slew
 int32_t TickGetSlew() { return slew; }
@@ -33,19 +25,58 @@
 void    TickSetPpb (int32_t value) { ppb  = value; LPC_RTC->GPREG0 = ppb; }
 void    TickAddPpb (int32_t value) { ppb += value; LPC_RTC->GPREG0 = ppb; }
 
-static uint32_t lastCall = 0;
+bool TickTicked = false;
+
+/*
++---------+---------------+
+| Seconds |   Base count  |
++---------+---------------+
+|    0    |             0 |
+|    1    |    96,000,000 |
+|   ...   |       ...     |
+|   44    | 4,224,000,000 |
+|   44.74 |          2^32 |
+|   45    |    25,032,704 |
+|   ...   |       ...     |
++---------+---------------+
+*/
+static uint32_t secondsBaseCount = 0;
+
+void TickSet(int64_t extClock)
+{
+    uint32_t       tc = LPC_TIM1->TC;
+    uint32_t  seconds =       tc / TICK_COUNT_PER_SECOND; //0 to 44
+    uint32_t     base =  seconds * TICK_COUNT_PER_SECOND; //0 to 2^32
+    uint32_t fraction =       tc % TICK_COUNT_PER_SECOND; //0 to 96,000,000
+    uint32_t fractionNs = fraction / 96 * 1000;           //0 to 1,000,000,000 which fits into 32 bits
+     int64_t       ns = extClock - fractionNs;
+     
+    __disable_irq();
+             nsTickCount = ns;
+             nsFreqCount = 0;
+             nsTimeCount = 0;
+        secondsBaseCount = base;
+    __enable_irq();
+    
+    nsCountIsSet = true;
+}
 void TickMain()
 {
-    uint32_t sinceLastCall = LPC_TIM1->TC - lastCall;
-    if (sinceLastCall > TICK_COUNT_PER_SECOND)
+    uint32_t sincesecondsBaseCount = LPC_TIM1->TC - secondsBaseCount;
+    if (sincesecondsBaseCount > TICK_COUNT_PER_SECOND)
     { 
         __disable_irq();
-           lastCall += TICK_COUNT_PER_SECOND;
-        nsTickCount += ONE_BILLION;
-        nsFreqCount += ppb;
-        nsTimeCount += slew;
-               slew  = 0;
+        secondsBaseCount += TICK_COUNT_PER_SECOND;
+             nsTickCount += ONE_BILLION;
+             nsFreqCount += ppb;
+             nsTimeCount += slew;
         __enable_irq();
+        slew  = 0;
+        TickTicked = true;
+    }
+    else
+    {
+        TickTicked = false;
     }
 }
 static volatile  int64_t nsTickSnapshot;
@@ -55,7 +86,7 @@
 
 void TickSaveSnapshotI()
 {
-     timerSnapshot = LPC_TIM1->TC - lastCall;
+     timerSnapshot = LPC_TIM1->TC - secondsBaseCount;
     nsTickSnapshot = nsTickCount;
     nsFreqSnapshot = nsFreqCount;
     nsTimeSnapshot = nsTimeCount;
@@ -92,12 +123,10 @@
      int64_t freqNs;
      int64_t timeNs;
     
-    __disable_irq();
-        timerCount = LPC_TIM1->TC - lastCall;
-         tickNs    = nsTickCount;
-         freqNs    = nsFreqCount;
-         timeNs    = nsTimeCount;
-    __enable_irq();
+    timerCount = LPC_TIM1->TC - secondsBaseCount;
+     tickNs    = nsTickCount;
+     freqNs    = nsFreqCount;
+     timeNs    = nsTimeCount;
     
     makeTimesFromCounts(timerCount, tickNs, freqNs, timeNs, pNsInt, pNsAbs);
 }