xref: /netbsd-src/external/bsd/ntp/dist/util/pps-api.c (revision cdfa2a7ef92791ba9db70a584a1d904730e6fb46)
1 /*	$NetBSD: pps-api.c,v 1.5 2020/05/25 20:47:37 christos Exp $	*/
2 
3 /*
4 
5 Try to run this program to see what the PPS-API finds. You give it the
6 device as argument and you may have to modify the pp.mode = BLA assignment.
7 
8 Poul-Henning
9 
10 */
11 
12 #include <stdio.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <err.h>
16 #include <sys/types.h>
17 #include <time.h>
18 #include <sys/timepps.h>
19 #include <sys/termios.h>
20 
21 #define timespecsub(vvp, uvp)                                           \
22         do {                                                            \
23                 (vvp)->tv_sec -= (uvp)->tv_sec;                         \
24                 (vvp)->tv_nsec -= (uvp)->tv_nsec;                       \
25                 if ((vvp)->tv_nsec < 0) {                               \
26                         (vvp)->tv_sec--;                                \
27                         (vvp)->tv_nsec += 1000000000;                   \
28                 }                                                       \
29         } while (0)
30 
31 
32 void
Chew(struct timespec * tsa,struct timespec * tsc,unsigned sa,unsigned sc)33 Chew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc)
34 {
35 	static int idx;
36 	struct timespec ts;
37 
38 	printf("%d.%09d ", tsa->tv_sec, tsa->tv_nsec);
39 	printf("%d.%09d ", tsc->tv_sec, tsc->tv_nsec);
40 	printf("%u %u ", sa, sc);
41 
42 	ts = *tsc;
43 	timespecsub(&ts,tsa);
44 	printf("%.9f ", ts.tv_sec + ts.tv_nsec / 1e9);
45 	printf("\n");
46 	fflush(stdout);
47 }
48 
49 int
main(int argc,char ** argv)50 main(int argc, char **argv)
51 {
52 	int fd;
53 	pps_info_t pi;
54 	pps_params_t pp;
55 	pps_handle_t ph;
56 	int i, mode;
57 	u_int olda, oldc;
58 	double d = 0;
59 	struct timespec to;
60 
61 	if (argc < 2)
62 		argv[1] = "/dev/cuaa1";
63 	setbuf(stdout, 0);
64 	fd = open(argv[1], O_RDONLY);
65 	if (fd < 0)
66 		err(1, argv[1]);
67 	i = time_pps_create(fd, &ph);
68 	if (i < 0)
69 		err(1, "time_pps_create");
70 
71 	i = time_pps_getcap(ph, &mode);
72 	if (i < 0)
73 		err(1, "time_pps_getcap");
74 
75 	pp.mode = PPS_CAPTUREASSERT | PPS_ECHOASSERT;
76 	pp.mode = PPS_CAPTUREBOTH;
77 	/* pp.mode = PPS_CAPTUREASSERT; */
78 
79 	i = time_pps_setparams(ph, &pp);
80 	if (i < 0)
81 		err(1, "time_pps_setparams");
82 
83 	while (1) {
84 		to.tv_nsec = 0;
85 		to.tv_sec = 0;
86 		i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
87 		if (i < 0)
88 			err(1, "time_pps_fetch");
89 		if (olda == pi.assert_sequence &&
90 		    oldc == pi.clear_sequence) {
91 			usleep(10000);
92 			continue;
93 		}
94 
95 		Chew(&pi.assert_timestamp, &pi.clear_timestamp,
96 			pi.assert_sequence, pi.clear_sequence);
97 		olda = pi.assert_sequence;
98 		oldc = pi.clear_sequence;
99 	}
100 
101 	return(0);
102 }
103