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
clock.c@17:927fc1eceb9d, 2018-01-11 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |