1/*	$NetBSD: pps-api.c,v 1.5 2020/05/25 20:47:37 christos Exp $	*/
2
3/*
4
5Try to run this program to see what the PPS-API finds. You give it the
6device as argument and you may have to modify the pp.mode = BLA assignment.
7
8Poul-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
32void
33Chew(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
49int
50main(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