1 /* $NetBSD: ntp_calgps.h,v 1.2 2020/05/25 20:47:19 christos Exp $ */ 2 3 /* 4 * ntp_calgps.h - calendar for GPS/GNSS based clocks 5 * 6 * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project. 7 * The contents of 'html/copyright.html' apply. 8 * 9 * -------------------------------------------------------------------- 10 * 11 * This module implements stuff often used with GPS/GNSS receivers 12 */ 13 #ifndef NTP_CALGPS_H 14 #define NTP_CALGPS_H 15 16 #include <time.h> 17 18 #include "ntp_types.h" 19 #include "ntp_fp.h" 20 #include "ntp_calendar.h" 21 22 /* GPS week calendar (extended weeks) 23 * We use weeks based on 1899-31-12, which was the last Sunday before 24 * the begin of the NTP epoch. (Which is equivalent to saying 1900-01-01 25 * was a Monday...) 26 * 27 * We simply pre-calculate the offsets and cycle shifts for the real GPS 28 * calendar, which starts at 1980-01-06, to simplyfy some expressions. 29 * 30 * This has a fringe benefit that should not be overlooked: Since week zero 31 * is around 1900, and we should never have to deal with dates before 32 * 1970 or 1980, a week number of zero can be easily used to indicate 33 * an invalid week time stamp. 34 */ 35 #define GPSNTP_WSHIFT 4175 /* weeks 1899-31-12 --> 1980-01-06 */ 36 #define GPSNTP_WCYCLE 79 /* above, modulo 1024 */ 37 #define GPSNTP_DSHIFT 1 /* day number of 1900-01-01 in week */ 38 39 struct gpsdatum { 40 uint32_t weeks; /* weeks since GPS epoch */ 41 int32_t wsecs; /* seconds since week start */ 42 uint32_t frac; /* fractional seconds */ 43 }; 44 typedef struct gpsdatum TGpsDatum; 45 typedef struct gpsdatum const TcGpsDatum; 46 47 /* NTP date/time in split representation */ 48 struct ntpdatum { 49 uint32_t days; /* since NTP epoch */ 50 int32_t secs; /* since midnight, denorm is ok */ 51 uint32_t frac; /* fractional seconds */ 52 }; 53 typedef struct ntpdatum TNtpDatum; 54 typedef struct ntpdatum const TcNtpDatum; 55 56 /* 57 * GPS week/sec calendar functions 58 * 59 * see the implementation for details, especially the 60 * 'gpscal_from_weektime{1,2}()' 61 */ 62 63 extern TGpsDatum 64 gpscal_fix_gps_era(TcGpsDatum *); 65 66 extern void 67 gpscal_add_offset(TGpsDatum *datum, l_fp offset); 68 69 extern TGpsDatum 70 gpscal_from_calendar_ex(TcCivilDate*, l_fp fofs, int/*BOOL*/ warp); 71 72 static inline TGpsDatum 73 gpscal_from_calendar(TcCivilDate *pCiv, l_fp fofs) { 74 return gpscal_from_calendar_ex(pCiv, fofs, TRUE); 75 } 76 77 extern TGpsDatum /* see source for semantic of the 'fofs' value! */ 78 gpscal_from_gpsweek(uint16_t w, int32_t s, l_fp fofs); 79 80 extern TGpsDatum 81 gpscal_from_weektime1(int32_t wsecs, l_fp fofs, l_fp pivot); 82 83 extern TGpsDatum 84 gpscal_from_weektime2(int32_t wsecs, l_fp fofs, TcGpsDatum *pivot); 85 86 extern void 87 gpscal_to_calendar(TCivilDate*, TcGpsDatum*); 88 89 extern TGpsDatum 90 gpscal_from_gpsntp(TcNtpDatum*); 91 92 extern l_fp 93 ntpfp_from_gpsdatum(TcGpsDatum *); 94 95 /* 96 * NTP day/sec calendar functions 97 * 98 * see the implementation for details, especially the 99 * 'gpscal_from_daytime{1,2}()' 100 */ 101 extern TNtpDatum 102 gpsntp_fix_gps_era(TcNtpDatum *); 103 104 extern void 105 gpsntp_add_offset(TNtpDatum *datum, l_fp offset); 106 107 extern TNtpDatum 108 gpsntp_from_calendar_ex(TcCivilDate*, l_fp fofs, int/*BOOL*/ warp); 109 110 static inline TNtpDatum 111 gpsntp_from_calendar(TcCivilDate * pCiv, l_fp fofs) { 112 return gpsntp_from_calendar_ex(pCiv, fofs, TRUE); 113 } 114 115 extern TNtpDatum 116 gpsntp_from_daytime1_ex(TcCivilDate *dt, l_fp fofs, l_fp pivot, int/*BOOL*/ warp); 117 118 static inline TNtpDatum 119 gpsntp_from_daytime1(TcCivilDate *dt, l_fp fofs, l_fp pivot) { 120 return gpsntp_from_daytime1_ex(dt, fofs, pivot, TRUE); 121 } 122 123 extern TNtpDatum 124 gpsntp_from_daytime2_ex(TcCivilDate *dt, l_fp fofs, TcNtpDatum *pivot, int/*BOOL*/ warp); 125 126 static inline TNtpDatum 127 gpsntp_from_daytime2(TcCivilDate *dt, l_fp fofs, TcNtpDatum *pivot) { 128 return gpsntp_from_daytime2_ex(dt, fofs, pivot, TRUE); 129 } 130 131 extern TNtpDatum 132 gpsntp_from_gpscal_ex(TcGpsDatum*, int/*BOOL*/ warp); 133 134 static inline TNtpDatum 135 gpsntp_from_gpscal(TcGpsDatum *wd) { 136 return gpsntp_from_gpscal_ex(wd, FALSE); 137 } 138 139 extern void 140 gpsntp_to_calendar(TCivilDate*, TcNtpDatum*); 141 142 extern l_fp 143 ntpfp_from_ntpdatum(TcNtpDatum*); 144 145 /* 146 * Some helpers 147 */ 148 149 /* apply fudge to time stamp: *SUBTRACT* the given offset from an l_fp*/ 150 extern l_fp 151 ntpfp_with_fudge(l_fp lfp, double ofs); 152 153 #endif /*!defined(NTP_CALGPS_H)*/ 154