Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Revision:
32:f915ccb1ece3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/time.c	Thu Nov 29 18:43:27 2018 +0000
@@ -0,0 +1,122 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "rtc.h"
+#include "tm.h"
+#include "time.h"
+#include "timer.h"
+#include "led.h"
+#include "log.h"
+
+#define GPREG0 (*((volatile unsigned *) 0x40024044))
+
+static int64_t     tickCount = 0;
+static int64_t     slewCount = 0;
+static bool       countIsSet = false;
+//static bool           ticked = false;
+static int64_t ticksThisScan = 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
+
+bool    TimeIsSet() { return countIsSet; }
+//bool    TimeTicked(){ return ticked; }
+int64_t TimeNow()  { return ticksThisScan; } //30th bit is one second
+
+int32_t TimeGetSlew() { return slew; }
+void    TimeSetSlew(int32_t value) { slew = value; }
+
+int32_t TimeGetPpb () { return ppb;  }
+void    TimeSetPpb (int32_t value) { ppb  = value; GPREG0 = ppb; }
+void    TimeAddPpb (int32_t value) { ppb += value; GPREG0 = ppb; }
+
+void    TimeToTmUtc  (int64_t ticks, struct tm* ptm)
+{
+    time_t t = ticks >> TIME_ONE_SECOND_SHIFT;
+    TmUtcFromTimeT(t, ptm);
+}
+int64_t TimeFromTmUtc(struct tm* ptm)
+{
+    time_t t = TmUtcToTimeT(ptm);
+    return t << TIME_ONE_SECOND_SHIFT;
+}
+
+
+/* Timer counts like this:
++---------+---------------+
+| Seconds |   Base count  |
++---------+---------------+
+|    0    |             0 |
+|    1    |    96,000,000 |
+|   ...   |       ...     |
+|   44    | 4,224,000,000 |
+|   44.74 |          2^32 |
+|   45    |    25,032,704 |
+|   ...   |       ...     |
++---------+---------------+
+Tick counts as a signed 64 bit integer
+1 bit sign, 33 bits for seconds, 30 bits for fraction
+giving +/- 272 years with a resolution of around approximately 1ns or 1 ppb per second (2^30 == 1024x1024x1024)
+*/
+
+void TimeSet(int64_t extClock)
+{    
+     int64_t timerCountSinceLastSecond = TimerCountSinceLastSecond();
+     int64_t fraction = (timerCountSinceLastSecond << TIME_ONE_SECOND_SHIFT) / TIMER_COUNT_PER_SECOND;
+     int64_t    ticks = extClock - fraction;
+
+    __disable_irq();
+        tickCount = ticks;
+        slewCount = 0;
+    __enable_irq();
+    
+    ticksThisScan = extClock;
+    
+    countIsSet = true;
+}
+void TimeMain()
+{    
+    //Update the times whenever there has been a system second
+    if (TimerHadSecond)
+    { 
+        __disable_irq();
+               tickCount += TIME_ONE_SECOND + ppb;
+               slewCount += slew;
+                    slew  = 0;
+        __enable_irq();
+    }
+    
+    //Update TickTime
+    ticksThisScan = tickCount + slewCount + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb + slew, TimerCountSinceLastSecond());
+    
+    //Update the ticked flag
+//    static bool lastTick = false;
+//    bool thisTick = ticksThisScan & TIME_ONE_SECOND;
+//    ticked = thisTick != lastTick;
+//    lastTick = thisTick;
+
+}
+static volatile  int64_t  tickSnapshot;
+static volatile  int64_t  slewSnapshot;
+static volatile uint32_t timerSnapshot;
+
+void TimeSaveSnapshot()
+{
+     timerSnapshot = TimerCountSinceLastSecond();
+      tickSnapshot = tickCount;
+      slewSnapshot = slewCount;
+}
+void TimesGetFromSnapshot(int64_t* pInt, int64_t* pAbs)
+{
+    *pInt = tickSnapshot                + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb,        timerSnapshot);
+    *pAbs = tickSnapshot + slewSnapshot + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb + slew, timerSnapshot);
+}
+void TimesGet(int64_t* pInt, int64_t* pAbs)
+{   
+    uint32_t timerCount = TimerCountSinceLastSecond();
+    *pInt = tickCount             + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb,        timerCount);
+    *pAbs = tickCount + slewCount + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb + slew, timerCount);
+}
+void TimeInit(void)
+{
+    ppb  = GPREG0; //This is saved each time Tickppb is updated
+}
\ No newline at end of file