Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
sync.cpp@10:19ed22b94c99, 2017-10-10 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |