Fix error handling: timeout=1500ms, sign of EINTR, cnt==0. Signed-off-by: Jürgen Appel <j...@dfm.dk> --- ts2phc_pps_sink.c | 66 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 17 deletions(-)
diff --git a/ts2phc_pps_sink.c b/ts2phc_pps_sink.c index d25bc89..1e86849 100644 --- a/ts2phc_pps_sink.c +++ b/ts2phc_pps_sink.c @@ -30,8 +30,8 @@ struct ts2phc_pps_sink { struct ptp_pin_desc pin_desc; unsigned int polarity; tmv_t correction; - uint32_t ignore_lower; - uint32_t ignore_upper; + int pulsewidth; + tmv_t last; struct ts2phc_clock *clock; }; @@ -175,9 +175,8 @@ static struct ts2phc_pps_sink *ts2phc_pps_sink_create(struct ts2phc_private *pri sink->correction = nanoseconds_to_tmv(correction); pulsewidth = config_get_int(cfg, device, "ts2phc.pulsewidth"); - pulsewidth /= 2; - sink->ignore_upper = 1000000000 - pulsewidth; - sink->ignore_lower = pulsewidth; + sink->pulsewidth = pulsewidth; + sink->last.ns = 0; sink->clock = ts2phc_clock_add(priv, device); if (!sink->clock) { @@ -238,15 +237,40 @@ static void ts2phc_pps_sink_destroy(struct ts2phc_pps_sink *sink) static bool ts2phc_pps_sink_ignore(struct ts2phc_private *priv, struct ts2phc_pps_sink *sink, + struct ptp_extts_event event, struct timespec source_ts) { - tmv_t source_tmv = timespec_to_tmv(source_ts); - - source_tmv = tmv_sub(source_tmv, priv->perout_phase); - source_ts = tmv_to_timespec(source_tmv); - - return source_ts.tv_nsec > sink->ignore_lower && - source_ts.tv_nsec < sink->ignore_upper; + tmv_t event_tmv, source_tmv, dt; + + if (sink->pulsewidth == NS_PER_SEC/2) { + /* + * 1pps has exactly 50% duty cycle: discriminate edges + * by CLOCK_REALTIME timestamp, requires CLOCK_REALTIME/ + * to be approximately correct and stable + */ + source_tmv = timespec_to_tmv(source_ts); + source_tmv = tmv_sub(source_tmv, priv->perout_phase); + source_ts = tmv_to_timespec(source_tmv); + + return (source_ts.tv_nsec > NS_PER_SEC/4) && + (source_ts.tv_nsec < NS_PER_SEC/4*3); + } else { + /* + * use pulse-width to discriminate rising/falling edges, + * does not require CLOCK_REALTIME to run correctly, + * tolerates jumps there + */ + event_tmv = pct_to_tmv(event.t); + if (sink->last.ns) { + dt = tmv_sub(event_tmv, sink->last); + sink->last = event_tmv; + return ((dt.ns < (NS_PER_SEC / 2)) ^ + (sink->pulsewidth > (NS_PER_SEC / 2))); + } else { /* ignore first event */ + sink->last = event_tmv; + return true; + } + } } static enum extts_result ts2phc_pps_sink_event(struct ts2phc_private *priv, @@ -277,7 +301,7 @@ static enum extts_result ts2phc_pps_sink_event(struct ts2phc_private *priv, } if (sink->polarity == (PTP_RISING_EDGE | PTP_FALLING_EDGE) && - ts2phc_pps_sink_ignore(priv, sink, source_ts)) { + ts2phc_pps_sink_ignore(priv, sink, event, source_ts)) { pr_debug("%s SKIP extts index %u at %lld.%09u src %" PRIi64 ".%ld", sink->name, event.index, event.t.sec, event.t.nsec, @@ -379,17 +403,25 @@ int ts2phc_pps_sink_poll(struct ts2phc_private *priv) while (!all_sinks_have_events) { struct ts2phc_pps_sink *sink; - cnt = poll(polling_array->pfd, priv->n_sinks, 2000); + cnt = poll(polling_array->pfd, priv->n_sinks, 1500); + /* + * timeout =1.5 s ensures that every missing pulse is + * detected, even if the PHC is running a little + * bit slow, and that a slightly fast PHC causes + * no false alarms. + */ if (cnt < 0) { - if (errno == -EINTR) { + if (errno == EINTR) { + /* signal occurred */ + pr_err("poll interrupted"); return 0; } else { - pr_emerg("poll failed"); + pr_err("poll failed"); return -1; } else if (!cnt) { pr_debug("poll returns zero, no events"); - return 0; for (i = 0; i < priv->n_sinks; i++) { -- _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel