From 39722542b94dfb53a3dfd4882f0e7abd71eaae5b Mon Sep 17 00:00:00 2001 From: John Grossman Date: Thu, 13 Oct 2011 16:03:56 -0700 Subject: [PATCH] AAH: Fix PID gain for HW clock recovery. Before HW came in, when doing SW clock recovery, gain had been set to produce a correction expressed in PPM from [-100, 100] PPM. The HW local clock HAL has been spec'ed to take a drive range from MIN_INT_16 to MAX_INT_16. This changes the PID recovery loop to use a range from MIN_INT_16 to MAX_INT_16, and adjusts the P and I gains to be the same as they were before, but adjusted for the scale change. Change-Id: I531175e5fbb20b7ba6ee06f457c5f4ad12c123ff --- services/aah_timesrv/clock_recovery.cpp | 39 ++++++++++++++++--------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/services/aah_timesrv/clock_recovery.cpp b/services/aah_timesrv/clock_recovery.cpp index f7798848c6e66..12ce4302c0be9 100644 --- a/services/aah_timesrv/clock_recovery.cpp +++ b/services/aah_timesrv/clock_recovery.cpp @@ -240,7 +240,7 @@ bool ClockRecoveryLoop::pushDisciplineEvent(int64_t local_time, } LOGV("rtt %lld observed %lld nominal %lld delta = %5lld " - "int = %7d correction %3d (P %3d, I %3d, D %3d)\n", + "int = %7d correction %5d (P %5d, I %5d, D %5d)\n", filter_data_[min_rtt].rtt, observed_common, nominal_common_time, @@ -270,20 +270,20 @@ void ClockRecoveryLoop::computePIDParams() { // level in case they have a HW clock discipline solution with parameters // tuned specifically for it. - // Correction factor is limited to +/-100 PPM. - pid_params_.correction_min = -100; - pid_params_.correction_max = 100; + // Correction factor is limited to MIN/MAX_INT_16 + pid_params_.correction_min = -0x8000; + pid_params_.correction_max = 0x7FFF; - // Default proportional gain to 1:10. (1 PPM of correction for - // every 10 uSec of instantaneous error) + // Default proportional gain to 2^15:1000. (max proportional drive at 1mSec + // of instantaneous error) memset(&pid_params_.gain_P, 0, sizeof(pid_params_.gain_P)); - pid_params_.gain_P.a_to_b_numer = 1; - pid_params_.gain_P.a_to_b_denom = 10; + pid_params_.gain_P.a_to_b_numer = 0x8000; + pid_params_.gain_P.a_to_b_denom = 1000; - // Set the integral gain to 1:50 + // Set the integral gain to 2^15:5000 memset(&pid_params_.gain_I, 0, sizeof(pid_params_.gain_I)); - pid_params_.gain_I.a_to_b_numer = 1; - pid_params_.gain_I.a_to_b_denom = 50; + pid_params_.gain_I.a_to_b_numer = 0x8000; + pid_params_.gain_I.a_to_b_denom = 5000; // Default controller is just a PI controller. Right now, the network based // measurements of the error are way to noisy to feed into the differential @@ -352,10 +352,21 @@ int32_t ClockRecoveryLoop::doGainScale(const LinearTransform& gain, } void ClockRecoveryLoop::applySlew() { - if (local_clock_can_slew_) + if (local_clock_can_slew_) { local_clock_->setLocalSlew(correction_cur_); - else - common_clock_->setSlew(local_clock_->getLocalTime(), correction_cur_); + } else { + // The SW clock recovery implemented by the common clock class expects + // values expressed in PPM. Map the MIN/MAX_INT_16 drive range to +/- + // 100ppm. + int sw_correction; + sw_correction = correction_cur_ - pid_params_.correction_min; + sw_correction *= 200; + sw_correction /= (pid_params_.correction_max - + pid_params_.correction_min); + sw_correction -= 100; + + common_clock_->setSlew(local_clock_->getLocalTime(), sw_correction); + } } } // namespace android