diff --git a/phc2sys.8 b/phc2sys.8 index 8e03e81..d7a4569 100644 --- a/phc2sys.8 +++ b/phc2sys.8 @@ -19,6 +19,10 @@ phc2sys \- synchronize two clocks ] [ .BI \-I " ki" ] [ +.BI \-S " step" +] [ +.BI \-F " step" +] [ .BI \-R " update-rate" ] [ .BI \-N " clock-readings" @@ -87,8 +91,16 @@ Specify the integral constant of the PI controller. The default is 0.3. .BI \-S " step" Specify the step threshold of the PI controller. It is the maximum offset that the controller corrects by changing the clock frequency instead of stepping the -clock. The clock is always stepped on start. The value of 0.0 disables stepping -after the start. The default is 0.0. +clock. The clock is stepped on start regardless of the option if the offset is +larger than 100 nanoseconds (unless the +.BI \-F +option is used). The value of 0.0 disables stepping after the start. The default +is 0.0. +.TP +.BI \-F " step" +Specify the step threshold applied only on the first update. It is the maximum +offset that is corrected by adjusting clock. The value of 0.0 disables stepping +on start. The default is 0.0000001 (100 nanoseconds). .TP .BI \-R " update-rate" Specify the slave clock update rate when running in the direct synchronization diff --git a/phc2sys.c b/phc2sys.c index 594fc1e..8f9e18b 100644 --- a/phc2sys.c +++ b/phc2sys.c @@ -555,6 +555,7 @@ static void usage(char *progname) " -P [kp] proportional constant (0.7)\n" " -I [ki] integration constant (0.3)\n" " -S [step] step threshold (disabled)\n" + " -F [step] step threshold only on start (0.0000001)\n" " -R [rate] slave clock update rate in HZ (1.0)\n" " -N [num] number of master clock readings per update (5)\n" " -O [offset] slave-master time offset (0)\n" @@ -593,7 +594,7 @@ int main(int argc, char *argv[]) progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; while (EOF != (c = getopt(argc, argv, - "c:d:hs:P:I:S:R:N:O:i:u:wn:xl:mqv"))) { + "c:d:s:P:I:S:F:R:N:O:i:u:wn:xl:mqvh"))) { switch (c) { case 'c': dst_clock.clkid = clock_open(optarg); @@ -627,6 +628,11 @@ int main(int argc, char *argv[]) 0.0, DBL_MAX)) return -1; break; + case 'F': + if (get_arg_val_d(c, optarg, &configured_pi_f_offset, + 0.0, DBL_MAX)) + return -1; + break; case 'R': if (get_arg_val_d(c, optarg, &phc_rate, 0.0, DBL_MAX)) return -1; diff --git a/pi.c b/pi.c index 78cbd3f..89080c4 100644 --- a/pi.c +++ b/pi.c @@ -35,6 +35,7 @@ double configured_pi_kp = 0.0; double configured_pi_ki = 0.0; double configured_pi_offset = 0.0; +double configured_pi_f_offset = 0.0000001; /* 100 nanoseconds */ int configured_pi_max_freq = 900000000; struct pi_servo { @@ -46,7 +47,9 @@ struct pi_servo { double kp; double ki; double max_offset; + double max_f_offset; int count; + int first_update; }; static void pi_destroy(struct servo *servo) @@ -88,7 +91,14 @@ static double pi_sample(struct servo *servo, else if (s->drift > s->maxppb) s->drift = s->maxppb; - *state = SERVO_JUMP; + if (!s->first_update || + (s->max_f_offset && (s->max_f_offset < fabs(offset))) || + (s->max_offset && (s->max_offset < fabs(offset)))) + *state = SERVO_JUMP; + else + *state = SERVO_LOCKED; + + s->first_update = 0; ppb = s->drift; s->count = 2; break; @@ -134,6 +144,7 @@ struct servo *pi_servo_create(int fadj, int max_ppb, int sw_ts) s->servo.sample = pi_sample; s->drift = fadj; s->maxppb = max_ppb; + s->first_update = 1; if (configured_pi_kp && configured_pi_ki) { s->kp = configured_pi_kp; @@ -152,6 +163,12 @@ struct servo *pi_servo_create(int fadj, int max_ppb, int sw_ts) s->max_offset = 0.0; } + if (configured_pi_f_offset > 0.0) { + s->max_f_offset = configured_pi_f_offset * NSEC_PER_SEC; + } else { + s->max_f_offset = 0.0; + } + if (configured_pi_max_freq && s->maxppb > configured_pi_max_freq) { s->maxppb = configured_pi_max_freq; } diff --git a/pi.h b/pi.h index 954f495..2f31bce 100644 --- a/pi.h +++ b/pi.h @@ -36,12 +36,21 @@ extern double configured_pi_ki; /** * When set to a non-zero value, this variable controls the maximum allowed * offset before a clock jump occurs instead of the default clock-slewing - * mechanism + * mechanism. * * Note that this variable is measured in seconds, and allows fractional values. */ extern double configured_pi_offset; +/** + * When set to zero, the clock is not stepped on start. When set to a non-zero + * value, the value bahaves as a threshold and the clock is stepped on start if + * the offset is bigger than the threshold. + * + * Note that this variable is measured in seconds, and allows fractional values. + */ +extern double configured_pi_f_offset; + /** * When set to a non-zero value, this variable sets an additional limit for * the frequency adjustment of the clock. It's in ppb.