aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/ntpd/refclock_ulink.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/ntpd/refclock_ulink.c')
-rw-r--r--contrib/ntp/ntpd/refclock_ulink.c230
1 files changed, 161 insertions, 69 deletions
diff --git a/contrib/ntp/ntpd/refclock_ulink.c b/contrib/ntp/ntpd/refclock_ulink.c
index 1f5e78a86db7..d7a62fef3a4b 100644
--- a/contrib/ntp/ntpd/refclock_ulink.c
+++ b/contrib/ntp/ntpd/refclock_ulink.c
@@ -1,6 +1,5 @@
/*
* refclock_ulink - clock driver for Ultralink WWVB receiver
- *
*/
/***********************************************************************
@@ -32,11 +31,9 @@
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_refclock.h"
-#include "ntp_calendar.h"
#include "ntp_stdlib.h"
-/*
- * This driver supports ultralink Model 320,330,331,332 WWVB radios
+/* This driver supports ultralink Model 320,325,330,331,332 WWVB radios
*
* this driver was based on the refclock_wwvb.c driver
* in the ntp distribution.
@@ -62,6 +59,8 @@
* 01/02/21 s.l.smith fixed 33x quality flag
* added more debugging stuff
* updated 33x time code explanation
+ * 04/01/23 frank migge added support for 325 decoder
+ * (tested with ULM325.F)
*
* Questions, bugs, ideas send to:
* Joseph C. Lang
@@ -70,10 +69,13 @@
* Dave Strout
* dstrout@linuxfoundry.com
*
+ * Frank Migge
+ * frank.migge@oracle.com
+ *
*
* on the Ultralink model 33X decoder Dip switch 2 controls
* polled or continous timecode
- * set fudge flag1 if using polled (needed for model 320)
+ * set fudge flag1 if using polled (needed for model 320 and 325)
* dont set fudge flag1 if dip switch 2 is set on model 33x decoder
*/
@@ -87,9 +89,12 @@
#define REFID "WWVB" /* reference ID */
#define DESCRIPTION "Ultralink WWVB Receiver" /* WRU */
-#define LEN33X 32 /* timecode length Model 325 & 33X */
+#define LEN33X 32 /* timecode length Model 33X and 325 */
#define LEN320 24 /* timecode length Model 320 */
+#define SIGLCHAR33x 'S' /* signal strength identifier char 325 */
+#define SIGLCHAR325 'R' /* signal strength identifier char 33x */
+
/*
* unit control structure
*/
@@ -210,6 +215,7 @@ ulink_receive(
char syncchar; /* synchronization indicator */
char leapchar; /* leap indicator */
char modechar; /* model 320 mode flag */
+ char siglchar; /* model difference between 33x/325 */
char char_quality[2]; /* temp quality flag */
/*
@@ -247,77 +253,163 @@ ulink_receive(
* its contents. If the timecode has invalid length or is not in
* proper format, we declare bad format and exit.
*/
- syncchar = leapchar = modechar = ' ';
+ syncchar = leapchar = modechar = siglchar = ' ';
switch (pp->lencode ) {
case LEN33X:
+
/*
- * Model 33X decoder:
- * Timecode format from January 29, 2001 datasheet is:
- * <CR><LF>S9+D 00 YYYY+DDDUTCS HH:MM:SSL+5
- * S WWVB decoder sync indicator. S for in-sync(?)
- * or N for noisy signal.
- * 9+ RF signal level in S-units, 0-9 followed by
- * a space (0x20). The space turns to '+' if the
- * level is over 9.
- * D Data bit 0, 1, 2 (position mark), or
- * 3 (unknown).
- * space Space character (0x20)
- * 00 Hours since last good WWVB frame sync. Will
- * be 00-23 hrs, or '1d' to '7d'. Will be 'Lk'
- * if currently in sync.
- * space Space character (0x20)
- * YYYY Current year, 1990-2089
- * + Leap year indicator. '+' if a leap year,
- * a space (0x20) if not.
- * DDD Day of year, 001 - 366.
- * UTC Timezone (always 'UTC').
- * S Daylight savings indicator
- * S - standard time (STD) in effect
- * O - during STD to DST day 0000-2400
- * D - daylight savings time (DST) in effect
- * I - during DST to STD day 0000-2400
- * space Space character (0x20)
- * HH Hours 00-23
- * : This is the REAL in sync indicator (: = insync)
- * MM Minutes 00-59
- * : : = in sync ? = NOT in sync
- * SS Seconds 00-59
- * L Leap second flag. Changes from space (0x20)
- * to '+' or '-' during month preceding leap
- * second adjustment.
- * +5 UT1 correction (sign + digit ))
- */
-
- if (sscanf(pp->a_lastcode,
- "%*4c %2c %4d%*c%3d%*4c %2d%c%2d:%2d%c%*2c",
- char_quality, &pp->year, &pp->day,
- &pp->hour, &syncchar, &pp->minute, &pp->second,
- &leapchar) == 8) {
+ * First we check if the format is 33x or 325:
+ * <CR><LF>S9+D 00 YYYY+DDDUTCS HH:MM:SSL+5 (33x)
+ * <CR><LF>R5_1C00LYYYY+DDDUTCS HH:MM:SSL+5 (325)
+ * simply by comparing if the signal level is 'S' or 'R'
+ */
+
+ if (sscanf(pp->a_lastcode, "%c%*31c",
+ &siglchar) == 1) {
+
+ if(siglchar == SIGLCHAR325) {
+
+ /*
+ * decode for a Model 325 decoder.
+ * Timecode format from January 23, 2004 datasheet is:
+ *
+ * <CR><LF>R5_1C00LYYYY+DDDUTCS HH:MM:SSL+5
+ *
+ * R WWVB decodersignal readability R1 - R5
+ * 5 R1 is unreadable, R5 is best
+ * space a space (0x20)
+ * 1 Data bit 0, 1, M (pos mark), or ? (unknown).
+ * C Reception from either (C)olorado or (H)awaii
+ * 00 Hours since last good WWVB frame sync. Will
+ * be 00-99
+ * space Space char (0x20) or (0xa5) if locked to wwvb
+ * YYYY Current year, 2000-2099
+ * + Leap year indicator. '+' if a leap year,
+ * a space (0x20) if not.
+ * DDD Day of year, 000 - 365.
+ * UTC Timezone (always 'UTC').
+ * S Daylight savings indicator
+ * S - standard time (STD) in effect
+ * O - during STD to DST day 0000-2400
+ * D - daylight savings time (DST) in effect
+ * I - during DST to STD day 0000-2400
+ * space Space character (0x20)
+ * HH Hours 00-23
+ * : This is the REAL in sync indicator (: = insync)
+ * MM Minutes 00-59
+ * : : = in sync ? = NOT in sync
+ * SS Seconds 00-59
+ * L Leap second flag. Changes from space (0x20)
+ * to 'I' or 'D' during month preceding leap
+ * second adjustment. (I)nsert or (D)elete
+ * +5 UT1 correction (sign + digit ))
+ */
+
+ if (sscanf(pp->a_lastcode,
+ "%*2c %*2c%2c%*c%4d%*c%3d%*4c %2d%c%2d:%2d%c%*2c",
+ char_quality, &pp->year, &pp->day,
+ &pp->hour, &syncchar, &pp->minute, &pp->second,
+ &leapchar) == 8) {
+
+ if (char_quality[0] == '0') {
+ quality = 0;
+ } else if (char_quality[0] == '0') {
+ quality = (char_quality[1] & 0x0f);
+ } else {
+ quality = 99;
+ }
+
+ if (leapchar == 'I' ) leapchar = '+';
+ if (leapchar == 'D' ) leapchar = '-';
+
+ /*
+ #ifdef DEBUG
+ if (debug) {
+ printf("ulink: char_quality %c %c\n",
+ char_quality[0], char_quality[1]);
+ printf("ulink: quality %d\n", quality);
+ printf("ulink: syncchar %x\n", syncchar);
+ printf("ulink: leapchar %x\n", leapchar);
+ }
+ #endif
+ */
+
+ }
+
+ }
+ if(siglchar == SIGLCHAR33x) {
+
+ /*
+ * We got a Model 33X decoder.
+ * Timecode format from January 29, 2001 datasheet is:
+ * <CR><LF>S9+D 00 YYYY+DDDUTCS HH:MM:SSL+5
+ * S WWVB decoder sync indicator. S for in-sync(?)
+ * or N for noisy signal.
+ * 9+ RF signal level in S-units, 0-9 followed by
+ * a space (0x20). The space turns to '+' if the
+ * level is over 9.
+ * D Data bit 0, 1, 2 (position mark), or
+ * 3 (unknown).
+ * space Space character (0x20)
+ * 00 Hours since last good WWVB frame sync. Will
+ * be 00-23 hrs, or '1d' to '7d'. Will be 'Lk'
+ * if currently in sync.
+ * space Space character (0x20)
+ * YYYY Current year, 1990-2089
+ * + Leap year indicator. '+' if a leap year,
+ * a space (0x20) if not.
+ * DDD Day of year, 001 - 366.
+ * UTC Timezone (always 'UTC').
+ * S Daylight savings indicator
+ * S - standard time (STD) in effect
+ * O - during STD to DST day 0000-2400
+ * D - daylight savings time (DST) in effect
+ * I - during DST to STD day 0000-2400
+ * space Space character (0x20)
+ * HH Hours 00-23
+ * : This is the REAL in sync indicator (: = insync)
+ * MM Minutes 00-59
+ * : : = in sync ? = NOT in sync
+ * SS Seconds 00-59
+ * L Leap second flag. Changes from space (0x20)
+ * to '+' or '-' during month preceding leap
+ * second adjustment.
+ * +5 UT1 correction (sign + digit ))
+ */
+
+ if (sscanf(pp->a_lastcode,
+ "%*4c %2c %4d%*c%3d%*4c %2d%c%2d:%2d%c%*2c",
+ char_quality, &pp->year, &pp->day,
+ &pp->hour, &syncchar, &pp->minute, &pp->second,
+ &leapchar) == 8) {
- if (char_quality[0] == 'L') {
+ if (char_quality[0] == 'L') {
quality = 0;
- } else if (char_quality[0] == '0') {
+ } else if (char_quality[0] == '0') {
quality = (char_quality[1] & 0x0f);
- } else {
+ } else {
quality = 99;
- }
+ }
-/*
-#ifdef DEBUG
- if (debug) {
- printf("ulink: char_quality %c %c\n",
- char_quality[0], char_quality[1]);
- printf("ulink: quality %d\n", quality);
- printf("ulink: syncchar %x\n", syncchar);
- printf("ulink: leapchar %x\n", leapchar);
- }
-#endif
-*/
-
- break;
+ /*
+ #ifdef DEBUG
+ if (debug) {
+ printf("ulink: char_quality %c %c\n",
+ char_quality[0], char_quality[1]);
+ printf("ulink: quality %d\n", quality);
+ printf("ulink: syncchar %x\n", syncchar);
+ printf("ulink: leapchar %x\n", leapchar);
+ }
+ #endif
+ */
+
+ }
+ }
+ break;
}
-
+
case LEN320:
+
/*
* Model 320 Decoder
* The timecode format is:
@@ -345,6 +437,7 @@ ulink_receive(
* T = DST <-> STD transition indicators
*
*/
+
if (sscanf(pp->a_lastcode, "%c%1d%c%4d%3d%*c%2d:%2d:%2d.%2ld%c",
&syncchar, &quality, &modechar, &pp->year, &pp->day,
&pp->hour, &pp->minute, &pp->second,
@@ -362,7 +455,6 @@ ulink_receive(
return;
}
-
/*
* Decode quality indicator
* For the 325 & 33x series, the lower the number the "better"
@@ -455,10 +547,10 @@ ulink_receive(
}
-
/*
* ulink_poll - called by the transmit procedure
*/
+
static void
ulink_poll(
int unit,