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 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 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