Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Revision:
17:927fc1eceb9d
Parent:
16:933cbe190bb0
Child:
18:207dd1474cd9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clock.c	Thu Jan 11 17:39:36 2018 +0000
@@ -0,0 +1,136 @@
+#include <stdint.h>
+#include <stdio.h>
+
+#include  "log.h"
+#include "tick.h"
+#include "sync.h"
+#include "time.h"
+#include  "rtc.h"
+
+#define ONE_BILLION 1000000000
+
+void    ClockNsToTmUtc  (int64_t ns, struct tm* ptm)
+{
+    time_t t = ns / ONE_BILLION;
+    TimeToTmUtc(t, ptm);
+}
+int64_t ClockNsFromTmUtc(struct tm* ptm)
+{
+    time_t t = TimeFromTmUtc(ptm);
+    return t * ONE_BILLION;
+}
+
+int ClockSlewDivisor       = 10;
+int ClockSlewMaxMs         = 10;
+int ClockPpbDivisor        = 10;
+int ClockPpbChangeMax      = 1000;
+int ClockSyncedLimitNs     = 10000000;
+int ClockSyncedHysterisNs  =  1000000;
+int ClockSyncedLimitPpb    = 1000;
+int ClockSyncedHysterisPpb =  100;
+int ClockMaxOffsetSecs     = 3;
+
+static int64_t nowNs = 0;
+static time_t  nowT  = 0;
+static void calculateTimes()
+{
+    int64_t nsInt;
+    TickGetTimes(&nsInt, &nowNs);
+    nowT = nowNs / ONE_BILLION;
+}
+
+static int64_t refNs = 0;
+int64_t ClockRefNs()
+{
+    return refNs;
+}
+int ClockIsSet()
+{
+    return TickIsSet();
+}
+int ClockIsSynced()
+{
+    return SyncedRate && SyncedTime;
+}
+
+int64_t ClockNowNs()
+{
+    return nowNs;
+}
+
+void ClockTmLocal(struct tm* ptm)
+{
+    TimeToTmLocal(nowT, ptm);
+}
+void ClockTmUtc(struct tm* ptm)
+{
+    TimeToTmUtc(nowT, ptm);
+}
+
+void ClockAscii(char* p)
+{
+    struct tm tm;
+    TimeToTmUtc(nowT, &tm);
+    sprintf(p, "%d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+}
+void ClockInit()
+{
+     RtcInit();
+    TickInit();
+}
+
+int ClockTicked = 0; //Set to true for one scan each time the second changes
+
+void ClockMain()
+{
+    //Calculate ns and time_t
+    calculateTimes();
+    
+    static int lastSyncedRate = 0;
+    static int lastSyncedTime = 0;
+    
+    if ( SyncedRate && !lastSyncedRate) LogTimeF("Rate sync acquired\r\n");
+    if (!SyncedRate &&  lastSyncedRate) LogTimeF("Rate sync lost\r\n");
+    if ( SyncedTime && !lastSyncedTime) LogTimeF("Time sync acquired\r\n");
+    if (!SyncedTime &&  lastSyncedTime) LogTimeF("Time sync lost\r\n");
+    
+    lastSyncedRate = SyncedRate;
+    lastSyncedTime = SyncedTime;
+         
+    //Record the time the clock started
+    if (SyncedTime && SyncedRate) refNs = nowNs;
+
+    //Set a one shot memory for having had a tick
+    static time_t lastT = 0;
+    ClockTicked = lastT > 0 && lastT != nowT;
+    lastT = nowT;
+        
+    if (TickIsSet())
+    {
+        //Save the time to the RTC on the second
+        if (ClockTicked)
+        {
+            struct tm tm;
+            ClockTmUtc(&tm);
+            RtcSetTm(&tm);
+        }
+    }
+    else
+    {
+        //Start the clock from the RTC if not started
+        if (RtcIsSet())
+        {
+            static int lastRtcSecond = -1;
+            struct tm tm;
+            RtcGetTm(&tm);
+            if (lastRtcSecond > 0 && tm.tm_sec != lastRtcSecond)
+            {
+                time_t t = TimeFromTmUtc(&tm);
+                TickSet(t * (int64_t)ONE_BILLION);
+                calculateTimes();
+                LogTimeF("Clock set from RTC\r\n");
+            }
+            lastRtcSecond = tm.tm_sec;
+        }
+    }
+}
\ No newline at end of file