Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Revision:
26:0421132e6eaf
Parent:
25:81014a201736
Child:
28:b4aa41fdeb68
--- a/tick.c	Mon Jan 22 18:54:23 2018 +0000
+++ b/tick.c	Thu Jan 25 07:54:54 2018 +0000
@@ -9,23 +9,36 @@
 #include "led.h"
 #include "log.h"
 
-#define ONE_BILLION 1000000000
+static int64_t     tickCount = 0;
+static int64_t     slewCount = 0;
+static bool       countIsSet = false;
+static bool           ticked = false;
+static int64_t         ticks = 0;
+static volatile int32_t slew = 0; //ns     - up to +/- 2.147s of slew
+static volatile int32_t ppb  = 0; //This gets set to the last recorded ppb in TickInit
 
-static volatile int64_t nsTickCount;
-static volatile int64_t nsSlewCount;
-static bool nsCountIsSet = false;
-bool  TickIsSet() { return nsCountIsSet; }
+bool    TickIsSet() { return countIsSet; }
+bool    Ticked()    { return ticked; }
+int64_t Ticks()     { return ticks; } //30th bit is one second
 
-static volatile int32_t slew = 0; //ns     - up to +/- 2.147s of slew
 int32_t TickGetSlew() { return slew; }
 void    TickSetSlew(int32_t value) { slew = value; }
 
-static volatile int32_t ppb  = 0;
 int32_t TickGetPpb () { return ppb;  }
 void    TickSetPpb (int32_t value) { ppb  = value; LPC_RTC->GPREG0 = ppb; }
 void    TickAddPpb (int32_t value) { ppb += value; LPC_RTC->GPREG0 = ppb; }
 
-bool TickTicked = false;
+void    TicksToTmUtc  (int64_t ticks, struct tm* ptm)
+{
+    time_t t = ticks >> TICK_ONE_SECOND_SHIFT;
+    TimeToTmUtc(t, ptm);
+}
+int64_t TicksFromTmUtc(struct tm* ptm)
+{
+    time_t t = TimeFromTmUtc(ptm);
+    return t << TICK_ONE_SECOND_SHIFT;
+}
+
 
 /*
 +---------+---------------+
@@ -40,102 +53,66 @@
 |   ...   |       ...     |
 +---------+---------------+
 */
-static uint32_t secondsBaseCount = 0;
-
-int64_t TickTime = 0; //30th bit is one second
 
 void TickSet(int64_t extClock)
 {
-    uint32_t       tc = TimerNowCount();
-    uint32_t  seconds =       tc / TIMER_COUNT_PER_SECOND; //0 to 44
-    uint32_t     base =  seconds * TIMER_COUNT_PER_SECOND; //0 to 2^32
-    uint32_t fraction =       tc % TIMER_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;
-     
+     int64_t timerCountSinceLastSecond = TimerCountSinceLastSecond();
+     int64_t fraction = (timerCountSinceLastSecond << TICK_ONE_SECOND_SHIFT) / TIMER_COUNT_PER_SECOND;
+     int64_t    ticks = extClock - fraction;
+
     __disable_irq();
-             nsTickCount = ns;
-             nsSlewCount = 0;
-        secondsBaseCount = base;
+        tickCount = ticks;
+        slewCount = 0;
     __enable_irq();
     
-    nsCountIsSet = true;
+    ticks = extClock;
+    
+    countIsSet = true;
 }
 void TickMain()
-{
-    uint32_t sinceSecondsBaseCount = TimerSinceCount(secondsBaseCount);
-    
+{    
     //Update the times whenever there has been a system second
-    if (sinceSecondsBaseCount > TIMER_COUNT_PER_SECOND)
+    if (TimerTicked)
     { 
         __disable_irq();
-        secondsBaseCount += TIMER_COUNT_PER_SECOND;
-             nsTickCount += ONE_BILLION + ppb;
-             nsSlewCount += slew;
+               tickCount += TICK_ONE_SECOND + ppb;
+               slewCount += slew;
                     slew  = 0;
         __enable_irq();
-        sinceSecondsBaseCount -= TIMER_COUNT_PER_SECOND;
     }
     
     //Update TickTime
-    int64_t   fraction = sinceSecondsBaseCount;
-              fraction <<= 32;
-              fraction /= TIMER_COUNT_PER_SECOND;
-    
-    int64_t nsBase     = nsTickCount + nsSlewCount;
-    int64_t nsPerTick  = ONE_BILLION + ppb + slew;
-    int64_t nsFraction = (nsPerTick * fraction) >> 32;
-    TickTime = nsBase + nsFraction;
+    ticks = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, TimerCountSinceLastSecond());
     
     //Update the ticked flag
     static bool lastTick = false;
-    bool thisTick = TickTime & (1ULL << 30);
-    TickTicked = thisTick && !lastTick;
-    lastTick = TickTicked;
+    bool thisTick = ticks & TICK_ONE_SECOND;
+    ticked = thisTick != lastTick;
+    lastTick = thisTick;
 
 }
-static volatile  int64_t nsTickSnapshot;
-static volatile  int64_t nsSlewSnapshot;
-static volatile uint32_t  timerSnapshot;
+static volatile  int64_t  tickSnapshot;
+static volatile  int64_t  slewSnapshot;
+static volatile uint32_t timerSnapshot;
 
 void TickSaveSnapshot()
 {
-     timerSnapshot = TimerSinceCount(secondsBaseCount);
-    nsTickSnapshot = nsTickCount;
-    nsSlewSnapshot = nsSlewCount;
+     timerSnapshot = TimerCountSinceLastSecond();
+      tickSnapshot = tickCount;
+      slewSnapshot = slewCount;
 }
-static void makeTimesFromCounts(uint32_t timerCount, int64_t tickNs, int64_t slewNs, int64_t* pNsInt, int64_t* pNsAbs)
+void TickGetTimesFromSnapshot(int64_t* pInt, int64_t* pAbs)
 {
-    int64_t   fraction = timerCount;
-              fraction <<= 32;
-              fraction /= TIMER_COUNT_PER_SECOND;
-
-    int64_t nsFraction;
-    
-    int64_t nsBase     = tickNs;
-    int64_t nsPerTick  = ONE_BILLION + ppb;
-    nsFraction = (nsPerTick * fraction) >> 32;
-    *pNsInt = nsBase + nsFraction;
-
-    nsBase    += slewNs;
-    nsPerTick += slew;
-    nsFraction = (nsPerTick * fraction) >> 32;
-    *pNsAbs = nsBase + nsFraction;
+    *pInt = tickSnapshot                + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb,        timerSnapshot);
+    *pAbs = tickSnapshot + slewSnapshot + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerSnapshot);
 }
-void TickGetTimesFromSnapshot(int64_t* pNsInt, int64_t* pNsAbs)
-{
-    makeTimesFromCounts(timerSnapshot, nsTickSnapshot, nsSlewSnapshot, pNsInt, pNsAbs);
-}
-void TickGetTimes(int64_t* pNsInt, int64_t* pNsAbs)
+void TickGetTimes(int64_t* pInt, int64_t* pAbs)
 {   
-    makeTimesFromCounts(TimerSinceCount(secondsBaseCount), nsTickCount, nsSlewCount, pNsInt, pNsAbs);
+    uint32_t timerCount = TimerCountSinceLastSecond();
+    *pInt = tickCount             + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb,        timerCount);
+    *pAbs = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerCount);
 }
 void TickInit(void)
 {
-    nsTickCount = 0;
-    nsSlewCount = 0;
-    
     ppb  = LPC_RTC->GPREG0; //This is saved each time Tickppb is updated
-    slew = 0;
-    nsCountIsSet = false;
 }
\ No newline at end of file