Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Tue Oct 10 08:39:51 2017 +0000
Revision:
10:19ed22b94c99
Parent:
9:cd30749dfa3d
Child:
12:3f338e85750f
Separated out the NTP conversion routines

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 4:095dfd4a316b 1 #include "mbed.h"
andrewboyson 4:095dfd4a316b 2 #include "log.h"
andrewboyson 4:095dfd4a316b 3 #include "tick.h"
andrewboyson 4:095dfd4a316b 4 #include "time.h"
andrewboyson 4:095dfd4a316b 5 #include "settings.h"
andrewboyson 0:33686e88f09a 6
andrewboyson 0:33686e88f09a 7 #define ONE_BILLION 1000000000
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 0:33686e88f09a 14
andrewboyson 0:33686e88f09a 15 static void setSlew(int64_t diff)
andrewboyson 0:33686e88f09a 16 {
andrewboyson 0:33686e88f09a 17 int64_t absDiff = llabs(diff);
andrewboyson 4:095dfd4a316b 18 int64_t limit = GetClockSyncedLimitNs();
andrewboyson 4:095dfd4a316b 19 int64_t hysterisis = GetClockSyncedHysterisNs();
andrewboyson 0:33686e88f09a 20
andrewboyson 3:92cfc43d493a 21 if (absDiff < limit - hysterisis) SyncedTime = true;
andrewboyson 3:92cfc43d493a 22 if (absDiff > limit + hysterisis) SyncedTime = false;
andrewboyson 0:33686e88f09a 23
andrewboyson 4:095dfd4a316b 24 int64_t slew = -diff / GetClockSlewDivisor();
andrewboyson 4:095dfd4a316b 25 int32_t slewMaxNs = GetClockSlewMaxMs() * ONE_MILLION;
andrewboyson 0:33686e88f09a 26
andrewboyson 0:33686e88f09a 27 if (slew > slewMaxNs) slew = slewMaxNs;
andrewboyson 0:33686e88f09a 28 if (slew < -slewMaxNs) slew = -slewMaxNs;
andrewboyson 0:33686e88f09a 29
andrewboyson 5:a3e37ce4975d 30 TickSetSlew(slew);
andrewboyson 5:a3e37ce4975d 31
andrewboyson 10:19ed22b94c99 32 if (SyncTrace) LogTimeF("Sync setSlew diff %lld gives slew %lld gives TickSlew %ld\r\n", diff, slew, TickGetSlew());
andrewboyson 0:33686e88f09a 33 }
andrewboyson 10:19ed22b94c99 34 static void adjustPpb(int64_t diff)
andrewboyson 2:55f070f05a43 35 {
andrewboyson 2:55f070f05a43 36
andrewboyson 0:33686e88f09a 37 int64_t absDiff = llabs(diff);
andrewboyson 4:095dfd4a316b 38 int64_t limit = GetClockSyncedLimitPpb();
andrewboyson 4:095dfd4a316b 39 int64_t hysterisis = GetClockSyncedHysterisPpb();
andrewboyson 0:33686e88f09a 40
andrewboyson 3:92cfc43d493a 41 if (absDiff < limit - hysterisis) SyncedRate = true;
andrewboyson 3:92cfc43d493a 42 if (absDiff > limit + hysterisis) SyncedRate = false;
andrewboyson 0:33686e88f09a 43
andrewboyson 4:095dfd4a316b 44 int64_t toAdd = diff / GetClockPpbDivisor();
andrewboyson 4:095dfd4a316b 45 int32_t maxAdd = GetClockPpbChangeMax();
andrewboyson 0:33686e88f09a 46
andrewboyson 3:92cfc43d493a 47 if (toAdd > maxAdd) toAdd = maxAdd;
andrewboyson 3:92cfc43d493a 48 if (toAdd < -maxAdd) toAdd = -maxAdd;
andrewboyson 2:55f070f05a43 49
andrewboyson 5:a3e37ce4975d 50 TickAddPpb(-toAdd);
andrewboyson 2:55f070f05a43 51
andrewboyson 10:19ed22b94c99 52 if (SyncTrace) LogTimeF("Sync setPpb diff %lld gives toAdd %lld gives TickPpb %ld\r\n", diff, toAdd, TickGetPpb());
andrewboyson 0:33686e88f09a 53 }
andrewboyson 0:33686e88f09a 54
andrewboyson 0:33686e88f09a 55
andrewboyson 0:33686e88f09a 56 void SyncPpsI()
andrewboyson 0:33686e88f09a 57 {
andrewboyson 0:33686e88f09a 58 TickSaveSnapshotI();
andrewboyson 0:33686e88f09a 59 }
andrewboyson 0:33686e88f09a 60
andrewboyson 0:33686e88f09a 61 void SyncPpsN(time_t t)
andrewboyson 2:55f070f05a43 62 {
andrewboyson 2:55f070f05a43 63 int64_t thisExtClock = t * (int64_t)ONE_BILLION; //Make sure one of the RHS is cast to 64 bit
andrewboyson 10:19ed22b94c99 64 static int64_t lastIntClock = -1;
andrewboyson 10:19ed22b94c99 65 static int64_t lastExtClock = -1;
andrewboyson 0:33686e88f09a 66
andrewboyson 5:a3e37ce4975d 67 if (!TickIsSet()) //Cold start - only ever true if the RTC was not set.
andrewboyson 0:33686e88f09a 68 {
andrewboyson 0:33686e88f09a 69 LogTimeF("Cold start of clock\r\n");
andrewboyson 0:33686e88f09a 70 TickSet(thisExtClock);
andrewboyson 10:19ed22b94c99 71 TickSetPpb(0);
andrewboyson 0:33686e88f09a 72 lastIntClock = 0;
andrewboyson 0:33686e88f09a 73 lastExtClock = 0;
andrewboyson 0:33686e88f09a 74 return;
andrewboyson 0:33686e88f09a 75 }
andrewboyson 0:33686e88f09a 76
andrewboyson 0:33686e88f09a 77 //Get the time at the time of the interrupt
andrewboyson 0:33686e88f09a 78 int64_t thisIntClock;
andrewboyson 0:33686e88f09a 79 int64_t thisAbsClock;
andrewboyson 0:33686e88f09a 80 TickRetrieveSnapshot(&thisIntClock, &thisAbsClock);
andrewboyson 0:33686e88f09a 81
andrewboyson 0:33686e88f09a 82 //Calulate the time error
andrewboyson 0:33686e88f09a 83 int64_t absDiff = thisAbsClock - thisExtClock;
andrewboyson 4:095dfd4a316b 84 if (abs(absDiff) > GetClockMaxOffsetSecs() * (int64_t)ONE_BILLION)
andrewboyson 0:33686e88f09a 85 {
andrewboyson 10:19ed22b94c99 86 if (SyncTrace) LogTimeF("Sync - offset is greater than %d seconds so resetting Tick time and rate\r\n", GetClockMaxOffsetSecs());
andrewboyson 0:33686e88f09a 87 TickSet(thisExtClock);
andrewboyson 10:19ed22b94c99 88 TickSetPpb(0);
andrewboyson 0:33686e88f09a 89 lastIntClock = 0;
andrewboyson 0:33686e88f09a 90 lastExtClock = 0;
andrewboyson 0:33686e88f09a 91 return;
andrewboyson 0:33686e88f09a 92 }
andrewboyson 0:33686e88f09a 93 setSlew(absDiff);
andrewboyson 0:33686e88f09a 94
andrewboyson 0:33686e88f09a 95 //Calculate the rate error
andrewboyson 10:19ed22b94c99 96 if (lastExtClock > -1)
andrewboyson 0:33686e88f09a 97 {
andrewboyson 0:33686e88f09a 98 int64_t extPeriod = thisExtClock - lastExtClock;
andrewboyson 0:33686e88f09a 99
andrewboyson 0:33686e88f09a 100 int64_t intPeriod = thisIntClock - lastIntClock;
andrewboyson 0:33686e88f09a 101 int64_t periodDiff = intPeriod - extPeriod;
andrewboyson 4:095dfd4a316b 102 if (extPeriod < ONE_BILLION + GetClockMaxPpsDifference() &&
andrewboyson 4:095dfd4a316b 103 extPeriod > ONE_BILLION - GetClockMaxPpsDifference())
andrewboyson 0:33686e88f09a 104 {
andrewboyson 10:19ed22b94c99 105 adjustPpb(periodDiff);
andrewboyson 0:33686e88f09a 106 }
andrewboyson 0:33686e88f09a 107 }
andrewboyson 0:33686e88f09a 108
andrewboyson 0:33686e88f09a 109 //Save last values
andrewboyson 0:33686e88f09a 110 lastIntClock = thisIntClock;
andrewboyson 0:33686e88f09a 111 lastExtClock = thisExtClock;
andrewboyson 0:33686e88f09a 112
andrewboyson 0:33686e88f09a 113 }
andrewboyson 1:f3746f3cc345 114 void SyncNs(int64_t ns)
andrewboyson 1:f3746f3cc345 115 {
andrewboyson 2:55f070f05a43 116 int64_t thisExtClock = ns;
andrewboyson 10:19ed22b94c99 117 static int64_t lastIntClock = -1; //-1 indicates invalid value. 0 is a valid value.
andrewboyson 10:19ed22b94c99 118 static int64_t lastExtClock = -1;
andrewboyson 2:55f070f05a43 119
andrewboyson 5:a3e37ce4975d 120 if (!TickIsSet()) //Cold start - only ever true if the RTC was not set.
andrewboyson 2:55f070f05a43 121 {
andrewboyson 2:55f070f05a43 122 LogTimeF("Cold start of clock\r\n");
andrewboyson 2:55f070f05a43 123 TickSet(thisExtClock);
andrewboyson 10:19ed22b94c99 124 TickSetPpb(0);
andrewboyson 2:55f070f05a43 125 lastIntClock = 0;
andrewboyson 2:55f070f05a43 126 lastExtClock = 0;
andrewboyson 2:55f070f05a43 127 return;
andrewboyson 2:55f070f05a43 128 }
andrewboyson 2:55f070f05a43 129
andrewboyson 2:55f070f05a43 130 //Get the time at the time of the interrupt
andrewboyson 2:55f070f05a43 131 TickSaveSnapshotI();
andrewboyson 2:55f070f05a43 132 int64_t thisIntClock;
andrewboyson 2:55f070f05a43 133 int64_t thisAbsClock;
andrewboyson 6:d8a6235486b7 134 TickGetTimes(&thisIntClock, &thisAbsClock);
andrewboyson 10:19ed22b94c99 135
andrewboyson 2:55f070f05a43 136 //Calulate the time error
andrewboyson 2:55f070f05a43 137 int64_t absDiff = thisAbsClock - thisExtClock;
andrewboyson 4:095dfd4a316b 138 if (abs(absDiff) > GetClockMaxOffsetSecs() * (int64_t)ONE_BILLION)
andrewboyson 2:55f070f05a43 139 {
andrewboyson 10:19ed22b94c99 140 if (SyncTrace) LogTimeF("Sync - offset is greater than %d seconds so resetting Tick time and rate\r\n", GetClockMaxOffsetSecs());
andrewboyson 2:55f070f05a43 141 TickSet(thisExtClock);
andrewboyson 10:19ed22b94c99 142 TickSetPpb(0);
andrewboyson 2:55f070f05a43 143 lastIntClock = 0;
andrewboyson 2:55f070f05a43 144 lastExtClock = 0;
andrewboyson 2:55f070f05a43 145 return;
andrewboyson 2:55f070f05a43 146 }
andrewboyson 2:55f070f05a43 147 setSlew(absDiff);
andrewboyson 2:55f070f05a43 148
andrewboyson 2:55f070f05a43 149 //Calculate the rate error
andrewboyson 10:19ed22b94c99 150 if (lastExtClock > -1)
andrewboyson 2:55f070f05a43 151 {
andrewboyson 2:55f070f05a43 152 int64_t extPeriod = thisExtClock - lastExtClock;
andrewboyson 2:55f070f05a43 153
andrewboyson 2:55f070f05a43 154 int64_t intPeriod = thisIntClock - lastIntClock;
andrewboyson 2:55f070f05a43 155 int64_t periodDiff = intPeriod - extPeriod;
andrewboyson 2:55f070f05a43 156
andrewboyson 2:55f070f05a43 157 int64_t ppb = periodDiff * ONE_BILLION / extPeriod;
andrewboyson 10:19ed22b94c99 158 adjustPpb(ppb);
andrewboyson 2:55f070f05a43 159 }
andrewboyson 2:55f070f05a43 160
andrewboyson 2:55f070f05a43 161 //Save last values
andrewboyson 2:55f070f05a43 162 lastIntClock = thisIntClock;
andrewboyson 2:55f070f05a43 163 lastExtClock = thisExtClock;
andrewboyson 2:55f070f05a43 164
andrewboyson 1:f3746f3cc345 165 }