Commit 5e2d1b36 authored by Cesar Prados's avatar Cesar Prados Committed by Alessandro Rubini

pdelay/servo: breakdown of pp_servo_got_resp into pices

the function can be broken down into common
functions that pdelay will use as well.
First step, the filtering of the mean path
delay.
Signed-off-by: Cesar Prados's avatarC.Prados <c.prados@gsi.de>
parent 9a4e0653
......@@ -378,6 +378,8 @@ extern void pp_servo_init(struct pp_instance *ppi);
extern void pp_servo_got_sync(struct pp_instance *ppi); /* got t1 and t2 */
extern void pp_servo_got_resp(struct pp_instance *ppi); /* got all t1..t4 */
extern void pp_servo_mpd_fltr(struct pp_instance *ppi,
struct pp_avg_fltr *mpd_fltr, TimeInternal * mpd);
/* bmc.c */
extern void m1(struct pp_instance *ppi);
......
......@@ -109,7 +109,6 @@ void pp_servo_got_resp(struct pp_instance *ppi)
int I_sign;
int P_sign;
Integer32 adj;
int s;
/* We sometimes enter here before we got sync/f-up */
......@@ -142,55 +141,8 @@ void pp_servo_got_resp(struct pp_instance *ppi)
if (pp_servo_bad_event(ppi))
return;
if (mpd_fltr->s_exp < 1) {
/* First time, keep what we have */
mpd_fltr->y = mpd->nanoseconds;
}
/* avoid overflowing filter */
s = OPTS(ppi)->s;
while (abs(mpd_fltr->y) >> (31 - s))
--s;
if (mpd_fltr->s_exp > 1 << s)
mpd_fltr->s_exp = 1 << s;
/* crank down filter cutoff by increasing 's_exp' */
if (mpd_fltr->s_exp < 1 << s)
++mpd_fltr->s_exp;
/*
* It may happen that mpd appears as negative. This happens when
* the slave clock is running fast to recover a late time: the
* (t3 - t2) measured in the slave appears longer than the (t4 - t1)
* measured in the master. Ignore such values, by keeping the
* current average instead.
*/
if (mpd->nanoseconds < 0)
mpd->nanoseconds = mpd_fltr->y;
if (mpd->nanoseconds < 0)
mpd->nanoseconds = 0;
/*
* It may happen that mpd appears to be very big. This happens
* when we have software timestamps and there is overhead
* involved -- or when the slave clock is running slow. In
* this case use a value just slightly bigger than the current
* average (so if it really got longer, we will adapt). This
* kills most outliers on loaded networks.
* The constant multipliers have been chosed arbitrarily, but
* they work well in testing environment.
*/
if (mpd->nanoseconds > 3 * mpd_fltr->y) {
pp_diag(ppi, servo, 1, "Trim too-long mpd: %i\n",
mpd->nanoseconds);
/* add fltr->s_exp to ensure we are not trapped into 0 */
mpd->nanoseconds = mpd_fltr->y * 2 + mpd_fltr->s_exp + 1;
}
/* filter 'meanPathDelay' (running average) */
mpd_fltr->y = (mpd_fltr->y * (mpd_fltr->s_exp - 1) + mpd->nanoseconds)
/ mpd_fltr->s_exp;
mpd->nanoseconds = mpd_fltr->y;
pp_diag(ppi, servo, 1, "After avg(%i), meanPathDelay: %i\n",
(int)mpd_fltr->s_exp, mpd->nanoseconds);
/* mean path delay filtering */
pp_servo_mpd_fltr(ppi, mpd_fltr, mpd);
/* update 'offsetFromMaster', (End to End mode) */
sub_TimeInternal(ofm, m_to_s_dly, mpd);
......@@ -294,3 +246,59 @@ void pp_servo_got_resp(struct pp_instance *ppi)
pp_diag(ppi, servo, 2, "Observed drift: %9i\n",
(int)SRV(ppi)->obs_drift >> 10);
}
void pp_servo_mpd_fltr(struct pp_instance *ppi, struct pp_avg_fltr *mpd_fltr,
TimeInternal * mpd)
{
int s;
if (mpd_fltr->s_exp < 1) {
/* First time, keep what we have */
mpd_fltr->y = mpd->nanoseconds;
}
/* avoid overflowing filter */
s = OPTS(ppi)->s;
while (abs(mpd_fltr->y) >> (31 - s))
--s;
if (mpd_fltr->s_exp > 1 << s)
mpd_fltr->s_exp = 1 << s;
/* crank down filter cutoff by increasing 's_exp' */
if (mpd_fltr->s_exp < 1 << s)
++mpd_fltr->s_exp;
/*
* It may happen that mpd appears as negative. This happens when
* the slave clock is running fast to recover a late time: the
* (t3 - t2) measured in the slave appears longer than the (t4 - t1)
* measured in the master. Ignore such values, by keeping the
* current average instead.
*/
if (mpd->nanoseconds < 0)
mpd->nanoseconds = mpd_fltr->y;
if (mpd->nanoseconds < 0)
mpd->nanoseconds = 0;
/*
* It may happen that mpd appears to be very big. This happens
* when we have software timestamps and there is overhead
* involved -- or when the slave clock is running slow. In
* this case use a value just slightly bigger than the current
* average (so if it really got longer, we will adapt). This
* kills most outliers on loaded networks.
* The constant multipliers have been chosed arbitrarily, but
* they work well in testing environment.
*/
if (mpd->nanoseconds > 3 * mpd_fltr->y) {
pp_diag(ppi, servo, 1, "Trim too-long mpd: %i\n",
mpd->nanoseconds);
/* add fltr->s_exp to ensure we are not trapped into 0 */
mpd->nanoseconds = mpd_fltr->y * 2 + mpd_fltr->s_exp + 1;
}
/* filter 'meanPathDelay' (running average) */
mpd_fltr->y = (mpd_fltr->y * (mpd_fltr->s_exp - 1) + mpd->nanoseconds)
/ mpd_fltr->s_exp;
mpd->nanoseconds = mpd_fltr->y;
pp_diag(ppi, servo, 1, "After avg(%i), meanPathDelay: %i\n",
(int)mpd_fltr->s_exp, mpd->nanoseconds);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment