]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
CHU, IRIG, and WWV improvements from Dave Mills
authorHarlan Stenn <stenn@ntp.org>
Fri, 26 Jan 2007 00:55:47 +0000 (19:55 -0500)
committerHarlan Stenn <stenn@ntp.org>
Fri, 26 Jan 2007 00:55:47 +0000 (19:55 -0500)
bk: 45b95193Ssg-Ks5_qeEcdN9w_Waslw

libntp/audio.c
ntpd/refclock_chu.c
ntpd/refclock_irig.c
ntpd/refclock_wwv.c

index 28038c59c495d77a97fc98c210ee659f2b50e006..ab5723eac84691e5b9bb7c43ac86807158627627 100644 (file)
@@ -244,18 +244,21 @@ audio_init(
 #endif
 
        /*
-        * Open audio device. Do not complain if not there.
+        * Open audio device
         */
        fd = open(dname, O_RDWR | O_NONBLOCK, 0777);
-       if (fd < 0)
+       if (fd < 0) {
+               msyslog(LOG_ERR, "audio_init: %s %m\n", dname);
                return (fd);
+       }
 
        /*
         * Open audio control device.
         */
        ctl_fd = open(actl, O_RDWR);
        if (ctl_fd < 0) {
-               msyslog(LOG_ERR, "audio_init: invalid control device <%s>\n", actl);
+               msyslog(LOG_ERR, "audio_init: invalid control device <%s>\n",
+                   actl);
                close(fd);
                return(ctl_fd);
        }
index 4262b0bf25a4ec9812cc52c988f20a4568547ba6..e96f9c6440758d47ac2ef6e2994828cb908cda6d 100644 (file)
  * 9600 bps if the high order 0x80 bit of the mode is zero and 1200 bps
  * if one. The C-IV trace is turned on if the debug level is greater
  * than one.
+ *
+ * Alarm codes
+ *
+ * CEVNT_BADTIME       invalid date or time
+ * CEVNT_PROP          propagation failure - no stations heard
  */
 /*
  * Interface definitions
 #define MINDIST                28      /* min burst distance (of 40)  */
 #define MINSYNC                8       /* min sync distance (of 16) */
 #define MINSTAMP       20      /* min timestamps (of 60) */
-#define METRIC         50      /* min channel metric (of 160) */
+#define MINMETRIC      50      /* min channel metric (of 160) */
 
 /*
  * The offset to the last stop bit of the first character, which defines
 #define AVALID         0x0100  /* valid A frame */
 #define BVALID         0x0200  /* valid B frame */
 #define INSYNC         0x0400  /* clock synchronized */
+#define        METRIC          0x0800  /* one or more stations heard */
 
 /*
  * Alarm status bits (alarm)
@@ -462,7 +468,7 @@ chu_start(
        double  step;           /* codec adjustment */
 
        /*
-        * Open audio device.
+        * Open audio device. Don't complain if not there.
         */
        fd_audio = audio_init(DEVICE_AUDIO, AUDIO_BUFSIZ, unit);
 #ifdef DEBUG
@@ -471,7 +477,7 @@ chu_start(
 #endif
 
        /*
-        * Open serial port in raw mode.
+        * If audio is unavailable, Open serial port in raw mode.
         */
        if (fd_audio > 0) {
                fd = fd_audio;
@@ -487,7 +493,7 @@ chu_start(
        sprintf(device, DEVICE, unit);
        fd = refclock_open(device, SPEED232, LDISC_RAW);
 #endif /* HAVE_AUDIO */
-       if (fd <= 0)
+       if (fd < 0)
                return (0);
 
        /*
@@ -556,16 +562,11 @@ chu_start(
        }
        if (up->fd_icom > 0) {
                if (chu_newchan(peer, 0) != 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 */
@@ -1331,7 +1332,7 @@ chu_second(
                qual |= DECERR;
        if (up->status & STAMP)
                qual |= TSPERR;
-       if (up->status & BVALID && dtemp >= METRIC)
+       if (up->status & BVALID && dtemp >= MINMETRIC)
                up->status |= INSYNC;
        synchar = leapchar = ' ';
        if (!(up->status & INSYNC)) {
@@ -1356,11 +1357,10 @@ chu_second(
        /*
         * If in sync and the signal metric is above threshold, the
         * timecode is ipso fatso valid and can be selected to
-        * discipline the clock. Be sure not to leave stray timestamps
-        * around if signals are too weak or the clock time is invalid.
+        * discipline the clock.
         */
        if (up->status & INSYNC && !(up->status & (DECODE | STAMP)) &&
-           dtemp > METRIC) {
+           dtemp > MINMETRIC) {
                if (!clocktime(pp->day, pp->hour, pp->minute, 0, GMT,
                    up->tstamp[0].l_ui, &pp->yearstart, &offset.l_ui)) {
                        up->errflg = CEVNT_BADTIME;
@@ -1418,7 +1418,7 @@ chu_major(
         * matrix encodes the number of occurences of each digit found
         * at the corresponding position. The maximum over all
         * occurrences at each position is the distance for this
-        * position and the corresponding digit is the maximum
+        * position and the corresponding digit is the maximum-
         * likelihood candidate. If the distance is not more than half
         * the total number of occurences, a majority has not been found
         * and the data are discarded. The decoding distance is defined
@@ -1478,7 +1478,7 @@ chu_clear(
         */
        up->ndx = up->prevsec = 0;
        up->burstcnt = up->ntstamp = 0;
-       up->status &= INSYNC;
+       up->status &= INSYNC | METRIC;
        for (i = 0; i < 20; i++) {
                for (j = 0; j < 16; j++)
                        up->decode[i][j] = 0;
@@ -1532,16 +1532,15 @@ chu_newchan(
        for (i = 0; i < NCHAN; i++) {
                up->xmtr[i].probe++;
                if (up->xmtr[i].metric > metric) {
+                       up->status |= METRIC;
                        metric = up->xmtr[i].metric;
                        up->chan = i;
                }
        }
 
        /*
-        * Start the next dwell. If the first or no stations have been
-        * heard, continue round-robin scan. If no stations are heard,
-        * skew the minute by a few seconds in case we landed in the
-        * middle of a burst.
+        * Start the next dwell. If the first dwell or no stations have
+        * been heard, continue round-robin scan.
         */
        up->dwell = (up->dwell + 1) % DWELL;
        if (up->dwell == 0 || metric == 0) {
@@ -1561,7 +1560,11 @@ chu_newchan(
            TUNE);
        sprintf(up->ident, "CHU%d", up->chan);
        memcpy(&pp->refid, up->ident, 4); 
-       memcpy(&peer->refid, up->ident, 4); 
+       memcpy(&peer->refid, up->ident, 4);
+       if (metric == 0 && up->status & METRIC) {
+               up->status &= ~METRIC;
+               refclock_report(peer, CEVNT_PROP);
+       } 
        return (rval);
 }
 #endif /* ICOM */
index e702d34a5b483460a81ac2bed2fbbad489ed6b4d..2141f494d9197cc75b1811a6df86b9fbec6c90b5 100644 (file)
  * port, where 0 is the mike port (default) and 1 is the line-in port.
  * 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. Fudgetime2 is used as a
+ * the monitor gain is set t a default value. Fudgetime2 is used as a
  * frequency vernier for broken codec sample frequency.
+ *
+ * Alarm codes
+ *
+ * CEVNT_BADTIME       invalid date or time
+ * CEVNT_TIMEOUT       no IRIG data since last poll
  */
 /*
  * Interface definitions
 #define SIZE           256     /* decompanding table size */
 #define CYCLE          8       /* samples per bit */
 #define SUBFLD         10      /* bits per frame */
-#define FIELD          10      /* frames per second */
+#define FIELD          100     /* bits per second */
 #define MINTC          2       /* min PLL time constant */
 #define MAXTC          20      /* max PLL time constant max */
 #define        MAXAMP          6000.   /* maximum signal level */
 #define BITP           2       /* position identifier */
 
 /*
- * Error flags (up->errflg)
+ * Error flags
  */
 #define IRIG_ERR_AMP   0x01    /* low carrier amplitude */
 #define IRIG_ERR_FREQ  0x02    /* frequency tolerance exceeded */
  * IRIG unit control structure
  */
 struct irigunit {
-       u_char  timecode[21];   /* timecode string */
+       u_char  timecode[2 * SUBFLD + 1]; /* timecode string */
        l_fp    timestamp;      /* audio sample timestamp */
        l_fp    tick;           /* audio sample increment */
        l_fp    refstamp;       /* reference timestamp */
@@ -225,8 +230,6 @@ struct irigunit {
        double  bpf[9];         /* IRIG-B filter shift register */
        double  lpf[5];         /* IRIG-E filter shift register */
        double  intmin, intmax; /* integrated envelope min and max */
-       double  envmax;         /* peak amplitude */
-       double  envmin;         /* noise amplitude */
        double  maxsignal;      /* integrated peak amplitude */
        double  noise;          /* integrated noise amplitude */
        double  lastenv[CYCLE]; /* last cycle amplitudes */
@@ -236,7 +239,6 @@ struct irigunit {
        int     decim;          /* sample decimation factor */
        int     envphase;       /* envelope phase */
        int     envptr;         /* envelope phase pointer */
-       int     carphase;       /* carrier phase */
        int     envsw;          /* envelope state */
        int     envxing;        /* envelope slice crossing */
        int     tc;             /* time constant */
@@ -249,7 +251,6 @@ struct irigunit {
        int     pulse;          /* cycle counter */
        int     cycles;         /* carrier cycles */
        int     dcycles;        /* data cycles */
-       int     xptr;           /* translate table pointer */
        int     lastbit;        /* last code element */
        int     second;         /* previous second */
        int     bitcnt;         /* bit count in character */
@@ -601,7 +602,9 @@ irig_base(
         */
        double  lope;           /* integrator output */
        double  env;            /* envelope detector output */
-       double  dtemp;          /* double temp */
+       int     carphase;       /* carrier phase */
+       double  dtemp;
+       l_fp    ltemp;
 
        pp = peer->procptr;
        up = (struct irigunit *)pp->unitptr;
@@ -613,12 +616,12 @@ irig_base(
         * raw and integrated data for later use.
         */
        up->envphase = (up->envphase + 1) % BAUD;
-       up->carphase = (up->carphase + 1) % CYCLE;
        up->integ[up->envphase] += (sample - up->integ[up->envphase]) /
            (5 * up->tc);
        lope = up->integ[up->envphase];
-       up->lastenv[up->carphase] = sample;
-       up->lastint[up->carphase] = lope;
+       carphase = up->envphase % CYCLE;
+       up->lastenv[carphase] = sample;
+       up->lastint[carphase] = lope;
 
        /*
         * Phase detector. Sample amplitudes are integrated over the
@@ -627,30 +630,24 @@ irig_base(
         * change of 360 degrees produces an output change of one unit.
         */ 
        if (up->lastsig > 0 && lope <= 0)
-               up->zxing += (double)(up->carphase - 4) / CYCLE;
+               up->zxing += (double)(carphase - 4) / CYCLE;
        up->lastsig = lope;
 
        /*
         * Update signal/noise estimates and PLL phase/frequency.
         */
        if (up->envphase == 0) {
-
-               /*
-                * Update envelope signal and noise estimates and mess
-                * with error bits.
-                */
-               up->maxsignal = up->intmax;
-               up->noise = up->intmin;
+               up->maxsignal = up->intmax; up->noise = up->intmin;
+               up->intmin = 1e6; up->intmax = -1e6;
                if (up->maxsignal < DRPOUT)
                        up->errflg |= IRIG_ERR_AMP;
                if (up->maxsignal > 0)
-                       up->modndx = (up->intmax - up->intmin) /
-                           up->intmax;
+                       up->modndx = (up->maxsignal - up->noise) /
+                           up->maxsignal;
                else
                        up->modndx = 0;
                if (up->modndx < MODMIN)
                        up->errflg |= IRIG_ERR_MOD;
-               up->intmin = 1e6; up->intmax = 0;
                if (up->errflg & (IRIG_ERR_AMP | IRIG_ERR_FREQ |
                   IRIG_ERR_MOD | IRIG_ERR_SYNCH)) {
                        up->tc = MINTC;
@@ -687,7 +684,7 @@ irig_base(
         * raw samples. The raw data bits are demodulated relative to
         * the slice level and left-shifted in the decoding register.
         */
-       if (up->carphase != 7)
+       if (carphase != 0)
                return;
 
        env = (up->lastenv[2] - up->lastenv[6]) / 2.;
@@ -704,89 +701,84 @@ irig_base(
         * when three correct frames have been found.
         */
        up->pulse = (up->pulse + 1) % 10;
-       if (up->pulse == 1)
-               up->envmax = env;
-       else if (up->pulse == 9)
-               up->envmin = env;
        up->dcycles <<= 1;
-       if (env >= (up->envmax + up->envmin) / 2.)
+       if (env >=  (up->maxsignal + up->noise) / 2.)
                up->dcycles |= 1;
        up->cycles <<= 1;
        if (lope >= (up->maxsignal + up->noise) / 2.)
                up->cycles |= 1;
        if ((up->cycles & 0x303c0f03) == 0x300c0300) {
-               l_fp    ltemp;
-               int     bitz;
-
-               /*
-                * The PLL time constant starts out small, in order to
-                * sustain a frequency tolerance of 250 PPM. It
-                * gradually increases as the loop settles down. Note
-                * that small wiggles are not believed, unless they
-                * persist for lots of samples.
-                */
-               if (up->pulse != 9)
+               if (up->pulse != 0)
                        up->errflg |= IRIG_ERR_SYNCH;
-               up->pulse = 9;
-               up->exing = -up->yxing;
-               if (fabs(up->envxing - up->envphase) <= 1) {
-                       up->tcount++;
-                       if (up->tcount > 50 * up->tc) {
-                               up->tc++;
-                               if (up->tc > MAXTC)
-                                       up->tc = MAXTC;
-                               up->tcount = 0;
-                               up->envxing = up->envphase;
-                       } else {
-                               up->exing -= up->envxing - up->envphase;
-                       }
-               } else {
+               up->pulse = 0;
+       }
+       if (up->pulse != 0)
+               return;
+
+       /*
+        * The PLL time constant starts out small, in order to
+        * sustain a frequency tolerance of 250 PPM. It
+        * gradually increases as the loop settles down. Note
+        * that small wiggles are not believed, unless they
+        * persist for lots of samples.
+        */
+       up->exing = -up->yxing;
+       if (fabs(up->envxing - up->envphase) <= 1) {
+               up->tcount++;
+               if (up->tcount > 50 * up->tc) {
+                       up->tc++;
+                       if (up->tc > MAXTC)
+                               up->tc = MAXTC;
                        up->tcount = 0;
                        up->envxing = up->envphase;
+               } else {
+                       up->exing -= up->envxing - up->envphase;
                }
+       } else {
+               up->tcount = 0;
+               up->envxing = up->envphase;
+       }
 
-               /*
-                * Strike the character timestamp as the positive zero
-                * crossing of the first bit, accounting for the codec
-                * delay and filter delay.
-                */
-               dtemp = up->decim * ((up->exing + 7 + BAUD) / SECOND) +
-                   up->fdelay;
-               DTOLFP(dtemp, &ltemp);
-               up->chrstamp = up->timestamp;
-               L_SUB(&up->chrstamp, &ltemp);
+       /*
+        * Strike the character timestamp as the positive zero
+        * crossing of the first bit, accounting for the codec
+        * delay and filter delay.
+        */
+       dtemp = up->decim * ((up->exing + 7 + BAUD) / SECOND) +
+           up->fdelay;
+       DTOLFP(dtemp, &ltemp);
+       up->chrstamp = up->timestamp;
+       L_SUB(&up->chrstamp, &ltemp);
 
-               /*
-                * The data bits are collected in ten-bit frames. The
-                * first two and last two bits are determined by frame
-                * sync and ignored here; the resulting patterns
-                * represent zero (0-1 bits), one (2-4 bits) and
-                * position identifier (5-6 bits). The remaining
-                * patterns represent errors and are treated as zeros.
-                */
-               bitz = up->dcycles & 0xfc;
-               switch(bitz) {
-
-               case 0x00:
-               case 0x80:
-                       irig_decode(peer, BIT0);
-                       break;
-
-               case 0xc0:
-               case 0xe0:
-               case 0xf0:
-                       irig_decode(peer, BIT1);
-                       break;
-
-               case 0xf8:
-               case 0xfc:
-                       irig_decode(peer, BITP);
-                       break;
-
-               default:
-                       irig_decode(peer, 0);
-                       up->errflg |= IRIG_ERR_DECODE;
-               }
+       /*
+        * The data bits are collected in ten-bit frames. The first two
+        * bits are not used; the resulting patterns represent zero (0-2
+        * bits), one (3-5 bits) and position identifier PI (6-7 bits).
+        * The remaining patterns represent errors and are treated as
+        * zeros.
+        */
+       switch (up->dcycles & 0xff) {
+
+       case 0x00:              /* 0 */
+       case 0x80:
+       case 0xc0:
+               irig_decode(peer, BIT0);
+               break;
+
+       case 0xe0:              /* 1 */
+       case 0xf0:
+       case 0xf8:
+               irig_decode(peer, BIT1);
+               break;
+
+       case 0xfc:              /* PI */
+       case 0xfe:
+               irig_decode(peer, BITP);
+               break;
+
+       default:                /* error */
+               irig_decode(peer, B0);
+               up->errflg |= IRIG_ERR_DECODE;
        }
 }
 
@@ -814,6 +806,8 @@ irig_decode(
        char    syncchar;       /* sync character (Spectracom) */
        char    sbs[6];         /* binary seconds since 0h */
        char    spare[2];       /* mulligan digits */
+       int     i;
+       int     temp;
 
         pp = peer->procptr;
        up = (struct irigunit *)pp->unitptr;
@@ -831,31 +825,33 @@ irig_decode(
                 * mark the beginning of the second. The reference time
                 * is the beginning of the second position identifier,
                 * so copy the character timestamp to the reference
-                * timestamp
+                * timestamp.
                 */
-               up->bitcnt = 1;
-               up->frmcnt = 0;
-               up->errflg = 0;
+               up->frmcnt = 1;
                up->refstamp = up->chrstamp;
        }
        up->lastbit = bit;
-       up->bitcnt = (up->bitcnt + 1) % SUBFLD;
-       if (up->bitcnt == 0) {
+       if (up->frmcnt % SUBFLD == 0) {
 
                /*
-                * End of character. Encode two hexadecimal digits in
+                * End of frame. Encode two hexadecimal digits in
                 * little-endian timecode field.
                 */
-               if (up->frmcnt == 0)
-                   up->bits <<= 1;
-               if (up->xptr < 2)
-                   up->xptr = 2 * FIELD;
-               up->timecode[--up->xptr] = hexchar[(up->bits >> 5) &
+               temp = up->bits;
+               i = (SUBFLD - 1 - up->frmcnt / SUBFLD) * 2;
+
+printf (" %d %1c%1c", i, hexchar[(temp >> 5) & 0xf], hexchar[temp & 0xf]);
+
+               up->timecode[i - 1] = hexchar[(temp >> 5) &
                    0xf];
-               up->timecode[--up->xptr] = hexchar[up->bits & 0xf];
-               up->frmcnt = (up->frmcnt + 1) % FIELD;
+
+
+               up->timecode[i - 2] = hexchar[temp & 0xf];
                if (up->frmcnt == 0) {
 
+printf("\n");
+printf("%20s\n", up->timecode);
+
                        /*
                         * End of second. Decode the timecode and wind
                         * the clock. Not all IRIG generators have the
@@ -869,7 +865,6 @@ irig_decode(
                         * refclock_process() will reject the timecode
                         * as invalid.
                         */
-                       up->xptr = 2 * FIELD;
                        if (sscanf((char *)up->timecode,
                           "%6s%2d%c%2s%3d%2d%2d%2d", sbs, &pp->year,
                            &syncchar, spare, &pp->day, &pp->hour,
@@ -886,7 +881,9 @@ irig_decode(
                        if (up->errflg == 0) {
                                pp->lastref = pp->lastrec;
                                pp->lastrec = up->refstamp;
-                               refclock_process(pp);
+                               if (!refclock_process(pp))
+                                       refclock_report(peer,
+                                           CEVNT_BADTIME);
                        }
                        sprintf(pp->a_lastcode,
                            "%02x %c %02d %03d %02d:%02d:%02d %4.0f %3d %6.3f %2d %6.2f %6.1f %s",
@@ -896,10 +893,10 @@ irig_decode(
                            up->tc, up->exing * 1e6 / SECOND, up->freq *
                            1e6 / SECOND, ulfptoa(&pp->lastrec, 6));
                        pp->lencode = strlen(pp->a_lastcode);
+                       up->errflg = 0;
                        if (pp->sloppyclockflag & CLK_FLAG4) {
                                record_clock_stats(&peer->srcadr,
                                    pp->a_lastcode);
-                               up->errflg = 0;
 #ifdef DEBUG
                                if (debug)
                                        printf("irig %s\n",
@@ -908,6 +905,7 @@ irig_decode(
                        }
                }
        }
+       up->frmcnt = (up->frmcnt + 1) % FIELD;
 }
 
 
@@ -916,8 +914,7 @@ irig_decode(
  *
  * This routine sweeps up the timecode updates since the last poll. For
  * IRIG-B there should be at least 60 updates; for IRIG-E there should
- * be at least 6. If nothing is heard, a timeout event is declared and
- * any orphaned timecode updates are sent to foster care. 
+ * be at least 6. If nothing is heard, a timeout event is declared. 
  */
 static void
 irig_poll(
@@ -936,10 +933,9 @@ irig_poll(
                return;
 
        }
+       refclock_receive(peer);
        if (!(pp->sloppyclockflag & CLK_FLAG4)) {
-               refclock_receive(peer);
                record_clock_stats(&peer->srcadr, pp->a_lastcode);
-               up->errflg = 0;
 #ifdef DEBUG
                if (debug)
                        printf("irig %s\n", pp->a_lastcode);
index 691a4c299fab93331e99be6314981a093b89ecd5..9ecd25f37ea8148b3033812a60f0580f1c4a8e38 100644 (file)
  * 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.
 #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 */
 
 /*
  * 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
+ * the codec delay about 0.5 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.
  */
-#define PDELAY (.0011 + .0047 + .0002) /* net system delay (s) */
+#define PDELAY (.0011 + .0047 + .0005) /* net system delay (s) */
 
 /*
  * Table of sine values at 4.5-degree increments. This is used by the
@@ -704,7 +709,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
@@ -718,25 +725,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 */
@@ -882,8 +878,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;
@@ -1484,8 +1478,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,
@@ -2194,7 +2188,7 @@ wwv_corr4(
                } else {
                        if (vp->count < BCMP)
                                vp->count++;
-                       else
+                       if (vp->count == BCMP)
                                up->digcnt++;
                }
        }
@@ -2448,6 +2442,10 @@ wwv_newchan(
        if (rank < MTHR) {
                up->dchan = (up->dchan + 1) % NCHAN;
                up->status &= ~(SELV | SELH);
+               if (up->status & METRIC) {
+                       up->status &= ~METRIC;
+                       refclock_report(peer, CEVNT_PROP);
+               }
                rval = FALSE;
        } else {
                up->dchan = j;
@@ -2455,6 +2453,7 @@ wwv_newchan(
                up->sptr = sp;
                memcpy(&pp->refid, sp->refid, 4);
                peer->refid = pp->refid;
+               up->status |= METRIC;
                rval = TRUE;
        }
 #ifdef ICOM
@@ -2468,18 +2467,15 @@ wwv_newchan(
 /*
  * 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
@@ -2499,6 +2495,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;