]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 1910] Support the Tristate Ltd. TS-GPSclock-01
authorHarlan Stenn <stenn@ntp.org>
Tue, 3 May 2011 04:16:22 +0000 (21:16 -0700)
committerHarlan Stenn <stenn@ntp.org>
Tue, 3 May 2011 04:16:22 +0000 (21:16 -0700)
bk: 4dbf8196h3LP8iXuintAOD8VtGopoA

ChangeLog
html/drivers/driver40.html
ntpd/refclock_jjy.c

index 9755b600eba649f8ff8b52e16dc0aa31d6439195..72eb2ee05b28d8bc9ba3ab8d393e0cea4f3faea7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* [Bug 1910] Support the Tristate Ltd. TS-GPSclock-01.
 (4.2.7p161) 2011/05/02 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 1904] 4.2.7p160 Windows build broken (POSIX_SHELL).
 * [Bug 1906] 4.2.7p160 - libtool: compile: cannot determine name of
index 1901dcdbff7442bf465d8b537e95bbab558908fe..98fe966e09c708197f3dc04684dd54106fa05b65 100644 (file)
                Address: 127.127.40.<em>u</em><br>
                Reference ID: <code>JJY</code><br>
                Driver ID: <code>JJY</code><br>
-               Serial Port: <code>/dev/jjy<em>u</em></code>; 9600|4800(See corresponding receiver) baud, 8-bits, no parity, 1 stop bit
+               Serial Port: <code>/dev/jjy<em>u</em></code>; See corresponding receiver
                <h4>Description</h4>
                <p>This driver supports the following JJY receivers sold in Japan.</p>
                <ul>
-                       <li>Tristate Ltd. JJY01 <a href="http://www.tristate.ne.jp/">http://www.tristate.ne.jp/</a> (Japanese only)<br>
+
+                       <li>
+                               <p>Tristate Ltd. JJY01, JJY02 <a href="http://www.tristate.ne.jp/">http://www.tristate.ne.jp/</a> (Japanese only)</p><br>
                                <dl>
                                        <dt>NTP configuration ( ntp.conf )</dt>
                                        <dd>
                                                <p>server &nbsp; 127.127.40.X &nbsp; mode 1</p>
+                                               <dl>
+                                                       <dt>fudge &nbsp; 127.127.40.X &nbsp; flag1 0|1</dt>
+                                                       <dd>
+                                                               <p>Flag1 has no effect for time synchronization. When a flag1 is set to 1, status commands are issued before DATE and STIM commands, and write a response text into a clockstats file.</p>
+                                                               <table border="1" summary="fudge flag1">
+                                                                       <tr><td>0 (Default)</td><td>DCST and STUS commands are not issued</td></tr>
+                                                                       <tr><td>1</td><td>DCST and STUS commands are issued</td></tr>
+                                                               </table>
+                                                       </dd>
+                                               </dl>
                                                <br>
                                        </dd>
-                                       <dt>RS-232C</dt>
+                                       <dt>Interface</dt>
                                        <dd>
-                                               <p>9600 Baud</p>
+                                               <p>RS-232C, 9600 baud, 8-bits, no parity, 1 stop bit</p>
                                                <br>
                                        </dd>
                                        <dt>Time code format</dt>
                                                                <td>Reply</td>
                                                        </tr>
                                                        <tr>
-                                                               <td><code>date&lt;CR&gt;&lt;LF&gt;</code></td>
+                                                               <td><code>date{CR}{LF}</code></td>
                                                                <td>&nbsp;--&gt;&nbsp;</td>
-                                                               <td><code>YYYY/MM/DD WWW&lt;CR&gt;&lt;LF&gt;</code></td>
+                                                               <td><code>YYYY/MM/DD WWW{CR}{LF}</code></td>
                                                        </tr>
                                                        <tr>
-                                                               <td><code>stim&lt;CR&gt;&lt;LF&gt;</code></td>
+                                                               <td><code>stim{CR}{LF}</code></td>
                                                                <td>&nbsp;--&gt;&nbsp;</td>
-                                                               <td><code>HH:MM:SS&lt;CR&gt;&lt;LF&gt;</code></td>
+                                                               <td><code>HH:MM:SS{CR}{LF}</code></td>
                                                        </tr>
                                                </table>
                                                <br>
                                        </dd>
                                </dl>
-                       <li>C-DEX Co.,Ltd. JST2000 <a href="http://www.c-dex.co.jp/">http://www.c-dex.co.jp/</a> (Japanese only)<br>
+                       </li>
+
+                       <li>
+                               <p>C-DEX Co.,Ltd. JST2000 <a href="http://www.c-dex.co.jp/">http://www.c-dex.co.jp/</a> (Japanese only)</p><br>
                                <dl>
                                        <dt>NTP configuration ( ntp.conf )</dt>
                                        <dd>
                                                <p>server &nbsp; 127.127.40.X &nbsp; mode 2</p>
                                                <br>
                                        </dd>
-                                       <dt>RS-232C</dt>
+                                       <dt>Interface</dt>
                                        <dd>
-                                               <p>9600 Baud</p>
+                                               <p>RS-232C, 9600 baud, 8-bits, no parity, 1 stop bit</p>
                                                <br>
                                        </dd>
                                        <dt>Time code format</dt>
                                                                <td>Reply</td>
                                                        </tr>
                                                        <tr>
-                                                               <td><code>&lt;ENQ&gt;1J&lt;ETX&gt;</code></td>
+                                                               <td><code>{ENQ}1J{ETX}</code></td>
                                                                <td>&nbsp;--&gt;&nbsp;</td>
-                                                               <td><code>&lt;STX&gt;JYYMMDD HHMMSSS&lt;ETX&gt;</code></td>
+                                                               <td><code>{STX}JYYMMDD HHMMSSS{ETX}</code></td>
                                                        </tr>
                                                </table>
                                                <br>
                                        </dd>
                                </dl>
+                       </li>
+
                        <li>
-                               <p>Echo Keisokuki Co.,Ltd. LT-2000 <a href="http://www.clock.co.jp/">http://www.clock.co.jp/</a> (Japanese only)</p>
+                               <p>Echo Keisokuki Co.,Ltd. LT-2000 <a href="http://www.clock.co.jp/">http://www.clock.co.jp/</a> (Japanese only)</p><br>
                                <dl>
                                        <dt>NTP configuration ( ntp.conf )</dt>
                                        <dd>
                                                <p>server &nbsp; 127.127.40.X &nbsp; mode 3</p>
                                                <br>
                                        </dd>
-                                       <dt>RS-232C</dt>
+                                       <dt>Interface</dt>
                                        <dd>
-                                               <p>9600 Baud</p>
+                                               <p>RS-232C, 9600 baud, 8-bits, no parity, 1 stop bit</p>
                                                <br>
                                        </dd>
                                        <dt>Time code format</dt>
                                                        <tr>
                                                                <td>( Every second before 0.5 second )</td>
                                                                <td></td>
-                                                               <td><code>YYMMDDWHHMMSS&lt;ST1&gt;&lt;ST2&gt;&lt;ST3&gt;&lt;ST4&gt;&lt;CR&gt;</code></td>
+                                                               <td><code>YYMMDDWHHMMSS{ST1}{ST2}{ST3}{ST4}{CR}</code></td>
                                                        </tr>
                                                        <tr>
                                                                <td><code>#</code></td>
                                                <br>
                                        </dd>
                                </dl>
+                       </li>
+
                        <li>
-                               <p>CITIZEN T.I.C. CO.,LTD. JJY-200 <a href="http://www.tic-citizen.co.jp/">http://www.tic-citizen.co.jp/</a> (Japanese only)</p>
+                               <p>CITIZEN T.I.C. CO.,LTD. JJY-200 <a href="http://www.tic-citizen.co.jp/">http://www.tic-citizen.co.jp/</a> (Japanese only)</p><br>
                                <dl>
                                        <dt>NTP configuration ( ntp.conf )</dt>
                                        <dd>
                                                <p>server &nbsp; 127.127.40.X &nbsp; mode 4</p>
                                                <br>
                                        </dd>
-                                       <dt>RS-232C</dt>
+                                       <dt>Interface</dt>
                                        <dd>
-                                               <p>4800 Baud</p>
+                                               <p>RS-232C, 4800 baud, 8-bits, no parity, 1 stop bit</p>
                                                <br>
                                        </dd>
                                        <dt>Time code format</dt>
                                                        <tr>
                                                                <td>( Every second )</td>
                                                                <td></td>
-                                                               <td><code>'XX YY/MM/DD W HH:MM:SS&lt;CR&gt;</code></td>
+                                                               <td><code>'XX YY/MM/DD W HH:MM:SS{CR}</code></td>
+                                                       </tr>
+                                               </table>
+                                               <br>
+                                       </dd>
+                               </dl>
+                       </li>
+
+                       <li>
+                               <p>Tristate Ltd. TS-GPSclock-01 <a href="http://www.tristate.ne.jp/">http://www.tristate.ne.jp/</a> (Japanese only)</p>
+                               <p>This driver supports the Tristate TS-GPSclock-01 in command/response mode, though it is a GPS clock, not JJY radio clock. Using the menus and the onboard switches, the TS-GPSclock-01 should be set to command/response mode and JST time zone.<br>
+                               Besides this driver ( Type 40 ), <a href="driver20.html">the generic NMEA GPS driver ( Type 20 )</a> supports the TS-GPSclock-01 in NMEA mode.</p>
+                               <dl>
+                                       <dt>NTP configuration ( ntp.conf )</dt>
+                                       <dd>
+                                               <p>server &nbsp; 127.127.40.X &nbsp; mode 5</p>
+                                               <dl>
+                                                       <dt>fudge &nbsp; 127.127.40.X &nbsp; flag1 0|1</dt>
+                                                       <dd>
+                                                               <p>Flag1 has no effect for time synchronization. When a flag1 is set to 1, status command is issued before DATE and TIME commands, and write a response text into a clockstats file.</p>
+                                                               <table border="1" summary="fudge flag1">
+                                                                       <tr><td>0 (Default)</td><td>STUS command is not issued</td></tr>
+                                                                       <tr><td>1</td><td>STUS command is issued</td></tr>
+                                                               </table>
+                                                       </dd>
+                                               </dl>
+                                               <br>
+                                       </dd>
+                                       <dt>Interface</dt>
+                                       <dd>
+                                               <p>USB ( /dev/ttyACM<em>0</em> )</p>
+                                               <br>
+                                       </dd>
+                                       <dt>Time code format</dt>
+                                       <dd><br>
+                                               <table summary="CommandAndReply">
+                                                       <tr>
+                                                               <td>Command</td>
+                                                               <td>&nbsp;--&gt;&nbsp;</td>
+                                                               <td>Reply</td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td><code>date{CR}{LF}</code></td>
+                                                               <td>&nbsp;--&gt;&nbsp;</td>
+                                                               <td><code>YYYY/MM/DD{CR}{LF}</code></td>
+                                                       </tr>
+                                                       <tr>
+                                                               <td><code>time{CR}{LF}</code></td>
+                                                               <td>&nbsp;--&gt;&nbsp;</td>
+                                                               <td><code>HH:MM:SS{CR}{LF}</code></td>
                                                        </tr>
                                                </table>
                                                <br>
                                        </dd>
                                </dl>
+                       </li>
+
                </ul>
                <p>JJY is the radio station which transmites the JST (Japan Standard Time) in long wave radio. The station JJY is operated by the National Institute of Information and Communications Technology. An operating announcement and some information are avaiable from <a href="http://www.nict.go.jp/">http://www.nict.go.jp/</a> (English and Japanese) and <a href="http://jjy.nict.go.jp/">http://jjy.nict.go.jp/</a> (English and Japanese)</p>
-               <p>The user is expected to provide a symbolic link to an available serial port device. This is typically performed by a command such as:</p>
+               <p>The user is expected to provide a symbolic link to an available serial port device. This is typically performed by a command such as;</p>
                <p><code>ln -s /dev/ttyS0 /dev/jjy0</code></p>
+               <p>Using RS232C to USB converter cable, the clock can be connected to an USB port instead of a serial port. In this case, typical symbolic link command is as follows;
+               <p><code>ln -s /dev/ttyUSB0 /dev/jjy0</code></p>
                <p>Windows NT does not support symbolic links to device files. COM<em>X</em>: is the unit used by the driver, based on the refclock unit number, where unit 1 corresponds to COM1: and unit 3 corresponds to COM3:</p>
                <h4>Monitor Data</h4>
                <p>The driver writes each timecode as received to the <code>clockstats</code> file.</p>
                        <dt><code>refid <em>string</em></code>
                        <dd>Specifies the driver reference identifier, an ASCII string from one to four characters, with default <code>JJY</code>.
                        <dt><code>flag1 0 | 1</code>
-                       <dd>Not used by this driver.
+                       <dd>See corresponding receiver.
                        <dt><code>flag2 0 | 1</code>
                        <dd>Not used by this driver.
                        <dt><code>flag3 0 | 1</code>
index 9514e6cf5da6b53a1aae71f3520aa4211157b249..b3e8ddc1be1fc4205d7f90fa0b90c8ab8a00bbcf 100644 (file)
@@ -4,7 +4,7 @@
 
 /**********************************************************************/
 /*                                                                   */
-/*  Copyright (C) 2001-2004, Takao Abe.  All rights reserved.        */
+/*  Copyright (C) 2001-2011, Takao Abe.  All rights reserved.        */
 /*                                                                   */
 /*  Permission to use, copy, modify, and distribute this software     */
 /*  and its documentation for any purpose is hereby granted          */
@@ -92,6 +92,9 @@
 /*            when "fudge 127.127.40.X flag1 1" is specified         */
 /*            ( DATE,STIM -> DCST,STUS,DATE,STIM )                   */
 /*                                                                   */
+/*  2011/04/30                                                       */
+/*    [Add]    Support the Tristate Ltd. TS-GPSclock-01                      */
+/*                                                                   */
 /**********************************************************************/
 
 #ifdef HAVE_CONFIG_H
 /*  dcst<CR><LF>   VALID|INVALID<CR><LF>                             */
 /*  stus<CR><LF>   ADJUSTED|UNADJUSTED<CR><LF>                       */
 /*  date<CR><LF>   YYYY/MM/DD XXX<CR><LF>                            */
-/*  time<CR><LF>   HH:MM:SS<CR><LF>                                  */
+/*  time<CR><LF>   HH:MM:SS<CR><LF>        Not used by this driver   */
 /*  stim<CR><LF>   HH:MM:SS<CR><LF>        Reply at just second      */
 /*                                                                   */
 /*  During synchronization after a receiver is turned on,            */
 /*                                         W:  0(Monday)-6(Sunday)   */
 /*                                                                   */
 /**********************************************************************/
+/*                                                                   */
+/*  The Tristate Ltd. GPS clock TS-GPSCLOCK-01                       */
+/*                                                                   */
+/*  This clock has NMEA mode and command/respose mode.               */
+/*  When this jjy driver are used, set to command/respose mode        */
+/*  of this clock by the onboard switch SW4, and make sure the        */
+/*  LED-Y is tured on.                                               */
+/*  Other than this JJY driver, the refclock driver type 20,         */
+/*  generic NMEA driver, works with the NMEA mode of this clock.      */
+/*                                                                   */
+/*  Command       Response                 Remarks                   */
+/*  ------------   ----------------------   ---------------------     */
+/*  stus<CR><LF>   *R|*G|*U|+U<CR><LF>                               */
+/*  date<CR><LF>   YY/MM/DD<CR><LF>                                  */
+/*  time<CR><LF>   HH:MM:SS<CR><LF>                                  */
+/*                                                                   */
+/**********************************************************************/
 
 /*
  * Interface definitions
 #define        SPEED232_CDEX_JST2000           B9600   /* UART speed (9600 baud) */
 #define        SPEED232_ECHOKEISOKUKI_LT2000   B9600   /* UART speed (9600 baud) */
 #define        SPEED232_CITIZENTIC_JJY200      B4800   /* UART speed (4800 baud) */
+#define        SPEED232_TRISTATE_GPSCLOCK01    B38400  /* USB  speed (38400 baud) */
 #define        REFID           "JJY"           /* reference ID */
 #define        DESCRIPTION     "JJY Receiver"
 #define        PRECISION       (-3)            /* precision assumed (about 100 ms) */
@@ -196,26 +217,32 @@ struct jjyunit {
        char    rawbuf [ MAX_RAWBUF ] ;
 };
 
-#define        UNITTYPE_TRISTATE_JJY01 1
-#define        UNITTYPE_CDEX_JST2000   2
+#define        UNITTYPE_TRISTATE_JJY01         1
+#define        UNITTYPE_CDEX_JST2000           2
 #define        UNITTYPE_ECHOKEISOKUKI_LT2000   3
 #define        UNITTYPE_CITIZENTIC_JJY200      4
+#define        UNITTYPE_TRISTATE_GPSCLOCK01    5
 
 /*
  * Function prototypes
  */
-static int     jjy_start                   (int, struct peer *);
-static void    jjy_shutdown                (int, struct peer *);
-static void    jjy_poll                    (int, struct peer *);
-static void    jjy_poll_tristate_jjy01     (int, struct peer *);
-static void    jjy_poll_cdex_jst2000       (int, struct peer *);
-static void    jjy_poll_echokeisokuki_lt2000(int, struct peer *);
-static void    jjy_poll_citizentic_jjy200  (int, struct peer *);
-static void    jjy_receive                 (struct recvbuf *);
-static int     jjy_receive_tristate_jjy01  (struct recvbuf *);
-static int     jjy_receive_cdex_jst2000    (struct recvbuf *);
+static int     jjy_start                       (int, struct peer *);
+static void    jjy_shutdown                    (int, struct peer *);
+
+static void    jjy_poll                        (int, struct peer *);
+static void    jjy_poll_tristate_jjy01         (int, struct peer *);
+static void    jjy_poll_cdex_jst2000           (int, struct peer *);
+static void    jjy_poll_echokeisokuki_lt2000   (int, struct peer *);
+static void    jjy_poll_citizentic_jjy200      (int, struct peer *);
+static void    jjy_poll_tristate_gpsclock01    (int, struct peer *);
+
+static void    jjy_receive                     (struct recvbuf *);
+static int     jjy_receive_tristate_jjy01      (struct recvbuf *);
+static int     jjy_receive_cdex_jst2000        (struct recvbuf *);
 static int     jjy_receive_echokeisokuki_lt2000 (struct recvbuf *);
-static  int    jjy_receive_citizentic_jjy200 (struct recvbuf *);
+static  int    jjy_receive_citizentic_jjy200   (struct recvbuf *);
+static int     jjy_receive_tristate_gpsclock01 (struct recvbuf *);
 
 static void    printableString ( char*, int, char*, int ) ;
 
@@ -284,9 +311,46 @@ static  struct
        { TS_JJY01_COMMAND_NUMBER_DATE, "date", "date\r\n", 6 },
        /* stim<CR><LF> -> HH:MM:SS<CR><LF> */
        { TS_JJY01_COMMAND_NUMBER_STIM, "stim", "stim\r\n", 6 },
-       { 0                           , NULL  , NULL      , 0 }
+       /* End of command */
+       { 0, NULL, NULL, 0 }
 } ;
 
+/*
+ * Tristate TS-GPSCLOCK01 constants definition
+ */
+
+#define        TS_GPSCLOCK01_COMMAND_NUMBER_DATE       1
+#define        TS_GPSCLOCK01_COMMAND_NUMBER_TIME       2
+#define        TS_GPSCLOCK01_COMMAND_NUMBER_STUS       4
+
+#define        TS_GPSCLOCK01_REPLY_DATE                "yyyy/mm/dd\r\n"
+#define        TS_GPSCLOCK01_REPLY_TIME                "hh:mm:ss\r\n"
+#define        TS_GPSCLOCK01_REPLY_STUS_RTC            "*R\r\n"
+#define        TS_GPSCLOCK01_REPLY_STUS_GPS            "*G\r\n"
+#define        TS_GPSCLOCK01_REPLY_STUS_UTC            "*U\r\n"
+#define        TS_GPSCLOCK01_REPLY_STUS_PPS            "+U\r\n"
+
+#define        TS_GPSCLOCK01_REPLY_LENGTH_DATE     10  /* Length without <CR><LF> */
+#define        TS_GPSCLOCK01_REPLY_LENGTH_TIME     8   /* Length without <CR><LF> */
+#define        TS_GPSCLOCK01_REPLY_LENGTH_STUS     2   /* Length without <CR><LF> */
+
+static  struct
+{
+       char    commandNumber ;
+       char    *commandLog ;
+       char    *command ;
+       int     commandLength ;
+} tristate_gpsclock01_command_sequence[] =
+{
+       /* stus<CR><LF> -> *R<CR><LF> or *G<CR><LF> or *U<CR><LF> or +U<CR><LF> */
+       { TS_GPSCLOCK01_COMMAND_NUMBER_STUS, "stus", "stus\r\n", 6 },
+       /* date<CR><LF> -> YYYY/MM/DD WWW<CR><LF> */
+       { TS_GPSCLOCK01_COMMAND_NUMBER_DATE, "date", "date\r\n", 6 },
+       /* time<CR><LF> -> HH:MM:SS<CR><LF> */
+       { TS_GPSCLOCK01_COMMAND_NUMBER_TIME, "time", "time\r\n", 6 },
+       /* End of command */
+       { 0, NULL, NULL, 0 }
+} ;
 
 /**************************************************************************************************/
 /*  jjy_start - open the devices and initialize data for processing                               */
@@ -302,6 +366,8 @@ jjy_start ( int unit, struct peer *peer )
        short   iDiscipline ;
        int     iSpeed232 ;
 
+       char    sLogText [ MAX_LOGTEXT ] , sDevText [ MAX_LOGTEXT ] ;
+
 #ifdef DEBUG
        if ( debug ) {
                printf ( "jjy_start (refclock_jjy.c) : %s  mode=%d  ", ntoa(&peer->srcadr), peer->ttl ) ;
@@ -309,6 +375,10 @@ jjy_start ( int unit, struct peer *peer )
                printf ( "\n" ) ;
        }
 #endif
+       snprintf ( sDevText, sizeof(sDevText), DEVICE, unit ) ;
+       snprintf ( sLogText, sizeof(sLogText), "*Initialze*  %s  mode=%d", sDevText, peer->ttl ) ;
+       record_clock_stats ( &peer->srcadr, sLogText ) ;
+
        /*
         * Open serial port
         */
@@ -336,6 +406,10 @@ jjy_start ( int unit, struct peer *peer )
                iDiscipline = LDISC_CLK ;
                iSpeed232   = SPEED232_CITIZENTIC_JJY200 ;
                break ;
+       case 5 :
+               iDiscipline = LDISC_CLK ;
+               iSpeed232   = SPEED232_TRISTATE_GPSCLOCK01 ;
+               break ;
        default :
                msyslog ( LOG_ERR, "JJY receiver [ %s mode %d ] : Unsupported mode",
                          ntoa(&peer->srcadr), peer->ttl ) ;
@@ -399,6 +473,9 @@ jjy_start ( int unit, struct peer *peer )
                up->lineexpect = 1 ;
                up->charexpect[0] = 23 ; /* 'XX YY/MM/DD W HH:MM:SS<CR> */
                break ;
+       case 5 :
+               up->unittype = UNITTYPE_TRISTATE_GPSCLOCK01 ;
+               break ;
 
        /* 2010/11/20 */
        /* The "default:" section of this switch block is never executed,     */
@@ -524,6 +601,17 @@ jjy_receive ( struct recvbuf *rbufp )
         * We get down to business
         */
 
+#ifdef DEBUG
+       if ( debug ) {
+               if ( up->linediscipline == LDISC_RAW ) {
+                       printableString( sLogText, MAX_LOGTEXT, up->rawbuf, up->charcount ) ;
+               } else {
+                       printableString( sLogText, MAX_LOGTEXT, pp->a_lastcode, pp->lencode ) ;
+               }
+               printf ( "jjy_receive (refclock_jjy.c) : [%s]\n", sLogText ) ;
+       }
+#endif
+
        pp->lastrec = tRecvTimestamp ;
 
        up->linecount ++ ;
@@ -548,6 +636,10 @@ jjy_receive ( struct recvbuf *rbufp )
                rc = jjy_receive_citizentic_jjy200 ( rbufp ) ;
                break ;
 
+       case UNITTYPE_TRISTATE_GPSCLOCK01 :
+               rc = jjy_receive_tristate_gpsclock01  ( rbufp ) ;
+               break ;
+
        default :
                rc = 0 ;
                break ;
@@ -568,8 +660,9 @@ jjy_receive ( struct recvbuf *rbufp )
                }
        }
 
-       if ( rc == 0 ) 
+       if ( rc == 0 ) {
                return ;
+       }
 
        up->bPollFlag = 0 ;
 
@@ -648,8 +741,9 @@ jjy_receive ( struct recvbuf *rbufp )
 static int
 jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
 {
-
+#ifdef DEBUG
        static  char    *sFunctionName = "jjy_receive_tristate_jjy01" ;
+#endif
 
        struct jjyunit      *up ;
        struct refclockproc *pp ;
@@ -732,8 +826,7 @@ jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
                }
 
                up->msecond = 0 ;
-               if ( up->hour == 0 && up->minute == 0 &&
-                    up->second <= 2 ) {
+               if ( up->hour == 0 && up->minute == 0 && up->second <= 2 ) {
                        /*
                         * The command "date" and "time" ( or "stim" ) were sent to the JJY receiver separately,
                         * and the JJY receiver replies a date and time separately.
@@ -837,8 +930,9 @@ jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp )
 static int
 jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp )
 {
-
+#ifdef DEBUG
        static  char    *sFunctionName = "jjy_receive_cdex_jst2000" ;
+#endif
 
        struct jjyunit      *up ;
        struct refclockproc *pp ;
@@ -916,8 +1010,9 @@ jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp )
 static int
 jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
 {
-
+#ifdef DEBUG
        static  char    *sFunctionName = "jjy_receive_echokeisokuki_lt2000" ;
+#endif
 
        struct jjyunit      *up ;
        struct refclockproc *pp ;
@@ -1074,8 +1169,9 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp )
 static int
 jjy_receive_citizentic_jjy200 ( struct recvbuf *rbufp )
 {
-
+#ifdef DEBUG
        static char *sFunctionName = "jjy_receive_citizentic_jjy200" ;
+#endif
 
        struct jjyunit          *up ;
        struct refclockproc     *pp ;
@@ -1163,6 +1259,199 @@ jjy_receive_citizentic_jjy200 ( struct recvbuf *rbufp )
 
 }
 
+/**************************************************************************************************/
+
+static int
+jjy_receive_tristate_gpsclock01 ( struct recvbuf *rbufp )
+{
+#ifdef DEBUG
+       static  char    *sFunctionName = "jjy_receive_tristate_gpsclock01" ;
+#endif
+
+       struct jjyunit      *up ;
+       struct refclockproc *pp ;
+       struct peer         *peer;
+
+       char    *pBuf ;
+       int     iLen ;
+       int     rc ;
+
+       int     bOverMidnight = 0 ;
+
+       char    sLogText [ MAX_LOGTEXT ], sReplyText [ MAX_LOGTEXT ] ;
+
+       char    *pCmd ;
+       int     iCmdLen ;
+
+       /*
+        * Initialize pointers and read the timecode and timestamp
+        */
+       peer = rbufp->recv_peer ;
+       pp = peer->procptr ;
+       up = pp->unitptr ;
+
+       if ( up->linediscipline == LDISC_RAW ) {
+               pBuf = up->rawbuf ;
+               iLen = up->charcount ;
+       } else {
+               pBuf = pp->a_lastcode ;
+               iLen = pp->lencode ;
+       }
+
+       /*
+        * Ignore NMEA data stream
+        */
+       if ( iLen > 5
+         && ( strncmp( pBuf, "$GP", 3 ) == 0 || strncmp( pBuf, "$PFEC", 5 ) == 0 ) ) {
+#ifdef DEBUG
+               if ( debug ) {
+                       printf ( "%s (refclock_jjy.c) : Skip NMEA stream [%s]\n",
+                               sFunctionName, pBuf ) ;
+               }
+#endif
+               return 0 ;
+       }
+
+       /*
+        * Skip command prompt '$Cmd>' from the TS-GPSclock-01
+        */
+       if ( iLen == 5 && strncmp( pBuf, "$Cmd>", 5 ) == 0 ) {
+               return 0 ;
+       } else if ( iLen > 5 && strncmp( pBuf, "$Cmd>", 5 ) == 0 ) {
+               pBuf += 5 ;
+               iLen -= 5 ;
+       }
+
+       /*
+        * Ignore NMEA data stream after command prompt
+        */
+       if ( iLen > 5
+         && ( strncmp( pBuf, "$GP", 3 ) == 0 || strncmp( pBuf, "$PFEC", 5 ) == 0 ) ) {
+#ifdef DEBUG
+               if ( debug ) {
+                       printf ( "%s (refclock_jjy.c) : Skip NMEA stream [%s]\n",
+                               sFunctionName, pBuf ) ;
+               }
+#endif
+               return 0 ;
+       }
+
+       switch ( tristate_gpsclock01_command_sequence[up->linecount-1].commandNumber ) {
+
+       case TS_GPSCLOCK01_COMMAND_NUMBER_DATE : /* YYYY/MM/DD */
+
+               if ( iLen != TS_GPSCLOCK01_REPLY_LENGTH_DATE ) {
+                       up->lineerror = 1 ;
+                       break ;
+               }
+
+               rc = sscanf ( pBuf, "%4d/%2d/%2d", &up->year, &up->month, &up->day ) ;
+               if ( rc != 3 || up->year < 2000 || up->month < 1 || up->month > 12 ||
+                    up->day < 1 || up->day > 31 ) {
+                       up->lineerror = 1 ;
+                       break ;
+               }
+
+               break ;
+
+       case TS_GPSCLOCK01_COMMAND_NUMBER_TIME : /* HH:MM:SS */
+
+               if ( iLen != TS_GPSCLOCK01_REPLY_LENGTH_TIME ) {
+                       up->lineerror = 1 ;
+                       break ;
+               }
+
+               rc = sscanf ( pBuf, "%2d:%2d:%2d", &up->hour, &up->minute, &up->second ) ;
+               if ( rc != 3 || up->hour > 23 || up->minute > 59 || up->second > 60 ) {
+                       up->lineerror = 1 ;
+                       break ;
+               }
+
+               up->msecond = 0 ;
+
+               if ( up->hour == 0 && up->minute == 0 && up->second <= 2 ) {
+                       /*
+                        * The command "date" and "time" were sent to the JJY receiver separately,
+                        * and the JJY receiver replies a date and time separately.
+                        * Just after midnight transitions, we ignore this time.
+                        */
+                       bOverMidnight = 1 ;
+               }
+
+               break ;
+
+       case TS_GPSCLOCK01_COMMAND_NUMBER_STUS :
+
+               if ( iLen == TS_GPSCLOCK01_REPLY_LENGTH_STUS
+                 && ( strncmp( pBuf, TS_GPSCLOCK01_REPLY_STUS_RTC, TS_GPSCLOCK01_REPLY_LENGTH_STUS ) == 0
+                   || strncmp( pBuf, TS_GPSCLOCK01_REPLY_STUS_GPS, TS_GPSCLOCK01_REPLY_LENGTH_STUS ) == 0
+                   || strncmp( pBuf, TS_GPSCLOCK01_REPLY_STUS_UTC, TS_GPSCLOCK01_REPLY_LENGTH_STUS ) == 0
+                   || strncmp( pBuf, TS_GPSCLOCK01_REPLY_STUS_PPS, TS_GPSCLOCK01_REPLY_LENGTH_STUS ) == 0 ) ) {
+                       /* Good */
+               } else {
+                       up->lineerror = 1 ;
+                       break ;
+               }
+
+               break ;
+
+       default : /*  Unexpected reply */
+
+               up->lineerror = 1 ;
+               break ;
+
+       }
+
+       /* Clockstats Log */
+
+       printableString( sReplyText, sizeof(sReplyText), pBuf, iLen ) ;
+       snprintf ( sLogText, sizeof(sLogText), "%d: %s -> %c: %s",
+                  up->linecount,
+                  tristate_gpsclock01_command_sequence[up->linecount-1].commandLog,
+                  ( up->lineerror == 0 ) 
+                       ? ( ( bOverMidnight == 0 )
+                               ? 'O' 
+                               : 'S' ) 
+                       : 'X',
+                  sReplyText ) ;
+       record_clock_stats ( &peer->srcadr, sLogText ) ;
+
+       /* Check before issue next command */
+
+       if ( up->lineerror != 0 ) {
+               /* Do not issue next command */
+               return 0 ;
+       }
+
+       if ( bOverMidnight != 0 ) {
+               /* Do not issue next command */
+               return 0 ;
+       }
+
+       if ( tristate_gpsclock01_command_sequence[up->linecount].command == NULL ) {
+               /* Command sequence completed */
+               return 1 ;
+       }
+
+       /* Issue next command */
+
+#ifdef DEBUG
+       if ( debug ) {
+               printf ( "%s (refclock_jjy.c) : send '%s'\n",
+                       sFunctionName, tristate_gpsclock01_command_sequence[up->linecount].commandLog ) ;
+       }
+#endif
+
+       pCmd =  tristate_gpsclock01_command_sequence[up->linecount].command ;
+       iCmdLen = tristate_gpsclock01_command_sequence[up->linecount].commandLength ;
+       if ( write ( pp->io.fd, pCmd, iCmdLen ) != iCmdLen ) {
+               refclock_report ( peer, CEVNT_FAULT ) ;
+       }
+
+       return 0 ;
+
+}
+
 /**************************************************************************************************/
 /*  jjy_poll - called by the transmit procedure                                                   */
 /**************************************************************************************************/
@@ -1214,6 +1503,10 @@ jjy_poll ( int unit, struct peer *peer )
                jjy_poll_citizentic_jjy200 ( unit, peer ) ;
                break ;
 
+       case UNITTYPE_TRISTATE_GPSCLOCK01 :
+               jjy_poll_tristate_gpsclock01  ( unit, peer ) ;
+               break ;
+
        default :
                break ;
 
@@ -1226,8 +1519,9 @@ jjy_poll ( int unit, struct peer *peer )
 static void
 jjy_poll_tristate_jjy01  ( int unit, struct peer *peer )
 {
-
+#ifdef DEBUG
        static char *sFunctionName = "jjy_poll_tristate_jjy01" ;
+#endif
 
        struct jjyunit      *up;
        struct refclockproc *pp;
@@ -1344,6 +1638,56 @@ jjy_poll_citizentic_jjy200 ( int unit, struct peer *peer )
 
 /**************************************************************************************************/
 
+static void
+jjy_poll_tristate_gpsclock01  ( int unit, struct peer *peer )
+{
+#ifdef DEBUG
+       static char *sFunctionName = "jjy_poll_tristate_gpsclock01" ;
+#endif
+
+       struct jjyunit      *up;
+       struct refclockproc *pp;
+
+       char    *pCmd ;
+       int     iCmdLen ;
+
+       pp = peer->procptr;
+       up = pp->unitptr ;
+
+       if ( ( pp->sloppyclockflag & CLK_FLAG1 ) == 0 ) {
+               up->linecount = 1 ;
+       }
+
+#ifdef DEBUG
+       if ( debug ) {
+               printf ( "%s (refclock_jjy.c) : flag1=%X CLK_FLAG1=%X up->linecount=%d\n",
+                       sFunctionName, pp->sloppyclockflag, CLK_FLAG1,
+                       up->linecount ) ;
+       }
+#endif
+
+       /*
+        * Send a first command
+        */
+
+#ifdef DEBUG
+       if ( debug ) {
+               printf ( "%s (refclock_jjy.c) : send '%s'\n",
+                        sFunctionName,
+                        tristate_gpsclock01_command_sequence[up->linecount].commandLog ) ;
+       }
+#endif
+
+       pCmd =  tristate_gpsclock01_command_sequence[up->linecount].command ;
+       iCmdLen = tristate_gpsclock01_command_sequence[up->linecount].commandLength ;
+       if ( write ( pp->io.fd, pCmd, iCmdLen ) != iCmdLen ) {
+               refclock_report ( peer, CEVNT_FAULT ) ;
+       }
+
+}
+
+/**************************************************************************************************/
+
 static void
 printableString ( char *sOutput, int iOutputLen, char *sInput, int iInputLen )
 {