aboutsummaryrefslogtreecommitdiff
path: root/ntpd/refclock_wwv.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/refclock_wwv.c')
-rw-r--r--ntpd/refclock_wwv.c301
1 files changed, 149 insertions, 152 deletions
diff --git a/ntpd/refclock_wwv.c b/ntpd/refclock_wwv.c
index b7e0d9a6b1df..b03cfe128702 100644
--- a/ntpd/refclock_wwv.c
+++ b/ntpd/refclock_wwv.c
@@ -39,11 +39,12 @@
* tuned automatically using this program as propagation conditions
* change throughout the weasons, both day and night.
*
- * The driver receives, demodulates and decodes the radio signals when
- * connected to the audio codec of a workstation running Solaris, SunOS
- * FreeBSD or Linux, and with a little help, other workstations with
- * similar codecs or sound cards. In this implementation, only one audio
- * driver and codec can be supported on a single machine.
+ * The driver requires an audio codec or sound card with sampling rate 8
+ * kHz and mu-law companding. This is the same standard as used by the
+ * telephone industry and is supported by most hardware and operating
+ * systems, including Solaris, SunOS, FreeBSD, NetBSD and Linux. In this
+ * implementation, only one audio driver and codec can be supported on a
+ * single machine.
*
* The demodulation and decoding algorithms used in this driver are
* based on those developed for the TAPR DSP93 development board and the
@@ -68,6 +69,10 @@
* It does not seem useful to select the compact disc player port. Fudge
* flag3 enables audio monitoring of the input signal. For this purpose,
* the monitor gain is set to a default value.
+ *
+ * CEVNT_BADTIME invalid date or time
+ * CEVNT_PROP propagation failure - no stations heard
+ * CEVNT_TIMEOUT timeout (see newgame() below)
*/
/*
* General definitions. These ordinarily do not need to be changed.
@@ -92,6 +97,7 @@
#define TCKSIZ (TCKCYC * MS) /* tick filter size */
#define NCHAN 5 /* number of radio channels */
#define AUDIO_PHI 5e-6 /* dispersion growth factor */
+#define TBUF 128 /* max monitor line length */
/*
* Tunable parameters. The DGAIN parameter can be changed to fit the
@@ -102,12 +108,10 @@
* radio is not tunable, the DCHAN parameter can be changed to fit the
* expected best propagation frequency: higher if further from the
* transmitter, lower if nearer. The compromise value works for the US
- * right coast. The FREQ_OFFSET parameter can be used as a frequency
- * vernier to correct codec requency if greater than MAXFREQ.
+ * right coast.
*/
#define DCHAN 3 /* default radio channel (15 Mhz) */
#define DGAIN 5. /* subcarrier gain */
-#define FREQ_OFFSET 0. /* codec frequency correction (PPM) */
/*
* General purpose status bits (status)
@@ -133,6 +137,7 @@
#define FGATE 0x0010 /* frequency gate */
#define DGATE 0x0020 /* data pulse amplitude error */
#define BGATE 0x0040 /* data pulse width error */
+#define METRIC 0x0080 /* one or more stations heard */
#define LEPSEC 0x1000 /* leap minute */
/*
@@ -150,10 +155,10 @@
* These bits indicate various alarm conditions, which are decoded to
* form the quality character included in the timecode.
*/
-#define CMPERR 1 /* digit or misc bit compare error */
-#define LOWERR 2 /* low bit or digit amplitude or SNR */
-#define NINERR 4 /* less than nine digits in minute */
-#define SYNERR 8 /* not tracking second sync */
+#define CMPERR 0x1 /* digit or misc bit compare error */
+#define LOWERR 0x2 /* low bit or digit amplitude or SNR */
+#define NINERR 0x4 /* less than nine digits in minute */
+#define SYNERR 0x8 /* not tracking second sync */
/*
* Watchcat timeouts (watch)
@@ -225,15 +230,21 @@
#define SECWAR 0x40 /* 3 leap second warning */
/*
- * The on-time synchronization point for the driver is the second epoch
- * sync pulse produced by the FIR matched filters. As the 5-ms delay of
- * these filters is compensated, the program delay is 1.1 ms due to the
- * 600-Hz IIR bandpass filter. The measured receiver delay is 4.7 ms and
- * the codec delay less than 0.2 ms. The additional propagation delay
- * specific to each receiver location can be programmed in the fudge
- * time1 and time2 values for WWV and WWVH, respectively.
+ * The on-time synchronization point is the positive-going zero crossing
+ * of the first cycle of the 5-ms second pulse. The IIR baseband filter
+ * phase delay is 0.91 ms, while the receiver delay is approximately 4.7
+ * ms at 1000 Hz. The fudge value -0.45 ms due to the codec and other
+ * causes was determined by calibrating to a PPS signal from a GPS
+ * receiver. The additional propagation delay specific to each receiver
+ * location can be programmed in the fudge time1 and time2 values for
+ * WWV and WWVH, respectively.
+ *
+ * The resulting offsets with a 2.4-GHz P4 running FreeBSD 6.1 are
+ * generally within .02 ms short-term with .02 ms jitter. The long-term
+ * offsets vary up to 0.3 ms due to ionosperhic layer height variations.
+ * The processor load due to the driver is 5.8 percent.
*/
-#define PDELAY (.0011 + .0047 + .0002) /* net system delay (s) */
+#define PDELAY ((.91 + 4.7 - 0.45) / 1000) /* system delay (s) */
/*
* Table of sine values at 4.5-degree increments. This is used by the
@@ -365,7 +376,7 @@ struct progx progx[] = {
};
/*
- * BCD coefficients for maximum likelihood digit decode
+ * BCD coefficients for maximum-likelihood digit decode
*/
#define P15 1. /* max positive number */
#define N15 -1. /* max negative number */
@@ -447,14 +458,13 @@ char dstcod[] = {
/*
* The decoding matrix consists of nine row vectors, one for each digit
* of the timecode. The digits are stored from least to most significant
- * order. The maximum likelihood timecode is formed from the digits
- * corresponding to the maximum likelihood values reading in the
+ * order. The maximum-likelihood timecode is formed from the digits
+ * corresponding to the maximum-likelihood values reading in the
* opposite order: yy ddd hh:mm.
*/
struct decvec {
int radix; /* radix (3, 4, 6, 10) */
int digit; /* current clock digit */
- int mldigit; /* maximum likelihood digit */
int count; /* match count */
double digprb; /* max digit probability */
double digsnr; /* likelihood function (dB) */
@@ -503,6 +513,7 @@ struct wwvunit {
l_fp tick; /* audio sample increment */
double phase, freq; /* logical clock phase and frequency */
double monitor; /* audio monitor point */
+ double pdelay; /* propagation delay (s) */
#ifdef ICOM
int fd_icom; /* ICOM file descriptor */
#endif /* ICOM */
@@ -513,7 +524,7 @@ struct wwvunit {
* Audio codec variables
*/
double comp[SIZE]; /* decompanding table */
- int port; /* codec port */
+ int port; /* codec port */
int gain; /* codec gain */
int mongain; /* codec monitor gain */
int clipcnt; /* sample clipped count */
@@ -568,32 +579,32 @@ struct wwvunit {
/*
* Function prototypes
*/
-static int wwv_start P((int, struct peer *));
-static void wwv_shutdown P((int, struct peer *));
-static void wwv_receive P((struct recvbuf *));
-static void wwv_poll P((int, struct peer *));
+static int wwv_start (int, struct peer *);
+static void wwv_shutdown (int, struct peer *);
+static void wwv_receive (struct recvbuf *);
+static void wwv_poll (int, struct peer *);
/*
* More function prototypes
*/
-static void wwv_epoch P((struct peer *));
-static void wwv_rf P((struct peer *, double));
-static void wwv_endpoc P((struct peer *, int));
-static void wwv_rsec P((struct peer *, double));
-static void wwv_qrz P((struct peer *, struct sync *, int));
-static void wwv_corr4 P((struct peer *, struct decvec *,
- double [], double [][4]));
-static void wwv_gain P((struct peer *));
-static void wwv_tsec P((struct peer *));
-static int timecode P((struct wwvunit *, char *));
-static double wwv_snr P((double, double));
-static int carry P((struct decvec *));
-static int wwv_newchan P((struct peer *));
-static void wwv_newgame P((struct peer *));
-static double wwv_metric P((struct sync *));
-static void wwv_clock P((struct peer *));
+static void wwv_epoch (struct peer *);
+static void wwv_rf (struct peer *, double);
+static void wwv_endpoc (struct peer *, int);
+static void wwv_rsec (struct peer *, double);
+static void wwv_qrz (struct peer *, struct sync *, int);
+static void wwv_corr4 (struct peer *, struct decvec *,
+ double [], double [][4]);
+static void wwv_gain (struct peer *);
+static void wwv_tsec (struct peer *);
+static int timecode (struct wwvunit *, char *);
+static double wwv_snr (double, double);
+static int carry (struct decvec *);
+static int wwv_newchan (struct peer *);
+static void wwv_newgame (struct peer *);
+static double wwv_metric (struct sync *);
+static void wwv_clock (struct peer *);
#ifdef ICOM
-static int wwv_qsy P((struct peer *, int));
+static int wwv_qsy (struct peer *, int);
#endif /* ICOM */
static double qsy[NCHAN] = {2.5, 5, 10, 15, 20}; /* frequencies (MHz) */
@@ -705,7 +716,9 @@ wwv_start(
/*
* Initialize autotune if available. Note that the ICOM select
* code must be less than 128, so the high order bit can be used
- * to select the line speed 0 (9600 bps) or 1 (1200 bps).
+ * to select the line speed 0 (9600 bps) or 1 (1200 bps). Note
+ * we don't complain if the ICOM device is not there; but, if it
+ * is, the radio better be working.
*/
temp = 0;
#ifdef DEBUG
@@ -719,25 +732,14 @@ wwv_start(
else
up->fd_icom = icom_init("/dev/icom", B9600,
temp);
- if (up->fd_icom < 0) {
- NLOG(NLOG_SYNCEVENT | NLOG_SYSEVENT)
- msyslog(LOG_NOTICE,
- "icom: %m");
- up->errflg = CEVNT_FAULT;
- }
}
if (up->fd_icom > 0) {
if (wwv_qsy(peer, DCHAN) != 0) {
- NLOG(NLOG_SYNCEVENT | NLOG_SYSEVENT)
- msyslog(LOG_NOTICE,
- "icom: radio not found");
- up->errflg = CEVNT_FAULT;
+ msyslog(LOG_NOTICE, "icom: radio not found");
close(up->fd_icom);
up->fd_icom = 0;
} else {
- NLOG(NLOG_SYNCEVENT | NLOG_SYSEVENT)
- msyslog(LOG_NOTICE,
- "icom: autotune enabled");
+ msyslog(LOG_NOTICE, "icom: autotune enabled");
}
}
#endif /* ICOM */
@@ -837,8 +839,7 @@ wwv_receive(
* per second, which results in a frequency change of
* 125 PPM.
*/
- up->phase += up->freq / SECOND;
- up->phase += FREQ_OFFSET / 1e6;
+ up->phase += (up->freq + clock_codec) / SECOND;
if (up->phase >= .5) {
up->phase -= 1.;
} else if (up->phase < -.5) {
@@ -884,8 +885,6 @@ wwv_poll(
pp = peer->procptr;
up = (struct wwvunit *)pp->unitptr;
- if (pp->coderecv == pp->codeproc)
- up->errflg = CEVNT_TIMEOUT;
if (up->errflg)
refclock_report(peer, up->errflg);
up->errflg = 0;
@@ -974,7 +973,6 @@ wwv_rf(
static int epopos; /* epoch second sync position buffer */
static int iniflg; /* initialization flag */
- int pdelay; /* propagation delay (samples) */
int epoch; /* comb filter index */
double dtemp;
int i;
@@ -1012,7 +1010,7 @@ wwv_rf(
* compensate for the radio audio response at 100 Hz.
*
* Matlab IIR 4th-order IIR elliptic, 150 Hz lowpass, 0.2 dB
- * passband ripple, -50 dB stopband ripple.
+ * passband ripple, -50 dB stopband ripple, phase delay 0.97 ms.
*/
data = (lpf[4] = lpf[3]) * 8.360961e-01;
data += (lpf[3] = lpf[2]) * -3.481740e+00;
@@ -1056,7 +1054,7 @@ wwv_rf(
* tones and most of the noise and voice modulation components.
*
* Matlab 4th-order IIR elliptic, 800-1400 Hz bandpass, 0.2 dB
- * passband ripple, -50 dB stopband ripple.
+ * passband ripple, -50 dB stopband ripple, phase delay 0.91 ms.
*/
syncx = (bpf[8] = bpf[7]) * 4.897278e-01;
syncx += (bpf[7] = bpf[6]) * -2.765914e+00;
@@ -1174,10 +1172,6 @@ wwv_rf(
*/
if (!wwv_newchan(peer))
up->watch = 0;
-#ifdef ICOM
- if (up->fd_icom > 0)
- wwv_qsy(peer, up->dchan);
-#endif /* ICOM */
} else {
/*
@@ -1212,7 +1206,8 @@ wwv_rf(
wwv_epoch(peer);
} else if (up->sptr != NULL) {
sp = up->sptr;
- if (sp->metric >= TTHR && epoch == sp->mepoch % SECOND) {
+ if (sp->metric >= TTHR && epoch == sp->mepoch % SECOND)
+ {
up->rsec = (60 - sp->mepoch / SECOND) % 60;
up->rphase = 0;
up->status |= MSYNC;
@@ -1232,18 +1227,14 @@ wwv_rf(
* provides a resolution of one sample (125 us). The filters run
* only if the station has been reliably determined.
*/
- if (up->status & SELV) {
- pdelay = (int)(pp->fudgetime1 * SECOND);
+ if (up->status & SELV)
mfsync = sqrt(csiamp * csiamp + csqamp * csqamp) /
TCKCYC;
- } else if (up->status & SELH) {
- pdelay = (int)(pp->fudgetime2 * SECOND);
+ else if (up->status & SELH)
mfsync = sqrt(hsiamp * hsiamp + hsqamp * hsqamp) /
TCKCYC;
- } else {
- pdelay = 0;
+ else
mfsync = 0;
- }
/*
* Enhance the seconds sync pulse using a 1-s (8000-sample) comb
@@ -1271,7 +1262,7 @@ wwv_rf(
if (epoch == 0) {
up->epomax = epomax;
up->eposnr = wwv_snr(epomax, nxtmax);
- epopos -= pdelay + TCKCYC * MS;
+ epopos -= TCKCYC * MS;
if (epopos < 0)
epopos += SECOND;
wwv_endpoc(peer, epopos);
@@ -1313,7 +1304,7 @@ wwv_qrz(
{
struct refclockproc *pp;
struct wwvunit *up;
- char tbuf[80]; /* monitor buffer */
+ char tbuf[TBUF]; /* monitor buffer */
long epoch;
pp = peer->procptr;
@@ -1365,7 +1356,7 @@ wwv_qrz(
sp->metric = wwv_metric(sp);
if (pp->sloppyclockflag & CLK_FLAG4) {
sprintf(tbuf,
- "wwv8 %04x %3d %s %04x %.0f %.0f/%.1f %4ld %4ld",
+ "wwv8 %04x %3d %s %04x %.0f %.0f/%.1f %ld %ld",
up->status, up->gain, sp->refid,
sp->reach & 0xffff, sp->metric, sp->synmax,
sp->synsnr, sp->pos % SECOND, epoch);
@@ -1413,7 +1404,7 @@ wwv_endpoc(
static int avgcnt; /* averaging interval counter */
static int avginc; /* averaging ratchet */
static int iniflg; /* initialization flag */
- char tbuf[80]; /* monitor buffer */
+ char tbuf[TBUF]; /* monitor buffer */
double dtemp;
int tmp2;
@@ -1489,8 +1480,8 @@ wwv_endpoc(
mepoch = xepoch;
syncnt = 0;
}
- if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status & MSYNC))
- {
+ if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status &
+ MSYNC)) {
sprintf(tbuf,
"wwv1 %04x %3d %4d %5.0f %5.1f %5d %4d %4d %4d",
up->status, up->gain, tepoch, up->epomax,
@@ -1768,7 +1759,7 @@ wwv_rsec(
struct wwvunit *up;
struct chan *cp;
struct sync *sp, *rp;
- char tbuf[80]; /* monitor buffer */
+ char tbuf[TBUF]; /* monitor buffer */
int sw, arg, nsec;
pp = peer->procptr;
@@ -1887,35 +1878,28 @@ wwv_rsec(
up->errcnt = up->digcnt = up->alarm = 0;
/*
- * We now begin the minute scan. If not yet synchronized
- * to a station, restart if the units digit has not been
- * found within the DATA timeout (15 m) or if not
- * synchronized within the SYNCH timeout (40 m). After
- * synchronizing to a station, restart if no stations
- * are found within the PANIC timeout (2 days).
+ * If synchronized to a station, restart if no stations
+ * have been heard within the PANIC timeout (2 days). If
+ * not and the minute digit has been found, restart if
+ * not synchronized withing the SYNCH timeout (40 m). If
+ * not, restart if the unit digit has not been found
+ * within the DATA timeout (15 m).
*/
if (up->status & INSYNC) {
if (up->watch > PANIC) {
wwv_newgame(peer);
return;
}
- } else {
- if (!(up->status & DSYNC)) {
- if (up->watch > DATA) {
- wwv_newgame(peer);
- return;
- }
- }
+ } else if (up->status & DSYNC) {
if (up->watch > SYNCH) {
wwv_newgame(peer);
return;
}
+ } else if (up->watch > DATA) {
+ wwv_newgame(peer);
+ return;
}
wwv_newchan(peer);
-#ifdef ICOM
- if (up->fd_icom > 0)
- wwv_qsy(peer, up->dchan);
-#endif /* ICOM */
break;
/*
@@ -1987,7 +1971,7 @@ wwv_rsec(
/*
* Save the data channel gain, then QSY to the probe channel and
- * dim the seconds comb filters. The newchan() routine will
+ * dim the seconds comb filters. The www_newchan() routine will
* light them back up.
*/
case MSC21: /* 58 */
@@ -2107,7 +2091,7 @@ wwv_clock(
pp->disp = 0;
pp->lastref = up->timestamp;
refclock_process_offset(pp, offset,
- up->timestamp, PDELAY);
+ up->timestamp, PDELAY + up->pdelay);
refclock_receive(peer);
}
}
@@ -2122,12 +2106,12 @@ wwv_clock(
/*
- * wwv_corr4 - determine maximum likelihood digit
+ * wwv_corr4 - determine maximum-likelihood digit
*
* This routine correlates the received digit vector with the BCD
* coefficient vectors corresponding to all valid digits at the given
* position in the decoding matrix. The maximum value corresponds to the
- * maximum likelihood digit, while the ratio of this value to the next
+ * maximum-likelihood digit, while the ratio of this value to the next
* lower value determines the likelihood function. Note that, if the
* digit is invalid, the likelihood vector is averaged toward a miss.
*/
@@ -2143,7 +2127,7 @@ wwv_corr4(
struct wwvunit *up;
double topmax, nxtmax; /* metrics */
double acc; /* accumulator */
- char tbuf[80]; /* monitor buffer */
+ char tbuf[TBUF]; /* monitor buffer */
int mldigit; /* max likelihood digit */
int i, j;
@@ -2176,9 +2160,9 @@ wwv_corr4(
vp->digsnr = wwv_snr(topmax, nxtmax);
/*
- * The current maximum likelihood digit is compared to the last
- * maximum likelihood digit. If different, the compare counter
- * and maximum likelihood digit are reset. When the compare
+ * The current maximum-likelihood digit is compared to the last
+ * maximum-likelihood digit. If different, the compare counter
+ * and maximum-likelihood digit are reset. When the compare
* counter reaches the BCMP threshold (3), the digit is assumed
* correct. When the compare counter of all nine digits have
* reached threshold, the clock is assumed correct.
@@ -2188,26 +2172,23 @@ wwv_corr4(
* not considered correct until all nine clock digits have
* reached threshold. This is intended as eye candy, but avoids
* mistakes when the signal is low and the SNR is very marginal.
- * once correctly set, the maximum likelihood digit is ignored
- * on the assumption the clock will always be correct unless for
- * some reason it drifts to a different second.
*/
- vp->mldigit = mldigit;
if (vp->digprb < BTHR || vp->digsnr < BSNR) {
- vp->count = 0;
up->status |= BGATE;
} else {
- up->status |= DSYNC;
if (vp->digit != mldigit) {
- vp->count = 0;
up->alarm |= CMPERR;
- if (!(up->status & INSYNC))
+ if (vp->count > 0)
+ vp->count--;
+ if (vp->count == 0)
vp->digit = mldigit;
} else {
if (vp->count < BCMP)
vp->count++;
- else
+ if (vp->count == BCMP) {
+ up->status |= DSYNC;
up->digcnt++;
+ }
}
}
if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status &
@@ -2215,7 +2196,7 @@ wwv_corr4(
sprintf(tbuf,
"wwv4 %2d %04x %3d %4d %5.0f %2d %d %d %d %5.0f %5.1f",
up->rsec - 1, up->status, up->gain, up->yepoch,
- up->epomax, vp->radix, vp->digit, vp->mldigit,
+ up->epomax, vp->radix, vp->digit, mldigit,
vp->count, vp->digprb, vp->digsnr);
record_clock_stats(&peer->srcadr, tbuf);
#ifdef DEBUG
@@ -2326,7 +2307,7 @@ wwv_tsec(
* This routine rotates a likelihood vector one position and increments
* the clock digit modulo the radix. It returns the new clock digit or
* zero if a carry occurred. Once synchronized, the clock digit will
- * match the maximum likelihood digit corresponding to that position.
+ * match the maximum-likelihood digit corresponding to that position.
*/
static int
carry(
@@ -2420,16 +2401,14 @@ wwv_newchan(
struct wwvunit *up;
struct sync *sp, *rp;
double rank, dtemp;
- int i, j;
+ int i, j, rval;
pp = peer->procptr;
up = (struct wwvunit *)pp->unitptr;
/*
* Search all five station pairs looking for the channel with
- * maximum metric. If no station is found above thresholds, tune
- * to WWV on 15 MHz, set the reference ID to NONE and wait for
- * hotter ions.
+ * maximum metric.
*/
sp = NULL;
j = 0;
@@ -2453,39 +2432,57 @@ wwv_newchan(
/*
* If the strongest signal is less than the MTHR threshold (13),
- * we are beneath the waves, so squelch the second sync. If the
- * strongest signal is greater than the threshold, tune to that
- * frequency and transmitter QTH.
+ * we are beneath the waves, so squelch the second sync and
+ * advance to the next station. This makes sure all stations are
+ * scanned when the ions grow dim. If the strongest signal is
+ * greater than the threshold, tune to that frequency and
+ * transmitter QTH.
*/
+ up->status &= ~(SELV | SELH);
if (rank < MTHR) {
up->dchan = (up->dchan + 1) % NCHAN;
- up->status &= ~(SELV | SELH);
- return (FALSE);
+ if (up->status & METRIC) {
+ up->status &= ~METRIC;
+ refclock_report(peer, CEVNT_PROP);
+ }
+ rval = FALSE;
+ } else {
+ up->dchan = j;
+ up->sptr = sp;
+ memcpy(&pp->refid, sp->refid, 4);
+ peer->refid = pp->refid;
+ up->status |= METRIC;
+ if (sp->select & SELV) {
+ up->status |= SELV;
+ up->pdelay = pp->fudgetime1;
+ } else if (sp->select & SELH) {
+ up->status |= SELH;
+ up->pdelay = pp->fudgetime2;
+ } else {
+ up->pdelay = 0;
+ }
+ rval = TRUE;
}
- up->dchan = j;
- up->status |= SELV | SELH;
- up->sptr = sp;
- memcpy(&pp->refid, sp->refid, 4);
- peer->refid = pp->refid;
- return (TRUE);
+#ifdef ICOM
+ if (up->fd_icom > 0)
+ wwv_qsy(peer, up->dchan);
+#endif /* ICOM */
+ return (rval);
}
/*
* wwv_newgame - reset and start over
*
- * There are four conditions resulting in a new game:
+ * There are three conditions resulting in a new game:
*
- * 1 During initial acquisition (MSYNC dark) going 6 minutes (ACQSN)
- * without reliably finding the minute pulse (MSYNC lit).
- *
- * 2 After finding the minute pulse (MSYNC lit), going 15 minutes
+ * 1 After finding the minute pulse (MSYNC lit), going 15 minutes
* (DATA) without finding the unit seconds digit.
*
- * 3 After finding good data (DATA lit), going more than 40 minutes
+ * 2 After finding good data (DSYNC lit), going more than 40 minutes
* (SYNCH) without finding station sync (INSYNC lit).
*
- * 4 After finding station sync (INSYNC lit), going more than 2 days
+ * 3 After finding station sync (INSYNC lit), going more than 2 days
* (PANIC) without finding any station.
*/
static void
@@ -2505,6 +2502,8 @@ wwv_newgame(
* Initialize strategic values. Note we set the leap bits
* NOTINSYNC and the refid "NONE".
*/
+ if (up->status)
+ up->errflg = CEVNT_TIMEOUT;
peer->leap = LEAP_NOTINSYNC;
up->watch = up->status = up->alarm = 0;
up->avgint = MINAVG;
@@ -2514,7 +2513,8 @@ wwv_newgame(
/*
* Initialize the station processes for audio gain, select bit,
* station/frequency identifier and reference identifier. Start
- * probing at the next channel after the data channel.
+ * probing at the strongest channel or the default channel if
+ * nothing heard.
*/
memset(up->mitig, 0, sizeof(up->mitig));
for (i = 0; i < NCHAN; i++) {
@@ -2525,13 +2525,9 @@ wwv_newgame(
cp->wwvh.select = SELH;
sprintf(cp->wwvh.refid, "WH%.0f", floor(qsy[i]));
}
- up->dchan = (DCHAN + NCHAN - 1) % NCHAN;;
+ up->dchan = (DCHAN + NCHAN - 1) % NCHAN;
wwv_newchan(peer);
- up->achan = up->schan = up->dchan;
-#ifdef ICOM
- if (up->fd_icom > 0)
- wwv_qsy(peer, up->dchan);
-#endif /* ICOM */
+ up->schan = up->dchan;
}
/*
@@ -2668,7 +2664,8 @@ timecode(
* there are no clips, the gain is bumped up; if there are more than
* MAXCLP clips (100), it is bumped down. The decoder is relatively
* insensitive to amplitude, so this crudity works just peachy. The
- * input port is set and the error flag is cleared, mostly to be ornery.
+ * routine also jiggles the input port and selectively mutes the
+ * monitor.
*/
static void
wwv_gain(