1123303Sphk/*- 2123303Sphk * Copyright (c) 1998-2003 Poul-Henning Kamp 3123303Sphk * 4123303Sphk * Please see src/share/examples/etc/bsd-style-copyright. 5123303Sphk * 6123303Sphk */ 7123303Sphk 8123303Sphk#include <sys/cdefs.h> 9123303Sphk__FBSDID("$FreeBSD: stable/11/tools/test/ppsapi/ppsapitest.c 323406 2017-09-11 00:19:09Z ian $"); 10123303Sphk 11123303Sphk#include <stdio.h> 12123303Sphk#include <stdint.h> 13123303Sphk#include <stdlib.h> 14123303Sphk#include <unistd.h> 15123303Sphk#include <fcntl.h> 16123303Sphk#include <err.h> 17123303Sphk#include <sys/timepps.h> 18123303Sphk 19123303Sphkstatic int aflag, Aflag, cflag, Cflag, eflag, uflag, vflag; 20123303Sphk 21123303Sphkstatic void 22123303SphkChew(struct timespec *tsa, struct timespec *tsc, unsigned sa, unsigned sc) 23123303Sphk{ 24123303Sphk printf("%jd .%09ld %u", (intmax_t)tsa->tv_sec, tsa->tv_nsec, sa); 25123303Sphk printf(" %jd .%09ld %u\n", (intmax_t)tsc->tv_sec, tsc->tv_nsec, sc); 26123303Sphk if (uflag) 27123303Sphk fflush(stdout); 28123303Sphk} 29123303Sphk 30123303Sphkint 31123303Sphkmain(int argc, char **argv) 32123303Sphk{ 33123303Sphk int fd; 34126820Sphk FILE *fdo; 35123303Sphk pps_info_t pi; 36123303Sphk pps_params_t pp; 37123303Sphk pps_handle_t ph; 38123303Sphk int i, mode; 39123303Sphk u_int olda, oldc; 40123303Sphk struct timespec to; 41126820Sphk char const *ofn; 42123303Sphk 43126820Sphk ofn = NULL; 44126820Sphk while ((i = getopt(argc, argv, "aAbBcCeo:uv")) != -1) { 45123303Sphk switch (i) { 46123303Sphk case 'a': aflag = 1; break; 47123303Sphk case 'A': Aflag = 1; break; 48123303Sphk case 'b': aflag = 1; cflag = 1; break; 49123303Sphk case 'B': Aflag = 1; Cflag = 1; break; 50123303Sphk case 'c': cflag = 1; break; 51123303Sphk case 'C': Cflag = 1; break; 52123303Sphk case 'e': eflag = 1; break; 53126820Sphk case 'o': ofn = optarg; break; 54123303Sphk case 'u': uflag = 1; break; 55123303Sphk case 'v': vflag = 1; break; 56123303Sphk case '?': 57123303Sphk default: 58123303Sphk fprintf(stderr, 59123303Sphk "Usage: ppsapitest [-aAcC] device\n"); 60123303Sphk exit (1); 61123303Sphk } 62123303Sphk } 63126820Sphk if (ofn != NULL) { 64126820Sphk fdo = fopen(ofn, "w"); 65126820Sphk if (fdo == NULL) 66126820Sphk err(1, "Cannot open %s", ofn); 67126820Sphk } else { 68126820Sphk fdo = NULL; 69126820Sphk } 70123303Sphk argc -= optind; 71123303Sphk argv += optind; 72123303Sphk if (argc > 0) { 73123303Sphk fd = open(argv[0], O_RDONLY); 74123303Sphk if (fd < 0) 75323406Sian err(1, "%s", argv[0]); 76123303Sphk } else { 77123303Sphk fd = 0; 78123303Sphk } 79123303Sphk i = time_pps_create(fd, &ph); 80123303Sphk if (i < 0) 81123303Sphk err(1, "time_pps_create"); 82123303Sphk 83123303Sphk i = time_pps_getcap(ph, &mode); 84123303Sphk if (i < 0) 85123303Sphk err(1, "time_pps_getcap"); 86123303Sphk if (vflag) { 87123303Sphk fprintf(stderr, "Supported modebits:"); 88123303Sphk if (mode & PPS_CAPTUREASSERT) 89123303Sphk fprintf(stderr, " CAPTUREASSERT"); 90123303Sphk if (mode & PPS_CAPTURECLEAR) 91123303Sphk fprintf(stderr, " CAPTURECLEAR"); 92123303Sphk if (mode & PPS_OFFSETASSERT) 93123303Sphk fprintf(stderr, " OFFSETASSERT"); 94123303Sphk if (mode & PPS_OFFSETCLEAR) 95123303Sphk fprintf(stderr, " OFFSETCLEAR"); 96123303Sphk if (mode & PPS_ECHOASSERT) 97123303Sphk fprintf(stderr, " ECHOASSERT"); 98123303Sphk if (mode & PPS_ECHOCLEAR) 99123303Sphk fprintf(stderr, " ECHOCLEAR"); 100123303Sphk if (mode & PPS_CANWAIT) 101123303Sphk fprintf(stderr, " CANWAIT"); 102123303Sphk if (mode & PPS_CANPOLL) 103123303Sphk fprintf(stderr, " CANPOLL"); 104123303Sphk if (mode & PPS_TSFMT_TSPEC) 105123303Sphk fprintf(stderr, " TSPEC"); 106123303Sphk if (mode & PPS_TSFMT_NTPFP) 107123303Sphk fprintf(stderr, " NTPFP"); 108123303Sphk fprintf(stderr, "\n"); 109123303Sphk } 110123303Sphk 111123303Sphk if (!aflag && !cflag) { 112123303Sphk if (mode & PPS_CAPTUREASSERT) 113123303Sphk aflag = 1; 114123303Sphk if (mode & PPS_CAPTURECLEAR) 115123303Sphk cflag = 1; 116123303Sphk } 117123303Sphk if (!Aflag && !Cflag) { 118123303Sphk Aflag = aflag; 119123303Sphk Cflag = cflag; 120123303Sphk } 121123303Sphk 122123303Sphk if (Cflag && !(mode & PPS_CAPTURECLEAR)) 123123303Sphk errx(1, "-C but cannot capture on clear flank"); 124123303Sphk 125123303Sphk if (Aflag && !(mode & PPS_CAPTUREASSERT)) 126123303Sphk errx(1, "-A but cannot capture on assert flank"); 127123303Sphk 128123303Sphk i = time_pps_getparams(ph, &pp); 129123303Sphk if (i < 0) 130123303Sphk err(1, "time_pps_getparams():"); 131123303Sphk 132123303Sphk if (aflag) 133123303Sphk pp.mode |= PPS_CAPTUREASSERT; 134123303Sphk if (cflag) 135123303Sphk pp.mode |= PPS_CAPTURECLEAR; 136123303Sphk 137123303Sphk if (eflag & aflag) 138123303Sphk pp.mode |= PPS_ECHOASSERT; 139123303Sphk 140123303Sphk if (eflag & cflag) 141123303Sphk pp.mode |= PPS_ECHOCLEAR; 142123303Sphk 143123303Sphk if (!(pp.mode & PPS_TSFMT_TSPEC)) 144123303Sphk pp.mode |= PPS_TSFMT_TSPEC; 145123303Sphk 146123303Sphk i = time_pps_setparams(ph, &pp); 147123303Sphk if (i < 0) { 148123303Sphk err(1, "time_pps_setparams(mode %x):", pp.mode); 149123303Sphk } 150123303Sphk 151123303Sphk /* 152123303Sphk * Pick up first event outside the loop in order to not 153123303Sphk * get something ancient into the outfile. 154123303Sphk */ 155123303Sphk to.tv_nsec = 0; 156123303Sphk to.tv_sec = 0; 157123303Sphk i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to); 158123303Sphk if (i < 0) 159123303Sphk err(1, "time_pps_fetch()"); 160123303Sphk olda = pi.assert_sequence; 161123303Sphk oldc = pi.clear_sequence; 162123303Sphk 163123303Sphk while (1) { 164123303Sphk to.tv_nsec = 0; 165123303Sphk to.tv_sec = 0; 166123303Sphk i = time_pps_fetch(ph, PPS_TSFMT_TSPEC, &pi, &to); 167123303Sphk if (i < 0) 168123303Sphk err(1, "time_pps_fetch()"); 169123303Sphk if (oldc != pi.clear_sequence && Cflag) 170123303Sphk ; 171123303Sphk else if (olda != pi.assert_sequence && Aflag) 172123303Sphk ; 173123303Sphk else { 174123303Sphk usleep(10000); 175123303Sphk continue; 176123303Sphk } 177126820Sphk if (fdo != NULL) { 178126820Sphk if (fwrite(&pi, sizeof pi, 1, fdo) != 1) 179126820Sphk err(1, "Write error on %s", ofn); 180126820Sphk if (uflag) 181126820Sphk fflush(fdo); 182126820Sphk } 183123303Sphk Chew(&pi.assert_timestamp, &pi.clear_timestamp, 184123303Sphk pi.assert_sequence, pi.clear_sequence); 185123303Sphk olda = pi.assert_sequence; 186123303Sphk oldc = pi.clear_sequence; 187123303Sphk } 188123303Sphk return(0); 189123303Sphk} 190