ppsapitest.c revision 126820
10Sduke/*-
22362Sohair * Copyright (c) 1998-2003 Poul-Henning Kamp
30Sduke *
40Sduke * Please see src/share/examples/etc/bsd-style-copyright.
50Sduke *
60Sduke */
70Sduke
80Sduke#include <sys/cdefs.h>
90Sduke__FBSDID("$FreeBSD: head/tools/test/ppsapi/ppsapitest.c 126820 2004-03-10 20:30:19Z phk $");
100Sduke
110Sduke#include <stdio.h>
120Sduke#include <stdint.h>
130Sduke#include <stdlib.h>
140Sduke#include <unistd.h>
150Sduke#include <fcntl.h>
160Sduke#include <err.h>
170Sduke#include <sys/timepps.h>
180Sduke
192362Sohairstatic int aflag, Aflag, cflag, Cflag, eflag, uflag, vflag;
202362Sohair
212362Sohairstatic void
220SdukeChew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc)
230Sduke{
240Sduke	printf("%jd .%09ld %u", (intmax_t)tsa->tv_sec, tsa->tv_nsec, sa);
250Sduke	printf(" %jd .%09ld %u\n", (intmax_t)tsc->tv_sec, tsc->tv_nsec, sc);
260Sduke	if (uflag)
270Sduke		fflush(stdout);
280Sduke}
290Sduke
300Sdukeint
310Sdukemain(int argc, char **argv)
320Sduke{
330Sduke	int fd;
340Sduke	FILE *fdo;
350Sduke	pps_info_t pi;
360Sduke	pps_params_t pp;
370Sduke	pps_handle_t ph;
380Sduke	int i, mode;
390Sduke	u_int olda, oldc;
400Sduke	struct timespec to;
410Sduke	char const *ofn;
420Sduke
430Sduke	ofn = NULL;
440Sduke	while ((i = getopt(argc, argv, "aAbBcCeo:uv")) != -1) {
450Sduke		switch (i) {
460Sduke		case 'a': aflag = 1; break;
470Sduke		case 'A': Aflag = 1; break;
480Sduke		case 'b': aflag = 1; cflag = 1; break;
490Sduke		case 'B': Aflag = 1; Cflag = 1; break;
500Sduke		case 'c': cflag = 1; break;
510Sduke		case 'C': Cflag = 1; break;
520Sduke		case 'e': eflag = 1; break;
530Sduke		case 'o': ofn = optarg; break;
540Sduke		case 'u': uflag = 1; break;
550Sduke		case 'v': vflag = 1; break;
560Sduke		case '?':
570Sduke		default:
580Sduke			fprintf(stderr,
590Sduke			    "Usage: ppsapitest [-aAcC] device\n");
600Sduke			exit (1);
610Sduke		}
620Sduke	}
630Sduke	if (ofn != NULL) {
640Sduke		fdo = fopen(ofn, "w");
650Sduke		if (fdo == NULL)
660Sduke			err(1, "Cannot open %s", ofn);
670Sduke	} else {
680Sduke		fdo = NULL;
690Sduke	}
700Sduke	argc -= optind;
710Sduke	argv += optind;
720Sduke	if (argc > 0) {
730Sduke		fd = open(argv[0], O_RDONLY);
740Sduke		if (fd < 0)
750Sduke			err(1, argv[0]);
760Sduke	} else {
770Sduke		fd = 0;
780Sduke	}
790Sduke	i = time_pps_create(fd, &ph);
800Sduke	if (i < 0)
810Sduke		err(1, "time_pps_create");
820Sduke
830Sduke	i = time_pps_getcap(ph, &mode);
840Sduke	if (i < 0)
850Sduke		err(1, "time_pps_getcap");
860Sduke	if (vflag) {
870Sduke		fprintf(stderr, "Supported modebits:");
880Sduke		if (mode & PPS_CAPTUREASSERT)
890Sduke			fprintf(stderr, " CAPTUREASSERT");
900Sduke		if (mode & PPS_CAPTURECLEAR)
910Sduke			fprintf(stderr, " CAPTURECLEAR");
920Sduke		if (mode & PPS_OFFSETASSERT)
930Sduke			fprintf(stderr, " OFFSETASSERT");
940Sduke		if (mode & PPS_OFFSETCLEAR)
950Sduke			fprintf(stderr, " OFFSETCLEAR");
960Sduke		if (mode & PPS_ECHOASSERT)
970Sduke			fprintf(stderr, " ECHOASSERT");
980Sduke		if (mode & PPS_ECHOCLEAR)
990Sduke			fprintf(stderr, " ECHOCLEAR");
1000Sduke		if (mode & PPS_CANWAIT)
1010Sduke			fprintf(stderr, " CANWAIT");
1020Sduke		if (mode & PPS_CANPOLL)
1030Sduke			fprintf(stderr, " CANPOLL");
1040Sduke		if (mode & PPS_TSFMT_TSPEC)
1050Sduke			fprintf(stderr, " TSPEC");
1060Sduke		if (mode & PPS_TSFMT_NTPFP)
1070Sduke			fprintf(stderr, " NTPFP");
1080Sduke		fprintf(stderr, "\n");
1090Sduke	}
1100Sduke
1110Sduke	if (!aflag && !cflag) {
1120Sduke		if (mode & PPS_CAPTUREASSERT)
1130Sduke			aflag = 1;
1140Sduke		if (mode & PPS_CAPTURECLEAR)
1150Sduke			cflag = 1;
1160Sduke	}
1170Sduke	if (!Aflag && !Cflag) {
1180Sduke		Aflag = aflag;
1190Sduke		Cflag = cflag;
1200Sduke	}
1210Sduke
1220Sduke	if (Cflag && !(mode & PPS_CAPTURECLEAR))
1230Sduke		errx(1, "-C but cannot capture on clear flank");
1240Sduke
1250Sduke	if (Aflag && !(mode & PPS_CAPTUREASSERT))
1260Sduke		errx(1, "-A but cannot capture on assert flank");
1270Sduke
1280Sduke	i = time_pps_getparams(ph, &pp);
1290Sduke	if (i < 0)
1300Sduke		err(1, "time_pps_getparams():");
1310Sduke
1320Sduke	if (aflag)
1330Sduke		pp.mode |= PPS_CAPTUREASSERT;
1340Sduke	if (cflag)
1350Sduke		pp.mode |= PPS_CAPTURECLEAR;
1360Sduke
1370Sduke	if (eflag & aflag)
1380Sduke		pp.mode |= PPS_ECHOASSERT;
1390Sduke
1400Sduke	if (eflag & cflag)
1410Sduke		pp.mode |= PPS_ECHOCLEAR;
1420Sduke
1430Sduke	if (!(pp.mode & PPS_TSFMT_TSPEC))
1440Sduke		pp.mode |= PPS_TSFMT_TSPEC;
1450Sduke
1460Sduke	i = time_pps_setparams(ph, &pp);
1470Sduke	if (i < 0) {
1480Sduke		err(1, "time_pps_setparams(mode %x):", pp.mode);
1490Sduke	}
1500Sduke
1510Sduke	/*
1520Sduke	 * Pick up first event outside the loop in order to not
1530Sduke	 * get something ancient into the outfile.
1540Sduke	 */
1550Sduke	to.tv_nsec = 0;
1560Sduke	to.tv_sec = 0;
157	i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
158	if (i < 0)
159		err(1, "time_pps_fetch()");
160	olda = pi.assert_sequence;
161	oldc = pi.clear_sequence;
162
163	while (1) {
164		to.tv_nsec = 0;
165		to.tv_sec = 0;
166		i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to);
167		if (i < 0)
168			err(1, "time_pps_fetch()");
169		if (oldc != pi.clear_sequence && Cflag)
170			;
171		else if (olda != pi.assert_sequence && Aflag)
172			;
173		else {
174			usleep(10000);
175			continue;
176		}
177		if (fdo != NULL) {
178			if (fwrite(&pi, sizeof pi, 1, fdo) != 1)
179				err(1, "Write error on %s", ofn);
180			if (uflag)
181				fflush(fdo);
182		}
183		Chew(&pi.assert_timestamp, &pi.clear_timestamp,
184			pi.assert_sequence, pi.clear_sequence);
185		olda = pi.assert_sequence;
186		oldc = pi.clear_sequence;
187	}
188	return(0);
189}
190