]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - ntpd/refclock_wwv.c
Fix compilation with gcc 4.1. This is imported on the vendor branch as it
[FreeBSD/FreeBSD.git] / ntpd / refclock_wwv.c
1 /*
2  * refclock_wwv - clock driver for NIST WWV/H time/frequency station
3  */
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7
8 #if defined(REFCLOCK) && defined(CLOCK_WWV)
9
10 #include "ntpd.h"
11 #include "ntp_io.h"
12 #include "ntp_refclock.h"
13 #include "ntp_calendar.h"
14 #include "ntp_stdlib.h"
15 #include "audio.h"
16
17 #include <stdio.h>
18 #include <ctype.h>
19 #include <math.h>
20 #ifdef HAVE_SYS_IOCTL_H
21 # include <sys/ioctl.h>
22 #endif /* HAVE_SYS_IOCTL_H */
23
24 #define ICOM 1
25
26 #ifdef ICOM
27 #include "icom.h"
28 #endif /* ICOM */
29
30 /*
31  * Audio WWV/H demodulator/decoder
32  *
33  * This driver synchronizes the computer time using data encoded in
34  * radio transmissions from NIST time/frequency stations WWV in Boulder,
35  * CO, and WWVH in Kauai, HI. Transmissions are made continuously on
36  * 2.5, 5, 10, 15 and 20 MHz in AM mode. An ordinary shortwave receiver
37  * can be tuned manually to one of these frequencies or, in the case of
38  * ICOM receivers, the receiver can be tuned automatically using this
39  * program as propagation conditions change throughout the day and
40  * night.
41  *
42  * The driver receives, demodulates and decodes the radio signals when
43  * connected to the audio codec of a workstation running Solaris, SunOS
44  * FreeBSD or Linux, and with a little help, other workstations with
45  * similar codecs or sound cards. In this implementation, only one audio
46  * driver and codec can be supported on a single machine.
47  *
48  * The demodulation and decoding algorithms used in this driver are
49  * based on those developed for the TAPR DSP93 development board and the
50  * TI 320C25 digital signal processor described in: Mills, D.L. A
51  * precision radio clock for WWV transmissions. Electrical Engineering
52  * Report 97-8-1, University of Delaware, August 1997, 25 pp., available
53  * from www.eecis.udel.edu/~mills/reports.htm. The algorithms described
54  * in this report have been modified somewhat to improve performance
55  * under weak signal conditions and to provide an automatic station
56  * identification feature.
57  *
58  * The ICOM code is normally compiled in the driver. It isn't used,
59  * unless the mode keyword on the server configuration command specifies
60  * a nonzero ICOM ID select code. The C-IV trace is turned on if the
61  * debug level is greater than one.
62  */
63 /*
64  * Interface definitions
65  */
66 #define DEVICE_AUDIO    "/dev/audio" /* audio device name */
67 #define AUDIO_BUFSIZ    320     /* audio buffer size (50 ms) */
68 #define PRECISION       (-10)   /* precision assumed (about 1 ms) */
69 #define DESCRIPTION     "WWV/H Audio Demodulator/Decoder" /* WRU */
70 #define SECOND          8000    /* second epoch (sample rate) (Hz) */
71 #define MINUTE          (SECOND * 60) /* minute epoch */
72 #define OFFSET          128     /* companded sample offset */
73 #define SIZE            256     /* decompanding table size */
74 #define MAXSIG          6000.   /* max signal level reference */
75 #define MAXCLP          100     /* max clips above reference per s */
76 #define MAXSNR          30.     /* max SNR reference */
77 #define DGAIN           20.     /* data channel gain reference */
78 #define SGAIN           10.     /* sync channel gain reference */
79 #define MAXFREQ         1.      /* max frequency tolerance (125 PPM) */
80 #define PI              3.1415926535 /* the real thing */
81 #define DATSIZ          (170 * MS) /* data matched filter size */
82 #define SYNSIZ          (800 * MS) /* minute sync matched filter size */
83 #define MAXERR          30      /* max data bit errors in minute */
84 #define NCHAN           5       /* number of radio channels */
85 #define AUDIO_PHI       5e-6    /* dispersion growth factor */
86 #ifdef IRIG_SUCKS
87 #define WIGGLE          11      /* wiggle filter length */
88 #endif /* IRIG_SUCKS */
89
90 /*
91  * General purpose status bits (status)
92  *
93  * SELV and/or SELH are set when WWV or WWVH has been heard and cleared
94  * on signal loss. SSYNC is set when the second sync pulse has been
95  * acquired and cleared by signal loss. MSYNC is set when the minute
96  * sync pulse has been acquired. DSYNC is set when a digit reaches the
97  * threshold and INSYNC is set when all nine digits have reached the
98  * threshold. The MSYNC, DSYNC and INSYNC bits are cleared only by
99  * timeout, upon which the driver starts over from scratch.
100  *
101  * DGATE is set if a data bit is invalid and BGATE is set if a BCD digit
102  * bit is invalid. SFLAG is set when during seconds 59, 0 and 1 while
103  * probing alternate frequencies. LEPDAY is set when SECWAR of the
104  * timecode is set on 30 June or 31 December. LEPSEC is set during the
105  * last minute of the day when LEPDAY is set. At the end of this minute
106  * the driver inserts second 60 in the seconds state machine and the
107  * minute sync slips a second. The SLOSS and SJITR bits are for monitor
108  * only.
109  */
110 #define MSYNC           0x0001  /* minute epoch sync */
111 #define SSYNC           0x0002  /* second epoch sync */
112 #define DSYNC           0x0004  /* minute units sync */
113 #define INSYNC          0x0008  /* clock synchronized */
114 #define FGATE           0x0010  /* frequency gate */
115 #define DGATE           0x0020  /* data bit error */
116 #define BGATE           0x0040  /* BCD digit bit error */
117 #define SFLAG           0x1000  /* probe flag */
118 #define LEPDAY          0x2000  /* leap second day */
119 #define LEPSEC          0x4000  /* leap second minute */
120
121 /*
122  * Station scoreboard bits
123  *
124  * These are used to establish the signal quality for each of the five
125  * frequencies and two stations.
126  */
127 #define SYNCNG          0x0001  /* sync or SNR below threshold */
128 #define DATANG          0x0002  /* data or SNR below threshold */
129 #define ERRRNG          0x0004  /* data error */
130 #define SELV            0x0100  /* WWV station select */
131 #define SELH            0x0200  /* WWVH station select */
132
133 /*
134  * Alarm status bits (alarm)
135  *
136  * These bits indicate various alarm conditions, which are decoded to
137  * form the quality character included in the timecode. If not tracking
138  * second sync, the SYNERR alarm is raised. The data error counter is
139  * incremented for each invalid data bit. If too many data bit errors
140  * are encountered in one minute, the MODERR alarm is raised. The DECERR
141  * alarm is raised if a maximum likelihood digit fails to compare with
142  * the current clock digit. If the probability of any miscellaneous bit
143  * or any digit falls below the threshold, the SYMERR alarm is raised.
144  */
145 #define DECERR          1       /* BCD digit compare error */
146 #define SYMERR          2       /* low bit or digit probability */
147 #define MODERR          4       /* too many data bit errors */
148 #define SYNERR          8       /* not synchronized to station */
149
150 /*
151  * Watchcat timeouts (watch)
152  *
153  * If these timeouts expire, the status bits are mashed to zero and the
154  * driver starts from scratch. Suitably more refined procedures may be
155  * developed in future. All these are in minutes.
156  */
157 #define ACQSN           5       /* station acquisition timeout */
158 #define DIGIT           30      /* minute unit digit timeout */
159 #define HOLD            30      /* reachable timeout */
160 #define PANIC           (2 * 1440) /* panic timeout */
161
162 /*
163  * Thresholds. These establish the minimum signal level, minimum SNR and
164  * maximum jitter thresholds which establish the error and false alarm
165  * rates of the driver. The values defined here may be on the
166  * adventurous side in the interest of the highest sensitivity.
167  */
168 #define MTHR            13.     /* acquisition signal gate (percent) */
169 #define TTHR            50.     /* tracking signal gate (percent) */
170 #define ATHR            2000.   /* acquisition amplitude threshold */
171 #define ASNR            6.      /* acquisition SNR threshold (dB) */
172 #define AWND            20.     /* acquisition jitter threshold (ms) */
173 #define AMIN            3       /* min bit count */
174 #define AMAX            6       /* max bit count */
175 #define QTHR            2000    /* QSY sync threshold */
176 #define QSNR            20.     /* QSY sync SNR threshold (dB) */
177 #define XTHR            1000.   /* QSY data threshold */
178 #define XSNR            10.     /* QSY data SNR threshold (dB) */
179 #define STHR            500     /* second sync amplitude threshold */
180 #define SSNR            10.     /* second sync SNR threshold */
181 #define SCMP            10      /* second sync compare threshold */
182 #define DTHR            1000    /* bit amplitude threshold */
183 #define DSNR            10.     /* bit SNR threshold (dB) */
184 #define BTHR            1000    /* digit amplitude threshold */
185 #define BSNR            3.      /* digit likelihood threshold (dB) */
186 #define BCMP            5       /* digit compare threshold */
187
188 /*
189  * Tone frequency definitions. The increments are for 4.5-deg sine
190  * table.
191  */
192 #define MS              (SECOND / 1000) /* samples per millisecond */
193 #define IN100           ((100 * 80) / SECOND) /* 100 Hz increment */
194 #define IN1000          ((1000 * 80) / SECOND) /* 1000 Hz increment */
195 #define IN1200          ((1200 * 80) / SECOND) /* 1200 Hz increment */
196
197 /*
198  * Acquisition and tracking time constants. Usually powers of 2.
199  */
200 #define MINAVG          8       /* min time constant */
201 #define MAXAVG          1024    /* max time constant */
202 #define TCONST          16      /* data bit/digit time constant */
203
204 /*
205  * Miscellaneous status bits (misc)
206  *
207  * These bits correspond to designated bits in the WWV/H timecode. The
208  * bit probabilities are exponentially averaged over several minutes and
209  * processed by a integrator and threshold.
210  */
211 #define DUT1            0x01    /* 56 DUT .1 */
212 #define DUT2            0x02    /* 57 DUT .2 */
213 #define DUT4            0x04    /* 58 DUT .4 */
214 #define DUTS            0x08    /* 50 DUT sign */
215 #define DST1            0x10    /* 55 DST1 leap warning */
216 #define DST2            0x20    /* 2 DST2 DST1 delayed one day */
217 #define SECWAR          0x40    /* 3 leap second warning */
218
219 /*
220  * The on-time synchronization point for the driver is the second epoch
221  * sync pulse produced by the FIR matched filters. As the 5-ms delay of
222  * these filters is compensated, the program delay is 1.1 ms due to the
223  * 600-Hz IIR bandpass filter. The measured receiver delay is 4.7 ms and
224  * the codec delay less than 0.2 ms. The additional propagation delay
225  * specific to each receiver location can be programmed in the fudge
226  * time1 and time2 values for WWV and WWVH, respectively.
227  */
228 #define PDELAY  (.0011 + .0047 + .0002) /* net system delay (s) */
229
230 /*
231  * Table of sine values at 4.5-degree increments. This is used by the
232  * synchronous matched filter demodulators. The integral of sine-squared
233  * over one complete cycle is PI, so the table is normallized by 1 / PI.
234  */
235 double sintab[] = {
236  0.000000e+00,  2.497431e-02,  4.979464e-02,  7.430797e-02, /* 0-3 */
237  9.836316e-02,  1.218119e-01,  1.445097e-01,  1.663165e-01, /* 4-7 */
238  1.870979e-01,  2.067257e-01,  2.250791e-01,  2.420447e-01, /* 8-11 */
239  2.575181e-01,  2.714038e-01,  2.836162e-01,  2.940800e-01, /* 12-15 */
240  3.027307e-01,  3.095150e-01,  3.143910e-01,  3.173286e-01, /* 16-19 */
241  3.183099e-01,  3.173286e-01,  3.143910e-01,  3.095150e-01, /* 20-23 */
242  3.027307e-01,  2.940800e-01,  2.836162e-01,  2.714038e-01, /* 24-27 */
243  2.575181e-01,  2.420447e-01,  2.250791e-01,  2.067257e-01, /* 28-31 */
244  1.870979e-01,  1.663165e-01,  1.445097e-01,  1.218119e-01, /* 32-35 */
245  9.836316e-02,  7.430797e-02,  4.979464e-02,  2.497431e-02, /* 36-39 */
246 -0.000000e+00, -2.497431e-02, -4.979464e-02, -7.430797e-02, /* 40-43 */
247 -9.836316e-02, -1.218119e-01, -1.445097e-01, -1.663165e-01, /* 44-47 */
248 -1.870979e-01, -2.067257e-01, -2.250791e-01, -2.420447e-01, /* 48-51 */
249 -2.575181e-01, -2.714038e-01, -2.836162e-01, -2.940800e-01, /* 52-55 */
250 -3.027307e-01, -3.095150e-01, -3.143910e-01, -3.173286e-01, /* 56-59 */
251 -3.183099e-01, -3.173286e-01, -3.143910e-01, -3.095150e-01, /* 60-63 */
252 -3.027307e-01, -2.940800e-01, -2.836162e-01, -2.714038e-01, /* 64-67 */
253 -2.575181e-01, -2.420447e-01, -2.250791e-01, -2.067257e-01, /* 68-71 */
254 -1.870979e-01, -1.663165e-01, -1.445097e-01, -1.218119e-01, /* 72-75 */
255 -9.836316e-02, -7.430797e-02, -4.979464e-02, -2.497431e-02, /* 76-79 */
256  0.000000e+00};                                             /* 80 */
257
258 /*
259  * Decoder operations at the end of each second are driven by a state
260  * machine. The transition matrix consists of a dispatch table indexed
261  * by second number. Each entry in the table contains a case switch
262  * number and argument.
263  */
264 struct progx {
265         int sw;                 /* case switch number */
266         int arg;                /* argument */
267 };
268
269 /*
270  * Case switch numbers
271  */
272 #define IDLE            0       /* no operation */
273 #define COEF            1       /* BCD bit */
274 #define COEF2           2       /* BCD bit ignored */
275 #define DECIM9          3       /* BCD digit 0-9 */
276 #define DECIM6          4       /* BCD digit 0-6 */
277 #define DECIM3          5       /* BCD digit 0-3 */
278 #define DECIM2          6       /* BCD digit 0-2 */
279 #define MSCBIT          7       /* miscellaneous bit */
280 #define MSC20           8       /* miscellaneous bit */         
281 #define MSC21           9       /* QSY probe channel */         
282 #define MIN1            10      /* minute */            
283 #define MIN2            11      /* leap second */
284 #define SYNC2           12      /* QSY data channel */          
285 #define SYNC3           13      /* QSY data channel */          
286
287 /*
288  * Offsets in decoding matrix
289  */
290 #define MN              0       /* minute digits (2) */
291 #define HR              2       /* hour digits (2) */
292 #define DA              4       /* day digits (3) */
293 #define YR              7       /* year digits (2) */
294
295 struct progx progx[] = {
296         {SYNC2, 0},             /* 0 latch sync max */
297         {SYNC3, 0},             /* 1 QSY data channel */
298         {MSCBIT, DST2},         /* 2 dst2 */
299         {MSCBIT, SECWAR},       /* 3 lw */
300         {COEF,  0},             /* 4 1 year units */
301         {COEF,  1},             /* 5 2 */
302         {COEF,  2},             /* 6 4 */
303         {COEF,  3},             /* 7 8 */
304         {DECIM9, YR},           /* 8 */
305         {IDLE,  0},             /* 9 p1 */
306         {COEF, 0},              /* 10 1 minute units */
307         {COEF,  1},             /* 11 2 */
308         {COEF,  2},             /* 12 4 */
309         {COEF,  3},             /* 13 8 */
310         {DECIM9, MN},           /* 14 */
311         {COEF,  0},             /* 15 10 minute tens */
312         {COEF,  1},             /* 16 20 */
313         {COEF,  2},             /* 17 40 */
314         {COEF2, 3},             /* 18 80 (not used) */
315         {DECIM6, MN + 1},       /* 19 p2 */
316         {COEF,  0},             /* 20 1 hour units */
317         {COEF,  1},             /* 21 2 */
318         {COEF,  2},             /* 22 4 */
319         {COEF,  3},             /* 23 8 */
320         {DECIM9, HR},           /* 24 */
321         {COEF,  0},             /* 25 10 hour tens */
322         {COEF,  1},             /* 26 20 */
323         {COEF2, 2},             /* 27 40 (not used) */
324         {COEF2, 3},             /* 28 80 (not used) */
325         {DECIM2, HR + 1},       /* 29 p3 */
326         {COEF,  0},             /* 30 1 day units */
327         {COEF,  1},             /* 31 2 */
328         {COEF,  2},             /* 32 4 */
329         {COEF,  3},             /* 33 8 */
330         {DECIM9, DA},           /* 34 */
331         {COEF,  0},             /* 35 10 day tens */
332         {COEF,  1},             /* 36 20 */
333         {COEF,  2},             /* 37 40 */
334         {COEF,  3},             /* 38 80 */
335         {DECIM9, DA + 1},       /* 39 p4 */
336         {COEF,  0},             /* 40 100 day hundreds */
337         {COEF,  1},             /* 41 200 */
338         {COEF2, 2},             /* 42 400 (not used) */
339         {COEF2, 3},             /* 43 800 (not used) */
340         {DECIM3, DA + 2},       /* 44 */
341         {IDLE,  0},             /* 45 */
342         {IDLE,  0},             /* 46 */
343         {IDLE,  0},             /* 47 */
344         {IDLE,  0},             /* 48 */
345         {IDLE,  0},             /* 49 p5 */
346         {MSCBIT, DUTS},         /* 50 dut+- */
347         {COEF,  0},             /* 51 10 year tens */
348         {COEF,  1},             /* 52 20 */
349         {COEF,  2},             /* 53 40 */
350         {COEF,  3},             /* 54 80 */
351         {MSC20, DST1},          /* 55 dst1 */
352         {MSCBIT, DUT1},         /* 56 0.1 dut */
353         {MSCBIT, DUT2},         /* 57 0.2 */
354         {MSC21, DUT4},          /* 58 0.4 QSY probe channel */
355         {MIN1,  0},             /* 59 p6 latch sync min */
356         {MIN2,  0}              /* 60 leap second */
357 };
358
359 /*
360  * BCD coefficients for maximum likelihood digit decode
361  */
362 #define P15     1.              /* max positive number */
363 #define N15     -1.             /* max negative number */
364
365 /*
366  * Digits 0-9
367  */
368 #define P9      (P15 / 4)       /* mark (+1) */
369 #define N9      (N15 / 4)       /* space (-1) */
370
371 double bcd9[][4] = {
372         {N9, N9, N9, N9},       /* 0 */
373         {P9, N9, N9, N9},       /* 1 */
374         {N9, P9, N9, N9},       /* 2 */
375         {P9, P9, N9, N9},       /* 3 */
376         {N9, N9, P9, N9},       /* 4 */
377         {P9, N9, P9, N9},       /* 5 */
378         {N9, P9, P9, N9},       /* 6 */
379         {P9, P9, P9, N9},       /* 7 */
380         {N9, N9, N9, P9},       /* 8 */
381         {P9, N9, N9, P9},       /* 9 */
382         {0, 0, 0, 0}            /* backstop */
383 };
384
385 /*
386  * Digits 0-6 (minute tens)
387  */
388 #define P6      (P15 / 3)       /* mark (+1) */
389 #define N6      (N15 / 3)       /* space (-1) */
390
391 double bcd6[][4] = {
392         {N6, N6, N6, 0},        /* 0 */
393         {P6, N6, N6, 0},        /* 1 */
394         {N6, P6, N6, 0},        /* 2 */
395         {P6, P6, N6, 0},        /* 3 */
396         {N6, N6, P6, 0},        /* 4 */
397         {P6, N6, P6, 0},        /* 5 */
398         {N6, P6, P6, 0},        /* 6 */
399         {0, 0, 0, 0}            /* backstop */
400 };
401
402 /*
403  * Digits 0-3 (day hundreds)
404  */
405 #define P3      (P15 / 2)       /* mark (+1) */
406 #define N3      (N15 / 2)       /* space (-1) */
407
408 double bcd3[][4] = {
409         {N3, N3, 0, 0},         /* 0 */
410         {P3, N3, 0, 0},         /* 1 */
411         {N3, P3, 0, 0},         /* 2 */
412         {P3, P3, 0, 0},         /* 3 */
413         {0, 0, 0, 0}            /* backstop */
414 };
415
416 /*
417  * Digits 0-2 (hour tens)
418  */
419 #define P2      (P15 / 2)       /* mark (+1) */
420 #define N2      (N15 / 2)       /* space (-1) */
421
422 double bcd2[][4] = {
423         {N2, N2, 0, 0},         /* 0 */
424         {P2, N2, 0, 0},         /* 1 */
425         {N2, P2, 0, 0},         /* 2 */
426         {0, 0, 0, 0}            /* backstop */
427 };
428
429 /*
430  * DST decode (DST2 DST1) for prettyprint
431  */
432 char dstcod[] = {
433         'S',                    /* 00 standard time */
434         'I',                    /* 01 set clock ahead at 0200 local */
435         'O',                    /* 10 set clock back at 0200 local */
436         'D'                     /* 11 daylight time */
437 };
438
439 /*
440  * The decoding matrix consists of nine row vectors, one for each digit
441  * of the timecode. The digits are stored from least to most significant
442  * order. The maximum likelihood timecode is formed from the digits
443  * corresponding to the maximum likelihood values reading in the
444  * opposite order: yy ddd hh:mm.
445  */
446 struct decvec {
447         int radix;              /* radix (3, 4, 6, 10) */
448         int digit;              /* current clock digit */
449         int mldigit;            /* maximum likelihood digit */
450         int phase;              /* maximum likelihood digit phase */
451         int count;              /* match count */
452         double digprb;          /* max digit probability */
453         double digsnr;          /* likelihood function (dB) */
454         double like[10];        /* likelihood integrator 0-9 */
455 };
456
457 /*
458  * The station structure is used to acquire the minute pulse from WWV
459  * and/or WWVH. These stations are distinguished by the frequency used
460  * for the second and minute sync pulses, 1000 Hz for WWV and 1200 Hz
461  * for WWVH. Other than frequency, the format is the same.
462  */
463 struct sync {
464         double  epoch;          /* accumulated epoch differences */
465         double  maxamp;         /* sync max envelope (square) */
466         double  noiamp;         /* sync noise envelope (square) */
467         long    pos;            /* max amplitude position */
468         long    lastpos;        /* last max position */
469         long    mepoch;         /* minute synch epoch */
470
471         double  amp;            /* sync amplitude (I, Q squares) */
472         double  synamp;         /* sync max envelope at 800 ms */
473         double  synmax;         /* sync envelope at 0 s */
474         double  synmin;         /* sync envelope at 59, 1 s */
475         double  synsnr;         /* sync signal SNR */
476         int     count;          /* bit counter */
477         char    refid[5];       /* reference identifier */
478         int     select;         /* select bits */
479         int     reach;          /* reachability register */
480 };
481
482 /*
483  * The channel structure is used to mitigate between channels.
484  */
485 struct chan {
486         int     gain;           /* audio gain */
487         double  sigamp;         /* data max envelope (square) */
488         double  noiamp;         /* data noise envelope (square) */
489         double  datsnr;         /* data signal SNR */
490         struct sync wwv;        /* wwv station */
491         struct sync wwvh;       /* wwvh station */
492 };
493
494 /*
495  * WWV unit control structure
496  */
497 struct wwvunit {
498         l_fp    timestamp;      /* audio sample timestamp */
499         l_fp    tick;           /* audio sample increment */
500         double  phase, freq;    /* logical clock phase and frequency */
501         double  monitor;        /* audio monitor point */
502         int     fd_icom;        /* ICOM file descriptor */
503         int     errflg;         /* error flags */
504         int     watch;          /* watchcat */
505
506         /*
507          * Audio codec variables
508          */
509         double  comp[SIZE];     /* decompanding table */
510         int     port;           /* codec port */
511         int     gain;           /* codec gain */
512         int     mongain;        /* codec monitor gain */
513         int     clipcnt;        /* sample clipped count */
514 #ifdef IRIG_SUCKS
515         l_fp    wigwag;         /* wiggle accumulator */
516         int     wp;             /* wiggle filter pointer */
517         l_fp    wiggle[WIGGLE]; /* wiggle filter */
518         l_fp    wigbot[WIGGLE]; /* wiggle bottom fisher*/
519 #endif /* IRIG_SUCKS */
520
521         /*
522          * Variables used to establish basic system timing
523          */
524         int     avgint;         /* master time constant */
525         int     tepoch;         /* sync epoch median */
526         int     yepoch;         /* sync epoch */
527         int     repoch;         /* buffered sync epoch */
528         double  epomax;         /* second sync amplitude */
529         double  eposnr;         /* second sync SNR */
530         double  irig;           /* data I channel amplitude */
531         double  qrig;           /* data Q channel amplitude */
532         int     datapt;         /* 100 Hz ramp */
533         double  datpha;         /* 100 Hz VFO control */
534         int     rphase;         /* second sample counter */
535         long    mphase;         /* minute sample counter */
536
537         /*
538          * Variables used to mitigate which channel to use
539          */
540         struct chan mitig[NCHAN]; /* channel data */
541         struct sync *sptr;      /* station pointer */
542         int     dchan;          /* data channel */
543         int     schan;          /* probe channel */
544         int     achan;          /* active channel */
545
546         /*
547          * Variables used by the clock state machine
548          */
549         struct decvec decvec[9]; /* decoding matrix */
550         int     rsec;           /* seconds counter */
551         int     digcnt;         /* count of digits synchronized */
552
553         /*
554          * Variables used to estimate signal levels and bit/digit
555          * probabilities
556          */
557         double  sigsig;         /* data max signal */
558         double  sigamp;         /* data max envelope (square) */
559         double  noiamp;         /* data noise envelope (square) */
560         double  datsnr;         /* data SNR (dB) */
561
562         /*
563          * Variables used to establish status and alarm conditions
564          */
565         int     status;         /* status bits */
566         int     alarm;          /* alarm flashers */
567         int     misc;           /* miscellaneous timecode bits */
568         int     errcnt;         /* data bit error counter */
569         int     errbit;         /* data bit errors in minute */
570 };
571
572 /*
573  * Function prototypes
574  */
575 static  int     wwv_start       P((int, struct peer *));
576 static  void    wwv_shutdown    P((int, struct peer *));
577 static  void    wwv_receive     P((struct recvbuf *));
578 static  void    wwv_poll        P((int, struct peer *));
579
580 /*
581  * More function prototypes
582  */
583 static  void    wwv_epoch       P((struct peer *));
584 static  void    wwv_rf          P((struct peer *, double));
585 static  void    wwv_endpoc      P((struct peer *, int));
586 static  void    wwv_rsec        P((struct peer *, double));
587 static  void    wwv_qrz         P((struct peer *, struct sync *,
588                                     double, int));
589 static  void    wwv_corr4       P((struct peer *, struct decvec *,
590                                     double [], double [][4]));
591 static  void    wwv_gain        P((struct peer *));
592 static  void    wwv_tsec        P((struct wwvunit *));
593 static  double  wwv_data        P((struct wwvunit *, double));
594 static  int     timecode        P((struct wwvunit *, char *));
595 static  double  wwv_snr         P((double, double));
596 static  int     carry           P((struct decvec *));
597 static  void    wwv_newchan     P((struct peer *));
598 static  void    wwv_newgame     P((struct peer *));
599 static  double  wwv_metric      P((struct sync *));
600 #ifdef ICOM
601 static  int     wwv_qsy         P((struct peer *, int));
602 #endif /* ICOM */
603
604 static double qsy[NCHAN] = {2.5, 5, 10, 15, 20}; /* frequencies (MHz) */
605
606 /*
607  * Transfer vector
608  */
609 struct  refclock refclock_wwv = {
610         wwv_start,              /* start up driver */
611         wwv_shutdown,           /* shut down driver */
612         wwv_poll,               /* transmit poll message */
613         noentry,                /* not used (old wwv_control) */
614         noentry,                /* initialize driver (not used) */
615         noentry,                /* not used (old wwv_buginfo) */
616         NOFLAGS                 /* not used */
617 };
618
619
620 /*
621  * wwv_start - open the devices and initialize data for processing
622  */
623 static int
624 wwv_start(
625         int     unit,           /* instance number (used by PCM) */
626         struct peer *peer       /* peer structure pointer */
627         )
628 {
629         struct refclockproc *pp;
630         struct wwvunit *up;
631 #ifdef ICOM
632         int     temp;
633 #endif /* ICOM */
634
635         /*
636          * Local variables
637          */
638         int     fd;             /* file descriptor */
639         int     i;              /* index */
640         double  step;           /* codec adjustment */
641
642         /*
643          * Open audio device
644          */
645         fd = audio_init(DEVICE_AUDIO, AUDIO_BUFSIZ, unit);
646         if (fd < 0)
647                 return (0);
648 #ifdef DEBUG
649         if (debug)
650                 audio_show();
651 #endif
652
653         /*
654          * Allocate and initialize unit structure
655          */
656         if (!(up = (struct wwvunit *)emalloc(sizeof(struct wwvunit)))) {
657                 close(fd);
658                 return (0);
659         }
660         memset(up, 0, sizeof(struct wwvunit));
661         pp = peer->procptr;
662         pp->unitptr = (caddr_t)up;
663         pp->io.clock_recv = wwv_receive;
664         pp->io.srcclock = (caddr_t)peer;
665         pp->io.datalen = 0;
666         pp->io.fd = fd;
667         if (!io_addclock(&pp->io)) {
668                 close(fd);
669                 free(up);
670                 return (0);
671         }
672
673         /*
674          * Initialize miscellaneous variables
675          */
676         peer->precision = PRECISION;
677         pp->clockdesc = DESCRIPTION;
678
679         /*
680          * The companded samples are encoded sign-magnitude. The table
681          * contains all the 256 values in the interest of speed.
682          */
683         up->comp[0] = up->comp[OFFSET] = 0.;
684         up->comp[1] = 1; up->comp[OFFSET + 1] = -1.;
685         up->comp[2] = 3; up->comp[OFFSET + 2] = -3.;
686         step = 2.;
687         for (i = 3; i < OFFSET; i++) {
688                 up->comp[i] = up->comp[i - 1] + step;
689                 up->comp[OFFSET + i] = -up->comp[i];
690                 if (i % 16 == 0)
691                     step *= 2.;
692         }
693         DTOLFP(1. / SECOND, &up->tick);
694
695         /*
696          * Initialize the decoding matrix with the radix for each digit
697          * position.
698          */
699         up->decvec[MN].radix = 10;      /* minutes */
700         up->decvec[MN + 1].radix = 6;
701         up->decvec[HR].radix = 10;      /* hours */
702         up->decvec[HR + 1].radix = 3;
703         up->decvec[DA].radix = 10;      /* days */
704         up->decvec[DA + 1].radix = 10;
705         up->decvec[DA + 2].radix = 4;
706         up->decvec[YR].radix = 10;      /* years */
707         up->decvec[YR + 1].radix = 10;
708         wwv_newgame(peer);
709         up->schan = up->achan = 3;
710
711         /*
712          * Initialize autotune if available. Start out at 15 MHz. Note
713          * that the ICOM select code must be less than 128, so the high
714          * order bit can be used to select the line speed.
715          */
716 #ifdef ICOM
717         temp = 0;
718 #ifdef DEBUG
719         if (debug > 1)
720                 temp = P_TRACE;
721 #endif
722         if (peer->ttl != 0) {
723                 if (peer->ttl & 0x80)
724                         up->fd_icom = icom_init("/dev/icom", B1200,
725                             temp);
726                 else
727                         up->fd_icom = icom_init("/dev/icom", B9600,
728                             temp);
729         }
730         if (up->fd_icom > 0) {
731                 if ((temp = wwv_qsy(peer, up->schan)) != 0) {
732                         NLOG(NLOG_SYNCEVENT | NLOG_SYSEVENT)
733                             msyslog(LOG_NOTICE,
734                             "icom: radio not found");
735                         up->errflg = CEVNT_FAULT;
736                         close(up->fd_icom);
737                         up->fd_icom = 0;
738                 } else {
739                         NLOG(NLOG_SYNCEVENT | NLOG_SYSEVENT)
740                             msyslog(LOG_NOTICE,
741                             "icom: autotune enabled");
742                 }
743         }
744 #endif /* ICOM */
745         return (1);
746 }
747
748
749 /*
750  * wwv_shutdown - shut down the clock
751  */
752 static void
753 wwv_shutdown(
754         int     unit,           /* instance number (not used) */
755         struct peer *peer       /* peer structure pointer */
756         )
757 {
758         struct refclockproc *pp;
759         struct wwvunit *up;
760
761         pp = peer->procptr;
762         up = (struct wwvunit *)pp->unitptr;
763         io_closeclock(&pp->io);
764         if (up->fd_icom > 0)
765                 close(up->fd_icom);
766         free(up);
767 }
768
769
770 /*
771  * wwv_receive - receive data from the audio device
772  *
773  * This routine reads input samples and adjusts the logical clock to
774  * track the A/D sample clock by dropping or duplicating codec samples.
775  * It also controls the A/D signal level with an AGC loop to mimimize
776  * quantization noise and avoid overload.
777  */
778 static void
779 wwv_receive(
780         struct recvbuf *rbufp   /* receive buffer structure pointer */
781         )
782 {
783         struct peer *peer;
784         struct refclockproc *pp;
785         struct wwvunit *up;
786
787         /*
788          * Local variables
789          */
790         double  sample;         /* codec sample */
791         u_char  *dpt;           /* buffer pointer */
792         int     bufcnt;         /* buffer counter */
793         l_fp    ltemp;
794
795         peer = (struct peer *)rbufp->recv_srcclock;
796         pp = peer->procptr;
797         up = (struct wwvunit *)pp->unitptr;
798
799         /*
800          * Main loop - read until there ain't no more. Note codec
801          * samples are bit-inverted.
802          */
803         DTOLFP((double)rbufp->recv_length / SECOND, &ltemp);
804         L_SUB(&rbufp->recv_time, &ltemp);
805         up->timestamp = rbufp->recv_time;
806         dpt = rbufp->recv_buffer;
807         for (bufcnt = 0; bufcnt < rbufp->recv_length; bufcnt++) {
808                 sample = up->comp[~*dpt++ & 0xff];
809
810                 /*
811                  * Clip noise spikes greater than MAXSIG. If no clips,
812                  * increase the gain a tad; if the clips are too high, 
813                  * decrease a tad.
814                  */
815                 if (sample > MAXSIG) {
816                         sample = MAXSIG;
817                         up->clipcnt++;
818                 } else if (sample < -MAXSIG) {
819                         sample = -MAXSIG;
820                         up->clipcnt++;
821                 }
822
823                 /*
824                  * Variable frequency oscillator. The codec oscillator
825                  * runs at the nominal rate of 8000 samples per second,
826                  * or 125 us per sample. A frequency change of one unit
827                  * results in either duplicating or deleting one sample
828                  * per second, which results in a frequency change of
829                  * 125 PPM.
830                  */
831                 up->phase += up->freq / SECOND;
832                 if (up->phase >= .5) {
833                         up->phase -= 1.;
834                 } else if (up->phase < -.5) {
835                         up->phase += 1.;
836                         wwv_rf(peer, sample);
837                         wwv_rf(peer, sample);
838                 } else {
839                         wwv_rf(peer, sample);
840                 }
841                 L_ADD(&up->timestamp, &up->tick);
842         }
843
844         /*
845          * Set the input port and monitor gain for the next buffer.
846          */
847         if (pp->sloppyclockflag & CLK_FLAG2)
848                 up->port = 2;
849         else
850                 up->port = 1;
851         if (pp->sloppyclockflag & CLK_FLAG3)
852                 up->mongain = MONGAIN;
853         else
854                 up->mongain = 0;
855 }
856
857
858 /*
859  * wwv_poll - called by the transmit procedure
860  *
861  * This routine keeps track of status. If no offset samples have been
862  * processed during a poll interval, a timeout event is declared. If
863  * errors have have occurred during the interval, they are reported as
864  * well. Once the clock is set, it always appears reachable, unless
865  * reset by watchdog timeout.
866  */
867 static void
868 wwv_poll(
869         int     unit,           /* instance number (not used) */
870         struct peer *peer       /* peer structure pointer */
871         )
872 {
873         struct refclockproc *pp;
874         struct wwvunit *up;
875
876         pp = peer->procptr;
877         up = (struct wwvunit *)pp->unitptr;
878         if (pp->coderecv == pp->codeproc)
879                 up->errflg = CEVNT_TIMEOUT;
880         if (up->errflg)
881                 refclock_report(peer, up->errflg);
882         up->errflg = 0;
883         pp->polls++;
884 }
885
886
887 /*
888  * wwv_rf - process signals and demodulate to baseband
889  *
890  * This routine grooms and filters decompanded raw audio samples. The
891  * output signals include the 100-Hz baseband data signal in quadrature
892  * form, plus the epoch index of the second sync signal and the second
893  * index of the minute sync signal.
894  *
895  * There are two 1-s ramps used by this program. Both count the 8000
896  * logical clock samples spanning exactly one second. The epoch ramp
897  * counts the samples starting at an arbitrary time. The rphase ramp
898  * counts the samples starting at the 5-ms second sync pulse found
899  * during the epoch ramp.
900  *
901  * There are two 1-m ramps used by this program. The mphase ramp counts
902  * the 480,000 logical clock samples spanning exactly one minute and
903  * starting at an arbitrary time. The rsec ramp counts the 60 seconds of
904  * the minute starting at the 800-ms minute sync pulse found during the
905  * mphase ramp. The rsec ramp drives the seconds state machine to
906  * determine the bits and digits of the timecode. 
907  *
908  * Demodulation operations are based on three synthesized quadrature
909  * sinusoids: 100 Hz for the data signal, 1000 Hz for the WWV sync
910  * signal and 1200 Hz for the WWVH sync signal. These drive synchronous
911  * matched filters for the data signal (170 ms at 100 Hz), WWV minute
912  * sync signal (800 ms at 1000 Hz) and WWVH minute sync signal (800 ms
913  * at 1200 Hz). Two additional matched filters are switched in
914  * as required for the WWV second sync signal (5 ms at 1000 Hz) and
915  * WWVH second sync signal (5 ms at 1200 Hz).
916  */
917 static void
918 wwv_rf(
919         struct peer *peer,      /* peerstructure pointer */
920         double isig             /* input signal */
921         )
922 {
923         struct refclockproc *pp;
924         struct wwvunit *up;
925         struct sync *sp;
926
927         static double lpf[5];   /* 150-Hz lpf delay line */
928         double data;            /* lpf output */
929         static double bpf[9];   /* 1000/1200-Hz bpf delay line */
930         double syncx;           /* bpf output */
931         static double mf[41];   /* 1000/1200-Hz mf delay line */
932         double mfsync;          /* mf output */
933
934         static int iptr;        /* data channel pointer */
935         static double ibuf[DATSIZ]; /* data I channel delay line */
936         static double qbuf[DATSIZ]; /* data Q channel delay line */
937
938         static int jptr;        /* sync channel pointer */
939         static double cibuf[SYNSIZ]; /* wwv I channel delay line */
940         static double cqbuf[SYNSIZ]; /* wwv Q channel delay line */
941         static double ciamp;    /* wwv I channel amplitude */
942         static double cqamp;    /* wwv Q channel amplitude */
943         static int csinptr;     /* wwv channel phase */
944         static double hibuf[SYNSIZ]; /* wwvh I channel delay line */
945         static double hqbuf[SYNSIZ]; /* wwvh Q channel delay line */
946         static double hiamp;    /* wwvh I channel amplitude */
947         static double hqamp;    /* wwvh Q channel amplitude */
948         static int hsinptr;     /* wwvh channels phase */
949
950         static double epobuf[SECOND]; /* epoch sync comb filter */
951         static double epomax;   /* epoch sync amplitude buffer */
952         static int epopos;      /* epoch sync position buffer */
953
954         static int iniflg;      /* initialization flag */
955         int     epoch;          /* comb filter index */
956         int     pdelay;         /* propagation delay (samples) */
957         double  dtemp;
958         int     i;
959
960         pp = peer->procptr;
961         up = (struct wwvunit *)pp->unitptr;
962
963         if (!iniflg) {
964                 iniflg = 1;
965                 memset((char *)lpf, 0, sizeof(lpf));
966                 memset((char *)bpf, 0, sizeof(bpf));
967                 memset((char *)mf, 0, sizeof(mf));
968                 memset((char *)ibuf, 0, sizeof(ibuf));
969                 memset((char *)qbuf, 0, sizeof(qbuf));
970                 memset((char *)cibuf, 0, sizeof(cibuf));
971                 memset((char *)cqbuf, 0, sizeof(cqbuf));
972                 memset((char *)hibuf, 0, sizeof(hibuf));
973                 memset((char *)hqbuf, 0, sizeof(hqbuf));
974                 memset((char *)epobuf, 0, sizeof(epobuf));
975         }
976
977         /*
978          * Baseband data demodulation. The 100-Hz subcarrier is
979          * extracted using a 150-Hz IIR lowpass filter. This attenuates
980          * the 1000/1200-Hz sync signals, as well as the 440-Hz and
981          * 600-Hz tones and most of the noise and voice modulation
982          * components.
983          *
984          * Matlab IIR 4th-order IIR elliptic, 150 Hz lowpass, 0.2 dB
985          * passband ripple, -50 dB stopband ripple.
986          */
987         data = (lpf[4] = lpf[3]) * 8.360961e-01;
988         data += (lpf[3] = lpf[2]) * -3.481740e+00;
989         data += (lpf[2] = lpf[1]) * 5.452988e+00;
990         data += (lpf[1] = lpf[0]) * -3.807229e+00;
991         lpf[0] = isig - data;
992         data = lpf[0] * 3.281435e-03
993             + lpf[1] * -1.149947e-02
994             + lpf[2] * 1.654858e-02
995             + lpf[3] * -1.149947e-02
996             + lpf[4] * 3.281435e-03;
997
998         /*
999          * The I and Q quadrature data signals are produced by
1000          * multiplying the filtered signal by 100-Hz sine and cosine
1001          * signals, respectively. The data signals are demodulated by
1002          * 170-ms synchronous matched filters to produce the amplitude
1003          * and phase signals used by the decoder.
1004          */
1005         i = up->datapt;
1006         up->datapt = (up->datapt + IN100) % 80;
1007         dtemp = sintab[i] * data / DATSIZ * DGAIN;
1008         up->irig -= ibuf[iptr];
1009         ibuf[iptr] = dtemp;
1010         up->irig += dtemp;
1011         i = (i + 20) % 80;
1012         dtemp = sintab[i] * data / DATSIZ * DGAIN;
1013         up->qrig -= qbuf[iptr];
1014         qbuf[iptr] = dtemp;
1015         up->qrig += dtemp;
1016         iptr = (iptr + 1) % DATSIZ;
1017
1018         /*
1019          * Baseband sync demodulation. The 1000/1200 sync signals are
1020          * extracted using a 600-Hz IIR bandpass filter. This removes
1021          * the 100-Hz data subcarrier, as well as the 440-Hz and 600-Hz
1022          * tones and most of the noise and voice modulation components.
1023          *
1024          * Matlab 4th-order IIR elliptic, 800-1400 Hz bandpass, 0.2 dB
1025          * passband ripple, -50 dB stopband ripple.
1026          */
1027         syncx = (bpf[8] = bpf[7]) * 4.897278e-01;
1028         syncx += (bpf[7] = bpf[6]) * -2.765914e+00;
1029         syncx += (bpf[6] = bpf[5]) * 8.110921e+00;
1030         syncx += (bpf[5] = bpf[4]) * -1.517732e+01;
1031         syncx += (bpf[4] = bpf[3]) * 1.975197e+01;
1032         syncx += (bpf[3] = bpf[2]) * -1.814365e+01;
1033         syncx += (bpf[2] = bpf[1]) * 1.159783e+01;
1034         syncx += (bpf[1] = bpf[0]) * -4.735040e+00;
1035         bpf[0] = isig - syncx;
1036         syncx = bpf[0] * 8.203628e-03
1037             + bpf[1] * -2.375732e-02
1038             + bpf[2] * 3.353214e-02
1039             + bpf[3] * -4.080258e-02
1040             + bpf[4] * 4.605479e-02
1041             + bpf[5] * -4.080258e-02
1042             + bpf[6] * 3.353214e-02
1043             + bpf[7] * -2.375732e-02
1044             + bpf[8] * 8.203628e-03;
1045
1046         /*
1047          * The I and Q quadrature minute sync signals are produced by
1048          * multiplying the filtered signal by 1000-Hz (WWV) and 1200-Hz
1049          * (WWVH) sine and cosine signals, respectively. The resulting
1050          * signals are demodulated by 800-ms synchronous matched filters
1051          * to synchronize the second and minute and to detect which one
1052          * (or both) the WWV or WWVH signal is present.
1053          *
1054          * Note the master timing ramps, which run continuously. The
1055          * minute counter (mphase) counts the samples in the minute,
1056          * while the second counter (epoch) counts the samples in the
1057          * second.
1058          */
1059         up->mphase = (up->mphase + 1) % MINUTE;
1060         epoch = up->mphase % SECOND;
1061         i = csinptr;
1062         csinptr = (csinptr + IN1000) % 80;
1063         dtemp = sintab[i] * syncx / SYNSIZ * SGAIN;
1064         ciamp = ciamp - cibuf[jptr] + dtemp;
1065         cibuf[jptr] = dtemp;
1066         i = (i + 20) % 80;
1067         dtemp = sintab[i] * syncx / SYNSIZ * SGAIN;
1068         cqamp = cqamp - cqbuf[jptr] + dtemp;
1069         cqbuf[jptr] = dtemp;
1070         sp = &up->mitig[up->schan].wwv;
1071         dtemp = ciamp * ciamp + cqamp * cqamp;
1072         sp->amp = dtemp;
1073         if (!(up->status & MSYNC))
1074                 wwv_qrz(peer, sp, dtemp, (int)(pp->fudgetime1 *
1075                     SECOND));
1076         i = hsinptr;
1077         hsinptr = (hsinptr + IN1200) % 80;
1078         dtemp = sintab[i] * syncx / SYNSIZ * SGAIN;
1079         hiamp = hiamp - hibuf[jptr] + dtemp;
1080         hibuf[jptr] = dtemp;
1081         i = (i + 20) % 80;
1082         dtemp = sintab[i] * syncx / SYNSIZ * SGAIN;
1083         hqamp = hqamp - hqbuf[jptr] + dtemp;
1084         hqbuf[jptr] = dtemp;
1085         sp = &up->mitig[up->schan].wwvh;
1086         dtemp = hiamp * hiamp + hqamp * hqamp;
1087         sp->amp = dtemp;
1088         if (!(up->status & MSYNC))
1089                 wwv_qrz(peer, sp, dtemp, (int)(pp->fudgetime2 *
1090                     SECOND));
1091         jptr = (jptr + 1) % SYNSIZ;
1092
1093         /*
1094          * The following section is called once per minute. It does
1095          * housekeeping and timeout functions and empties the dustbins.
1096          */
1097         if (up->mphase == 0) {
1098                 up->watch++;
1099                 if (!(up->status & MSYNC)) {
1100
1101                         /*
1102                          * If minute sync has not been acquired before
1103                          * timeout, or if no signal is heard, the
1104                          * program cycles to the next frequency and
1105                          * tries again.
1106                          */
1107                         wwv_newchan(peer);
1108                         if (!(up->status & (SELV | SELH)) || up->watch >
1109                             ACQSN) {
1110                                 wwv_newgame(peer);
1111 #ifdef ICOM
1112                                 if (up->fd_icom > 0) {
1113                                         up->schan = (up->schan + 1) %
1114                                             NCHAN;
1115                                         wwv_qsy(peer, up->schan);
1116                                 }
1117 #endif /* ICOM */
1118                         }
1119                 } else {
1120
1121                         /*
1122                          * If the leap bit is set, set the minute epoch
1123                          * back one second so the station processes
1124                          * don't miss a beat.
1125                          */
1126                         if (up->status & LEPSEC) {
1127                                 up->mphase -= SECOND;
1128                                 if (up->mphase < 0)
1129                                         up->mphase += MINUTE;
1130                         }
1131                 }
1132         }
1133
1134         /*
1135          * When the channel metric reaches threshold and the second
1136          * counter matches the minute epoch within the second, the
1137          * driver has synchronized to the station. The second number is
1138          * the remaining seconds until the next minute epoch, while the
1139          * sync epoch is zero. Watch out for the first second; if
1140          * already synchronized to the second, the buffered sync epoch
1141          * must be set. 
1142          */
1143         if (up->status & MSYNC) {
1144                 wwv_epoch(peer);
1145         } else if ((sp = up->sptr) != NULL) {
1146                 struct chan *cp;
1147
1148                 if (sp->count >= AMIN && epoch == sp->mepoch % SECOND) {
1149                         up->rsec = 60 - sp->mepoch / SECOND;
1150                         up->rphase = 0;
1151                         up->status |= MSYNC;
1152                         up->watch = 0;
1153                         if (!(up->status & SSYNC))
1154                                 up->repoch = up->yepoch = epoch;
1155                         else
1156                                 up->repoch = up->yepoch;
1157                         for (i = 0; i < NCHAN; i++) {
1158                                 cp = &up->mitig[i];
1159                                 cp->wwv.count = cp->wwv.reach = 0;
1160                                 cp->wwvh.count = cp->wwvh.reach = 0;
1161                         }
1162                 }
1163         }
1164
1165         /*
1166          * The second sync pulse is extracted using 5-ms (40 sample) FIR
1167          * matched filters at 1000 Hz for WWV or 1200 Hz for WWVH. This
1168          * pulse is used for the most precise synchronization, since if
1169          * provides a resolution of one sample (125 us). The filters run
1170          * only if the station has been reliably determined.
1171          */
1172         if (up->status & SELV) {
1173                 pdelay = (int)(pp->fudgetime1 * SECOND);
1174
1175                 /*
1176                  * WWV FIR matched filter, five cycles of 1000-Hz
1177                  * sinewave.
1178                  */
1179                 mf[40] = mf[39];
1180                 mfsync = (mf[39] = mf[38]) * 4.224514e-02;
1181                 mfsync += (mf[38] = mf[37]) * 5.974365e-02;
1182                 mfsync += (mf[37] = mf[36]) * 4.224514e-02;
1183                 mf[36] = mf[35];
1184                 mfsync += (mf[35] = mf[34]) * -4.224514e-02;
1185                 mfsync += (mf[34] = mf[33]) * -5.974365e-02;
1186                 mfsync += (mf[33] = mf[32]) * -4.224514e-02;
1187                 mf[32] = mf[31];
1188                 mfsync += (mf[31] = mf[30]) * 4.224514e-02;
1189                 mfsync += (mf[30] = mf[29]) * 5.974365e-02;
1190                 mfsync += (mf[29] = mf[28]) * 4.224514e-02;
1191                 mf[28] = mf[27];
1192                 mfsync += (mf[27] = mf[26]) * -4.224514e-02;
1193                 mfsync += (mf[26] = mf[25]) * -5.974365e-02;
1194                 mfsync += (mf[25] = mf[24]) * -4.224514e-02;
1195                 mf[24] = mf[23];
1196                 mfsync += (mf[23] = mf[22]) * 4.224514e-02;
1197                 mfsync += (mf[22] = mf[21]) * 5.974365e-02;
1198                 mfsync += (mf[21] = mf[20]) * 4.224514e-02;
1199                 mf[20] = mf[19];
1200                 mfsync += (mf[19] = mf[18]) * -4.224514e-02;
1201                 mfsync += (mf[18] = mf[17]) * -5.974365e-02;
1202                 mfsync += (mf[17] = mf[16]) * -4.224514e-02;
1203                 mf[16] = mf[15];
1204                 mfsync += (mf[15] = mf[14]) * 4.224514e-02;
1205                 mfsync += (mf[14] = mf[13]) * 5.974365e-02;
1206                 mfsync += (mf[13] = mf[12]) * 4.224514e-02;
1207                 mf[12] = mf[11];
1208                 mfsync += (mf[11] = mf[10]) * -4.224514e-02;
1209                 mfsync += (mf[10] = mf[9]) * -5.974365e-02;
1210                 mfsync += (mf[9] = mf[8]) * -4.224514e-02;
1211                 mf[8] = mf[7];
1212                 mfsync += (mf[7] = mf[6]) * 4.224514e-02;
1213                 mfsync += (mf[6] = mf[5]) * 5.974365e-02;
1214                 mfsync += (mf[5] = mf[4]) * 4.224514e-02;
1215                 mf[4] = mf[3];
1216                 mfsync += (mf[3] = mf[2]) * -4.224514e-02;
1217                 mfsync += (mf[2] = mf[1]) * -5.974365e-02;
1218                 mfsync += (mf[1] = mf[0]) * -4.224514e-02;
1219                 mf[0] = syncx;
1220         } else if (up->status & SELH) {
1221                 pdelay = (int)(pp->fudgetime2 * SECOND);
1222
1223                 /*
1224                  * WWVH FIR matched filter, six cycles of 1200-Hz
1225                  * sinewave.
1226                  */
1227                 mf[40] = mf[39];
1228                 mfsync = (mf[39] = mf[38]) * 4.833363e-02;
1229                 mfsync += (mf[38] = mf[37]) * 5.681959e-02;
1230                 mfsync += (mf[37] = mf[36]) * 1.846180e-02;
1231                 mfsync += (mf[36] = mf[35]) * -3.511644e-02;
1232                 mfsync += (mf[35] = mf[34]) * -5.974365e-02;
1233                 mfsync += (mf[34] = mf[33]) * -3.511644e-02;
1234                 mfsync += (mf[33] = mf[32]) * 1.846180e-02;
1235                 mfsync += (mf[32] = mf[31]) * 5.681959e-02;
1236                 mfsync += (mf[31] = mf[30]) * 4.833363e-02;
1237                 mf[30] = mf[29];
1238                 mfsync += (mf[29] = mf[28]) * -4.833363e-02;
1239                 mfsync += (mf[28] = mf[27]) * -5.681959e-02;
1240                 mfsync += (mf[27] = mf[26]) * -1.846180e-02;
1241                 mfsync += (mf[26] = mf[25]) * 3.511644e-02;
1242                 mfsync += (mf[25] = mf[24]) * 5.974365e-02;
1243                 mfsync += (mf[24] = mf[23]) * 3.511644e-02;
1244                 mfsync += (mf[23] = mf[22]) * -1.846180e-02;
1245                 mfsync += (mf[22] = mf[21]) * -5.681959e-02;
1246                 mfsync += (mf[21] = mf[20]) * -4.833363e-02;
1247                 mf[20] = mf[19];
1248                 mfsync += (mf[19] = mf[18]) * 4.833363e-02;
1249                 mfsync += (mf[18] = mf[17]) * 5.681959e-02;
1250                 mfsync += (mf[17] = mf[16]) * 1.846180e-02;
1251                 mfsync += (mf[16] = mf[15]) * -3.511644e-02;
1252                 mfsync += (mf[15] = mf[14]) * -5.974365e-02;
1253                 mfsync += (mf[14] = mf[13]) * -3.511644e-02;
1254                 mfsync += (mf[13] = mf[12]) * 1.846180e-02;
1255                 mfsync += (mf[12] = mf[11]) * 5.681959e-02;
1256                 mfsync += (mf[11] = mf[10]) * 4.833363e-02;
1257                 mf[10] = mf[9];
1258                 mfsync += (mf[9] = mf[8]) * -4.833363e-02;
1259                 mfsync += (mf[8] = mf[7]) * -5.681959e-02;
1260                 mfsync += (mf[7] = mf[6]) * -1.846180e-02;
1261                 mfsync += (mf[6] = mf[5]) * 3.511644e-02;
1262                 mfsync += (mf[5] = mf[4]) * 5.974365e-02;
1263                 mfsync += (mf[4] = mf[3]) * 3.511644e-02;
1264                 mfsync += (mf[3] = mf[2]) * -1.846180e-02;
1265                 mfsync += (mf[2] = mf[1]) * -5.681959e-02;
1266                 mfsync += (mf[1] = mf[0]) * -4.833363e-02;
1267                 mf[0] = syncx;
1268         } else {
1269                 mfsync = 0;
1270                 pdelay = 0;
1271         }
1272
1273         /*
1274          * Enhance the seconds sync pulse using a 1-s (8000-sample) comb
1275          * filter. Correct for the FIR matched filter delay, which is 5
1276          * ms for both the WWV and WWVH filters, and also for the
1277          * propagation delay. Once each second look for second sync. If
1278          * not in minute sync, fiddle the codec gain. Note the SNR is
1279          * computed from the maximum sample and the two samples 6 ms
1280          * before and 6 ms after it, so if we slip more than a cycle the
1281          * SNR should plummet.
1282          */
1283         dtemp = (epobuf[epoch] += (mfsync - epobuf[epoch]) /
1284             up->avgint);
1285         if (dtemp > epomax) {
1286                 epomax = dtemp;
1287                 epopos = epoch;
1288         }
1289         if (epoch == 0) {
1290                 int k, j;
1291
1292                 up->epomax = epomax;
1293                 k = epopos - 6 * MS;
1294                 if (k < 0)
1295                         k += SECOND;
1296                 j = epopos + 6 * MS;
1297                 if (j >= SECOND)
1298                         i -= SECOND;
1299                 up->eposnr = wwv_snr(epomax, max(abs(epobuf[k]),
1300                     abs(epobuf[j])));
1301                 epopos -= pdelay + 5 * MS; 
1302                 if (epopos < 0)
1303                         epopos += SECOND;
1304                 wwv_endpoc(peer, epopos);
1305                 if (!(up->status & SSYNC))
1306                         up->alarm |= SYNERR;
1307                 epomax = 0;
1308                 if (!(up->status & MSYNC))
1309                         wwv_gain(peer);
1310         }
1311 }
1312
1313
1314 /*
1315  * wwv_qrz - identify and acquire WWV/WWVH minute sync pulse
1316  *
1317  * This routine implements a virtual station process used to acquire
1318  * minute sync and to mitigate among the ten frequency and station
1319  * combinations. During minute sync acquisition the process probes each
1320  * frequency in turn for the minute pulse from either station, which
1321  * involves searching through the entire minute of samples. After
1322  * finding a candidate, the process searches only the seconds before and
1323  * after the candidate for the signal and all other seconds for the
1324  * noise.
1325  *
1326  * Students of radar receiver technology will discover this algorithm
1327  * amounts to a range gate discriminator. The discriminator requires
1328  * that the peak minute pulse amplitude be at least 2000 and the SNR be
1329  * at least 6 dB. In addition after finding a candidate, The peak second
1330  * pulse amplitude must be at least 2000, the SNR at least 6 dB and the
1331  * difference between the current and previous epoch must be less than
1332  * 7.5 ms, which corresponds to a frequency error of 125 PPM.. A compare
1333  * counter keeps track of the number of successive intervals which
1334  * satisfy these criteria.
1335  *
1336  * Note that, while the minute pulse is found by by the discriminator,
1337  * the actual value is determined from the second epoch. The assumption
1338  * is that the discriminator peak occurs about 800 ms into the second,
1339  * so the timing is retarted to the previous second epoch.
1340  */
1341 static void
1342 wwv_qrz(
1343         struct peer *peer,      /* peer structure pointer */
1344         struct sync *sp,        /* sync channel structure */
1345         double  syncx,          /* bandpass filtered sync signal */
1346         int     pdelay          /* propagation delay (samples) */
1347         )
1348 {
1349         struct refclockproc *pp;
1350         struct wwvunit *up;
1351         char tbuf[80];          /* monitor buffer */
1352         double snr;             /* on-pulse/off-pulse ratio (dB) */
1353         long epoch, fpoch;
1354         int isgood;
1355
1356         pp = peer->procptr;
1357         up = (struct wwvunit *)pp->unitptr;
1358
1359         /*
1360          * Find the sample with peak energy, which defines the minute
1361          * epoch. If a sample has been found with good amplitude,
1362          * accumulate the noise squares for all except the second before
1363          * and after that position.
1364          */
1365         isgood = up->epomax > STHR && up->eposnr > SSNR;
1366         if (isgood) {
1367                 fpoch = up->mphase % SECOND - up->tepoch;
1368                 if (fpoch < 0)
1369                         fpoch += SECOND;
1370         } else {
1371                 fpoch = pdelay + SYNSIZ;
1372         }
1373         epoch = up->mphase - fpoch;
1374         if (epoch < 0)
1375                 epoch += MINUTE;
1376         if (syncx > sp->maxamp) {
1377                 sp->maxamp = syncx;
1378                 sp->pos = epoch;
1379         }
1380         if (abs((epoch - sp->lastpos) % MINUTE) > SECOND)
1381                 sp->noiamp += syncx;
1382
1383         /*
1384          * At the end of the minute, determine the epoch of the
1385          * sync pulse, as well as the SNR and difference between
1386          * the current and previous epoch, which represents the
1387          * intrinsic frequency error plus jitter.
1388          */
1389         if (up->mphase == 0) {
1390                 sp->synmax = sqrt(sp->maxamp);
1391                 sp->synmin = sqrt(sp->noiamp / (MINUTE - 2 * SECOND));
1392                 epoch = (sp->pos - sp->lastpos) % MINUTE;
1393
1394                 /*
1395                  * If not yet in minute sync, we have to do a little
1396                  * dance to find a valid minute sync pulse, emphasis
1397                  * valid.
1398                  */
1399                 snr = wwv_snr(sp->synmax, sp->synmin);
1400                 isgood = isgood && sp->synmax > ATHR && snr > ASNR;
1401                 switch (sp->count) {
1402
1403                 /*
1404                  * In state 0 the station was not heard during the
1405                  * previous probe. Look for the biggest blip greater
1406                  * than the amplitude threshold in the minute and assume
1407                  * that the minute sync pulse. We're fishing here, since
1408                  * the range gate has not yet been determined. If found,
1409                  * bump to state 1.
1410                  */
1411                 case 0:
1412                         if (sp->synmax >= ATHR)
1413                                 sp->count++;
1414                         break;
1415
1416                 /*
1417                  * In state 1 a candidate blip has been found and the
1418                  * next minute has been searched for another blip. If
1419                  * none are found acceptable, drop back to state 0 and
1420                  * hunt some more. Otherwise, a legitimate minute pulse
1421                  * may have been found, so bump to state 2.
1422                  */
1423                 case 1:
1424                         if (!isgood) {
1425                                 sp->count = 0;
1426                                 break;
1427                         }
1428                         sp->count++;
1429                         break;
1430
1431                 /*
1432                  * In states 2 and above, continue to groom samples as
1433                  * before and drop back to state 0 if the groom fails.
1434                  * If it succeeds, set the epoch and bump to the next
1435                  * state until reaching the threshold, if ever.
1436                  */
1437                 default:
1438                         if (!isgood || abs(epoch) > AWND * MS) {
1439                                 sp->count = 0;
1440                                 break;
1441                         }
1442                         sp->mepoch = sp->pos;
1443                         sp->count++;
1444                         break;
1445                 }
1446                 if (pp->sloppyclockflag & CLK_FLAG4) {
1447                         sprintf(tbuf,
1448                             "wwv8 %d %3d %s %d %5.0f %5.1f %5ld %5d %ld",
1449                             up->port, up->gain, sp->refid, sp->count,
1450                             sp->synmax, snr, sp->pos, up->tepoch,
1451                             epoch);
1452                         record_clock_stats(&peer->srcadr, tbuf);
1453 #ifdef DEBUG
1454                         if (debug)
1455                                 printf("%s\n", tbuf);
1456 #endif
1457                 }
1458                 sp->lastpos = sp->pos;
1459                 sp->maxamp = sp->noiamp = 0;
1460         }
1461 }
1462
1463
1464 /*
1465  * wwv_endpoc - identify and acquire second sync pulse
1466  *
1467  * This routine is called at the end of the second sync interval. It
1468  * determines the second sync epoch position within the interval and
1469  * disciplines the sample clock using a frequency-lock loop (FLL).
1470  *
1471  * Second sync is determined in the RF input routine as the maximum
1472  * over all 8000 samples in the second comb filter. To assure accurate
1473  * and reliable time and frequency discipline, this routine performs a
1474  * great deal of heavy-handed heuristic data filtering and grooming.
1475  *
1476  * Note that, since the minute sync pulse is very wide (800 ms), precise
1477  * minute sync epoch acquisition requires at least a rough estimate of
1478  * the second sync pulse (5 ms). This becomes more important in choppy
1479  * conditions at the lower frequencies at night, since sferics and
1480  * cochannel crude can badly distort the minute pulse. 
1481  */
1482 static void
1483 wwv_endpoc(
1484         struct peer *peer,      /* peer structure pointer */
1485         int epopos              /* epoch max position */
1486         )
1487 {
1488         struct refclockproc *pp;
1489         struct wwvunit *up;
1490         static int epoch_mf[3]; /* epoch median filter */
1491         static int xepoch;      /* last second epoch */
1492         static int zepoch;      /* last averaging interval epoch */
1493         static int syncnt;      /* run length counter */
1494         static int maxrun;      /* longest run length */
1495         static int mepoch;      /* longest run epoch */
1496         static int avgcnt;      /* averaging interval counter */
1497         static int avginc;      /* averaging ratchet */
1498         static int iniflg;      /* initialization flag */
1499         char tbuf[80];          /* monitor buffer */
1500         double dtemp;
1501         int tmp2;
1502
1503         pp = peer->procptr;
1504         up = (struct wwvunit *)pp->unitptr;
1505         if (!iniflg) {
1506                 iniflg = 1;
1507                 memset((char *)epoch_mf, 0, sizeof(epoch_mf));
1508         }
1509
1510         /*
1511          * A three-stage median filter is used to help denoise the
1512          * second sync pulse. The median sample becomes the candidate
1513          * epoch.
1514          */
1515         epoch_mf[2] = epoch_mf[1];
1516         epoch_mf[1] = epoch_mf[0];
1517         epoch_mf[0] = epopos;
1518         if (epoch_mf[0] > epoch_mf[1]) {
1519                 if (epoch_mf[1] > epoch_mf[2])
1520                         up->tepoch = epoch_mf[1];       /* 0 1 2 */
1521                 else if (epoch_mf[2] > epoch_mf[0])
1522                         up->tepoch = epoch_mf[0];       /* 2 0 1 */
1523                 else
1524                         up->tepoch = epoch_mf[2];       /* 0 2 1 */
1525         } else {
1526                 if (epoch_mf[1] < epoch_mf[2])
1527                         up->tepoch = epoch_mf[1];       /* 2 1 0 */
1528                 else if (epoch_mf[2] < epoch_mf[0])
1529                         up->tepoch = epoch_mf[0];       /* 1 0 2 */
1530                 else
1531                         up->tepoch = epoch_mf[2];       /* 1 2 0 */
1532         }
1533
1534         /*
1535          * If the signal amplitude or SNR fall below thresholds or if no
1536          * stations are heard, dim the second sync lamp and start over.
1537          */
1538         if (!(up->status & (SELV | SELH)) || up->epomax < STHR ||
1539             up->eposnr < SSNR) {
1540                 up->status &= ~(SSYNC | FGATE);
1541                 avgcnt = syncnt = maxrun = 0;
1542                 return;
1543         }
1544         avgcnt++;
1545
1546         /*
1547          * If the epoch candidate is the same as the last one, increment
1548          * the compare counter. If not, save the length and epoch of the
1549          * current run for use later and reset the counter.
1550          */
1551         tmp2 = (up->tepoch - xepoch) % SECOND;
1552         if (tmp2 == 0) {
1553                 syncnt++;
1554         } else {
1555                 if (maxrun > 0 && mepoch == xepoch) {
1556                         maxrun += syncnt;
1557                 } else if (syncnt > maxrun) {
1558                         maxrun = syncnt;
1559                         mepoch = xepoch;
1560                 }
1561                 syncnt = 0;
1562         }
1563         if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status & (SSYNC |
1564             MSYNC))) {
1565                 sprintf(tbuf,
1566                     "wwv1 %04x %5.0f %5.1f %5d %5d %4d %4d",
1567                     up->status, up->epomax, up->eposnr, up->tepoch,
1568                     tmp2, avgcnt, syncnt);
1569                 record_clock_stats(&peer->srcadr, tbuf);
1570 #ifdef DEBUG
1571                 if (debug)
1572                         printf("%s\n", tbuf);
1573 #endif /* DEBUG */
1574         }
1575
1576         /*
1577          * The sample clock frequency is disciplined using a first order
1578          * feedback loop with time constant consistent with the Allan
1579          * intercept of typical computer clocks.
1580          *
1581          * The frequency update is calculated from the epoch change in
1582          * 125-us units divided by the averaging interval in seconds.
1583          * The averaging interval affects other receiver functions,
1584          * including the the 1000/1200-Hz comb filter and codec clock
1585          * loop. It also affects the 100-Hz subcarrier loop and the bit
1586          * and digit comparison counter thresholds.
1587          */
1588         if (avgcnt < up->avgint) {
1589                 xepoch = up->tepoch;
1590                 return;
1591         }
1592
1593         /*
1594          * During the averaging interval the longest run of identical
1595          * epoches is determined. If the longest run is at least 10
1596          * seconds, the SSYNC bit is lit and the value becomes the
1597          * reference epoch for the next interval. If not, the second
1598          * synd lamp is dark and flashers set.
1599          */
1600         if (maxrun > 0 && mepoch == xepoch) {
1601                 maxrun += syncnt;
1602         } else if (syncnt > maxrun) {
1603                 maxrun = syncnt;
1604                 mepoch = xepoch;
1605         }
1606         xepoch = up->tepoch;
1607         if (maxrun > SCMP) {
1608                 up->status |= SSYNC;
1609                 up->yepoch = mepoch;
1610         } else {
1611                 up->status &= ~SSYNC;
1612         }
1613
1614         /*
1615          * If the epoch change over the averaging interval is less than
1616          * 1 ms, the frequency is adjusted, but clamped at +-125 PPM. If
1617          * greater than 1 ms, the counter is decremented. If the epoch
1618          * change is less than 0.5 ms, the counter is incremented. If
1619          * the counter increments to +3, the averaging interval is
1620          * doubled and the counter set to zero; if it increments to -3,
1621          * the interval is halved and the counter set to zero.
1622          *
1623          * Here be spooks. From careful observations, the epoch
1624          * sometimes makes a long run of identical samples, then takes a
1625          * lurch due apparently to lost interrupts or spooks. If this
1626          * happens, the epoch change times the maximum run length will
1627          * be greater than the averaging interval, so the lurch should
1628          * be believed but the frequency left alone. Really intricate
1629          * here.
1630          */
1631         if (maxrun == 0)
1632                 mepoch = up->tepoch;
1633         dtemp = (mepoch - zepoch) % SECOND;
1634         if (up->status & FGATE) {
1635                 if (abs(dtemp) < MAXFREQ * MINAVG) {
1636                         if (maxrun * abs(mepoch - zepoch) <
1637                             avgcnt) {
1638                                 up->freq += dtemp / avgcnt;
1639                                 if (up->freq > MAXFREQ)
1640                                         up->freq = MAXFREQ;
1641                                 else if (up->freq < -MAXFREQ)
1642                                         up->freq = -MAXFREQ;
1643                         }
1644                         if (abs(dtemp) < MAXFREQ * MINAVG / 2) {
1645                                 if (avginc < 3) {
1646                                         avginc++;
1647                                 } else {
1648                                         if (up->avgint < MAXAVG) {
1649                                                 up->avgint <<= 1;
1650                                                 avginc = 0;
1651                                         }
1652                                 }
1653                         }
1654                 } else {
1655                         if (avginc > -3) {
1656                                 avginc--;
1657                         } else {
1658                                 if (up->avgint > MINAVG) {
1659                                         up->avgint >>= 1;
1660                                         avginc = 0;
1661                                 }
1662                         }
1663                 }
1664         }
1665         if (pp->sloppyclockflag & CLK_FLAG4) {
1666                 sprintf(tbuf,
1667                     "wwv2 %04x %4.0f %4d %4d %2d %4d %4.0f %6.1f",
1668                     up->status, up->epomax, mepoch, maxrun, avginc,
1669                     avgcnt, dtemp, up->freq * 1e6 / SECOND);
1670                 record_clock_stats(&peer->srcadr, tbuf);
1671 #ifdef DEBUG
1672                 if (debug)
1673                         printf("%s\n", tbuf);
1674 #endif /* DEBUG */
1675         }
1676         up->status |= FGATE;
1677         zepoch = mepoch;
1678         avgcnt = syncnt = maxrun = 0;
1679 }
1680
1681
1682 /*
1683  * wwv_epoch - epoch scanner
1684  *
1685  * This routine scans the receiver second epoch to determine the signal
1686  * amplitudes and pulse timings. Receiver synchronization is determined
1687  * by the minute sync pulse detected in the wwv_rf() routine and the
1688  * second sync pulse detected in the wwv_epoch() routine. A pulse width
1689  * discriminator extracts data signals from the 100-Hz subcarrier. The
1690  * transmitted signals are delayed by the propagation delay, receiver
1691  * delay and filter delay of this program. Delay corrections are
1692  * introduced separately for WWV and WWVH. 
1693  *
1694  * Most communications radios use a highpass filter in the audio stages,
1695  * which can do nasty things to the subcarrier phase relative to the
1696  * sync pulses. Therefore, the data subcarrier reference phase is
1697  * disciplined using the hardlimited quadrature-phase signal sampled at
1698  * the same time as the in-phase signal. The phase tracking loop uses
1699  * phase adjustments of plus-minus one sample (125 us).
1700  */
1701 static void
1702 wwv_epoch(
1703         struct peer *peer       /* peer structure pointer */
1704         )
1705 {
1706         struct refclockproc *pp;
1707         struct wwvunit *up;
1708         struct chan *cp;
1709         static double dpulse;   /* data pulse length */
1710         double dtemp;
1711
1712         pp = peer->procptr;
1713         up = (struct wwvunit *)pp->unitptr;
1714
1715         /*
1716          * Sample the minute sync pulse envelopes at epoch 800 for both
1717          * the WWV and WWVH stations. This will be used later for
1718          * channel and station mitigation. Note that the seconds epoch
1719          * is set here well before the end of the second to make sure we
1720          * never seet the epoch backwards.
1721          */
1722         if (up->rphase == 800 * MS) {
1723                 up->repoch = up->yepoch;
1724                 cp = &up->mitig[up->achan];
1725                 cp->wwv.synamp = cp->wwv.amp;
1726                 cp->wwvh.synamp = cp->wwvh.amp;
1727         }
1728
1729         /*
1730          * Sample the data subcarrier at epoch 15 ms, giving a guard
1731          * time of +-15 ms from the beginning of the second until the
1732          * pulse rises at 30 ms. The I-channel amplitude is used to
1733          * calculate the slice level. The envelope amplitude is used
1734          * during the probe seconds to determine the SNR. There is a
1735          * compromise here; we want to delay the sample as long as
1736          * possible to give the radio time to change frequency and the
1737          * AGC to stabilize, but as early as possible if the second
1738          * epoch is not exact.
1739          */
1740         if (up->rphase == 15 * MS) {
1741                 up->noiamp = up->irig * up->irig + up->qrig * up->qrig;
1742
1743         /*
1744          * Sample the data subcarrier at epoch 215 ms, giving a guard
1745          * time of +-15 ms from the earliest the pulse peak can be
1746          * reached to the earliest it can begin to fall. For the data
1747          * channel latch the I-channel amplitude for all except the
1748          * probe seconds and adjust the 100-Hz reference oscillator
1749          * phase using the Q-channel amplitude at this epoch. For the
1750          * probe channel latch the envelope amplitude.
1751          */
1752         } else if (up->rphase == 215 * MS) {
1753                 up->sigsig = up->irig;
1754                 if (up->sigsig < 0)
1755                         up->sigsig = 0;
1756                 up->datpha = up->qrig / up->avgint;
1757                 if (up->datpha >= 0) {
1758                         up->datapt++;
1759                         if (up->datapt >= 80)
1760                                 up->datapt -= 80;
1761                 } else {
1762                         up->datapt--;
1763                         if (up->datapt < 0)
1764                                 up->datapt += 80;
1765                 }
1766                 up->sigamp = up->irig * up->irig + up->qrig * up->qrig;
1767
1768         /*
1769          * The slice level is set half way between the peak signal and
1770          * noise levels. Sample the negative zero crossing after epoch
1771          * 200 ms and record the epoch at that time. This defines the
1772          * length of the data pulse, which will later be converted into
1773          * scaled bit probabilities.
1774          */
1775         } else if (up->rphase > 200 * MS) {
1776                 dtemp = (up->sigsig + sqrt(up->noiamp)) / 2;
1777                 if (up->irig < dtemp && dpulse == 0)
1778                         dpulse = up->rphase;
1779         }
1780
1781         /*
1782          * At the end of the second crank the clock state machine and
1783          * adjust the codec gain. Note the epoch is buffered from the
1784          * center of the second in order to avoid jitter while the
1785          * seconds synch is diddling the epoch. Then, determine the true
1786          * offset and update the median filter in the driver interface.
1787          *
1788          * Sample the data subcarrier envelope at the end of the second
1789          * to determine the SNR for the pulse. This gives a guard time
1790          * of +-30 ms from the decay of the longest pulse to the rise of
1791          * the next pulse.
1792          */
1793         up->rphase++;
1794         if (up->mphase % SECOND == up->repoch) {
1795                 up->datsnr = wwv_snr(up->sigsig, sqrt(up->noiamp));
1796                 wwv_rsec(peer, dpulse);
1797                 wwv_gain(peer);
1798                 up->rphase = dpulse = 0;
1799         }
1800 }
1801
1802
1803 /*
1804  * wwv_rsec - process receiver second
1805  *
1806  * This routine is called at the end of each receiver second to
1807  * implement the per-second state machine. The machine assembles BCD
1808  * digit bits, decodes miscellaneous bits and dances the leap seconds.
1809  *
1810  * Normally, the minute has 60 seconds numbered 0-59. If the leap
1811  * warning bit is set, the last minute (1439) of 30 June (day 181 or 182
1812  * for leap years) or 31 December (day 365 or 366 for leap years) is
1813  * augmented by one second numbered 60. This is accomplished by
1814  * extending the minute interval by one second and teaching the state
1815  * machine to ignore it.
1816  */
1817 static void
1818 wwv_rsec(
1819         struct peer *peer,      /* peer structure pointer */
1820         double dpulse
1821         )
1822 {
1823         static int iniflg;      /* initialization flag */
1824         static double bcddld[4]; /* BCD data bits */
1825         static double bitvec[61]; /* bit integrator for misc bits */
1826         struct refclockproc *pp;
1827         struct wwvunit *up;
1828         struct chan *cp;
1829         struct sync *sp, *rp;
1830         l_fp offset;            /* offset in NTP seconds */
1831         double bit;             /* bit likelihood */
1832         char tbuf[80];          /* monitor buffer */
1833         int sw, arg, nsec;
1834 #ifdef IRIG_SUCKS
1835         int     i;
1836         l_fp    ltemp;
1837 #endif /* IRIG_SUCKS */
1838
1839         pp = peer->procptr;
1840         up = (struct wwvunit *)pp->unitptr;
1841         if (!iniflg) {
1842                 iniflg = 1;
1843                 memset((char *)bitvec, 0, sizeof(bitvec));
1844         }
1845
1846         /*
1847          * The bit represents the probability of a hit on zero (negative
1848          * values), a hit on one (positive values) or a miss (zero
1849          * value). The likelihood vector is the exponential average of
1850          * these probabilities. Only the bits of this vector
1851          * corresponding to the miscellaneous bits of the timecode are
1852          * used, but it's easier to do them all. After that, crank the
1853          * seconds state machine.
1854          */
1855         nsec = up->rsec + 1;
1856         bit = wwv_data(up, dpulse);
1857         bitvec[up->rsec] += (bit - bitvec[up->rsec]) / TCONST;
1858         sw = progx[up->rsec].sw;
1859         arg = progx[up->rsec].arg;
1860         switch (sw) {
1861
1862         /*
1863          * Ignore this second.
1864          */
1865         case IDLE:                      /* 9, 45-49 */
1866                 break;
1867
1868         /*
1869          * Probe channel stuff
1870          *
1871          * The WWV/H format contains data pulses in second 59 (position
1872          * identifier), second 1 (not used) and the minute sync pulse in
1873          * second 0. At the end of second 58, QSY to the probe channel,
1874          * which rotates over all WWV/H frequencies. At the end of
1875          * second 1 QSY back to the data channel.
1876          *
1877          * At the end of second 0 save the minute sync pulse peak value
1878          * previously latched at 800 ms.
1879          */
1880         case SYNC2:                     /* 0 */
1881                 cp = &up->mitig[up->achan];
1882                 cp->wwv.synmax = sqrt(cp->wwv.synamp);
1883                 cp->wwvh.synmax = sqrt(cp->wwvh.synamp);
1884                 break;
1885
1886         /*
1887          * At the end of second 1 determine the minute sync pulse
1888          * amplitude and SNR and set SYNCNG if these values are below
1889          * thresholds. Determine the data pulse amplitude and SNR and
1890          * set DATANG if these values are below thresholds. Set ERRRNG
1891          * if data pulses in second 59 and second 1 are decoded in
1892          * error. Shift a 1 into the reachability register if SYNCNG and
1893          * DATANG are both lit; otherwise shift a 0. Ignore ERRRNG for
1894          * the present. The number of 1 bits in the last six intervals
1895          * represents the channel metric used by the mitigation routine.
1896          * Finally, QSY back to the data channel.
1897          */
1898         case SYNC3:                     /* 1 */
1899                 cp = &up->mitig[up->achan];
1900                 cp->sigamp = sqrt(up->sigamp);
1901                 cp->noiamp = sqrt(up->noiamp);
1902                 cp->datsnr = wwv_snr(cp->sigamp, cp->noiamp);
1903
1904                 /*
1905                  * WWV station
1906                  */
1907                 sp = &cp->wwv;
1908                 sp->synmin = sqrt((sp->synmin + sp->synamp) / 2.);
1909                 sp->synsnr = wwv_snr(sp->synmax, sp->synmin);
1910                 sp->select &= ~(SYNCNG | DATANG | ERRRNG);
1911                 if (sp->synmax < QTHR || sp->synsnr < QSNR)
1912                         sp->select |= SYNCNG;
1913                 if (cp->sigamp < XTHR || cp->datsnr < XSNR)
1914                         sp->select |= DATANG;
1915                 if (up->errcnt > 2)
1916                         sp->select |= ERRRNG;
1917                 sp->reach <<= 1;
1918                 if (sp->reach & (1 << AMAX))
1919                         sp->count--;
1920                 if (!(sp->select & (SYNCNG | DATANG))) {
1921                         sp->reach |= 1;
1922                         sp->count++;
1923                 }
1924
1925                 /*
1926                  * WWVH station
1927                  */
1928                 rp = &cp->wwvh;
1929                 rp->synmin = sqrt((rp->synmin + rp->synamp) / 2.);
1930                 rp->synsnr = wwv_snr(rp->synmax, rp->synmin);
1931                 rp->select &= ~(SYNCNG | DATANG | ERRRNG);
1932                 if (rp->synmax < QTHR || rp->synsnr < QSNR)
1933                         rp->select |= SYNCNG;
1934                 if (cp->sigamp < XTHR || cp->datsnr < XSNR)
1935                         rp->select |= DATANG;
1936                 if (up->errcnt > 2)
1937                         rp->select |= ERRRNG;
1938                 rp->reach <<= 1;
1939                 if (rp->reach & (1 << AMAX))
1940                         rp->count--;
1941                 if (!(rp->select & (SYNCNG | DATANG | ERRRNG))) {
1942                         rp->reach |= 1;
1943                         rp->count++;
1944                 }
1945
1946                 /*
1947                  * Set up for next minute.
1948                  */
1949                 if (pp->sloppyclockflag & CLK_FLAG4) {
1950                         sprintf(tbuf,
1951                             "wwv5 %2d %04x %3d %4d %d %.0f/%.1f %s %04x %.0f %.0f/%.1f %s %04x %.0f %.0f/%.1f",
1952                             up->port, up->status, up->gain, up->yepoch,
1953                             up->errcnt, cp->sigamp, cp->datsnr,
1954                             sp->refid, sp->reach & 0xffff,
1955                             wwv_metric(sp), sp->synmax, sp->synsnr,
1956                             rp->refid, rp->reach & 0xffff,
1957                             wwv_metric(rp), rp->synmax, rp->synsnr);
1958                         record_clock_stats(&peer->srcadr, tbuf);
1959 #ifdef DEBUG
1960                         if (debug)
1961                                 printf("%s\n", tbuf);
1962 #endif /* DEBUG */
1963                 }
1964 #ifdef ICOM
1965                 if (up->fd_icom > 0)
1966                         wwv_qsy(peer, up->dchan);
1967 #endif /* ICOM */
1968                 up->status &= ~SFLAG;
1969                 up->errcnt = 0;
1970                 up->alarm = 0;
1971                 wwv_newchan(peer);
1972                 break;
1973
1974         /*
1975          * Save the bit probability in the BCD data vector at the index
1976          * given by the argument. Note that all bits of the vector have
1977          * to be above the data gate threshold for the digit to be
1978          * considered valid. Bits not used in the digit are forced to
1979          * zero and not checked for errors.
1980          */
1981         case COEF:                      /* 4-7, 10-13, 15-17, 20-23,
1982                                            25-26, 30-33, 35-38, 40-41,
1983                                            51-54 */ 
1984                 if (up->status & DGATE)
1985                         up->status |= BGATE;
1986                 bcddld[arg] = bit;
1987                 break;
1988
1989         case COEF2:                     /* 18, 27-28, 42-43 */
1990                 bcddld[arg] = 0;
1991                 break;
1992
1993         /*
1994          * Correlate coefficient vector with each valid digit vector and
1995          * save in decoding matrix. We step through the decoding matrix
1996          * digits correlating each with the coefficients and saving the
1997          * greatest and the next lower for later SNR calculation.
1998          */
1999         case DECIM2:                    /* 29 */
2000                 wwv_corr4(peer, &up->decvec[arg], bcddld, bcd2);
2001                 break;
2002
2003         case DECIM3:                    /* 44 */
2004                 wwv_corr4(peer, &up->decvec[arg], bcddld, bcd3);
2005                 break;
2006
2007         case DECIM6:                    /* 19 */
2008                 wwv_corr4(peer, &up->decvec[arg], bcddld, bcd6);
2009                 break;
2010
2011         case DECIM9:                    /* 8, 14, 24, 34, 39 */
2012                 wwv_corr4(peer, &up->decvec[arg], bcddld, bcd9);
2013                 break;
2014
2015         /*
2016          * Miscellaneous bits. If above the positive threshold, declare
2017          * 1; if below the negative threshold, declare 0; otherwise
2018          * raise the SYMERR alarm. At the end of second 58, QSY to the
2019          * probe channel. The design is intended to preserve the bits
2020          * over periods of signal loss.
2021          */
2022         case MSC20:                     /* 55 */
2023                 wwv_corr4(peer, &up->decvec[YR + 1], bcddld, bcd9);
2024                 /* fall through */
2025
2026         case MSCBIT:                    /* 2-3, 50, 56-57 */
2027                 if (bitvec[up->rsec] > BTHR)
2028                         up->misc |= arg;
2029                 else if (bitvec[up->rsec] < -BTHR)
2030                         up->misc &= ~arg;
2031                 else
2032                         up->alarm |= SYMERR;
2033                 break;
2034
2035         /*
2036          * Save the data channel gain, then QSY to the probe channel.
2037          */
2038         case MSC21:                     /* 58 */
2039                 if (bitvec[up->rsec] > BTHR)
2040                         up->misc |= arg;
2041                 else if (bitvec[up->rsec] < -BTHR)
2042                         up->misc &= ~arg;
2043                 else
2044                         up->alarm |= SYMERR;
2045                 up->mitig[up->dchan].gain = up->gain;
2046 #ifdef ICOM
2047                 if (up->fd_icom > 0) {
2048                         up->schan = (up->schan + 1) % NCHAN;
2049                         wwv_qsy(peer, up->schan);
2050                 }
2051 #endif /* ICOM */
2052                 up->status |= SFLAG | SELV | SELH;
2053                 up->errbit = up->errcnt;
2054                 up->errcnt = 0;
2055                 break;
2056
2057         /*
2058          * The endgames
2059          *
2060          * During second 59 the receiver and codec AGC are settling
2061          * down, so the data pulse is unusable. At the end of this
2062          * second, latch the minute sync pulse noise floor. Then do the
2063          * minute processing and update the system clock. If a leap
2064          * second sail on to the next second (60); otherwise, set up for
2065          * the next minute.
2066          */
2067         case MIN1:                      /* 59 */
2068                 cp = &up->mitig[up->achan];
2069                 cp->wwv.synmin = cp->wwv.synamp;
2070                 cp->wwvh.synmin = cp->wwvh.synamp;
2071
2072                 /*
2073                  * Dance the leap if necessary and the kernel has the
2074                  * right stuff. Then, wind up the clock and initialize
2075                  * for the following minute. If the leap dance, note the
2076                  * kernel is armed one second before the actual leap is
2077                  * scheduled.
2078                  */
2079                 if (up->status & SSYNC && up->digcnt >= 9)
2080                         up->status |= INSYNC;
2081                 if (up->status & LEPDAY) {
2082                         pp->leap = LEAP_ADDSECOND;
2083                 } else {
2084                         pp->leap = LEAP_NOWARNING;
2085                         wwv_tsec(up);
2086                         nsec = up->digcnt = 0;
2087                 }
2088                 pp->lencode = timecode(up, pp->a_lastcode);
2089                 record_clock_stats(&peer->srcadr, pp->a_lastcode);
2090 #ifdef DEBUG
2091                 if (debug)
2092                         printf("wwv: timecode %d %s\n", pp->lencode,
2093                             pp->a_lastcode);
2094 #endif /* DEBUG */
2095                 if (up->status & INSYNC && up->watch < HOLD)
2096                         refclock_receive(peer);
2097                 break;
2098
2099         /*
2100          * If LEPDAY is set on the last minute of 30 June or 31
2101          * December, the LEPSEC bit is set. At the end of the minute in
2102          * which LEPSEC is set the transmitter and receiver insert an
2103          * extra second (60) in the timescale and the minute sync skips
2104          * a second. We only get to test this wrinkle at intervals of
2105          * about 18 months; the actual mileage may vary.
2106          */
2107         case MIN2:                      /* 60 */
2108                 wwv_tsec(up);
2109                 nsec = up->digcnt = 0;
2110                 break;
2111         }
2112
2113         /*
2114          * If digit sync has not been acquired before timeout or if no
2115          * station has been heard, game over and restart from scratch.
2116          */
2117         if (!(up->status & DSYNC) && (!(up->status & (SELV | SELH)) ||
2118             up->watch > DIGIT)) {
2119                 wwv_newgame(peer);
2120                 return;
2121         }
2122
2123         /*
2124          * If no timestamps have been struck before timeout, game over
2125          * and restart from scratch.
2126          */
2127         if (up->watch > PANIC) {
2128                 wwv_newgame(peer);
2129                 return;
2130         }
2131         pp->disp += AUDIO_PHI;
2132         up->rsec = nsec;
2133
2134 #ifdef IRIG_SUCKS
2135         /*
2136          * You really don't wanna know what comes down here. Leave it to
2137          * say Solaris 2.8 broke the nice clean audio stream, apparently
2138          * affected by a 5-ms sawtooth jitter. Sundown on Solaris. This
2139          * leaves a little twilight.
2140          *
2141          * The scheme involves differentiation, forward learning and
2142          * integration. The sawtooth has a period of 11 seconds. The
2143          * timestamp differences are integrated and subtracted from the
2144          * signal.
2145          */
2146         ltemp = pp->lastrec;
2147         L_SUB(&ltemp, &pp->lastref);
2148         if (ltemp.l_f < 0)
2149                 ltemp.l_i = -1;
2150         else
2151                 ltemp.l_i = 0;
2152         pp->lastref = pp->lastrec;
2153         if (!L_ISNEG(&ltemp))
2154                 L_CLR(&up->wigwag);
2155         else
2156                 L_ADD(&up->wigwag, &ltemp);
2157         L_SUB(&pp->lastrec, &up->wigwag);
2158         up->wiggle[up->wp] = ltemp;
2159
2160         /*
2161          * Bottom fisher. To understand this, you have to know about
2162          * velocity microphones and AM transmitters. No further
2163          * explanation is offered, as this is truly a black art.
2164          */
2165         up->wigbot[up->wp] = pp->lastrec;
2166         for (i = 0; i < WIGGLE; i++) {
2167                 if (i != up->wp)
2168                         up->wigbot[i].l_ui++;
2169                 L_SUB(&pp->lastrec, &up->wigbot[i]);
2170                 if (L_ISNEG(&pp->lastrec))
2171                         L_ADD(&pp->lastrec, &up->wigbot[i]);
2172                 else
2173                         pp->lastrec = up->wigbot[i];
2174         }
2175         up->wp++;
2176         up->wp %= WIGGLE;
2177 #endif /* IRIG_SUCKS */
2178
2179         /*
2180          * If victory has been declared and seconds sync is lit, strike
2181          * a timestamp. It should not be a surprise, especially if the
2182          * radio is not tunable, that sometimes no stations are above
2183          * the noise and the reference ID set to NONE.
2184          */
2185         if (up->status & INSYNC && up->status & SSYNC) {
2186                 pp->second = up->rsec;
2187                 pp->minute = up->decvec[MN].digit + up->decvec[MN +
2188                     1].digit * 10;
2189                 pp->hour = up->decvec[HR].digit + up->decvec[HR +
2190                     1].digit * 10;
2191                 pp->day = up->decvec[DA].digit + up->decvec[DA +
2192                     1].digit * 10 + up->decvec[DA + 2].digit * 100;
2193                 pp->year = up->decvec[YR].digit + up->decvec[YR +
2194                     1].digit * 10;
2195                 pp->year += 2000;
2196                 L_CLR(&offset);
2197                 if (!clocktime(pp->day, pp->hour, pp->minute,
2198                     pp->second, GMT, up->timestamp.l_ui,
2199                     &pp->yearstart, &offset.l_ui)) {
2200                         up->errflg = CEVNT_BADTIME;
2201                 } else {
2202                         up->watch = 0;
2203                         pp->disp = 0;
2204                         refclock_process_offset(pp, offset,
2205                             up->timestamp, PDELAY);
2206                 }
2207         }
2208         if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status &
2209             DSYNC)) {
2210                 sprintf(tbuf,
2211                     "wwv3 %2d %04x %5.0f %5.1f %5.0f %5.1f %5.0f",
2212                     up->rsec, up->status, up->epomax, up->eposnr,
2213                     up->sigsig, up->datsnr, bit);
2214                 record_clock_stats(&peer->srcadr, tbuf);
2215 #ifdef DEBUG
2216                 if (debug)
2217                         printf("%s\n", tbuf);
2218 #endif /* DEBUG */
2219         }
2220 }
2221
2222
2223 /*
2224  * wwv_data - calculate bit probability
2225  *
2226  * This routine is called at the end of the receiver second to calculate
2227  * the probabilities that the previous second contained a zero (P0), one
2228  * (P1) or position indicator (P2) pulse. If not in sync or if the data
2229  * bit is bad, a bit error is declared and the probabilities are forced
2230  * to zero. Otherwise, the data gate is enabled and the probabilities
2231  * are calculated. Note that the data matched filter contributes half
2232  * the pulse width, or 85 ms.
2233  *
2234  * It's important to observe that there are three conditions to
2235  * determine: average to +1 (hit), average to -1 (miss) or average to
2236  * zero (erasure). The erasure condition results from insufficient
2237  * signal (noise) and has no bias toward either a hit or miss.
2238  */
2239 static double
2240 wwv_data(
2241         struct wwvunit *up,     /* driver unit pointer */
2242         double pulse            /* pulse length (sample units) */
2243         )
2244 {
2245         double p0, p1, p2;      /* probabilities */
2246         double dpulse;          /* pulse length in ms */
2247
2248         p0 = p1 = p2 = 0;
2249         dpulse = pulse - DATSIZ / 2;
2250
2251         /*
2252          * If no station is being tracked, if either the data amplitude
2253          * or SNR are below threshold or if the pulse length is less
2254          * than 170 ms, declare an erasure.
2255          */
2256         if (!(up->status & (SELV | SELH)) || up->sigsig < DTHR ||
2257             up->datsnr < DSNR || dpulse < DATSIZ) {
2258                 up->status |= DGATE;
2259                 up->errcnt++;
2260                 if (up->errcnt > MAXERR)
2261                         up->alarm |= MODERR;
2262                 return (0); 
2263         }
2264
2265         /*
2266          * The probability of P0 is one below 200 ms falling to zero at
2267          * 500 ms. The probability of P1 is zero below 200 ms rising to
2268          * one at 500 ms and falling to zero at 800 ms. The probability
2269          * of P2 is zero below 500 ms, rising to one above 800 ms.
2270          */
2271         up->status &= ~DGATE;
2272         if (dpulse < (200 * MS)) {
2273                 p0 = 1;
2274         } else if (dpulse < 500 * MS) {
2275                 dpulse -= 200 * MS;
2276                 p1 = dpulse / (300 * MS);
2277                 p0 = 1 - p1;
2278         } else if (dpulse < 800 * MS) {
2279                 dpulse -= 500 * MS;
2280                 p2 = dpulse / (300 * MS);
2281                 p1 = 1 - p2;
2282         } else {
2283                 p2 = 1;
2284         }
2285
2286         /*
2287          * The ouput is a metric that ranges from -1 (P0), to +1 (P1)
2288          * scaled for convenience. An output of zero represents an
2289          * erasure, either because of a data error or pulse length
2290          * greater than 500 ms. At the moment, we don't use P2.
2291          */
2292         return ((p1 - p0) * MAXSIG);
2293 }
2294
2295
2296 /*
2297  * wwv_corr4 - determine maximum likelihood digit
2298  *
2299  * This routine correlates the received digit vector with the BCD
2300  * coefficient vectors corresponding to all valid digits at the given
2301  * position in the decoding matrix. The maximum value corresponds to the
2302  * maximum likelihood digit, while the ratio of this value to the next
2303  * lower value determines the likelihood function. Note that, if the
2304  * digit is invalid, the likelihood vector is averaged toward a miss.
2305  */
2306 static void
2307 wwv_corr4(
2308         struct peer *peer,      /* peer unit pointer */
2309         struct decvec *vp,      /* decoding table pointer */
2310         double data[],          /* received data vector */
2311         double tab[][4]         /* correlation vector array */
2312         )
2313 {
2314         struct refclockproc *pp;
2315         struct wwvunit *up;
2316
2317         double topmax, nxtmax;  /* metrics */
2318         double acc;             /* accumulator */
2319         char tbuf[80];          /* monitor buffer */
2320         int mldigit;            /* max likelihood digit */
2321         int diff;               /* decoding difference */
2322         int i, j;
2323
2324         pp = peer->procptr;
2325         up = (struct wwvunit *)pp->unitptr;
2326
2327         /*
2328          * Correlate digit vector with each BCD coefficient vector. If
2329          * any BCD digit bit is bad, consider all bits a miss.
2330          */
2331         mldigit = 0;
2332         topmax = nxtmax = -MAXSIG;
2333         for (i = 0; tab[i][0] != 0; i++) {
2334                 acc = 0;
2335                 for (j = 0; j < 4; j++) {
2336                         if (!(up->status & BGATE))
2337                                 acc += data[j] * tab[i][j];
2338                 }
2339                 acc = (vp->like[i] += (acc - vp->like[i]) / TCONST);
2340                 if (acc > topmax) {
2341                         nxtmax = topmax;
2342                         topmax = acc;
2343                         mldigit = i;
2344                 } else if (acc > nxtmax) {
2345                         nxtmax = acc;
2346                 }
2347         }
2348         vp->mldigit = mldigit;
2349         vp->digprb = topmax;
2350         vp->digsnr = wwv_snr(topmax, nxtmax);
2351
2352         /*
2353          * The maximum likelihood digit is compared with the current
2354          * clock digit. The difference represents the decoding phase
2355          * error. If the clock is not yet synchronized, the phase error
2356          * is corrected even of the digit probability and likelihood are
2357          * below thresholds. This avoids lengthy averaging times should
2358          * a carry mistake occur. However, the digit is not declared
2359          * synchronized until these values are above thresholds and the
2360          * last five decoded values are identical. If the clock is
2361          * synchronized, the phase error is not corrected unless the
2362          * last five digits are all above thresholds and identical. This
2363          * avoids mistakes when the signal is coming out of the noise
2364          * and the SNR is very marginal.
2365          */
2366         diff = mldigit - vp->digit;
2367         if (diff < 0)
2368                 diff += vp->radix;
2369         if (diff != vp->phase) {
2370                 vp->count = 0;
2371                 vp->phase = diff;
2372         }
2373         if (vp->digsnr < BSNR) {
2374                 vp->count = 0;
2375                 up->alarm |= SYMERR;
2376         } else if (vp->digprb < BTHR) {
2377                 vp->count = 0;
2378                 up->alarm |= SYMERR;
2379                 if (!(up->status & INSYNC)) {
2380                         vp->phase = 0;
2381                         vp->digit = mldigit;
2382                 }
2383         } else if (vp->count < BCMP) {
2384                 vp->count++;
2385                 up->status |= DSYNC;
2386                 if (!(up->status & INSYNC)) {
2387                         vp->phase = 0;
2388                         vp->digit = mldigit;
2389                 }
2390         } else {
2391                 vp->phase = 0;
2392                 vp->digit = mldigit;
2393                 up->digcnt++;
2394         }
2395         if (vp->digit != mldigit)
2396                 up->alarm |= DECERR;
2397         if ((pp->sloppyclockflag & CLK_FLAG4) && !(up->status &
2398             INSYNC)) {
2399                 sprintf(tbuf,
2400                     "wwv4 %2d %04x %5.0f %2d %d %d %d %d %5.0f %5.1f",
2401                     up->rsec, up->status, up->epomax, vp->radix,
2402                     vp->digit, vp->mldigit, vp->phase, vp->count,
2403                     vp->digprb, vp->digsnr);
2404                 record_clock_stats(&peer->srcadr, tbuf);
2405 #ifdef DEBUG
2406                 if (debug)
2407                         printf("%s\n", tbuf);
2408 #endif /* DEBUG */
2409         }
2410         up->status &= ~BGATE;
2411 }
2412
2413
2414 /*
2415  * wwv_tsec - transmitter minute processing
2416  *
2417  * This routine is called at the end of the transmitter minute. It
2418  * implements a state machine that advances the logical clock subject to
2419  * the funny rules that govern the conventional clock and calendar.
2420  */
2421 static void
2422 wwv_tsec(
2423         struct wwvunit *up      /* driver structure pointer */
2424         )
2425 {
2426         int minute, day, isleap;
2427         int temp;
2428
2429         /*
2430          * Advance minute unit of the day.
2431          */
2432         temp = carry(&up->decvec[MN]);  /* minute units */
2433
2434         /*
2435          * Propagate carries through the day.
2436          */ 
2437         if (temp == 0)                  /* carry minutes */
2438                 temp = carry(&up->decvec[MN + 1]);
2439         if (temp == 0)                  /* carry hours */
2440                 temp = carry(&up->decvec[HR]);
2441         if (temp == 0)
2442                 temp = carry(&up->decvec[HR + 1]);
2443
2444         /*
2445          * Decode the current minute and day. Set leap day if the
2446          * timecode leap bit is set on 30 June or 31 December. Set leap
2447          * minute if the last minute on leap day. This code fails in
2448          * 2400 AD.
2449          */
2450         minute = up->decvec[MN].digit + up->decvec[MN + 1].digit *
2451             10 + up->decvec[HR].digit * 60 + up->decvec[HR +
2452             1].digit * 600;
2453         day = up->decvec[DA].digit + up->decvec[DA + 1].digit * 10 +
2454             up->decvec[DA + 2].digit * 100;
2455         isleap = (up->decvec[YR].digit & 0x3) == 0;
2456         if (up->misc & SECWAR && (day == (isleap ? 182 : 183) || day ==
2457             (isleap ? 365 : 366)) && up->status & INSYNC && up->status &
2458             SSYNC)
2459                 up->status |= LEPDAY;
2460         else
2461                 up->status &= ~LEPDAY;
2462         if (up->status & LEPDAY && minute == 1439)
2463                 up->status |= LEPSEC;
2464         else
2465                 up->status &= ~LEPSEC;
2466
2467         /*
2468          * Roll the day if this the first minute and propagate carries
2469          * through the year.
2470          */
2471         if (minute != 1440)
2472                 return;
2473         minute = 0;
2474         while (carry(&up->decvec[HR]) != 0); /* advance to minute 0 */
2475         while (carry(&up->decvec[HR + 1]) != 0);
2476         day++;
2477         temp = carry(&up->decvec[DA]);  /* carry days */
2478         if (temp == 0)
2479                 temp = carry(&up->decvec[DA + 1]);
2480         if (temp == 0)
2481                 temp = carry(&up->decvec[DA + 2]);
2482
2483         /*
2484          * Roll the year if this the first day and propagate carries
2485          * through the century.
2486          */
2487         if (day != (isleap ? 365 : 366))
2488                 return;
2489         day = 1;
2490         while (carry(&up->decvec[DA]) != 1); /* advance to day 1 */
2491         while (carry(&up->decvec[DA + 1]) != 0);
2492         while (carry(&up->decvec[DA + 2]) != 0);
2493         temp = carry(&up->decvec[YR]);  /* carry years */
2494         if (temp)
2495                 carry(&up->decvec[YR + 1]);
2496 }
2497
2498
2499 /*
2500  * carry - process digit
2501  *
2502  * This routine rotates a likelihood vector one position and increments
2503  * the clock digit modulo the radix. It returns the new clock digit or
2504  * zero if a carry occurred. Once synchronized, the clock digit will
2505  * match the maximum likelihood digit corresponding to that position.
2506  */
2507 static int
2508 carry(
2509         struct decvec *dp       /* decoding table pointer */
2510         )
2511 {
2512         int temp;
2513         int j;
2514
2515         dp->digit++;                    /* advance clock digit */
2516         if (dp->digit == dp->radix) {   /* modulo radix */
2517                 dp->digit = 0;
2518         }
2519         temp = dp->like[dp->radix - 1]; /* rotate likelihood vector */
2520         for (j = dp->radix - 1; j > 0; j--)
2521                 dp->like[j] = dp->like[j - 1];
2522         dp->like[0] = temp;
2523         return (dp->digit);
2524 }
2525
2526
2527 /*
2528  * wwv_snr - compute SNR or likelihood function
2529  */
2530 static double
2531 wwv_snr(
2532         double signal,          /* signal */
2533         double noise            /* noise */
2534         )
2535 {
2536         double rval;
2537
2538         /*
2539          * This is a little tricky. Due to the way things are measured,
2540          * either or both the signal or noise amplitude can be negative
2541          * or zero. The intent is that, if the signal is negative or
2542          * zero, the SNR must always be zero. This can happen with the
2543          * subcarrier SNR before the phase has been aligned. On the
2544          * other hand, in the likelihood function the "noise" is the
2545          * next maximum down from the peak and this could be negative.
2546          * However, in this case the SNR is truly stupendous, so we
2547          * simply cap at MAXSNR dB.
2548          */
2549         if (signal <= 0) {
2550                 rval = 0;
2551         } else if (noise <= 0) {
2552                 rval = MAXSNR;
2553         } else {
2554                 rval = 20 * log10(signal / noise);
2555                 if (rval > MAXSNR)
2556                         rval = MAXSNR;
2557         }
2558         return (rval);
2559 }
2560
2561
2562 /*
2563  * wwv_newchan - change to new data channel
2564  *
2565  * The radio actually appears to have ten channels, one channel for each
2566  * of five frequencies and each of two stations (WWV and WWVH), although
2567  * if not tunable only the 15 MHz channels appear live. While the radio
2568  * is tuned to the working data channel frequency and station for most
2569  * of the minute, during seconds 59, 0 and 1 the radio is tuned to a
2570  * probe frequency in order to search for minute sync pulse and data
2571  * subcarrier from other transmitters.
2572  *
2573  * The search for WWV and WWVH operates simultaneously, with WWV minute
2574  * sync pulse at 1000 Hz and WWVH at 1200 Hz. The probe frequency
2575  * rotates each minute over 2.5, 5, 10, 15 and 20 MHz in order and yes,
2576  * we all know WWVH is dark on 20 MHz, but few remember when WWV was lit
2577  * on 25 MHz.
2578  *
2579  * This routine selects the best channel using a metric computed from
2580  * the reachability register and minute pulse amplitude. Normally, the
2581  * award goes to the the channel with the highest metric; but, in case
2582  * of ties, the award goes to the channel with the highest minute sync
2583  * pulse amplitude and then to the highest frequency.
2584  *
2585  * The routine performs an important squelch function to keep dirty data
2586  * from polluting the integrators. During acquisition and until the
2587  * clock is synchronized, the signal metric must be at least MTR (13);
2588  * after that the metrict must be at least TTHR (50). If either of these
2589  * is not true, the station select bits are cleared so the second sync
2590  * is disabled and the data bit integrators averaged to a miss. 
2591  */
2592 static void
2593 wwv_newchan(
2594         struct peer *peer       /* peer structure pointer */
2595         )
2596 {
2597         struct refclockproc *pp;
2598         struct wwvunit *up;
2599         struct sync *sp, *rp;
2600         double rank, dtemp;
2601         int i, j;
2602
2603         pp = peer->procptr;
2604         up = (struct wwvunit *)pp->unitptr;
2605
2606         /*
2607          * Search all five station pairs looking for the channel with
2608          * maximum metric. If no station is found above thresholds, the
2609          * reference ID is set to NONE and we wait for hotter ions.
2610          */
2611         j = 0;
2612         sp = NULL;
2613         rank = 0;
2614         for (i = 0; i < NCHAN; i++) {
2615                 rp = &up->mitig[i].wwvh;
2616                 dtemp = wwv_metric(rp);
2617                 if (dtemp >= rank) {
2618                         rank = dtemp;
2619                         sp = rp;
2620                         j = i;
2621                 }
2622                 rp = &up->mitig[i].wwv;
2623                 dtemp = wwv_metric(rp);
2624                 if (dtemp >= rank) {
2625                         rank = dtemp;
2626                         sp = rp;
2627                         j = i;
2628                 }
2629         }
2630         up->dchan = j;
2631         up->sptr = sp;
2632         up->status &= ~(SELV | SELH);
2633         memcpy(&pp->refid, "NONE", 4);
2634         if ((!(up->status & INSYNC) && rank >= MTHR) || ((up->status &
2635             INSYNC) && rank >= TTHR)) {
2636                 up->status |= sp->select & (SELV | SELH);
2637                 memcpy(&pp->refid, sp->refid, 4);
2638         }
2639         if (peer->stratum <= 1)
2640                 memcpy(&peer->refid, &pp->refid, 4);
2641 }
2642
2643
2644 /*
2645  * www_newgame - reset and start over
2646  */
2647 static void
2648 wwv_newgame(
2649         struct peer *peer       /* peer structure pointer */
2650         )
2651 {
2652         struct refclockproc *pp;
2653         struct wwvunit *up;
2654         struct chan *cp;
2655         int i;
2656
2657         pp = peer->procptr;
2658         up = (struct wwvunit *)pp->unitptr;
2659
2660         /*
2661          * Initialize strategic values. Note we set the leap bits
2662          * NOTINSYNC and the refid "NONE".
2663          */
2664         peer->leap = LEAP_NOTINSYNC;
2665         up->watch = up->status = up->alarm = 0;
2666         up->avgint = MINAVG;
2667         up->freq = 0;
2668         up->sptr = NULL;
2669         up->gain = MAXGAIN / 2;
2670
2671         /*
2672          * Initialize the station processes for audio gain, select bit,
2673          * station/frequency identifier and reference identifier.
2674          */
2675         memset(up->mitig, 0, sizeof(up->mitig));
2676         for (i = 0; i < NCHAN; i++) {
2677                 cp = &up->mitig[i];
2678                 cp->gain = up->gain;
2679                 cp->wwv.select = SELV;
2680                 sprintf(cp->wwv.refid, "WV%.0f", floor(qsy[i])); 
2681                 cp->wwvh.select = SELH;
2682                 sprintf(cp->wwvh.refid, "WH%.0f", floor(qsy[i])); 
2683         }
2684         wwv_newchan(peer);
2685 }
2686
2687 /*
2688  * wwv_metric - compute station metric
2689  *
2690  * The most significant bits represent the number of ones in the
2691  * reachability register. The least significant bits represent the
2692  * minute sync pulse amplitude. The combined value is scaled 0-100.
2693  */
2694 double
2695 wwv_metric(
2696         struct sync *sp         /* station pointer */
2697         )
2698 {
2699         double  dtemp;
2700
2701         dtemp = sp->count * MAXSIG;
2702         if (sp->synmax < MAXSIG)
2703                 dtemp += sp->synmax;
2704         else
2705                 dtemp += MAXSIG - 1;
2706         dtemp /= (AMAX + 1) * MAXSIG;
2707         return (dtemp * 100.);
2708 }
2709
2710
2711 #ifdef ICOM
2712 /*
2713  * wwv_qsy - Tune ICOM receiver
2714  *
2715  * This routine saves the AGC for the current channel, switches to a new
2716  * channel and restores the AGC for that channel. If a tunable receiver
2717  * is not available, just fake it.
2718  */
2719 static int
2720 wwv_qsy(
2721         struct peer *peer,      /* peer structure pointer */
2722         int     chan            /* channel */
2723         )
2724 {
2725         int rval = 0;
2726         struct refclockproc *pp;
2727         struct wwvunit *up;
2728
2729         pp = peer->procptr;
2730         up = (struct wwvunit *)pp->unitptr;
2731         if (up->fd_icom > 0) {
2732                 up->mitig[up->achan].gain = up->gain;
2733                 rval = icom_freq(up->fd_icom, peer->ttl & 0x7f,
2734                     qsy[chan]);
2735                 up->achan = chan;
2736                 up->gain = up->mitig[up->achan].gain;
2737         }
2738         return (rval);
2739 }
2740 #endif /* ICOM */
2741
2742
2743 /*
2744  * timecode - assemble timecode string and length
2745  *
2746  * Prettytime format - similar to Spectracom
2747  *
2748  * sq yy ddd hh:mm:ss ld dut lset agc iden sig errs freq avgt
2749  *
2750  * s    sync indicator ('?' or ' ')
2751  * q    error bits (hex 0-F)
2752  * yyyy year of century
2753  * ddd  day of year
2754  * hh   hour of day
2755  * mm   minute of hour
2756  * ss   second of minute)
2757  * l    leap second warning (' ' or 'L')
2758  * d    DST state ('S', 'D', 'I', or 'O')
2759  * dut  DUT sign and magnitude (0.1 s)
2760  * lset minutes since last clock update
2761  * agc  audio gain (0-255)
2762  * iden reference identifier (station and frequency)
2763  * sig  signal quality (0-100)
2764  * errs bit errors in last minute
2765  * freq frequency offset (PPM)
2766  * avgt averaging time (s)
2767  */
2768 static int
2769 timecode(
2770         struct wwvunit *up,     /* driver structure pointer */
2771         char *ptr               /* target string */
2772         )
2773 {
2774         struct sync *sp;
2775         int year, day, hour, minute, second, dut;
2776         char synchar, leapchar, dst;
2777         char cptr[50];
2778         
2779
2780         /*
2781          * Common fixed-format fields
2782          */
2783         synchar = (up->status & INSYNC) ? ' ' : '?';
2784         year = up->decvec[YR].digit + up->decvec[YR + 1].digit * 10 +
2785             2000;
2786         day = up->decvec[DA].digit + up->decvec[DA + 1].digit * 10 +
2787             up->decvec[DA + 2].digit * 100;
2788         hour = up->decvec[HR].digit + up->decvec[HR + 1].digit * 10;
2789         minute = up->decvec[MN].digit + up->decvec[MN + 1].digit * 10;
2790         second = 0;
2791         leapchar = (up->misc & SECWAR) ? 'L' : ' ';
2792         dst = dstcod[(up->misc >> 4) & 0x3];
2793         dut = up->misc & 0x7;
2794         if (!(up->misc & DUTS))
2795                 dut = -dut;
2796         sprintf(ptr, "%c%1X", synchar, up->alarm);
2797         sprintf(cptr, " %4d %03d %02d:%02d:%02d %c%c %+d",
2798             year, day, hour, minute, second, leapchar, dst, dut);
2799         strcat(ptr, cptr);
2800
2801         /*
2802          * Specific variable-format fields
2803          */
2804         sp = up->sptr;
2805         sprintf(cptr, " %d %d %s %.0f %d %.1f %d", up->watch,
2806             up->mitig[up->dchan].gain, sp->refid, wwv_metric(sp),
2807             up->errbit, up->freq / SECOND * 1e6, up->avgint);
2808         strcat(ptr, cptr);
2809         return (strlen(ptr));
2810 }
2811
2812
2813 /*
2814  * wwv_gain - adjust codec gain
2815  *
2816  * This routine is called at the end of each second. It counts the
2817  * number of signal clips above the MAXSIG threshold during the previous
2818  * second. If there are no clips, the gain is bumped up; if too many
2819  * clips, it is bumped down. The decoder is relatively insensitive to
2820  * amplitude, so this crudity works just fine. The input port is set and
2821  * the error flag is cleared, mostly to be ornery.
2822  */
2823 static void
2824 wwv_gain(
2825         struct peer *peer       /* peer structure pointer */
2826         )
2827 {
2828         struct refclockproc *pp;
2829         struct wwvunit *up;
2830
2831         pp = peer->procptr;
2832         up = (struct wwvunit *)pp->unitptr;
2833
2834         /*
2835          * Apparently, the codec uses only the high order bits of the
2836          * gain control field. Thus, it may take awhile for changes to
2837          * wiggle the hardware bits.
2838          */
2839         if (up->clipcnt == 0) {
2840                 up->gain += 4;
2841                 if (up->gain > MAXGAIN)
2842                         up->gain = MAXGAIN;
2843         } else if (up->clipcnt > MAXCLP) {
2844                 up->gain -= 4;
2845                 if (up->gain < 0)
2846                         up->gain = 0;
2847         }
2848         audio_gain(up->gain, up->mongain, up->port);
2849         up->clipcnt = 0;
2850 #if DEBUG
2851         if (debug > 1)
2852                 audio_show();
2853 #endif
2854 }
2855
2856
2857 #else
2858 int refclock_wwv_bs;
2859 #endif /* REFCLOCK */