<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
- <title>TrueTime GPS/GOES/OMEGA Receivers</title>
+ <title>TrueTime GPS/GOES/OMEGA/WWV Receivers</title>
<link href="scripts/style.css" type="text/css" rel="stylesheet">
</head>
<body>
- <h3>TrueTime GPS/GOES/OMEGA Receivers</h3>
+ <h3>TrueTime GPS/GOES/OMEGA/WWV Receivers</h3>
<hr>
<h4>Synopsis</h4>
Address: 127.127.5.<i>u</i><br>
- Reference ID: <tt>GPS, OMEGA, GOES</tt><br>
+ Reference ID: <tt>GPS, OMEGA, GOES, WWV</tt><br>
Driver ID: <tt>TRUETIME</tt><br>
Serial Port: <tt>/dev/true<i>u</i></tt>; 9600 baud, 8-bits, no parity<br>
Features: <tt>tty_clk</tt>
<h4>Description</h4>
- <p>This driver supports several models models of Kinemetrics/TrueTime timing receivers, including 468-DC MK III GOES Synchronized Clock, GPS- DC MK III and GPS/TM-TMD GPS Synchronized Clock, XL-DC (a 151-602-210, reported by the driver as a GPS/TM-TMD), GPS-800 TCU (an 805-957 with the RS232 Talker/Listener module), OM-DC OMEGA Synchronized Clock, and very likely others in the same model family that use the same timecode formats.</p>
+ <p>This driver supports several models models of Kinemetrics/TrueTime timing receivers, including 468-DC MK III GOES Synchronized Clock, GPS- DC MK III and GPS/TM-TMD GPS Synchronized Clock, XL-DC (a 151-602-210, reported by the driver as a GPS/TM-TMD), GPS-800 TCU (an 805-957 with the RS232 Talker/Listener module), OM-DC OMEGA Synchronized Clock, the TL-3 WWV receiver, and very likely others in the same model families that use the same timecode formats.</p>
<p>Most of this code is originally from refclock_wwvb.c with thanks. It has been so mangled that wwvb is not a recognizable ancestor.</p>
- <p>Timcode format: <tt>ADDD:HH:MM:SSQCL</tt> A - control A (this is stripped before we see it) Q - Quality indication (see below) C - Carriage return L - Line feed Quality codes indicate possible error of</p>
+ <p>Timcode format: <tt>ADDD:HH:MM:SSQCL</tt><br>
+A - control A (this is stripped before we see it) Q - Quality indication (see below) C - Carriage return L - Line feed</p><br>
+Quality codes indicate possible error of:
<dl>
<dt>468-DC GOES Receiver<br>
GPS-TM/TMD Receiver
A-H less than 1 millisecond. Character indicates which station is being received as follows<br>
A = Norway, B = Liberia, C = Hawaii, D = North Dakota, E = La Reunion, F = Argentina, G = Australia, H = Japan<br>
The carriage return start bit begins on 0 seconds and extends to 1 bit time.
+ <dt>TL-3 WWV Receiver:
+ <dd>? receiver is unlocked<br>
+ <dd>space +/- 5 milliseconds<br>
</dl>
<h4>Notes on 468-DC and OMEGA receiver:</h4>
<p>Send the clock a <tt>R</tt> or <tt>C</tt> and once per second a timestamp will appear. Send a <tt>R</tt> to get the satellite position once (GOES only).</p>
<p><tt>fudge 127.127.5.0 time1 +0.008 time2 -0.004</tt></p>
<p>This corrects the 4 milliseconds advance and 8 milliseconds retard needed. The software will ask the clock which satellite it sees.</p>
<p>The PCL720 from PC Labs has an Intel 8253 look-alike, as well as a bunch of TTL input and output pins, all brought out to the back panel. If you wire a PPS signal (such as the TTL PPS coming out of a GOES or other Kinemetrics/Truetime clock) to the 8253's GATE0, and then also wire the 8253's OUT0 to the PCL720's INPUT3.BIT0, then we can read CTR0 to get the number of microseconds since the last PPS upward edge, mediated by reading OUT0 to find out if the counter has wrapped around (this happens if more than 65535us (65ms) elapses between the PPS event and our being called.)</p>
+ <h4>Notes on the TL-3 receiver:</h4>
+ <p>The mini-DIN RS-232 port uses the Apple pinout.<br>
+ Send the clock ST1 to turn on continuous (1/sec) timecodes.
+You can also enable "mode C" via the front panel. ST0 turns off this mode.<br>
+QV will return the firmware revision (and is useful in identifying this clock.)<br>
+QW will return its weekly signal log, useful if you're testing antennas. You may wish to turn the loss interval down from 4h (04) to 1h (01), so the receiver declares itself unlocked sooner. When in holdover, drift can be on the order of 10 ms/hr since there is no high quality reference oscillator.</p>
<h4>Monitor Data</h4>
<p>When enabled by the <tt>flag4</tt> fudge flag, every received timecode is written as-is to the <tt>clockstats</tt> file.</p>
<h4>Fudge Factors</h4>
<dt><tt>flag3 0 | 1</tt>
<dd>Not used by this driver.
<dt><tt>flag4 0 | 1</tt>
- <dd>Not used by this driver.
+ <dd>Enable verbose <tt>clockstats</tt> recording if set.
</dl>
<h4>Additional Information</h4>
<p><a href="../refclock.html">Reference Clock Drivers</a></p>
/*
- * refclock_true - clock driver for the Kinemetrics Truetime receivers
+ * refclock_true - clock driver for the Kinemetrics/TrueTime receivers
* Receiver Version 3.0C - tested plain, with CLKLDISC
- * Developement work being done:
- * - Properly handle varying satellite positions (more acurately)
- * - Integrate GPSTM and/or OMEGA and/or TRAK and/or ??? drivers
+ * Development work being done:
+ * - Support TL-3 WWV TOD receiver
*/
#ifdef HAVE_CONFIG_H
/*
* Support for Kinemetrics Truetime Receivers
- * GOES
- * GPS/TM-TMD
- * XL-DC (a 151-602-210, reported by the driver as a GPS/TM-TMD)
- * GPS-800 TCU (an 805-957 with the RS232 Talker/Listener module)
+ * GOES: (468-DC, usable with GPS->GOES converting antenna)
+ * GPS/TM-TMD:
+ * XL-DC: (a 151-602-210, reported by the driver as a GPS/TM-TMD)
+ * GPS-800 TCU: (an 805-957 with the RS232 Talker/Listener module)
+ * TL-3: 3 channel WWV/H receiver w/ IRIG and RS-232 outputs
* OM-DC: getting stale ("OMEGA")
*
* Most of this code is originally from refclock_wwvb.c with thanks.
* ? +/- 1 milliseconds # +/- 100 microseconds
* * +/- 10 microseconds . +/- 1 microsecond
* space less than 1 microsecond
+ * TL-3 Receiver: (default quality codes for TL-3)
+ * ? unknown quality (receiver is unlocked)
+ * space +/- 5 milliseconds
* OM-DC OMEGA Receiver: (default quality codes for OMEGA)
* WARNING OMEGA navigation system is no longer existent
* > >+- 5 seconds
* This corrects the 4 milliseconds advance and 8 milliseconds retard
* needed. The software will ask the clock which satellite it sees.
*
- * Ntp.conf parameters:
- * time1 - offset applied to samples when reading WEST satellite (default = 0)
- * time2 - offset applied to samples when reading EAST satellite (default = 0)
- * val1 - stratum to assign to this clock (default = 0)
- * val2 - refid assigned to this clock (default = "TRUE", see below)
- * flag1 - will silence the clock side of ntpd, just reading the clock
- * without trying to write to it. (default = 0)
- * flag2 - generate a debug file /tmp/true%d.
- * flag3 - enable ppsclock streams module
- * flag4 - use the PCL-720 (BSD/OS only)
+ * Notes on the TrueTime TimeLink TL-3 WWV TOD receiver:
+ *
+ * This clock may be polled, or send one timecode per second.
+ * That mode may be toggled via the front panel ("C" mode), or controlled
+ * from the RS-232 port. Send the receiver "ST1" to turn it on, and
+ * "ST0" to turn it off. Send "QV" to get the firmware revision (useful
+ * for identifying this model.)
+ *
+ * Note that it can take several polling cycles, especially if the receiver
+ * was in the continuous timecode mode. (It can be slow to leave that mode.)
+ *
+ * ntp.conf parameters:
+ * time1 - offset applied to samples when reading WEST satellite (default = 0)
+ * time2 - offset applied to samples when reading EAST satellite (default = 0)
+ * stratum - stratum to assign to this clock (default = 0)
+ * refid - refid assigned to this clock (default = "TRUE", see below)
+ * flag1 - will silence the clock side of ntpd, just reading the clock
+ * without trying to write to it. (default = 0)
+ * flag2 - generate a debug file /tmp/true%d.
+ * flag3 - enable ppsclock streams module
+ * flag4 - use the PCL-720 (BSD/OS only)
*/
* used by the state machine
*/
enum true_event {e_Init, e_Huh, e_F18, e_F50, e_F51, e_Satellite,
- e_Poll, e_Location, e_TS, e_Max};
+ e_TL3, e_Poll, e_Location, e_TS, e_Max};
const char *events[] = {"Init", "Huh", "F18", "F50", "F51", "Satellite",
- "Poll", "Location", "TS"};
+ "TL3", "Poll", "Location", "TS"};
#define eventStr(x) (((int)x<(int)e_Max) ? events[(int)x] : "?")
enum true_state {s_Base, s_InqTM, s_InqTCU, s_InqOmega, s_InqGOES,
- s_Init, s_F18, s_F50, s_Start, s_Auto, s_Max};
+ s_InqTL3, s_Init, s_F18, s_F50, s_Start, s_Auto, s_Max};
const char *states[] = {"Base", "InqTM", "InqTCU", "InqOmega", "InqGOES",
- "Init", "F18", "F50", "Start", "Auto"};
+ "InqTL3", "Init", "F18", "F50", "Start", "Auto"};
#define stateStr(x) (((int)x<(int)s_Max) ? states[(int)x] : "?")
-enum true_type {t_unknown, t_goes, t_tm, t_tcu, t_omega, t_Max};
-const char *types[] = {"unknown", "goes", "tm", "tcu", "omega"};
+enum true_type {t_unknown, t_goes, t_tm, t_tcu, t_omega, t_tl3, t_Max};
+const char *types[] = {"unknown", "goes", "tm", "tcu", "omega", "tl3"};
#define typeStr(x) (((int)x<(int)t_Max) ? types[(int)x] : "?")
/*
return;
}
+ /*
+ * Timecode: "VER xx.xx"
+ * (from a TL3 when sent "QV", so id's it during initialization.)
+ */
+ if (pp->a_lastcode[0] == 'V' && pp->a_lastcode[1] == 'E' &&
+ pp->a_lastcode[2] == 'R' && pp->a_lastcode[6] == '.') {
+ true_doevent(peer, e_TL3);
+ NLOG(NLOG_CLOCKSTATUS) {
+ msyslog(LOG_INFO, "TL3: %s", pp->a_lastcode);
+ }
+ return;
+ }
+
/*
* Timecode: " TRUETIME Mk III" or " TRUETIME XL"
* (from a TM/TMD/XL clock during initialization.)
if (!up->polled)
return;
- true_doevent(peer, e_Poll);
+ /* We only call doevent if additional things need be done
+ * at poll interval. Currently, its only for GOES. We also
+ * call it for clock unknown so that it gets logged.
+ */
+ if (up->type == t_goes || up->type == t_unknown)
+ true_doevent(peer, e_Poll);
+
if (!refclock_process(pp)) {
refclock_report(peer, CEVNT_BADTIME);
return;
break;
case e_F18:
true_send(peer, "F50\r");
+ /*
+ * Timecode: " TRUETIME Mk III" or " TRUETIME XL"
+ * (from a TM/TMD/XL clock during initialization.)
+ */
+ if ( strcmp(pp->a_lastcode, " TRUETIME Mk III") == 0 ||
+ strncmp(pp->a_lastcode, " TRUETIME XL", 12) == 0) {
+ true_doevent(peer, e_F18);
+ NLOG(NLOG_CLOCKSTATUS) {
+ msyslog(LOG_INFO, "TM/TMD/XL: %s",
+ pp->a_lastcode);
+ }
+ return;
+ }
up->state = s_F18;
break;
case e_F50:
break;
}
break;
+ case t_tl3:
+ switch (event) {
+ case e_Init:
+ true_send(peer, "ST1"); /* Turn on continuous stream */
+ break;
+ case e_TS:
+ up->state = s_Auto;
+ break;
+ default:
+ break;
+ }
+ break;
case t_unknown:
+ if (event == e_Poll)
+ break;
switch (up->state) {
case s_Base:
if (event != e_Init)
true_doevent(peer, e_Init);
break;
case e_Init: /*FALLTHROUGH*/
- case e_Huh: /*FALLTHROUGH*/
+ case e_Huh:
case e_TS:
+ true_send(peer, "ST0"); /* turn off TL3 auto */
+ sleep(1); /* wait for it */
+ up->state = s_InqTL3;
+ true_send(peer, "QV"); /* see if its a TL3 */
+ break;
+ default:
+ abort();
+ }
+ break;
+ case s_InqTL3:
+ switch (event) {
+ case e_TL3:
+ up->type = t_tl3;
+ up->state = s_Auto; /* Inq side-effect. */
+ true_send(peer, "ST1"); /* Turn on 1/sec data */
+ break;
+ case e_Init: /*FALLTHROUGH*/
+ case e_Huh:
up->state = s_InqOmega;
true_send(peer, "C\r");
break;
+ case e_TS:
+ up->type = t_tl3; /* Already sending data */
+ up->state = s_Auto;
+ break;
+ case e_Poll:
+ break;
default:
- abort();
+ msyslog(LOG_INFO,
+ "TRUE: TL3 init fellthrough!");
+ break;
}
break;
case s_InqOmega:
up->state = s_InqTCU;
break;
default:
- abort();
+ msyslog(LOG_INFO,
+ "TRUE: TM/TMD init fellthrough!");
+ break;
}
break;
case s_InqTCU:
sleep(1); /* XXX */
break;
default:
- abort();
+ msyslog(LOG_INFO,
+ "TRUE: TCU init fellthrough!");
+ break;
}
break;
/*
}
break;
default:
- abort();
+ msyslog(LOG_INFO, "TRUE: cannot identify refclock!");
+ abort();
/* NOTREACHED */
}