[ntp:hackers] Patch making NeoClock4x understanding NeoClock3x

Peter Sobisch petersob at gmx.net
Tue Oct 24 01:55:47 PDT 2006


Hi folks,

I've done a small patch which extends the NeoClock4x (44) driver to evaluate
time from NeoClock3x. The NeoClock4x functionality is untouched.

The patch should be applied with: patch -p 1 <patch.refclock4x

--- ntp-4.2.2p4/ntpd/refclock_neoclock4x.c.orig	2006-10-23 13:13:54.000000000 +0200
+++ ntp-4.2.2p4/ntpd/refclock_neoclock4x.c	2006-10-24 10:24:52.000000000 +0200
@@ -15,6 +15,27 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  *
  *
+ *---------------------------------------------------------------------------------------------
+ *
+ * This driver allows to evaluate date and time from older NeoClock3x
+ *
+ * Note to NeoClock3x:
+ *
+ * this older version of NeoClock is programable and supports 3 Modes: binary 1 ("8"), binary 2 ("N") and ASCII ("9")
+ * the period of data output can be set to 1sek ("A"), 60 ("E") seconds and on request ("@").
+ * It communicates also over serial interface with the same communication settings as the NeoClock4x: 2400 8n2
+ * 
+ * This driver extension implements the ASCII mode so you have to set the clock first to: ASCII mode, data output every 1second
+ * to do so, open terminal application and set the serial port parameters and type "9A"
+ * now you should get every second a date string written to your terminal:
+ * for example: "DCF 20/10/06-11:18:38:89-05-ASI-56-08\r\n"
+ * the clock is now set and ready to be used with this extension.
+ *
+ * The NEOCLOCK4X_FIRMWARE feature is not supported for now, so the driver will send "V" to your clock to ask for the version.
+ *
+ * Peter Sobisch <petersob at gmx.net>
+ *
+ *
  */
 
 #ifdef HAVE_CONFIG_H
@@ -109,7 +130,25 @@
 #define NEOCLOCK4X_OFFSET_ANTENNA2         33
 #define NEOCLOCK4X_OFFSET_CRC              35
 
-#define NEOCLOCK4X_DRIVER_VERSION          "1.15 (2006-01-11)"
+#define NEOCLOCK4X_DRIVER_VERSION          "1.15 (2006-01-11) + NeoClock3x Patch"
+
+/* settings for NeoClock3x */
+#define NEOCLOCK3X_OFFSET_RADIOSIGNAL       0
+#define NEOCLOCK3X_OFFSET_DAY               4
+#define NEOCLOCK3X_OFFSET_MONTH             7
+#define NEOCLOCK3X_OFFSET_YEAR             10
+#define NEOCLOCK3X_OFFSET_HOUR             13
+#define NEOCLOCK3X_OFFSET_MINUTE           16
+#define NEOCLOCK3X_OFFSET_SECOND           19
+#define NEOCLOCK3X_OFFSET_HSEC             22
+#define NEOCLOCK3X_OFFSET_DOW              25
+#define NEOCLOCK3X_OFFSET_TIMESOURCE       28
+#define NEOCLOCK3X_OFFSET_DSTSTATUS        29
+#define NEOCLOCK3X_OFFSET_QUARZSTATUS      30
+#define NEOCLOCK3X_OFFSET_ANTENNA1         32
+#define NEOCLOCK3X_OFFSET_ANTENNA2         35
+
+
 
 #define NSEC_TO_MILLI                      1000000
 
@@ -136,6 +175,7 @@
   int   utc_minute;
   int   utc_second;
   int   utc_msec;
+  int	version;	/* contains the version 3 or 4 */
 };
 
 static	int	neoclock4x_start        P((int, struct peer *));
@@ -340,6 +380,7 @@
   up->utc_minute  = 0;
   up->utc_second  = 0;
   up->utc_msec    = 0;
+  up->version     = 4;	/* default is the previous behaviour */
 
 #if defined(NEOCLOCK4X_FIRMWARE)
 #if NEOCLOCK4X_FIRMWARE == NEOCLOCK4X_FIRMWARE_VERSION_A
@@ -367,6 +408,8 @@
 	}
     }
 
+  if (!(NULL == strstr(up->firmware,"NDF:")))	/* NeoClock3x: no firmware check  */
+  {
   /* can I handle this firmware version? */
   if(!neol_check_firmware(up->unit, up->firmware, &up->firmwaretag))
     {
@@ -376,6 +419,14 @@
       pp->unitptr = NULL;
       return (0);
     }
+    msyslog(LOG_INFO, "NeoClock4X(%d): recognized NeoClock4X version (%s)", unit,up->firmware);
+  }
+  else
+  {
+    up->version = 3;
+    up->firmwaretag = '?';
+    msyslog(LOG_INFO, "NeoClock4X(%d): assume NeoClock3X version (%s)", unit,up->firmware);
+  }
 #endif
 
   if(!io_addclock(&pp->io))
@@ -485,6 +536,8 @@
       return;
     }
 
+if (up->version == 4)	/* NeoClock3x has no crc */
+{
   neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_CRC], &recv_chksum, 2);
 
   /* calculate checksum */
@@ -501,6 +554,7 @@
       refclock_report(peer, CEVNT_BADREPLY);
       return;
     }
+}
 
   /* Allow synchronization even is quartz clock is
    * never initialized.
@@ -553,6 +607,9 @@
 	      up->unit, pp->a_lastcode);
     }
 
+if (up->version == 4)
+{
+
   /* 123456789012345678901234567890123456789012345 */
   /* S/N123456DCF1004021010001202ASX1213CR\r\n */
 
@@ -576,6 +633,34 @@
   up->dststatus = pp->a_lastcode[NEOCLOCK4X_OFFSET_DSTSTATUS];
   neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_ANTENNA1], &up->antenna1, 2);
   neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK4X_OFFSET_ANTENNA2], &up->antenna2, 2);
+} 
+else
+{
+  /* 123456789012345678901234567890123456789012345 */
+  /* DCF 20/10/06-11:18:38:89-05-ASI-56-08\r\n        (NeoClock3x) */
+
+  neol_atoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_YEAR], &pp->year, 2);
+  neol_atoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_MONTH], &month, 2);
+  neol_atoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_DAY], &day, 2);
+  neol_atoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_HOUR], &pp->hour, 2);
+  neol_atoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_MINUTE], &pp->minute, 2);
+  neol_atoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_SECOND], &pp->second, 2);
+  neol_atoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_HSEC], &dsec, 2);
+# if defined(NTP_PRE_420)
+  pp->msec = dsec * 10; /* convert 1/100s from neoclock to real miliseconds */
+#else
+  pp->nsec = dsec * 10 * NSEC_TO_MILLI; /* convert 1/100s from neoclock to nanoseconds */
+#endif
+
+  memcpy(up->radiosignal, &pp->a_lastcode[NEOCLOCK3X_OFFSET_RADIOSIGNAL], 3);
+  up->radiosignal[3] = 0;
+
+  up->serial[0] = 0;	/* NeoClock3x has no serial number readable */
+
+  up->dststatus = pp->a_lastcode[NEOCLOCK3X_OFFSET_DSTSTATUS];
+  neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_ANTENNA1], &up->antenna1, 2);
+  neol_hexatoi_len(&pp->a_lastcode[NEOCLOCK3X_OFFSET_ANTENNA2], &up->antenna2, 2);
+}
 
   /*
     Validate received values at least enough to prevent internal
@@ -986,6 +1071,8 @@
 		{
 		  char *ptr;
 		  ptr = strstr(&tmpbuf[lastsearch], "S/N");
+		  if (!ptr)
+		    ptr = strstr(&tmpbuf[lastsearch], "DCF");      /* if no "S/N" found, try DCF for NeoClock3x */
 		  if(NULL != ptr)
 		    {
 		      tmpbuf[last_crlf_conv_len] = 0;



with best regards
Peter Sobisch


More information about the hackers mailing list