xref: /freebsd/contrib/ntp/include/ntp_calgps.h (revision e43d33d286a1aa41b6fc6a209f28a18e8cd7437a)
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
gpscal_from_calendar(TcCivilDate * pCiv,l_fp fofs)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
gpsntp_from_calendar(TcCivilDate * pCiv,l_fp fofs)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
gpsntp_from_daytime1(TcCivilDate * dt,l_fp fofs,l_fp pivot)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
gpsntp_from_daytime2(TcCivilDate * dt,l_fp fofs,TcNtpDatum * pivot)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
gpsntp_from_gpscal(TcGpsDatum * wd)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