On Tue, Nov 23, 2021 at 02:14:21AM +0200, Vladimir Oltean wrote: > This API was introduced for 2 reasons: > > 1. Some hardware can emit PPS signals but not starting from arbitrary > absolute times, but rather just emit at a certain phase offset from > the beginning of each second. We _could_ patch ts2phc to always > specify a start time of 0.000000000 to PTP_PEROUT_REQUEST, and in > theory that should then become the kernel's responsibility to advance > that time in the past by an integer number of seconds while keeping > the phase untouched, but in practice, we would never know whether > that would actually work with all in-kernel PHC drivers, since it > wasn't enforced as a requirement before. So there was a need for a > new flag that only specifies the phase of the periodic signal, and > not the absolute start time. > > 2. Some hardware can, rather unfortunately, not distinguish between a > rising and a falling extts edge. And, since whatever rises also has > to fall before rising again, the strategy in ts2phc is to set a > 'large' pulse width (half the period) and ignore the extts event > corresponding to the mid-way between one second and another. This is > all fine, but currently, ts2phc.pulsewidth is a read-only property in > the config file. The kernel is not instructed in any way to use this > value, it is simply that must be configured based on prior knowledge > of the PHC's implementation. This API changes that. > > The introduction of a phase adjustment for the PHC kind of PPS sources > means we have to adjust our approximation of the precise perout
It is not an approximation. It is exact, but the correct association of event to ToD is implicit. > timestamp. We put that code into a common function and convert all call > sites to call that. We also need to do the same thing for the edge > ignoring logic. > > Signed-off-by: Vladimir Oltean <olte...@gmail.com> > --- > v4->v5: rebase on top of variable renames > v3->v4: patch is new. > > config.c | 1 + > missing.h | 52 +++++++++++++++++++++++++ > ts2phc.8 | 17 +++++++- > ts2phc.c | 86 +++++++++++++++++++++++++++-------------- > ts2phc.h | 1 + > ts2phc_phc_pps_source.c | 44 ++++++++++++++++++--- > ts2phc_pps_sink.c | 16 +++++++- > 7 files changed, 180 insertions(+), 37 deletions(-) > > diff --git a/config.c b/config.c > index f3c52baff765..760d0e12b0b6 100644 > --- a/config.c > +++ b/config.c > @@ -321,6 +321,7 @@ struct config_item config_tab[] = { > GLOB_ITEM_STR("ts2phc.nmea_remote_host", ""), > GLOB_ITEM_STR("ts2phc.nmea_remote_port", ""), > GLOB_ITEM_STR("ts2phc.nmea_serialport", "/dev/ttyS0"), > + PORT_ITEM_INT("ts2phc.perout_phase", -1, 0, 999999999), > PORT_ITEM_INT("ts2phc.pin_index", 0, 0, INT_MAX), > GLOB_ITEM_INT("ts2phc.pulsewidth", 500000000, 1000000, 999000000), > PORT_ITEM_ENU("tsproc_mode", TSPROC_FILTER, tsproc_enu), > diff --git a/missing.h b/missing.h > index 89cb51360ef7..7f06da3220f2 100644 > --- a/missing.h > +++ b/missing.h > @@ -97,6 +97,58 @@ struct compat_ptp_clock_caps { > > #endif /*LINUX_VERSION_CODE < 5.8*/ > > +/* > + * Bits of the ptp_perout_request.flags field: > + */ > + > +#ifndef PTP_PEROUT_ONE_SHOT > +#define PTP_PEROUT_ONE_SHOT (1<<0) > +#endif > + > +#ifndef PTP_PEROUT_DUTY_CYCLE > +#define PTP_PEROUT_DUTY_CYCLE (1<<1) > +#endif > + > +#ifndef PTP_PEROUT_PHASE > +#define PTP_PEROUT_PHASE (1<<2) > +#endif > + > +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0) > + > +struct compat_ptp_perout_request { > + union { > + /* > + * Absolute start time. > + * Valid only if (flags & PTP_PEROUT_PHASE) is unset. > + */ > + struct ptp_clock_time start; > + /* > + * Phase offset. The signal should start toggling at an > + * unspecified integer multiple of the period, plus this value. > + * The start time should be "as soon as possible". > + * Valid only if (flags & PTP_PEROUT_PHASE) is set. > + */ > + struct ptp_clock_time phase; > + }; > + struct ptp_clock_time period; /* Desired period, zero means disable. */ > + unsigned int index; /* Which channel to configure. */ > + unsigned int flags; > + union { > + /* > + * The "on" time of the signal. > + * Must be lower than the period. > + * Valid only if (flags & PTP_PEROUT_DUTY_CYCLE) is set. > + */ > + struct ptp_clock_time on; > + /* Reserved for future use. */ > + unsigned int rsv[4]; > + }; > +}; > + > +#define ptp_perout_request compat_ptp_perout_request > + > +#endif /* LINUX_VERSION_CODE < 5.9 */ > + > #ifndef PTP_MAX_SAMPLES > #define PTP_MAX_SAMPLES 25 /* Maximum allowed offset measurement samples. */ > #endif /* PTP_MAX_SAMPLES */ > diff --git a/ts2phc.8 b/ts2phc.8 > index 36d56cce0270..ded6f9ac8afb 100644 > --- a/ts2phc.8 > +++ b/ts2phc.8 > @@ -176,10 +176,23 @@ connection will be used in preference to the configured > serial port. > The default serial port is "/dev/ttyS0". > The default baudrate is 9600 bps. > .TP > +.B ts2phc.perout_phase > +Configures the offset between the beginning of the second and the PPS > +source's rising edge. Available only for the PHC kind of PPS source. The > supported > +range is 0 to 999999999 nanoseconds. The default is 0 nanoseconds, but > +leaving this option unspecified will not transmit the phase to the kernel, > +instead PPS will be requested to start at an absolute time equal to the > +nearest 2nd full second since the start of the program. This should yield > +the same effect, but may not work with drivers that do not support > +starting periodic output at an absolute time. > +.TP > .B ts2phc.pulsewidth > -The expected pulse width of the external PPS signal in nanoseconds. > +The pulse width of the external PPS signal in nanoseconds. > When 'ts2phc.extts_polarity' is "both", the given pulse width is used > -to detect and discard the time stamp of the unwanted edge. > +to detect and discard the time stamp of the unwanted edge. In case the PPS > +source is of the PHC kind, an attempt is made to request the kernel to > actually > +emit using this pulse width. If this fails, it is assumed that the specified > +pulse width is correct, and the value is used in the edge rejection > algorithm. > The supported range is 1000000 to 990000000 nanoseconds. > The default is 500000000 nanoseconds. > .TP > diff --git a/ts2phc.c b/ts2phc.c > index 25c8bb3a5fa6..de7445830dbb 100644 > --- a/ts2phc.c > +++ b/ts2phc.c > @@ -407,6 +407,40 @@ static void ts2phc_reconfigure(struct ts2phc_private > *priv) > pr_info("selecting %s as the reference clock", ref_clk->name); > } > > +static int ts2phc_approximate_pps_source_tstamp(struct ts2phc_private *priv, > + tmv_t *source_tmv) > +{ I really object to the word "approximate" here. Just call it ts2phc_pps_source_tstamp(); If you REALLY must, then call it ts2phc_implicit_pps_source_tstamp(); Thanks, Richard _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel