1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef __CLOCK_RECOVERY_H__ 18#define __CLOCK_RECOVERY_H__ 19 20#include <stdint.h> 21#include <common_time/ICommonClock.h> 22#include <utils/LinearTransform.h> 23#include <utils/threads.h> 24 25#ifdef TIME_SERVICE_DEBUG 26#include "diag_thread.h" 27#endif 28 29namespace android { 30 31class CommonClock; 32class LocalClock; 33 34class ClockRecoveryLoop { 35 public: 36 ClockRecoveryLoop(LocalClock* local_clock, CommonClock* common_clock); 37 ~ClockRecoveryLoop(); 38 39 void reset(bool position, bool frequency); 40 bool pushDisciplineEvent(int64_t local_time, 41 int64_t nominal_common_time, 42 int64_t data_point_rtt); 43 int32_t getLastErrorEstimate(); 44 45 private: 46 47 // Tuned using the "Good Gain" method. 48 // See: 49 // http://techteach.no/publications/books/dynamics_and_control/tuning_pid_controller.pdf 50 51 // Controller period (1Hz for now). 52 static const float dT; 53 54 // Controller gain, positive and unitless. Larger values converge faster, 55 // but can cause instability. 56 static const float Kc; 57 58 // Integral reset time. Smaller values cause loop to track faster, but can 59 // also cause instability. 60 static const float Ti; 61 62 // Controller output filter time constant. Range (0-1). Smaller values make 63 // output smoother, but slow convergence. 64 static const float Tf; 65 66 // Low-pass filter for bias tracker. 67 static const float bias_Fc; // HZ 68 static const float bias_RC; // Computed in constructor. 69 static const float bias_Alpha; // Computed inconstructor. 70 71 // The maximum allowed error (as indicated by a pushDisciplineEvent) before 72 // we panic. 73 static const int64_t panic_thresh_; 74 75 // The maximum allowed error rtt time for packets to be used for control 76 // feedback, unless the packet is the best in recent memory. 77 static const int64_t control_thresh_; 78 79 typedef struct { 80 int64_t local_time; 81 int64_t observed_common_time; 82 int64_t nominal_common_time; 83 int64_t rtt; 84 bool point_used; 85 } DisciplineDataPoint; 86 87 static uint32_t findMinRTTNdx(DisciplineDataPoint* data, uint32_t count); 88 89 void reset_l(bool position, bool frequency); 90 void applySlew(); 91 92 // The local clock HW abstraction we use as the basis for common time. 93 LocalClock* local_clock_; 94 bool local_clock_can_slew_; 95 96 // The common clock we end up controlling along with the lock used to 97 // serialize operations. 98 CommonClock* common_clock_; 99 Mutex lock_; 100 101 // parameters maintained while running and reset during a reset 102 // of the frequency correction. 103 bool last_delta_valid_; 104 int32_t last_delta_; 105 float last_delta_f_; 106 int32_t integrated_error_; 107 int32_t correction_cur_; 108 109 // Contoller Output. 110 float CO; 111 112 // Bias tracking for trajectory estimation. 113 float CObias; 114 float lastCObias; 115 116 // Controller output bounds. The controller will not try to 117 // slew faster that +/-100ppm offset from center per interation. 118 static const float COmin; 119 static const float COmax; 120 121 // State kept for filtering the discipline data. 122 static const uint32_t kFilterSize = 16; 123 DisciplineDataPoint filter_data_[kFilterSize]; 124 uint32_t filter_wr_; 125 bool filter_full_; 126 127 static const uint32_t kStartupFilterSize = 4; 128 DisciplineDataPoint startup_filter_data_[kStartupFilterSize]; 129 uint32_t startup_filter_wr_; 130 131#ifdef TIME_SERVICE_DEBUG 132 sp<DiagThread> diag_thread_; 133#endif 134}; 135 136} // namespace android 137 138#endif // __CLOCK_RECOVERY_H__ 139