diff options
Diffstat (limited to 'contrib/ntp/ntpd/refclock_wwvb.c')
-rw-r--r-- | contrib/ntp/ntpd/refclock_wwvb.c | 96 |
1 files changed, 57 insertions, 39 deletions
diff --git a/contrib/ntp/ntpd/refclock_wwvb.c b/contrib/ntp/ntpd/refclock_wwvb.c index c5ef9f9..7bddd3a 100644 --- a/contrib/ntp/ntpd/refclock_wwvb.c +++ b/contrib/ntp/ntpd/refclock_wwvb.c @@ -1,5 +1,5 @@ /* - * refclock_wwvb - clock driver for Spectracom WWVB receivers + * refclock_wwvb - clock driver for Spectracom WWVB and GPS receivers */ #ifdef HAVE_CONFIG_H @@ -43,7 +43,7 @@ * * Format 0 (22 ASCII printing characters): * - * <cr><lf>i ddd hh:mm:ss TZ=zz<cr><lf> + * <cr><lf>i ddd hh:mm:ss TZ=zz<cr><lf> * * on-time = first <cr> * hh:mm:ss = hours, minutes, seconds @@ -80,19 +80,20 @@ * synchronized to the indicated time as returned. * * This driver does not need to be told which format is in use - it - * figures out which one from the length of the message.The driver makes - * no attempt to correct for the intrinsic jitter of the radio itself, - * which is a known problem with the older radios. + * figures out which one from the length of the message. The driver + * makes no attempt to correct for the intrinsic jitter of the radio + * itself, which is a known problem with the older radios. * * Fudge Factors * * This driver can retrieve a table of quality data maintained * internally by the Netclock/2 clock. If flag4 of the fudge * configuration command is set to 1, the driver will retrieve this - * table and write it to the clockstats file on when the first timecode + * table and write it to the clockstats file when the first timecode * message of a new day is received. + * + * PPS calibration fudge time 1: format 0 .003134, format 2 .004034 */ - /* * Interface definitions */ @@ -100,7 +101,7 @@ #define SPEED232 B9600 /* uart speed (9600 baud) */ #define PRECISION (-13) /* precision assumed (about 100 us) */ #define REFID "WWVB" /* reference ID */ -#define DESCRIPTION "Spectracom WWVB/GPS Receivers" /* WRU */ +#define DESCRIPTION "Spectracom WWVB/GPS Receiver" /* WRU */ #define LENWWVB0 22 /* format 0 timecode length */ #define LENWWVB1 22 /* format 1 timecode length */ @@ -112,7 +113,6 @@ * WWVB unit control structure */ struct wwvbunit { - u_char tcswitch; /* timecode switch */ l_fp laststamp; /* last receive timestamp */ u_char lasthour; /* last hour (for monitor) */ u_char linect; /* count ignored lines (for monitor */ @@ -125,6 +125,7 @@ static int wwvb_start P((int, struct peer *)); static void wwvb_shutdown P((int, struct peer *)); static void wwvb_receive P((struct recvbuf *)); static void wwvb_poll P((int, struct peer *)); +static void wwvb_timer P((int, struct peer *)); /* * Transfer vector @@ -136,7 +137,7 @@ struct refclock refclock_wwvb = { noentry, /* not used (old wwvb_control) */ noentry, /* initialize driver (not used) */ noentry, /* not used (old wwvb_buginfo) */ - NOFLAGS /* not used */ + wwvb_timer /* called once per second */ }; @@ -157,7 +158,7 @@ wwvb_start( /* * Open serial port. Use CLK line discipline, if available. */ - (void)sprintf(device, DEVICE, unit); + sprintf(device, DEVICE, unit); if (!(fd = refclock_open(device, SPEED232, LDISC_CLK))) return (0); @@ -166,7 +167,7 @@ wwvb_start( */ if (!(up = (struct wwvbunit *) emalloc(sizeof(struct wwvbunit)))) { - (void) close(fd); + close(fd); return (0); } memset((char *)up, 0, sizeof(struct wwvbunit)); @@ -177,7 +178,7 @@ wwvb_start( pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { - (void) close(fd); + close(fd); free(up); return (0); } @@ -188,7 +189,6 @@ wwvb_start( peer->precision = PRECISION; pp->clockdesc = DESCRIPTION; memcpy((char *)&pp->refid, REFID, 4); - peer->burst = MAXSTAGE; return (1); } @@ -249,21 +249,15 @@ wwvb_receive( * +-50 us relative to the pps; however, on an unmodified 8170 * the start bit can be delayed up to 10 ms. In format 2 the * reading precision is only to the millisecond. Thus, unless - * you have a pps gadget and don't have to have the year, format + * you have a PPS gadget and don't have to have the year, format * 0 provides the lowest jitter. */ if (temp == 0) { - if (up->tcswitch == 0) { - up->tcswitch = 1; - up->laststamp = trtmp; - } else - up->tcswitch = 0; + up->laststamp = trtmp; return; } pp->lencode = temp; pp->lastrec = up->laststamp; - up->laststamp = trtmp; - up->tcswitch = 1; /* * We get down to business, check the timecode format and decode @@ -378,14 +372,16 @@ wwvb_receive( */ if (!refclock_process(pp)) refclock_report(peer, CEVNT_BADTIME); + if (peer->disp > MAXDISTANCE) + refclock_receive(peer); } /* - * wwvb_poll - called by the transmit procedure + * wwvb_timer - called once per second by the transmit procedure */ static void -wwvb_poll( +wwvb_timer( int unit, struct peer *peer ) @@ -399,8 +395,7 @@ wwvb_poll( * 'T' by returning a timecode in the format(s) specified above. * Note there is no checking on state, since this may not be the * only customer reading the clock. Only one customer need poll - * the clock; all others just listen in. If the clock becomes - * unreachable, declare a timeout and keep going. + * the clock; all others just listen in. */ pp = peer->procptr; up = (struct wwvbunit *)pp->unitptr; @@ -410,8 +405,42 @@ wwvb_poll( pollchar = 'T'; if (write(pp->io.fd, &pollchar, 1) != 1) refclock_report(peer, CEVNT_FAULT); - if (peer->burst > 0) - return; +} + + +/* + * wwvb_poll - called by the transmit procedure + */ +static void +wwvb_poll( + int unit, + struct peer *peer + ) +{ + register struct wwvbunit *up; + struct refclockproc *pp; + + /* + * Sweep up the samples received since the last poll. If none + * are received, declare a timeout and keep going. + */ + pp = peer->procptr; + up = (struct wwvbunit *)pp->unitptr; + pp->polls++; + + /* + * If the monitor flag is set (flag4), we dump the internal + * quality table at the first timecode beginning the day. + */ + if (pp->sloppyclockflag & CLK_FLAG4 && pp->hour < + (int)up->lasthour) + up->linect = MONLIN; + up->lasthour = pp->hour; + + /* + * Process median filter samples. If none received, declare a + * timeout and keep going. + */ if (pp->coderecv == pp->codeproc) { refclock_report(peer, CEVNT_TIMEOUT); return; @@ -423,17 +452,6 @@ wwvb_poll( printf("wwvb: timecode %d %s\n", pp->lencode, pp->a_lastcode); #endif - peer->burst = MAXSTAGE; - pp->polls++; - - /* - * If the monitor flag is set (flag4), we dump the internal - * quality table at the first timecode beginning the day. - */ - if (pp->sloppyclockflag & CLK_FLAG4 && pp->hour < - (int)up->lasthour) - up->linect = MONLIN; - up->lasthour = pp->hour; } #else |