Subject: PPS diffs, round #4
To: Jason Thorpe <thorpej@nas.nasa.gov>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-kern
Date: 04/21/1998 23:09:24
This does the timespec thing, tho' using the dreaded a local temp
rather than a kludgy pointer cast. Since the API is more general
than just PPS, i changed the softc names too.
Getting close to something we can commit?
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 06:11:35
***************
*** 595,600 ****
--- 595,604 ----
/* Clear any break condition set with TIOCSBRK. */
com_break(sc, 0);
+ /* Turn off PPS on last close. */
+ sc->sc_timestamp_state = PPS_NONE;
+ sc->sc_ppsmask = 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 ****
--- 693,703 ----
/* 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_ppsmask = 0;
+ sc->sc_timestamp_state = PPS_NONE;
+ bzero(&sc->sc_pps_timestamp, sizeof(sc->sc_pps_timestamp));
+
splx(s2);
/*
***************
*** 933,938 ****
--- 942,999 ----
*(int *)data = bits;
break;
}
+
+ case TIOCGTSTAMP:
+ *(int*) data = sc->sc_timestamp_state;
+ break;
+
+ case TIOCSTSTAMP:
+ /*
+ * Compute msr masks from user-specified timestamp state.
+ */
+ switch (sc->sc_timestamp_state) {
+ case PPS_NONE:
+ sc->sc_ppsmask = 0;
+ sc->sc_ppsedge = 0;
+ break;
+
+ case PPS_DCD_LEADING_EDGE:
+ sc->sc_ppsedge = MSR_DCD;
+ sc->sc_ppsmask = MSR_DCD;
+ break;
+
+ case PPS_DCD_TRAILING_EDGE:
+ sc->sc_ppsedge = 0;
+ sc->sc_ppsmask = MSR_DCD;
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+ sc->sc_timestamp_state = *(int*) data;
+ break;
+
+ case TIOCDCDTIMESTAMP: /* XXX old, overloaded API */
+ /*
+ * 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_ppsedge = MSR_DCD;
+ #else
+ sc->sc_ppsmask = 0;
+ #endif
+ sc->sc_ppsedge = MSR_DCD;
+ TIMESPEC_TO_TIMEVAL((struct timeval*)data,
+ &sc->sc_pps_timestamp);
+ break;
+
+ case TIOCTSTAMP:
+ *(struct timespec *)data = sc->sc_pps_timestamp;
+ break;
+
default:
error = ENOTTY;
break;
***************
*** 1749,1754 ****
--- 1810,1831 ----
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 (ISSET(delta, sc->sc_ppsmask) &&
+ (msr & sc->sc_ppsmask) == sc->sc_ppsedge) {
+ struct timeval tv;
+
+ /* XXX nanotime() */
+ microtime(&tv);
+ TIMEVAL_TO_TIMESPEC(&tv,
+ &sc->sc_pps_timestamp);
+ #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 06:11:35
***************
*** 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_ppsmask; /* pps signal mask */
+ int sc_ppsedge; /* pps edge mask */
+ struct timespec sc_pps_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 06:11:35
***************
*** 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 PPS_NONE 0
+ #define PPS_DCD_LEADING_EDGE 1
+ #define PPS_DCD_TRAILING_EDGE 2
+ #endif
+ #define TIOCTSTAMP _IOR('t', 84, struct timespec)
+ /* fetch most recent timestamp */
#define TTYDISC 0 /* termios tty line discipline */
#define TABLDISC 3 /* tablet discipline */