Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Sun Oct 15 17:52:27 2017 +0000
Revision:
13:0200519c9bbf
Parent:
12:3f338e85750f
Child:
14:7ef557918bb1
Moved all settings variables into the library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 13:0200519c9bbf 1 #include "mbed.h"
andrewboyson 13:0200519c9bbf 2 #include "log.h"
andrewboyson 13:0200519c9bbf 3 #include "tick.h"
andrewboyson 13:0200519c9bbf 4 #include "time.h"
andrewboyson 13:0200519c9bbf 5 #include "clock.h"
andrewboyson 0:33686e88f09a 6
andrewboyson 12:3f338e85750f 7 #define ONE_BILLION 1000000000LL //Make sure ONE_BILLION is 64 bit by putting LL on the end
andrewboyson 0:33686e88f09a 8 #define ONE_MILLION 1000000
andrewboyson 0:33686e88f09a 9
andrewboyson 10:19ed22b94c99 10 bool SyncTrace = false;
andrewboyson 2:55f070f05a43 11
andrewboyson 0:33686e88f09a 12 bool SyncedTime = false;
andrewboyson 0:33686e88f09a 13 bool SyncedRate = false;
andrewboyson 12:3f338e85750f 14 static void setSyncedTime(int64_t diff)
andrewboyson 0:33686e88f09a 15 {
andrewboyson 0:33686e88f09a 16 int64_t absDiff = llabs(diff);
andrewboyson 13:0200519c9bbf 17 int64_t limit = ClockSyncedLimitNs;
andrewboyson 13:0200519c9bbf 18 int64_t hysterisis = ClockSyncedHysterisNs;
andrewboyson 0:33686e88f09a 19
andrewboyson 3:92cfc43d493a 20 if (absDiff < limit - hysterisis) SyncedTime = true;
andrewboyson 3:92cfc43d493a 21 if (absDiff > limit + hysterisis) SyncedTime = false;
andrewboyson 12:3f338e85750f 22 }
andrewboyson 12:3f338e85750f 23 static void setSyncedRate(int64_t diff)
andrewboyson 12:3f338e85750f 24 {
andrewboyson 12:3f338e85750f 25
andrewboyson 12:3f338e85750f 26 int64_t absDiff = llabs(diff);
andrewboyson 13:0200519c9bbf 27 int64_t limit = ClockSyncedLimitPpb;
andrewboyson 13:0200519c9bbf 28 int64_t hysterisis = ClockSyncedHysterisPpb;
andrewboyson 12:3f338e85750f 29
andrewboyson 12:3f338e85750f 30 if (absDiff < limit - hysterisis) SyncedRate = true;
andrewboyson 12:3f338e85750f 31 if (absDiff > limit + hysterisis) SyncedRate = false;
andrewboyson 12:3f338e85750f 32 }
andrewboyson 0:33686e88f09a 33
andrewboyson 12:3f338e85750f 34 static void setSlew(int64_t diff)
andrewboyson 12:3f338e85750f 35 {
andrewboyson 13:0200519c9bbf 36 int64_t slew = -diff / ClockSlewDivisor;
andrewboyson 13:0200519c9bbf 37 int32_t slewMaxNs = ClockSlewMaxMs * ONE_MILLION;
andrewboyson 0:33686e88f09a 38
andrewboyson 0:33686e88f09a 39 if (slew > slewMaxNs) slew = slewMaxNs;
andrewboyson 0:33686e88f09a 40 if (slew < -slewMaxNs) slew = -slewMaxNs;
andrewboyson 0:33686e88f09a 41
andrewboyson 5:a3e37ce4975d 42 TickSetSlew(slew);
andrewboyson 5:a3e37ce4975d 43
andrewboyson 10:19ed22b94c99 44 if (SyncTrace) LogTimeF("Sync setSlew diff %lld gives slew %lld gives TickSlew %ld\r\n", diff, slew, TickGetSlew());
andrewboyson 0:33686e88f09a 45 }
andrewboyson 10:19ed22b94c99 46 static void adjustPpb(int64_t diff)
andrewboyson 12:3f338e85750f 47 {
andrewboyson 13:0200519c9bbf 48 int64_t toAdd = diff / ClockPpbDivisor;
andrewboyson 13:0200519c9bbf 49 int32_t maxAdd = ClockPpbChangeMax;
andrewboyson 0:33686e88f09a 50
andrewboyson 3:92cfc43d493a 51 if (toAdd > maxAdd) toAdd = maxAdd;
andrewboyson 3:92cfc43d493a 52 if (toAdd < -maxAdd) toAdd = -maxAdd;
andrewboyson 2:55f070f05a43 53
andrewboyson 5:a3e37ce4975d 54 TickAddPpb(-toAdd);
andrewboyson 2:55f070f05a43 55
andrewboyson 10:19ed22b94c99 56 if (SyncTrace) LogTimeF("Sync setPpb diff %lld gives toAdd %lld gives TickPpb %ld\r\n", diff, toAdd, TickGetPpb());
andrewboyson 0:33686e88f09a 57 }
andrewboyson 0:33686e88f09a 58
andrewboyson 13:0200519c9bbf 59 static int64_t lastIntClock = -1; //-1 indicates invalid value. 0 is a valid value.
andrewboyson 13:0200519c9bbf 60 static int64_t lastExtClock = -1;
andrewboyson 13:0200519c9bbf 61 static void reset(int64_t thisExtClock)
andrewboyson 0:33686e88f09a 62 {
andrewboyson 13:0200519c9bbf 63 TickSet(thisExtClock);
andrewboyson 13:0200519c9bbf 64 TickSetPpb(0);
andrewboyson 13:0200519c9bbf 65 lastIntClock = 0;
andrewboyson 13:0200519c9bbf 66 lastExtClock = 0;
andrewboyson 0:33686e88f09a 67 }
andrewboyson 0:33686e88f09a 68
andrewboyson 12:3f338e85750f 69 static void sync(int64_t thisExtClock)
andrewboyson 2:55f070f05a43 70 {
andrewboyson 13:0200519c9bbf 71
andrewboyson 5:a3e37ce4975d 72 if (!TickIsSet()) //Cold start - only ever true if the RTC was not set.
andrewboyson 0:33686e88f09a 73 {
andrewboyson 13:0200519c9bbf 74 LogTimeF("Sync - cold start of clock so resetting\r\n");
andrewboyson 13:0200519c9bbf 75 reset(thisExtClock);
andrewboyson 0:33686e88f09a 76 return;
andrewboyson 0:33686e88f09a 77 }
andrewboyson 0:33686e88f09a 78
andrewboyson 0:33686e88f09a 79 //Get the time at the time of the interrupt
andrewboyson 0:33686e88f09a 80 int64_t thisIntClock;
andrewboyson 0:33686e88f09a 81 int64_t thisAbsClock;
andrewboyson 12:3f338e85750f 82 TickGetTimes(&thisIntClock, &thisAbsClock);
andrewboyson 12:3f338e85750f 83
andrewboyson 0:33686e88f09a 84 //Calulate the time error
andrewboyson 0:33686e88f09a 85 int64_t absDiff = thisAbsClock - thisExtClock;
andrewboyson 13:0200519c9bbf 86 if (abs(absDiff) > ClockMaxOffsetSecs * ONE_BILLION)
andrewboyson 0:33686e88f09a 87 {
andrewboyson 13:0200519c9bbf 88 LogTimeF("Sync - offset is greater than %d seconds so resetting\r\n", ClockMaxOffsetSecs);
andrewboyson 13:0200519c9bbf 89 reset(thisExtClock);
andrewboyson 0:33686e88f09a 90 return;
andrewboyson 0:33686e88f09a 91 }
andrewboyson 0:33686e88f09a 92 setSlew(absDiff);
andrewboyson 12:3f338e85750f 93 setSyncedTime(absDiff);
andrewboyson 2:55f070f05a43 94
andrewboyson 2:55f070f05a43 95 //Calculate the rate error
andrewboyson 10:19ed22b94c99 96 if (lastExtClock > -1)
andrewboyson 2:55f070f05a43 97 {
andrewboyson 2:55f070f05a43 98 int64_t extPeriod = thisExtClock - lastExtClock;
andrewboyson 2:55f070f05a43 99
andrewboyson 2:55f070f05a43 100 int64_t intPeriod = thisIntClock - lastIntClock;
andrewboyson 2:55f070f05a43 101 int64_t periodDiff = intPeriod - extPeriod;
andrewboyson 2:55f070f05a43 102
andrewboyson 12:3f338e85750f 103 int64_t ppb;
andrewboyson 12:3f338e85750f 104 if (extPeriod == ONE_BILLION) ppb = periodDiff; //This saves a 64bit multiplication and division for PPS
andrewboyson 12:3f338e85750f 105 else ppb = periodDiff * ONE_BILLION / extPeriod;
andrewboyson 12:3f338e85750f 106
andrewboyson 10:19ed22b94c99 107 adjustPpb(ppb);
andrewboyson 12:3f338e85750f 108 setSyncedRate(ppb);
andrewboyson 2:55f070f05a43 109 }
andrewboyson 2:55f070f05a43 110
andrewboyson 2:55f070f05a43 111 //Save last values
andrewboyson 2:55f070f05a43 112 lastIntClock = thisIntClock;
andrewboyson 2:55f070f05a43 113 lastExtClock = thisExtClock;
andrewboyson 12:3f338e85750f 114 }
andrewboyson 13:0200519c9bbf 115 void SyncPpsI( ) { TickSaveSnapshotI(); }
andrewboyson 13:0200519c9bbf 116 void SyncPpsN(time_t t ) { int64_t ns = t * ONE_BILLION; sync(ns); }
andrewboyson 13:0200519c9bbf 117 void SyncNs (int64_t ns) { TickSaveSnapshotI(); sync(ns); }