Subject: PPS diffs, round #3
To: None <tech-kern@NetBSD.ORG>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-kern
Date: 04/21/1998 20:51:02
OK, I think this patch addresses Chris Torek's point. It could in
principle be extended from just PPS phase-error sampling to other
kinds of ``timestamping'', though that'd still require an extended
ioctl interface to fetch those other timestamps.
For now, I'm punting on POSIX timespecs, since xntpd doesn't use them.
Obviously the API should include nanosecond resolution (or even
CPU-tick, for CPUs faster than 1Gz) when the kernel supports
nanotime() or better. Right now it'd be syntactic sugar,. and since
ntp expects timevals anyway, that's all I did.
I confess I cant rememebr the POSIX namespace rules: do just the DCD_*
`edge' values need to be protected, or the TIOC* namespace, too?
Index: sys/dev/ic/com.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/com.c,v
retrieving revision 1.143
diff -c -r1.143 com.c
*** com.c 1998/03/22 00:55:37 1.143
--- com.c 1998/04/22 03:44:48
***************
*** 595,600 ****
--- 595,605 ----
/* Clear any break condition set with TIOCSBRK. */
com_break(sc, 0);
+ /* Turn off PPS on last close. */
+ sc->sc_timestamp_state = DCD_NONE;
+ sc->sc_dopps = 0;
+
+
/*
* Hang up if necessary. Wait a bit, so the other side has time to
* notice even if we immediately open the port again.
***************
*** 689,694 ****
--- 694,704 ----
/* Fetch the current modem control status, needed later. */
sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr);
+ /* Clear PPS state on open. */
+ sc->sc_dopps = 0;
+ sc->sc_timestamp_state = 0;
+ bzero(&sc->sc_dcd_timestamp, sizeof(sc->sc_dcd_timestamp));
+
splx(s2);
/*
***************
*** 933,938 ****
--- 943,995 ----
*(int *)data = bits;
break;
}
+
+ case TIOCGTSTAMP:
+ *(int*) data = sc->sc_timestamp_state;
+ break;
+
+ case TIOCSTSTAMP:
+ sc->sc_timestamp_state = *(int*) data;
+ switch (sc->sc_timestamp_state) {
+ case DCD_NONE:
+ sc->sc_dopps = 0;
+ sc->sc_dcd_edgemask = 0;
+ break;
+
+ case DCD_LEADING_EDGE:
+ sc->sc_dopps = 1;
+ sc->sc_dcd_edgemask = MSR_DCD;
+ break;
+
+ case DCD_TRAILING_EDGE:
+ sc->sc_dopps = 1;
+ sc->sc_dcd_edgemask = 0;
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ break;
+
+ case TIOCDCDTIMESTAMP: /* XXX old, overloaded API */
+ sc->sc_dopps = 1;
+ /*
+ * Some GPS clocks models use the falling rather than
+ * rising edge as the on-the-second signal.
+ * The old API has no way to specify PPS polarity.
+ */
+ #ifndef PPS_TRAILING_EDGE
+ sc->sc_dcd_edgemask = MSR_DCD;
+ #else
+ sc->sc_dcd_edgemask = 0;
+ #endif
+ /*FALLTHROUGH*/
+
+ case TIOCFETCHLASTTSTAMP:
+ *(struct timeval *)data = sc->sc_dcd_timestamp;
+ break;
+
default:
error = ENOTTY;
break;
***************
*** 1749,1754 ****
--- 1806,1825 ----
sc->sc_msr = msr;
if (ISSET(delta, sc->sc_msr_mask)) {
SET(sc->sc_msr_delta, delta);
+
+ /*
+ * Pulse-per-second clock signal on edge of DCD?
+ */
+ if (sc->sc_dopps && ISSET(delta, MSR_DCD) &&
+ (delta & MSR_DCD) == sc->sc_dcd_edgemask) {
+ struct timeval tv;
+
+ microtime(&tv);
+ sc->sc_dcd_timestamp = tv;
+ #ifdef PPS_SYNC
+ hardpps(&tv, tv.usec);
+ #endif
+ }
/*
* Stop output immediately if we lose the output
Index: sys/dev/ic/comvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/comvar.h,v
retrieving revision 1.22
diff -c -r1.22 comvar.h
*** comvar.h 1998/02/02 23:01:05 1.22
--- comvar.h 1998/04/22 03:44:48
***************
*** 109,114 ****
--- 109,120 ----
void (*disable) __P((struct com_softc *));
int enabled;
+ /* Discipline system clock to pulse-per-second signal wire to DCD? */
+ int sc_timestamp_state; /* userlevel ioctl state */
+ int sc_dopps; /* boolean flag */
+ int sc_dcd_edgemask; /* edge mask */
+ struct timeval sc_dcd_timestamp;; /* XXX nanotime()? */
+
#if NRND > 0 && defined(RND_COM)
rndsource_element_t rnd_source;
#endif
Index: sys/sys/ttycom.h
===================================================================
RCS file: /cvsroot/src/sys/sys/ttycom.h,v
retrieving revision 1.8
diff -c -r1.8 ttycom.h
*** ttycom.h 1998/03/26 02:45:01 1.8
--- ttycom.h 1998/04/22 03:44:48
***************
*** 129,136 ****
--- 129,146 ----
#define TIOCFLAG_CRTSCTS 0x04 /* set crtscts on open */
#define TIOCFLAG_MDMBUF 0x08 /* set mdmbuf on open */
#define TIOCFLAG_CDTRCTS 0x10 /* set cdtrcts on open */
+
#define TIOCDCDTIMESTAMP _IOR('t', 88, struct timeval) /* get timestamp of last
* Cd rise, stamp next rise */
+ #define TIOCGTSTAMP _IOR('t', 82, int) /* get DCD-PPS timestamp state */
+ #define TIOCSTSTAMP _IOW('t', 83, int) /* set DCD-timestamp state */
+ #if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE)
+ #define DCD_NONE 0
+ #define DCD_LEADING_EDGE 1
+ #define DCD_TRAILING_EDGE 2
+ #endif
+ #define TIOCFETCHLASTTSTAMP _IOR('t', 84, struct timeval)
+ /* fetch most recent timestamp */
#define TTYDISC 0 /* termios tty line discipline */
#define TABLDISC 3 /* tablet discipline */