xref: /netbsd-src/external/bsd/ntp/dist/include/ntp_calgps.h (revision cdfa2a7ef92791ba9db70a584a1d904730e6fb46)
1*cdfa2a7eSchristos /*	$NetBSD: ntp_calgps.h,v 1.2 2020/05/25 20:47:19 christos Exp $	*/
2067f5680Schristos 
3067f5680Schristos /*
4067f5680Schristos  * ntp_calgps.h - calendar for GPS/GNSS based clocks
5067f5680Schristos  *
6067f5680Schristos  * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
7067f5680Schristos  * The contents of 'html/copyright.html' apply.
8067f5680Schristos  *
9067f5680Schristos  * --------------------------------------------------------------------
10067f5680Schristos  *
11067f5680Schristos  * This module implements stuff often used with GPS/GNSS receivers
12067f5680Schristos  */
13067f5680Schristos #ifndef NTP_CALGPS_H
14067f5680Schristos #define NTP_CALGPS_H
15067f5680Schristos 
16067f5680Schristos #include <time.h>
17067f5680Schristos 
18067f5680Schristos #include "ntp_types.h"
19067f5680Schristos #include "ntp_fp.h"
20067f5680Schristos #include "ntp_calendar.h"
21067f5680Schristos 
22067f5680Schristos /* GPS week calendar (extended weeks)
23067f5680Schristos  * We use weeks based on 1899-31-12, which was the last Sunday before
24067f5680Schristos  * the begin of the NTP epoch. (Which is equivalent to saying 1900-01-01
25067f5680Schristos  * was a Monday...)
26067f5680Schristos  *
27067f5680Schristos  * We simply pre-calculate the offsets and cycle shifts for the real GPS
28067f5680Schristos  * calendar, which starts at 1980-01-06, to simplyfy some expressions.
29067f5680Schristos  *
30067f5680Schristos  * This has a fringe benefit that should not be overlooked: Since week zero
31067f5680Schristos  * is around 1900, and we should never have to deal with dates before
32067f5680Schristos  * 1970 or 1980, a week number of zero can be easily used to indicate
33067f5680Schristos  * an invalid week time stamp.
34067f5680Schristos  */
35067f5680Schristos #define GPSNTP_WSHIFT	4175	/* weeks 1899-31-12 --> 1980-01-06 */
36067f5680Schristos #define GPSNTP_WCYCLE	  79	/* above, modulo 1024 */
37067f5680Schristos #define GPSNTP_DSHIFT	   1	/* day number of 1900-01-01 in week */
38067f5680Schristos 
39067f5680Schristos struct gpsdatum {
40067f5680Schristos 	uint32_t weeks;		/* weeks since GPS epoch	*/
41067f5680Schristos 	int32_t  wsecs;		/* seconds since week start	*/
42067f5680Schristos 	uint32_t frac;		/* fractional seconds		*/
43067f5680Schristos };
44067f5680Schristos typedef struct gpsdatum TGpsDatum;
45067f5680Schristos typedef struct gpsdatum const TcGpsDatum;
46067f5680Schristos 
47067f5680Schristos /* NTP date/time in split representation */
48067f5680Schristos struct ntpdatum {
49067f5680Schristos 	uint32_t days;		/* since NTP epoch		*/
50067f5680Schristos 	int32_t  secs;		/* since midnight, denorm is ok */
51067f5680Schristos 	uint32_t frac;		/* fractional seconds		*/
52067f5680Schristos };
53067f5680Schristos typedef struct ntpdatum TNtpDatum;
54067f5680Schristos typedef struct ntpdatum const TcNtpDatum;
55067f5680Schristos 
56067f5680Schristos /*
57067f5680Schristos  * GPS week/sec calendar functions
58067f5680Schristos  *
59067f5680Schristos  * see the implementation for details, especially the
60067f5680Schristos  * 'gpscal_from_weektime{1,2}()'
61067f5680Schristos  */
62067f5680Schristos 
63067f5680Schristos extern TGpsDatum
64067f5680Schristos gpscal_fix_gps_era(TcGpsDatum *);
65067f5680Schristos 
66067f5680Schristos extern void
67067f5680Schristos gpscal_add_offset(TGpsDatum *datum, l_fp offset);
68067f5680Schristos 
69067f5680Schristos extern TGpsDatum
70067f5680Schristos gpscal_from_calendar_ex(TcCivilDate*, l_fp fofs, int/*BOOL*/ warp);
71067f5680Schristos 
72067f5680Schristos static inline TGpsDatum
gpscal_from_calendar(TcCivilDate * pCiv,l_fp fofs)73067f5680Schristos gpscal_from_calendar(TcCivilDate *pCiv, l_fp fofs) {
74067f5680Schristos     return gpscal_from_calendar_ex(pCiv, fofs, TRUE);
75067f5680Schristos }
76067f5680Schristos 
77067f5680Schristos extern TGpsDatum 	/* see source for semantic of the 'fofs' value! */
78067f5680Schristos gpscal_from_gpsweek(uint16_t w, int32_t s, l_fp fofs);
79067f5680Schristos 
80067f5680Schristos extern TGpsDatum
81067f5680Schristos gpscal_from_weektime1(int32_t wsecs, l_fp fofs, l_fp pivot);
82067f5680Schristos 
83067f5680Schristos extern TGpsDatum
84067f5680Schristos gpscal_from_weektime2(int32_t wsecs, l_fp fofs,	TcGpsDatum *pivot);
85067f5680Schristos 
86067f5680Schristos extern void
87067f5680Schristos gpscal_to_calendar(TCivilDate*, TcGpsDatum*);
88067f5680Schristos 
89067f5680Schristos extern TGpsDatum
90067f5680Schristos gpscal_from_gpsntp(TcNtpDatum*);
91067f5680Schristos 
92067f5680Schristos extern l_fp
93067f5680Schristos ntpfp_from_gpsdatum(TcGpsDatum *);
94067f5680Schristos 
95067f5680Schristos /*
96067f5680Schristos  * NTP day/sec calendar functions
97067f5680Schristos  *
98067f5680Schristos  * see the implementation for details, especially the
99067f5680Schristos  * 'gpscal_from_daytime{1,2}()'
100067f5680Schristos  */
101067f5680Schristos extern TNtpDatum
102067f5680Schristos gpsntp_fix_gps_era(TcNtpDatum *);
103067f5680Schristos 
104067f5680Schristos extern void
105067f5680Schristos gpsntp_add_offset(TNtpDatum *datum, l_fp offset);
106067f5680Schristos 
107067f5680Schristos extern TNtpDatum
108067f5680Schristos gpsntp_from_calendar_ex(TcCivilDate*, l_fp fofs, int/*BOOL*/ warp);
109067f5680Schristos 
110067f5680Schristos static inline TNtpDatum
gpsntp_from_calendar(TcCivilDate * pCiv,l_fp fofs)111067f5680Schristos gpsntp_from_calendar(TcCivilDate * pCiv, l_fp fofs) {
112067f5680Schristos 	return gpsntp_from_calendar_ex(pCiv, fofs, TRUE);
113067f5680Schristos }
114067f5680Schristos 
115067f5680Schristos extern TNtpDatum
116067f5680Schristos gpsntp_from_daytime1_ex(TcCivilDate *dt, l_fp fofs, l_fp pivot, int/*BOOL*/ warp);
117067f5680Schristos 
118067f5680Schristos static inline TNtpDatum
gpsntp_from_daytime1(TcCivilDate * dt,l_fp fofs,l_fp pivot)119067f5680Schristos gpsntp_from_daytime1(TcCivilDate *dt, l_fp fofs, l_fp pivot) {
120067f5680Schristos 	return gpsntp_from_daytime1_ex(dt, fofs, pivot, TRUE);
121067f5680Schristos }
122067f5680Schristos 
123067f5680Schristos extern TNtpDatum
124067f5680Schristos gpsntp_from_daytime2_ex(TcCivilDate *dt, l_fp fofs, TcNtpDatum *pivot, int/*BOOL*/ warp);
125067f5680Schristos 
126067f5680Schristos static inline TNtpDatum
gpsntp_from_daytime2(TcCivilDate * dt,l_fp fofs,TcNtpDatum * pivot)127067f5680Schristos gpsntp_from_daytime2(TcCivilDate *dt, l_fp fofs, TcNtpDatum *pivot) {
128067f5680Schristos 	return gpsntp_from_daytime2_ex(dt, fofs, pivot, TRUE);
129067f5680Schristos }
130067f5680Schristos 
131067f5680Schristos extern TNtpDatum
132067f5680Schristos gpsntp_from_gpscal_ex(TcGpsDatum*, int/*BOOL*/ warp);
133067f5680Schristos 
134067f5680Schristos static inline TNtpDatum
gpsntp_from_gpscal(TcGpsDatum * wd)135067f5680Schristos gpsntp_from_gpscal(TcGpsDatum *wd) {
136067f5680Schristos 	return gpsntp_from_gpscal_ex(wd, FALSE);
137067f5680Schristos }
138067f5680Schristos 
139067f5680Schristos extern void
140067f5680Schristos gpsntp_to_calendar(TCivilDate*, TcNtpDatum*);
141067f5680Schristos 
142067f5680Schristos extern l_fp
143067f5680Schristos ntpfp_from_ntpdatum(TcNtpDatum*);
144067f5680Schristos 
145067f5680Schristos /*
146067f5680Schristos  * Some helpers
147067f5680Schristos  */
148067f5680Schristos 
149067f5680Schristos /* apply fudge to time stamp: *SUBTRACT* the given offset from an l_fp*/
150067f5680Schristos extern l_fp
151067f5680Schristos ntpfp_with_fudge(l_fp lfp, double ofs);
152067f5680Schristos 
153067f5680Schristos #endif /*!defined(NTP_CALGPS_H)*/
154