Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Jan 11 17:39:36 2018 +0000
Revision:
17:927fc1eceb9d
Parent:
clock.cpp@16:933cbe190bb0
Child:
18:207dd1474cd9
Removed dependence on Mbed OS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 17:927fc1eceb9d 1 #include <stdint.h>
andrewboyson 17:927fc1eceb9d 2 #include <stdio.h>
andrewboyson 17:927fc1eceb9d 3
andrewboyson 0:33686e88f09a 4 #include "log.h"
andrewboyson 0:33686e88f09a 5 #include "tick.h"
andrewboyson 0:33686e88f09a 6 #include "sync.h"
andrewboyson 0:33686e88f09a 7 #include "time.h"
andrewboyson 0:33686e88f09a 8 #include "rtc.h"
andrewboyson 0:33686e88f09a 9
andrewboyson 0:33686e88f09a 10 #define ONE_BILLION 1000000000
andrewboyson 0:33686e88f09a 11
andrewboyson 15:e6d1d763ca18 12 void ClockNsToTmUtc (int64_t ns, struct tm* ptm)
andrewboyson 15:e6d1d763ca18 13 {
andrewboyson 15:e6d1d763ca18 14 time_t t = ns / ONE_BILLION;
andrewboyson 15:e6d1d763ca18 15 TimeToTmUtc(t, ptm);
andrewboyson 15:e6d1d763ca18 16 }
andrewboyson 15:e6d1d763ca18 17 int64_t ClockNsFromTmUtc(struct tm* ptm)
andrewboyson 15:e6d1d763ca18 18 {
andrewboyson 15:e6d1d763ca18 19 time_t t = TimeFromTmUtc(ptm);
andrewboyson 15:e6d1d763ca18 20 return t * ONE_BILLION;
andrewboyson 15:e6d1d763ca18 21 }
andrewboyson 15:e6d1d763ca18 22
andrewboyson 13:0200519c9bbf 23 int ClockSlewDivisor = 10;
andrewboyson 13:0200519c9bbf 24 int ClockSlewMaxMs = 10;
andrewboyson 13:0200519c9bbf 25 int ClockPpbDivisor = 10;
andrewboyson 13:0200519c9bbf 26 int ClockPpbChangeMax = 1000;
andrewboyson 13:0200519c9bbf 27 int ClockSyncedLimitNs = 10000000;
andrewboyson 13:0200519c9bbf 28 int ClockSyncedHysterisNs = 1000000;
andrewboyson 13:0200519c9bbf 29 int ClockSyncedLimitPpb = 1000;
andrewboyson 13:0200519c9bbf 30 int ClockSyncedHysterisPpb = 100;
andrewboyson 13:0200519c9bbf 31 int ClockMaxOffsetSecs = 3;
andrewboyson 13:0200519c9bbf 32
andrewboyson 7:54a52594b084 33 static int64_t nowNs = 0;
andrewboyson 7:54a52594b084 34 static time_t nowT = 0;
andrewboyson 8:4ba6b0434d2b 35 static void calculateTimes()
andrewboyson 8:4ba6b0434d2b 36 {
andrewboyson 8:4ba6b0434d2b 37 int64_t nsInt;
andrewboyson 8:4ba6b0434d2b 38 TickGetTimes(&nsInt, &nowNs);
andrewboyson 8:4ba6b0434d2b 39 nowT = nowNs / ONE_BILLION;
andrewboyson 8:4ba6b0434d2b 40 }
andrewboyson 7:54a52594b084 41
andrewboyson 8:4ba6b0434d2b 42 static int64_t refNs = 0;
andrewboyson 0:33686e88f09a 43 int64_t ClockRefNs()
andrewboyson 0:33686e88f09a 44 {
andrewboyson 0:33686e88f09a 45 return refNs;
andrewboyson 0:33686e88f09a 46 }
andrewboyson 17:927fc1eceb9d 47 int ClockIsSet()
andrewboyson 0:33686e88f09a 48 {
andrewboyson 5:a3e37ce4975d 49 return TickIsSet();
andrewboyson 0:33686e88f09a 50 }
andrewboyson 17:927fc1eceb9d 51 int ClockIsSynced()
andrewboyson 0:33686e88f09a 52 {
andrewboyson 0:33686e88f09a 53 return SyncedRate && SyncedTime;
andrewboyson 0:33686e88f09a 54 }
andrewboyson 0:33686e88f09a 55
andrewboyson 0:33686e88f09a 56 int64_t ClockNowNs()
andrewboyson 0:33686e88f09a 57 {
andrewboyson 7:54a52594b084 58 return nowNs;
andrewboyson 0:33686e88f09a 59 }
andrewboyson 0:33686e88f09a 60
andrewboyson 1:f3746f3cc345 61 void ClockTmLocal(struct tm* ptm)
andrewboyson 1:f3746f3cc345 62 {
andrewboyson 7:54a52594b084 63 TimeToTmLocal(nowT, ptm);
andrewboyson 1:f3746f3cc345 64 }
andrewboyson 1:f3746f3cc345 65 void ClockTmUtc(struct tm* ptm)
andrewboyson 1:f3746f3cc345 66 {
andrewboyson 7:54a52594b084 67 TimeToTmUtc(nowT, ptm);
andrewboyson 1:f3746f3cc345 68 }
andrewboyson 1:f3746f3cc345 69
andrewboyson 0:33686e88f09a 70 void ClockAscii(char* p)
andrewboyson 0:33686e88f09a 71 {
andrewboyson 0:33686e88f09a 72 struct tm tm;
andrewboyson 7:54a52594b084 73 TimeToTmUtc(nowT, &tm);
andrewboyson 0:33686e88f09a 74 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);
andrewboyson 0:33686e88f09a 75 }
andrewboyson 17:927fc1eceb9d 76 void ClockInit()
andrewboyson 0:33686e88f09a 77 {
andrewboyson 0:33686e88f09a 78 RtcInit();
andrewboyson 0:33686e88f09a 79 TickInit();
andrewboyson 0:33686e88f09a 80 }
andrewboyson 1:f3746f3cc345 81
andrewboyson 17:927fc1eceb9d 82 int ClockTicked = 0; //Set to true for one scan each time the second changes
andrewboyson 5:a3e37ce4975d 83
andrewboyson 17:927fc1eceb9d 84 void ClockMain()
andrewboyson 0:33686e88f09a 85 {
andrewboyson 7:54a52594b084 86 //Calculate ns and time_t
andrewboyson 8:4ba6b0434d2b 87 calculateTimes();
andrewboyson 17:927fc1eceb9d 88
andrewboyson 17:927fc1eceb9d 89 static int lastSyncedRate = 0;
andrewboyson 17:927fc1eceb9d 90 static int lastSyncedTime = 0;
andrewboyson 0:33686e88f09a 91
andrewboyson 0:33686e88f09a 92 if ( SyncedRate && !lastSyncedRate) LogTimeF("Rate sync acquired\r\n");
andrewboyson 0:33686e88f09a 93 if (!SyncedRate && lastSyncedRate) LogTimeF("Rate sync lost\r\n");
andrewboyson 0:33686e88f09a 94 if ( SyncedTime && !lastSyncedTime) LogTimeF("Time sync acquired\r\n");
andrewboyson 0:33686e88f09a 95 if (!SyncedTime && lastSyncedTime) LogTimeF("Time sync lost\r\n");
andrewboyson 0:33686e88f09a 96
andrewboyson 0:33686e88f09a 97 lastSyncedRate = SyncedRate;
andrewboyson 0:33686e88f09a 98 lastSyncedTime = SyncedTime;
andrewboyson 16:933cbe190bb0 99
andrewboyson 0:33686e88f09a 100 //Record the time the clock started
andrewboyson 7:54a52594b084 101 if (SyncedTime && SyncedRate) refNs = nowNs;
andrewboyson 0:33686e88f09a 102
andrewboyson 5:a3e37ce4975d 103 //Set a one shot memory for having had a tick
andrewboyson 7:54a52594b084 104 static time_t lastT = 0;
andrewboyson 7:54a52594b084 105 ClockTicked = lastT > 0 && lastT != nowT;
andrewboyson 7:54a52594b084 106 lastT = nowT;
andrewboyson 17:927fc1eceb9d 107
andrewboyson 5:a3e37ce4975d 108 if (TickIsSet())
andrewboyson 5:a3e37ce4975d 109 {
andrewboyson 5:a3e37ce4975d 110 //Save the time to the RTC on the second
andrewboyson 5:a3e37ce4975d 111 if (ClockTicked)
andrewboyson 5:a3e37ce4975d 112 {
andrewboyson 5:a3e37ce4975d 113 struct tm tm;
andrewboyson 5:a3e37ce4975d 114 ClockTmUtc(&tm);
andrewboyson 5:a3e37ce4975d 115 RtcSetTm(&tm);
andrewboyson 5:a3e37ce4975d 116 }
andrewboyson 5:a3e37ce4975d 117 }
andrewboyson 5:a3e37ce4975d 118 else
andrewboyson 0:33686e88f09a 119 {
andrewboyson 5:a3e37ce4975d 120 //Start the clock from the RTC if not started
andrewboyson 5:a3e37ce4975d 121 if (RtcIsSet())
andrewboyson 0:33686e88f09a 122 {
andrewboyson 5:a3e37ce4975d 123 static int lastRtcSecond = -1;
andrewboyson 5:a3e37ce4975d 124 struct tm tm;
andrewboyson 5:a3e37ce4975d 125 RtcGetTm(&tm);
andrewboyson 5:a3e37ce4975d 126 if (lastRtcSecond > 0 && tm.tm_sec != lastRtcSecond)
andrewboyson 5:a3e37ce4975d 127 {
andrewboyson 5:a3e37ce4975d 128 time_t t = TimeFromTmUtc(&tm);
andrewboyson 5:a3e37ce4975d 129 TickSet(t * (int64_t)ONE_BILLION);
andrewboyson 8:4ba6b0434d2b 130 calculateTimes();
andrewboyson 5:a3e37ce4975d 131 LogTimeF("Clock set from RTC\r\n");
andrewboyson 5:a3e37ce4975d 132 }
andrewboyson 5:a3e37ce4975d 133 lastRtcSecond = tm.tm_sec;
andrewboyson 0:33686e88f09a 134 }
andrewboyson 0:33686e88f09a 135 }
andrewboyson 0:33686e88f09a 136 }