From a3d971d99da6c9c2a860d0863b2f7995f7605ffb Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 7 Jun 1998 19:44:22 +0000 Subject: This is a prototype implementation of the draft-mogul-pps-api-##.txt paper. It will be updated along with the draft and possible subsequent standard. The ppbus based pps driver is updated to implement this API. --- include/Makefile | 6 +-- include/timepps.h | 86 ++++++++++++++++++++++++++++++++++++++ sys/dev/ppbus/ppbconf.h | 3 +- sys/dev/ppbus/pps.c | 109 ++++++++++++++++++++++++++---------------------- sys/sys/timepps.h | 67 +++++++++++++++++++++++++++++ 5 files changed, 218 insertions(+), 53 deletions(-) create mode 100644 include/timepps.h create mode 100644 sys/sys/timepps.h diff --git a/include/Makefile b/include/Makefile index cca7b0b..a03da72 100644 --- a/include/Makefile +++ b/include/Makefile @@ -1,5 +1,5 @@ # From: @(#)Makefile 8.2 (Berkeley) 1/4/94 -# $Id: Makefile,v 1.76 1998/03/28 11:48:14 dufault Exp $ +# $Id: Makefile,v 1.77 1998/05/21 19:21:43 eivind Exp $ # # Doing a make install builds /usr/include # @@ -18,8 +18,8 @@ FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \ paths.h pthread.h pthread_np.h pwd.h \ ranlib.h regex.h regexp.h resolv.h rune.h runetype.h setjmp.h sgtty.h \ signal.h stab.h stddef.h stdio.h stdlib.h string.h stringlist.h \ - strings.h struct.h sysexits.h tar.h time.h timers.h ttyent.h unistd.h \ - utime.h utmp.h vis.h + strings.h struct.h sysexits.h tar.h time.h timepps.h timers.h \ + ttyent.h unistd.h utime.h utmp.h vis.h .if defined(WANT_CSRG_LIBM) FILES+= math.h .endif diff --git a/include/timepps.h b/include/timepps.h new file mode 100644 index 0000000..c9277ce --- /dev/null +++ b/include/timepps.h @@ -0,0 +1,86 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + * The is a FreeBSD protype version of the "draft-mogul-pps-api-02.txt" + * specification for Pulse Per Second timing interfaces. + * + */ + +#ifndef _TIME_PPS_H_ +#define _TIME_PPS_H_ + +#include + +int time_pps_create(int filedes, pps_handle_t *handle); +int time_pps_destroy(pps_handle_t handle); +int time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams); +int time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams); +int time_pps_getcap(pps_handle_t handle, int *mode); +int time_pps_fetch(pps_handle_t handle, pps_info_t *ppsinfobuf); +int time_pps_wait(pps_handle_t handle, const struct timespec *timeout, + pps_info_t *ppsinfobuf); + +__inline int +time_pps_create(int filedes, pps_handle_t *handle) +{ + int error; + + *handle = -1; + error = ioctl(filedes, PPS_IOC_CREATE, 0); + if (error < 0) + return (-1); + *handle = filedes; + return (0); +} + +__inline int +time_pps_destroy(pps_handle_t handle) +{ + return (ioctl(handle, PPS_IOC_DESTROY, 0)); +} + +__inline int +time_pps_setparams(pps_handle_t handle, const pps_params_t *ppsparams) +{ + return (ioctl(handle, PPS_IOC_SETPARAMS, ppsparams)); +} + +__inline int +time_pps_getparams(pps_handle_t handle, pps_params_t *ppsparams) +{ + return (ioctl(handle, PPS_IOC_GETPARAMS, ppsparams)); +} + +__inline int +time_pps_getcap(pps_handle_t handle, int *mode) +{ + return (ioctl(handle, PPS_IOC_GETCAP, mode)); +} + +__inline int +time_pps_fetch(pps_handle_t handle, pps_info_t *ppsinfobuf) +{ + return (ioctl(handle, PPS_IOC_FETCH, ppsinfobuf)); +} + +__inline int +time_pps_wait(pps_handle_t handle, const struct timespec *timeout, + pps_info_t *ppsinfobuf) +{ + int error; + struct pps_wait_args arg; + + arg.timeout = *timeout; + error = ioctl(handle, PPS_IOC_WAIT, &arg); + *ppsinfobuf = arg.pps_info_buf; + return (error); +} + +#endif /* !_TIME_PPS_H_ */ diff --git a/sys/dev/ppbus/ppbconf.h b/sys/dev/ppbus/ppbconf.h index 57d98b7..5a69d85 100644 --- a/sys/dev/ppbus/ppbconf.h +++ b/sys/dev/ppbus/ppbconf.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ppbconf.h,v 1.4 1997/09/01 00:51:48 bde Exp $ + * $Id: ppbconf.h,v 1.5 1997/09/01 18:39:37 bde Exp $ * */ #ifndef __PPBCONF_H @@ -59,6 +59,7 @@ #define AUTOFEED 0x02 #define nINIT 0x04 #define SELECTIN 0x08 +#define IRQENABLE 0x10 #define PCD 0x20 /* diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c index 2894abf..931b829 100644 --- a/sys/dev/ppbus/pps.c +++ b/sys/dev/ppbus/pps.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: pps.c,v 1.3 1998/02/15 14:54:09 phk Exp $ + * $Id: pps.c,v 1.4 1998/02/16 23:51:00 eivind Exp $ * */ @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef DEVFS #include #endif @@ -25,18 +26,21 @@ #include #include "pps.h" -#define PPS_NAME "pps" /* our official name */ +#define PPS_NAME "lppps" /* our official name */ static struct pps_data { int pps_unit; struct ppb_device pps_dev; - struct ppsclockev { - struct timespec timestamp; - u_int serial; - } ev; - int sawtooth; + pps_params_t ppsparam; + pps_info_t ppsinfo; } *softc[NPPS]; +static int ppscap = + PPS_CAPTUREASSERT | + PPS_HARDPPSONASSERT | + PPS_OFFSETASSERT | + PPS_ECHOASSERT; + static int npps; /* @@ -56,13 +60,12 @@ DATA_SET(ppbdriver_set, ppsdriver); static d_open_t ppsopen; static d_close_t ppsclose; -static d_read_t ppsread; -static d_write_t ppswrite; +static d_ioctl_t ppsioctl; #define CDEV_MAJOR 89 static struct cdevsw pps_cdevsw = - { ppsopen, ppsclose, ppsread, ppswrite, - noioctl, nullstop, nullreset, nodevtotty, + { ppsopen, ppsclose, noread, nowrite, + ppsioctl, nullstop, nullreset, nodevtotty, seltrue, nommap, nostrat, PPS_NAME, NULL, -1 }; @@ -122,7 +125,7 @@ ppsopen(dev_t dev, int flags, int fmt, struct proc *p) if (ppb_request_bus(&sc->pps_dev, PPB_WAIT|PPB_INTR)) return (EINTR); - ppb_wctr(&sc->pps_dev, 0x10); + ppb_wctr(&sc->pps_dev, IRQENABLE); return(0); } @@ -132,6 +135,7 @@ ppsclose(dev_t dev, int flags, int fmt, struct proc *p) { struct pps_data *sc = softc[minor(dev)]; + sc->ppsparam.mode = 0; ppb_release_bus(&sc->pps_dev); return(0); } @@ -139,60 +143,67 @@ ppsclose(dev_t dev, int flags, int fmt, struct proc *p) static void ppsintr(int unit) { -/* - * XXX: You want to thing carefully about what you actually want to do - * here. - */ -#if 1 struct pps_data *sc = softc[unit]; struct timespec tc; -#if 1 struct timeval tv; -#endif nanotime(&tc); if (!(ppb_rstr(&sc->pps_dev) & nACK)) return; - tc.tv_nsec -= sc->sawtooth; - sc->sawtooth = 0; - if (tc.tv_nsec > 1000000000) { - tc.tv_sec++; - tc.tv_nsec -= 1000000000; - } else if (tc.tv_nsec < 0) { + if (sc->ppsparam.mode & PPS_ECHOASSERT) + ppb_wctr(&sc->pps_dev, IRQENABLE | AUTOFEED); + timespecadd(&tc, &sc->ppsparam.assert_offset); + if (tc.tv_nsec < 0) { tc.tv_sec--; tc.tv_nsec += 1000000000; } - sc->ev.timestamp = tc; - sc->ev.serial++; -#if 1 - tv.tv_sec = tc.tv_sec; - tv.tv_usec = tc.tv_nsec / 1000; - hardpps(&tv, tv.tv_usec); -#endif -#endif + sc->ppsinfo.assert_timestamp = tc; + sc->ppsinfo.assert_sequence++; + if (sc->ppsparam.mode & PPS_HARDPPSONASSERT) { + tv.tv_sec = tc.tv_sec; + tv.tv_usec = tc.tv_nsec / 1000; + hardpps(&tv, tv.tv_usec); + } + if (sc->ppsparam.mode & PPS_ECHOASSERT) + ppb_wctr(&sc->pps_dev, IRQENABLE); } -static int -ppsread(dev_t dev, struct uio *uio, int ioflag) +static int +ppsioctl(dev_t dev, int cmd, caddr_t data, int flags, struct proc *p) { struct pps_data *sc = softc[minor(dev)]; - int err, c; + pps_params_t *pp; + pps_info_t *pi; - c = imin(uio->uio_resid, (int)sizeof sc->ev); - err = uiomove((caddr_t)&sc->ev, c, uio); - return(err); + switch (cmd) { + case PPS_IOC_CREATE: + return (0); + case PPS_IOC_DESTROY: + return (0); + case PPS_IOC_SETPARAMS: + pp = (pps_params_t *)data; + if (pp->mode & ~ppscap) + return (EINVAL); + sc->ppsparam = *pp; + return (0); + case PPS_IOC_GETPARAMS: + pp = (pps_params_t *)data; + *pp = sc->ppsparam; + return (0); + case PPS_IOC_GETCAP: + *(int*)data = ppscap; + return (0); + case PPS_IOC_FETCH: + pi = (pps_info_t *)data; + *pi = sc->ppsinfo; + return (0); + case PPS_IOC_WAIT: + return (EOPNOTSUPP); + default: + return (ENODEV); + } } -static int -ppswrite(dev_t dev, struct uio *uio, int ioflag) -{ - struct pps_data *sc = softc[minor(dev)]; - int err, c; - - c = imin(uio->uio_resid, (int)sizeof sc->sawtooth); - err = uiomove((caddr_t)&sc->sawtooth, c, uio); - return(err); -} static pps_devsw_installed = 0; diff --git a/sys/sys/timepps.h b/sys/sys/timepps.h new file mode 100644 index 0000000..b2bf4e3 --- /dev/null +++ b/sys/sys/timepps.h @@ -0,0 +1,67 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + * The is a FreeBSD protype version of the "draft-mogul-pps-api-02.txt" + * specification for Pulse Per Second timing interfaces. + * + */ + +#ifndef _SYS_TIMEPPS_H_ +#define _SYS_TIMEPPS_H_ + +#include + +typedef int pps_handle_t; + +typedef unsigned pps_seq_t; + +typedef struct { + pps_seq_t assert_sequence; + pps_seq_t clear_sequence; + struct timespec assert_timestamp; + struct timespec clear_timestamp; + int current_mode; +} pps_info_t; + +typedef struct { + int mode; + struct timespec assert_offset; + struct timespec clear_offset; +} pps_params_t; + +#define PPS_CAPTUREASSERT 0x01 +#define PPS_CAPTURECLEAR 0x01 +#define PPS_CAPTUREBOTH 0x03 + +#define PPS_HARDPPSONASSERT 0x04 +#define PPS_HARDPPSONCLEAR 0x08 + +#define PPS_OFFSETASSERT 0x10 +#define PPS_OFFSETCLEAR 0x20 + +#define PPS_ECHOASSERT 0x40 +#define PPS_ECHOCLEAR 0x80 + +#define PPS_CANWAIT 0x100 + +struct pps_wait_args { + struct timespec timeout; + pps_info_t pps_info_buf; +}; + +#define PPS_IOC_CREATE _IO('1', 1) +#define PPS_IOC_DESTROY _IO('1', 2) +#define PPS_IOC_SETPARAMS _IOW('1', 3, pps_params_t) +#define PPS_IOC_GETPARAMS _IOR('1', 4, pps_params_t) +#define PPS_IOC_GETCAP _IOR('1', 5, int) +#define PPS_IOC_FETCH _IOWR('1', 6, pps_info_t) +#define PPS_IOC_WAIT _IOWR('1', 6, struct pps_wait_args) + +#endif /* _SYS_TIMEPPS_H_ */ -- cgit v1.1