From f722bda9153af4f95f98739d77e2099d7b073671 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Mon, 3 Jun 2024 16:43:54 +0200 Subject: [PATCH] ts2phc: Add option to correct for NMEA delay. Add an option to specify the minimum expected delay of NMEA RMC messages to correct timestamps returned by the NMEA PPS time source. This enables operation with receivers that have delays outside of the expected 0-1.0s interval, or 0-pulsewidth if the PPS edge rejection is enabled. [ RPC: Preserve alphabetical ordering in the ts2phc man page. ] Signed-off-by: Miroslav Lichvar Signed-off-by: Richard Cochran Reviewed-by: Jacob Keller --- config.c | 1 + ts2phc.8 | 30 ++++++++++++++++++++---------- ts2phc_nmea_pps_source.c | 4 ++++ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/config.c b/config.c index 5dcf7ca7..d0bc32ca 100644 --- a/config.c +++ b/config.c @@ -373,6 +373,7 @@ struct config_item config_tab[] = { PORT_ITEM_INT("ts2phc.holdover", 0, 0, INT_MAX), PORT_ITEM_INT("ts2phc.master", 0, 0, 1), PORT_ITEM_INT("ts2phc.nmea_baudrate", 9600, 300, INT_MAX), + PORT_ITEM_INT("ts2phc.nmea_delay", 0, INT_MIN, INT_MAX), GLOB_ITEM_STR("ts2phc.nmea_remote_host", ""), GLOB_ITEM_STR("ts2phc.nmea_remote_port", ""), GLOB_ITEM_STR("ts2phc.nmea_serialport", "/dev/ttyS0"), diff --git a/ts2phc.8 b/ts2phc.8 index 8b5bd8be..0ee0022b 100644 --- a/ts2phc.8 +++ b/ts2phc.8 @@ -170,16 +170,6 @@ with the log level of the message as a number. The default is an empty string (which cannot be set in the configuration file as the option requires an argument). -.TP -.B ts2phc.holdover -The holdover interval, specified in seconds. When the ToD information stops -working (e.g. GNSS receiver lost its fix), ts2phc is allowed for the specified -interval to continue synchronizing the target clock as long as the servo is in -the SERVO_LOCKED_STABLE state. The servo state needs be enabled by the -\fBservo_num_offset_values\fP option. The holdover is not supported with the -\fB-a\fP option and when \fBts2phc.extts_polarity\fP is set to \fIboth\fP. -The default is 0 (disabled). - .TP .B sa_file Specifies the location of the file containing Security Associations used @@ -204,6 +194,26 @@ for all messages in accordance to the corresponding security association sourced via the \fBsa_file\fR directive. Not compatible with one step ports. Must be in the range of -1 to 255, inclusive. The default is -1 (disabled). +.TP +.B ts2phc.holdover +The holdover interval, specified in seconds. When the ToD information stops +working (e.g. GNSS receiver lost its fix), ts2phc is allowed for the specified +interval to continue synchronizing the target clock as long as the servo is in +the SERVO_LOCKED_STABLE state. The servo state needs be enabled by the +\fBservo_num_offset_values\fP option. The holdover is not supported with the +\fB-a\fP option and when \fBts2phc.extts_polarity\fP is set to \fIboth\fP. +The default is 0 (disabled). + +.TP +.B ts2phc.nmea_delay +Specifies the minimum expected delay of NMEA RMC messages in nanoseconds. +If the maximum delay is longer than 1 second, or 'ts2phc.pulsewidth' +if 'ts2phc.extts_polarity' is set to "both", this option needs to be set +accordingly to allow the timestamps from NMEA messages to be correctly +assigned to pulses from the PPS signal and wrong PPS edges to be rejected if +the edge rejection is enabled. +The default is 0 nanoseconds. + .TP .B ts2phc.nmea_remote_host, ts2phc.nmea_remote_port Specifies the remote host providing ToD information when using the diff --git a/ts2phc_nmea_pps_source.c b/ts2phc_nmea_pps_source.c index 7a284335..3385e393 100644 --- a/ts2phc_nmea_pps_source.c +++ b/ts2phc_nmea_pps_source.c @@ -33,6 +33,7 @@ struct ts2phc_nmea_pps_source { pthread_t worker; /* Protects anonymous struct fields, below, from concurrent access. */ pthread_mutex_t mutex; + tmv_t delay_correction; struct { struct timespec local_monotime; struct timespec local_utctime; @@ -187,6 +188,7 @@ static int ts2phc_nmea_pps_source_getppstime(struct ts2phc_pps_source *src, return -1; } rmc = tmv_add(rmc, duration_since_rmc); + rmc = tmv_add(rmc, m->delay_correction); utc_time = tmv_to_nanoseconds(rmc); utc_time /= (int64_t) 1000000000; *ts = tmv_to_timespec(rmc); @@ -232,6 +234,8 @@ struct ts2phc_pps_source *ts2phc_nmea_pps_source_create(struct ts2phc_private *p s->pps_source.destroy = ts2phc_nmea_pps_source_destroy; s->pps_source.getppstime = ts2phc_nmea_pps_source_getppstime; s->config = priv->cfg; + s->delay_correction = nanoseconds_to_tmv( + config_get_int(priv->cfg, NULL, "ts2phc.nmea_delay")); pthread_mutex_init(&s->mutex, NULL); err = pthread_create(&s->worker, NULL, monitor_nmea_status, s); if (err) {