1 /*-
2 * Copyright (c) 1998-2003 Poul-Henning Kamp
3 *
4 * Please see src/share/examples/etc/bsd-style-copyright.
5 *
6 */
7
8 #include <sys/cdefs.h>
9 #include <stdio.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <err.h>
15 #include <sys/timepps.h>
16
17 static int aflag, Aflag, cflag, Cflag, eflag, uflag, vflag;
18
19 static void
Chew(struct timespec * tsa,struct timespec * tsc,unsigned sa,unsigned sc)20 Chew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc)
21 {
22 printf("%jd .%09ld %u", (intmax_t)tsa->tv_sec, tsa->tv_nsec, sa);
23 printf(" %jd .%09ld %u\n", (intmax_t)tsc->tv_sec, tsc->tv_nsec, sc);
24 if (uflag)
25 fflush(stdout);
26 }
27
28 int
main(int argc,char ** argv)29 main(int argc, char **argv)
30 {
31 int fd;
32 FILE *fdo;
33 pps_info_t pi;
34 pps_params_t pp;
35 pps_handle_t ph;
36 int i, mode;
37 u_int olda, oldc;
38 struct timespec to;
39 char const *ofn;
40
41 ofn = NULL;
42 while ((i = getopt(argc, argv, "aAbBcCeo:uv")) != -1) {
43 switch (i) {
44 case 'a': aflag = 1; break;
45 case 'A': Aflag = 1; break;
46 case 'b': aflag = 1; cflag = 1; break;
47 case 'B': Aflag = 1; Cflag = 1; break;
48 case 'c': cflag = 1; break;
49 case 'C': Cflag = 1; break;
50 case 'e': eflag = 1; break;
51 case 'o': ofn = optarg; break;
52 case 'u': uflag = 1; break;
53 case 'v': vflag = 1; break;
54 case '?':
55 default:
56 fprintf(stderr,
57 "Usage: ppsapitest [-aAcC] device\n");
58 exit (1);
59 }
60 }
61 if (ofn != NULL) {
62 fdo = fopen(ofn, "w");
63 if (fdo == NULL)
64 err(1, "Cannot open %s", ofn);
65 } else {
66 fdo = NULL;
67 }
68 argc -= optind;
69 argv += optind;
70 if (argc > 0) {
71 fd = open(argv[0], O_RDONLY);
72 if (fd < 0)
73 err(1, "%s", argv[0]);
74 } else {
75 fd = 0;
76 }
77 i = time_pps_create(fd, &ph);
78 if (i < 0)
79 err(1, "time_pps_create");
80
81 i = time_pps_getcap(ph, &mode);
82 if (i < 0)
83 err(1, "time_pps_getcap");
84 if (vflag) {
85 fprintf(stderr, "Supported modebits:");
86 if (mode & PPS_CAPTUREASSERT)
87 fprintf(stderr, " CAPTUREASSERT");
88 if (mode & PPS_CAPTURECLEAR)
89 fprintf(stderr, " CAPTURECLEAR");
90 if (mode & PPS_OFFSETASSERT)
91 fprintf(stderr, " OFFSETASSERT");
92 if (mode & PPS_OFFSETCLEAR)
93 fprintf(stderr, " OFFSETCLEAR");
94 if (mode & PPS_ECHOASSERT)
95 fprintf(stderr, " ECHOASSERT");
96 if (mode & PPS_ECHOCLEAR)
97 fprintf(stderr, " ECHOCLEAR");
98 if (mode & PPS_CANWAIT)
99 fprintf(stderr, " CANWAIT");
100 if (mode & PPS_CANPOLL)
101 fprintf(stderr, " CANPOLL");
102 if (mode & PPS_TSFMT_TSPEC)
103 fprintf(stderr, " TSPEC");
104 if (mode & PPS_TSFMT_NTPFP)
105 fprintf(stderr, " NTPFP");
106 fprintf(stderr, "\n");
107 }
108
109 if (!aflag && !cflag) {
110 if (mode & PPS_CAPTUREASSERT)
111 aflag = 1;
112 if (mode & PPS_CAPTURECLEAR)
113 cflag = 1;
114 }
115 if (!Aflag && !Cflag) {
116 Aflag = aflag;
117 Cflag = cflag;
118 }
119
120 if (Cflag && !(mode & PPS_CAPTURECLEAR))
121 errx(1, "-C but cannot capture on clear flank");
122
123 if (Aflag && !(mode & PPS_CAPTUREASSERT))
124 errx(1, "-A but cannot capture on assert flank");
125
126 i = time_pps_getparams(ph, &pp);
127 if (i < 0)
128 err(1, "time_pps_getparams():");
129
130 if (aflag)
131 pp.mode |= PPS_CAPTUREASSERT;
132 if (cflag)
133 pp.mode |= PPS_CAPTURECLEAR;
134
135 if (eflag & aflag)
136 pp.mode |= PPS_ECHOASSERT;
137
138 if (eflag & cflag)
139 pp.mode |= PPS_ECHOCLEAR;
140
141 if (!(pp.mode & PPS_TSFMT_TSPEC))
142 pp.mode |= PPS_TSFMT_TSPEC;
143
144 i = time_pps_setparams(ph, &pp);
145 if (i < 0) {
146 err(1, "time_pps_setparams(mode %x):", pp.mode);
147 }
148
149 /*
150 * Pick up first event outside the loop in order to not
151 * get something ancient into the outfile.
152 */
153 to.tv_nsec = 0;
154 to.tv_sec = 0;
155 i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
156 if (i < 0)
157 err(1, "time_pps_fetch()");
158 olda = pi.assert_sequence;
159 oldc = pi.clear_sequence;
160
161 while (1) {
162 to.tv_nsec = 0;
163 to.tv_sec = 0;
164 i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
165 if (i < 0)
166 err(1, "time_pps_fetch()");
167 if (oldc != pi.clear_sequence && Cflag)
168 ;
169 else if (olda != pi.assert_sequence && Aflag)
170 ;
171 else {
172 usleep(10000);
173 continue;
174 }
175 if (fdo != NULL) {
176 if (fwrite(&pi, sizeof pi, 1, fdo) != 1)
177 err(1, "Write error on %s", ofn);
178 if (uflag)
179 fflush(fdo);
180 }
181 Chew(&pi.assert_timestamp, &pi.clear_timestamp,
182 pi.assert_sequence, pi.clear_sequence);
183 olda = pi.assert_sequence;
184 oldc = pi.clear_sequence;
185 }
186 return(0);
187 }
188