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