int
HCL_ProcessReadings(HCL_Instance clock, int n_readings, struct timespec tss[][3],
- struct timespec *hw_ts, struct timespec *local_ts, double *err)
+ struct timespec *hw_ts, struct timespec *local_ts, double *err,
+ int *quality)
{
double delay, raw_delay, min_delay, low_delay, high_delay, e, pred_err;
double delay_sum, hw_sum, local_sum, local_prec, freq;
UTI_AddDoubleToTimespec(&tss[0][1], hw_sum / combined, hw_ts);
UTI_AddDoubleToTimespec(&tss[0][0], local_sum / combined, local_ts);
*err = MAX(delay_sum / combined / 2.0, clock->precision);
+ *quality = 2;
return 1;
}
- /* Accept the reading with minimum delay if its interval does not contain
- the current offset predicted from previous samples */
+ /* Indicate acceptable quality of the reading with minimum delay if its
+ interval does not contain the current offset predicted from previous
+ samples, or a new sample is needed to get the tracking working */
*hw_ts = tss[min_reading][1];
UTI_AddDoubleToTimespec(&tss[min_reading][0], min_delay / freq / 2.0, local_ts);
LCL_CookTime(local_ts, &ts1, NULL);
if (!HCL_CookTime(clock, hw_ts, &ts2, &e) ||
((pred_err = UTI_DiffTimespecsToDouble(&ts1, &ts2)) > *err)) {
- DEBUG_LOG("Accepted reading err=%e prerr=%e", *err, pred_err);
- return 1;
+ *quality = 1;
+ } else {
+ *quality = 0;
}
- return 0;
+ DEBUG_LOG("Min-delay reading err=%e prerr=%e ql=%d", *err, pred_err, *quality);
+
+ return 1;
}
/* ================================================== */
/* Check if a new sample should be accumulated at this time */
extern int HCL_NeedsNewSample(HCL_Instance clock, struct timespec *now);
-/* Process new readings of the HW clock in form of (sys, hw, sys) triplets and
- produce a sample which can be accumulated */
+/* Process new readings of the HW clock in the form of (sys, hw, sys) triplets
+ and produce a sample which can be accumulated by HCL_AccumulateSample().
+ Indicate the quality of the sample relative to already processed samples as
+ a value of 0, 1, or 2, where a sample of quality 0 should normally be
+ dropped. */
extern int HCL_ProcessReadings(HCL_Instance clock, int n_readings, struct timespec tss[][3],
- struct timespec *hw_ts, struct timespec *local_ts, double *err);
+ struct timespec *hw_ts, struct timespec *local_ts, double *err,
+ int *quality);
/* Accumulate a new sample */
extern void HCL_AccumulateSample(HCL_Instance clock, struct timespec *hw_ts,
struct timespec sample_phc_ts, sample_sys_ts, sample_local_ts;
struct timespec phc_readings[PHC_READINGS][3];
double phc_err, local_err, interval;
- int n_readings;
+ int n_readings, quality;
if (!HCL_NeedsNewSample(iface->clock, now))
return;
return;
if (!HCL_ProcessReadings(iface->clock, n_readings, phc_readings,
- &sample_phc_ts, &sample_sys_ts, &phc_err))
+ &sample_phc_ts, &sample_sys_ts, &phc_err, &quality) ||
+ quality <= 0)
return;
LCL_CookTime(&sample_sys_ts, &sample_local_ts, &local_err);
struct timespec phc_ts, sys_ts, local_ts, readings[PHC_READINGS][3];
struct phc_instance *phc;
double phc_err, local_err;
- int n_readings;
+ int n_readings, quality;
phc = (struct phc_instance *)RCL_GetDriverData(instance);
if (!phc->extpps)
RCL_UpdateReachability(instance);
- if (!HCL_ProcessReadings(phc->clock, n_readings, readings, &phc_ts, &sys_ts, &phc_err))
+ if (!HCL_ProcessReadings(phc->clock, n_readings, readings,
+ &phc_ts, &sys_ts, &phc_err, &quality))
return 0;
LCL_CookTime(&sys_ts, &local_ts, &local_err);
- HCL_AccumulateSample(phc->clock, &phc_ts, &local_ts, phc_err + local_err);
+ if (quality > 0)
+ HCL_AccumulateSample(phc->clock, &phc_ts, &local_ts, phc_err + local_err);
if (phc->extpps)
return 0;
+ if (quality <= 0)
+ return 0;
+
DEBUG_LOG("PHC offset: %+.9f err: %.9f",
UTI_DiffTimespecsToDouble(&phc_ts, &sys_ts), phc_err);
{
struct timespec start_hw_ts, start_local_ts, hw_ts, local_ts, ts;
struct timespec readings[MAX_READINGS][3];
+ int i, j, k, l, new_sample, n_readings, count, quality;
HCL_Instance clock;
double freq, jitter, interval, dj, err, sum;
- int i, j, k, l, new_sample, n_readings, count;
LCL_Initialise();
TST_RegisterDummyDrivers();
UTI_ZeroTimespec(&hw_ts);
UTI_ZeroTimespec(&local_ts);
- if (HCL_ProcessReadings(clock, n_readings, readings, &hw_ts, &local_ts, &err)) {
- HCL_AccumulateSample(clock, &hw_ts, &local_ts, 2.0 * jitter);
- new_sample = 1;
- } else {
- new_sample = 0;
+ new_sample = 0;
+ if (HCL_ProcessReadings(clock, n_readings, readings, &hw_ts, &local_ts, &err, &quality)) {
+ TEST_CHECK(quality >= 0 && quality <= 2);
+ if (quality > 0) {
+ HCL_AccumulateSample(clock, &hw_ts, &local_ts, 2.0 * jitter);
+ new_sample = 1;
+ }
}
}