summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gr-digital/lib/clock_tracking_loop.cc12
-rw-r--r--gr-digital/lib/clock_tracking_loop.h8
-rw-r--r--gr-digital/lib/symbol_sync_cc_impl.cc1
-rw-r--r--gr-digital/lib/symbol_sync_ff_impl.cc1
4 files changed, 16 insertions, 6 deletions
diff --git a/gr-digital/lib/clock_tracking_loop.cc b/gr-digital/lib/clock_tracking_loop.cc
index 0eaa8f29cf..ed8b3efe05 100644
--- a/gr-digital/lib/clock_tracking_loop.cc
+++ b/gr-digital/lib/clock_tracking_loop.cc
@@ -126,8 +126,20 @@ namespace gr {
// Integral arm of PI filter
d_avg_period = d_avg_period + d_beta * error;
+ // Limit the integral arm output here, as a large negative
+ // error input can lead to a negative d_avg_period, which
+ // will cause an infitine loop in the phase wrap method.
+ period_limit();
+
// Proportional arm of PI filter and final sum of PI filter arms
d_inst_period = d_avg_period + d_alpha * error;
+ // Limit the filter output here, for the errant case of a large
+ // negative error input, that can lead to a negative d_inst_period,
+ // which results in an incorrect phase increment, as it is assumed
+ // to be moving forward to the next symbol.
+ if (d_inst_period <= 0.f)
+ d_inst_period = d_avg_period;
+
// Compute the new, unwrapped clock phase
d_phase = d_phase + d_inst_period;
}
diff --git a/gr-digital/lib/clock_tracking_loop.h b/gr-digital/lib/clock_tracking_loop.h
index bc4aee1e6a..e8f0fe7989 100644
--- a/gr-digital/lib/clock_tracking_loop.h
+++ b/gr-digital/lib/clock_tracking_loop.h
@@ -415,12 +415,12 @@ namespace gr {
* integrator portion of an IIR filter, so T_avg could potentially
* wander very far during periods of noise/nonsense input.
*
- * This function should be called after advance_loop to keep the
+ * This function is called in advance_loop to keep the
* estimated average clock period, T_avg, in the specified range.
- * It is set as a separate method in case another way is desired as
- * this is fairly heavy-handed.
+ * It is set as a separate virtual method in case another way is desired
+ * as this is fairly heavy-handed.
*/
- void period_limit();
+ virtual void period_limit();
/*******************************************************************
* SET FUNCTIONS
diff --git a/gr-digital/lib/symbol_sync_cc_impl.cc b/gr-digital/lib/symbol_sync_cc_impl.cc
index e00edeeeb8..c9e44c708b 100644
--- a/gr-digital/lib/symbol_sync_cc_impl.cc
+++ b/gr-digital/lib/symbol_sync_cc_impl.cc
@@ -538,7 +538,6 @@ namespace gr {
d_inst_clock_period = d_clock->get_inst_period();
d_avg_clock_period = d_clock->get_avg_period();
d_clock->phase_wrap();
- d_clock->period_limit();
// Symbol Clock and Interpolator Positioning & Alignment
d_inst_interp_period = d_inst_clock_period / d_interps_per_symbol;
diff --git a/gr-digital/lib/symbol_sync_ff_impl.cc b/gr-digital/lib/symbol_sync_ff_impl.cc
index 180204f77e..da14f05282 100644
--- a/gr-digital/lib/symbol_sync_ff_impl.cc
+++ b/gr-digital/lib/symbol_sync_ff_impl.cc
@@ -538,7 +538,6 @@ namespace gr {
d_inst_clock_period = d_clock->get_inst_period();
d_avg_clock_period = d_clock->get_avg_period();
d_clock->phase_wrap();
- d_clock->period_limit();
// Symbol Clock and Interpolator Positioning & Alignment
d_inst_interp_period = d_inst_clock_period / d_interps_per_symbol;