From: Harlan Stenn Date: Tue, 28 Jan 2014 02:32:42 +0000 (-0500) Subject: [Bug 792] TrueTime TL-3 WWV refclock support X-Git-Tag: NTP_4_2_7P414~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d185a5369c3aabc3891b80965f68f3c9d2738c51;p=thirdparty%2Fntp.git [Bug 792] TrueTime TL-3 WWV refclock support bk: 52e716caa5xqqueH2xELWtX99o0qcw --- diff --git a/ChangeLog b/ChangeLog index 43c527484..2ee126cf0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* [Bug 792] TrueTime TL-3 WWV refclock support. (4.2.7p413) 2014/01/27 Released by Harlan Stenn * Require a version string for perl scripts that use autogen. * html/ cleanup. diff --git a/html/drivers/driver5.html b/html/drivers/driver5.html index 699dfa39f..fa19764fa 100644 --- a/html/drivers/driver5.html +++ b/html/drivers/driver5.html @@ -4,23 +4,25 @@ - TrueTime GPS/GOES/OMEGA Receivers + TrueTime GPS/GOES/OMEGA/WWV Receivers -

TrueTime GPS/GOES/OMEGA Receivers

+

TrueTime GPS/GOES/OMEGA/WWV Receivers


Synopsis

Address: 127.127.5.u
- Reference ID: GPS, OMEGA, GOES
+ Reference ID: GPS, OMEGA, GOES, WWV
Driver ID: TRUETIME
Serial Port: /dev/trueu; 9600 baud, 8-bits, no parity
Features: tty_clk

Description

-

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.

+

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.

Most of this code is originally from refclock_wwvb.c with thanks. It has been so mangled that wwvb is not a recognizable ancestor.

-

Timcode format: ADDD:HH:MM:SSQCL 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

+

Timcode format: ADDD:HH:MM:SSQCL
+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:
468-DC GOES Receiver
GPS-TM/TMD Receiver @@ -34,6 +36,9 @@ A-H less than 1 millisecond. Character indicates which station is being received as follows
A = Norway, B = Liberia, C = Hawaii, D = North Dakota, E = La Reunion, F = Argentina, G = Australia, H = Japan
The carriage return start bit begins on 0 seconds and extends to 1 bit time. +
TL-3 WWV Receiver: +
? receiver is unlocked
+
space +/- 5 milliseconds

Notes on 468-DC and OMEGA receiver:

Send the clock a R or C and once per second a timestamp will appear. Send a R to get the satellite position once (GOES only).

@@ -42,6 +47,12 @@

fudge 127.127.5.0 time1 +0.008 time2 -0.004

This corrects the 4 milliseconds advance and 8 milliseconds retard needed. The software will ask the clock which satellite it sees.

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.)

+

Notes on the TL-3 receiver:

+

The mini-DIN RS-232 port uses the Apple pinout.
+ 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.
+QV will return the firmware revision (and is useful in identifying this clock.)
+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.

Monitor Data

When enabled by the flag4 fudge flag, every received timecode is written as-is to the clockstats file.

Fudge Factors

@@ -61,7 +72,7 @@
flag3 0 | 1
Not used by this driver.
flag4 0 | 1 -
Not used by this driver. +
Enable verbose clockstats recording if set.

Additional Information

Reference Clock Drivers

diff --git a/ntpd/refclock_true.c b/ntpd/refclock_true.c index dcbed76bd..04a1001f4 100644 --- a/ntpd/refclock_true.c +++ b/ntpd/refclock_true.c @@ -1,9 +1,8 @@ /* - * 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 @@ -50,10 +49,11 @@ extern int async_write(int, const void *, unsigned int); /* * 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. @@ -71,6 +71,9 @@ extern int async_write(int, const void *, unsigned int); * ? +/- 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 @@ -103,16 +106,27 @@ extern int async_write(int, const void *, unsigned int); * 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) */ @@ -139,19 +153,19 @@ extern int async_write(int, const void *, unsigned int); * 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] : "?") /* @@ -457,6 +471,19 @@ true_receive( 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.) @@ -560,7 +587,13 @@ true_receive( 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; @@ -685,6 +718,19 @@ true_doevent( 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: @@ -725,7 +771,21 @@ true_doevent( 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) @@ -740,13 +800,39 @@ true_doevent( 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: @@ -776,7 +862,9 @@ true_doevent( up->state = s_InqTCU; break; default: - abort(); + msyslog(LOG_INFO, + "TRUE: TM/TMD init fellthrough!"); + break; } break; case s_InqTCU: @@ -791,7 +879,9 @@ true_doevent( sleep(1); /* XXX */ break; default: - abort(); + msyslog(LOG_INFO, + "TRUE: TCU init fellthrough!"); + break; } break; /* @@ -809,7 +899,8 @@ true_doevent( } break; default: - abort(); + msyslog(LOG_INFO, "TRUE: cannot identify refclock!"); + abort(); /* NOTREACHED */ }