xref: /netbsd-src/external/bsd/ntp/dist/include/ntp_calgps.h (revision cdfa2a7ef92791ba9db70a584a1d904730e6fb46)
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
gpscal_from_calendar(TcCivilDate * pCiv,l_fp fofs)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
gpsntp_from_calendar(TcCivilDate * pCiv,l_fp fofs)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
gpsntp_from_daytime1(TcCivilDate * dt,l_fp fofs,l_fp pivot)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
gpsntp_from_daytime2(TcCivilDate * dt,l_fp fofs,TcNtpDatum * pivot)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
gpsntp_from_gpscal(TcGpsDatum * wd)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