13d9368b2SPoul-Henning Kamp /*- 23d9368b2SPoul-Henning Kamp * Copyright (c) 1998-2003 Poul-Henning Kamp 33d9368b2SPoul-Henning Kamp * 43d9368b2SPoul-Henning Kamp * Please see src/share/examples/etc/bsd-style-copyright. 53d9368b2SPoul-Henning Kamp * 63d9368b2SPoul-Henning Kamp */ 73d9368b2SPoul-Henning Kamp 83d9368b2SPoul-Henning Kamp #include <sys/cdefs.h> 93d9368b2SPoul-Henning Kamp __FBSDID("$FreeBSD$"); 103d9368b2SPoul-Henning Kamp 113d9368b2SPoul-Henning Kamp #include <stdio.h> 123d9368b2SPoul-Henning Kamp #include <stdint.h> 133d9368b2SPoul-Henning Kamp #include <stdlib.h> 143d9368b2SPoul-Henning Kamp #include <unistd.h> 153d9368b2SPoul-Henning Kamp #include <fcntl.h> 163d9368b2SPoul-Henning Kamp #include <err.h> 173d9368b2SPoul-Henning Kamp #include <sys/timepps.h> 183d9368b2SPoul-Henning Kamp 193d9368b2SPoul-Henning Kamp static int aflag, Aflag, cflag, Cflag, eflag, uflag, vflag; 203d9368b2SPoul-Henning Kamp 213d9368b2SPoul-Henning Kamp static void 223d9368b2SPoul-Henning Kamp Chew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc) 233d9368b2SPoul-Henning Kamp { 243d9368b2SPoul-Henning Kamp printf("%jd .%09ld %u", (intmax_t)tsa->tv_sec, tsa->tv_nsec, sa); 253d9368b2SPoul-Henning Kamp printf(" %jd .%09ld %u\n", (intmax_t)tsc->tv_sec, tsc->tv_nsec, sc); 263d9368b2SPoul-Henning Kamp if (uflag) 273d9368b2SPoul-Henning Kamp fflush(stdout); 283d9368b2SPoul-Henning Kamp } 293d9368b2SPoul-Henning Kamp 303d9368b2SPoul-Henning Kamp int 313d9368b2SPoul-Henning Kamp main(int argc, char **argv) 323d9368b2SPoul-Henning Kamp { 333d9368b2SPoul-Henning Kamp int fd; 34724e52cdSPoul-Henning Kamp FILE *fdo; 353d9368b2SPoul-Henning Kamp pps_info_t pi; 363d9368b2SPoul-Henning Kamp pps_params_t pp; 373d9368b2SPoul-Henning Kamp pps_handle_t ph; 383d9368b2SPoul-Henning Kamp int i, mode; 393d9368b2SPoul-Henning Kamp u_int olda, oldc; 403d9368b2SPoul-Henning Kamp struct timespec to; 41724e52cdSPoul-Henning Kamp char const *ofn; 423d9368b2SPoul-Henning Kamp 43724e52cdSPoul-Henning Kamp ofn = NULL; 44724e52cdSPoul-Henning Kamp while ((i = getopt(argc, argv, "aAbBcCeo:uv")) != -1) { 453d9368b2SPoul-Henning Kamp switch (i) { 463d9368b2SPoul-Henning Kamp case 'a': aflag = 1; break; 473d9368b2SPoul-Henning Kamp case 'A': Aflag = 1; break; 483d9368b2SPoul-Henning Kamp case 'b': aflag = 1; cflag = 1; break; 493d9368b2SPoul-Henning Kamp case 'B': Aflag = 1; Cflag = 1; break; 503d9368b2SPoul-Henning Kamp case 'c': cflag = 1; break; 513d9368b2SPoul-Henning Kamp case 'C': Cflag = 1; break; 523d9368b2SPoul-Henning Kamp case 'e': eflag = 1; break; 53724e52cdSPoul-Henning Kamp case 'o': ofn = optarg; break; 543d9368b2SPoul-Henning Kamp case 'u': uflag = 1; break; 553d9368b2SPoul-Henning Kamp case 'v': vflag = 1; break; 563d9368b2SPoul-Henning Kamp case '?': 573d9368b2SPoul-Henning Kamp default: 583d9368b2SPoul-Henning Kamp fprintf(stderr, 593d9368b2SPoul-Henning Kamp "Usage: ppsapitest [-aAcC] device\n"); 603d9368b2SPoul-Henning Kamp exit (1); 613d9368b2SPoul-Henning Kamp } 623d9368b2SPoul-Henning Kamp } 63724e52cdSPoul-Henning Kamp if (ofn != NULL) { 64724e52cdSPoul-Henning Kamp fdo = fopen(ofn, "w"); 65724e52cdSPoul-Henning Kamp if (fdo == NULL) 66724e52cdSPoul-Henning Kamp err(1, "Cannot open %s", ofn); 67724e52cdSPoul-Henning Kamp } else { 68724e52cdSPoul-Henning Kamp fdo = NULL; 69724e52cdSPoul-Henning Kamp } 703d9368b2SPoul-Henning Kamp argc -= optind; 713d9368b2SPoul-Henning Kamp argv += optind; 723d9368b2SPoul-Henning Kamp if (argc > 0) { 733d9368b2SPoul-Henning Kamp fd = open(argv[0], O_RDONLY); 743d9368b2SPoul-Henning Kamp if (fd < 0) 753d9368b2SPoul-Henning Kamp err(1, argv[0]); 763d9368b2SPoul-Henning Kamp } else { 773d9368b2SPoul-Henning Kamp fd = 0; 783d9368b2SPoul-Henning Kamp } 793d9368b2SPoul-Henning Kamp i = time_pps_create(fd, &ph); 803d9368b2SPoul-Henning Kamp if (i < 0) 813d9368b2SPoul-Henning Kamp err(1, "time_pps_create"); 823d9368b2SPoul-Henning Kamp 833d9368b2SPoul-Henning Kamp i = time_pps_getcap(ph, &mode); 843d9368b2SPoul-Henning Kamp if (i < 0) 853d9368b2SPoul-Henning Kamp err(1, "time_pps_getcap"); 863d9368b2SPoul-Henning Kamp if (vflag) { 873d9368b2SPoul-Henning Kamp fprintf(stderr, "Supported modebits:"); 883d9368b2SPoul-Henning Kamp if (mode & PPS_CAPTUREASSERT) 893d9368b2SPoul-Henning Kamp fprintf(stderr, " CAPTUREASSERT"); 903d9368b2SPoul-Henning Kamp if (mode & PPS_CAPTURECLEAR) 913d9368b2SPoul-Henning Kamp fprintf(stderr, " CAPTURECLEAR"); 923d9368b2SPoul-Henning Kamp if (mode & PPS_OFFSETASSERT) 933d9368b2SPoul-Henning Kamp fprintf(stderr, " OFFSETASSERT"); 943d9368b2SPoul-Henning Kamp if (mode & PPS_OFFSETCLEAR) 953d9368b2SPoul-Henning Kamp fprintf(stderr, " OFFSETCLEAR"); 963d9368b2SPoul-Henning Kamp if (mode & PPS_ECHOASSERT) 973d9368b2SPoul-Henning Kamp fprintf(stderr, " ECHOASSERT"); 983d9368b2SPoul-Henning Kamp if (mode & PPS_ECHOCLEAR) 993d9368b2SPoul-Henning Kamp fprintf(stderr, " ECHOCLEAR"); 1003d9368b2SPoul-Henning Kamp if (mode & PPS_CANWAIT) 1013d9368b2SPoul-Henning Kamp fprintf(stderr, " CANWAIT"); 1023d9368b2SPoul-Henning Kamp if (mode & PPS_CANPOLL) 1033d9368b2SPoul-Henning Kamp fprintf(stderr, " CANPOLL"); 1043d9368b2SPoul-Henning Kamp if (mode & PPS_TSFMT_TSPEC) 1053d9368b2SPoul-Henning Kamp fprintf(stderr, " TSPEC"); 1063d9368b2SPoul-Henning Kamp if (mode & PPS_TSFMT_NTPFP) 1073d9368b2SPoul-Henning Kamp fprintf(stderr, " NTPFP"); 1083d9368b2SPoul-Henning Kamp fprintf(stderr, "\n"); 1093d9368b2SPoul-Henning Kamp } 1103d9368b2SPoul-Henning Kamp 1113d9368b2SPoul-Henning Kamp if (!aflag && !cflag) { 1123d9368b2SPoul-Henning Kamp if (mode & PPS_CAPTUREASSERT) 1133d9368b2SPoul-Henning Kamp aflag = 1; 1143d9368b2SPoul-Henning Kamp if (mode & PPS_CAPTURECLEAR) 1153d9368b2SPoul-Henning Kamp cflag = 1; 1163d9368b2SPoul-Henning Kamp } 1173d9368b2SPoul-Henning Kamp if (!Aflag && !Cflag) { 1183d9368b2SPoul-Henning Kamp Aflag = aflag; 1193d9368b2SPoul-Henning Kamp Cflag = cflag; 1203d9368b2SPoul-Henning Kamp } 1213d9368b2SPoul-Henning Kamp 1223d9368b2SPoul-Henning Kamp if (Cflag && !(mode & PPS_CAPTURECLEAR)) 1233d9368b2SPoul-Henning Kamp errx(1, "-C but cannot capture on clear flank"); 1243d9368b2SPoul-Henning Kamp 1253d9368b2SPoul-Henning Kamp if (Aflag && !(mode & PPS_CAPTUREASSERT)) 1263d9368b2SPoul-Henning Kamp errx(1, "-A but cannot capture on assert flank"); 1273d9368b2SPoul-Henning Kamp 1283d9368b2SPoul-Henning Kamp i = time_pps_getparams(ph, &pp); 1293d9368b2SPoul-Henning Kamp if (i < 0) 1303d9368b2SPoul-Henning Kamp err(1, "time_pps_getparams():"); 1313d9368b2SPoul-Henning Kamp 1323d9368b2SPoul-Henning Kamp if (aflag) 1333d9368b2SPoul-Henning Kamp pp.mode |= PPS_CAPTUREASSERT; 1343d9368b2SPoul-Henning Kamp if (cflag) 1353d9368b2SPoul-Henning Kamp pp.mode |= PPS_CAPTURECLEAR; 1363d9368b2SPoul-Henning Kamp 1373d9368b2SPoul-Henning Kamp if (eflag & aflag) 1383d9368b2SPoul-Henning Kamp pp.mode |= PPS_ECHOASSERT; 1393d9368b2SPoul-Henning Kamp 1403d9368b2SPoul-Henning Kamp if (eflag & cflag) 1413d9368b2SPoul-Henning Kamp pp.mode |= PPS_ECHOCLEAR; 1423d9368b2SPoul-Henning Kamp 1433d9368b2SPoul-Henning Kamp if (!(pp.mode & PPS_TSFMT_TSPEC)) 1443d9368b2SPoul-Henning Kamp pp.mode |= PPS_TSFMT_TSPEC; 1453d9368b2SPoul-Henning Kamp 1463d9368b2SPoul-Henning Kamp i = time_pps_setparams(ph, &pp); 1473d9368b2SPoul-Henning Kamp if (i < 0) { 1483d9368b2SPoul-Henning Kamp err(1, "time_pps_setparams(mode %x):", pp.mode); 1493d9368b2SPoul-Henning Kamp } 1503d9368b2SPoul-Henning Kamp 1513d9368b2SPoul-Henning Kamp /* 1523d9368b2SPoul-Henning Kamp * Pick up first event outside the loop in order to not 1533d9368b2SPoul-Henning Kamp * get something ancient into the outfile. 1543d9368b2SPoul-Henning Kamp */ 1553d9368b2SPoul-Henning Kamp to.tv_nsec = 0; 1563d9368b2SPoul-Henning Kamp to.tv_sec = 0; 1573d9368b2SPoul-Henning Kamp i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to); 1583d9368b2SPoul-Henning Kamp if (i < 0) 1593d9368b2SPoul-Henning Kamp err(1, "time_pps_fetch()"); 1603d9368b2SPoul-Henning Kamp olda = pi.assert_sequence; 1613d9368b2SPoul-Henning Kamp oldc = pi.clear_sequence; 1623d9368b2SPoul-Henning Kamp 1633d9368b2SPoul-Henning Kamp while (1) { 1643d9368b2SPoul-Henning Kamp to.tv_nsec = 0; 1653d9368b2SPoul-Henning Kamp to.tv_sec = 0; 1663d9368b2SPoul-Henning Kamp i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to); 1673d9368b2SPoul-Henning Kamp if (i < 0) 1683d9368b2SPoul-Henning Kamp err(1, "time_pps_fetch()"); 1693d9368b2SPoul-Henning Kamp if (oldc != pi.clear_sequence && Cflag) 1703d9368b2SPoul-Henning Kamp ; 1713d9368b2SPoul-Henning Kamp else if (olda != pi.assert_sequence && Aflag) 1723d9368b2SPoul-Henning Kamp ; 1733d9368b2SPoul-Henning Kamp else { 1743d9368b2SPoul-Henning Kamp usleep(10000); 1753d9368b2SPoul-Henning Kamp continue; 1763d9368b2SPoul-Henning Kamp } 177724e52cdSPoul-Henning Kamp if (fdo != NULL) { 178724e52cdSPoul-Henning Kamp if (fwrite(&pi, sizeof pi, 1, fdo) != 1) 179724e52cdSPoul-Henning Kamp err(1, "Write error on %s", ofn); 180724e52cdSPoul-Henning Kamp if (uflag) 181724e52cdSPoul-Henning Kamp fflush(fdo); 182724e52cdSPoul-Henning Kamp } 1833d9368b2SPoul-Henning Kamp Chew(&pi.assert_timestamp, &pi.clear_timestamp, 1843d9368b2SPoul-Henning Kamp pi.assert_sequence, pi.clear_sequence); 1853d9368b2SPoul-Henning Kamp olda = pi.assert_sequence; 1863d9368b2SPoul-Henning Kamp oldc = pi.clear_sequence; 1873d9368b2SPoul-Henning Kamp } 1883d9368b2SPoul-Henning Kamp return(0); 1893d9368b2SPoul-Henning Kamp } 190