summaryrefslogtreecommitdiff
path: root/gnuradio-core/src
diff options
context:
space:
mode:
authorTom Rondeau2009-10-12 17:55:17 -0400
committerTom Rondeau2009-10-12 17:55:17 -0400
commitc1ab962946bb05b8a20a0f19dd294eb3b3056142 (patch)
tree83e609752d3d522ef01b75f795a0b22548bad905 /gnuradio-core/src
parent2b60291c2883dbd3b85c6f694d830fa3ccf0a6e6 (diff)
downloadgnuradio-c1ab962946bb05b8a20a0f19dd294eb3b3056142.tar.gz
gnuradio-c1ab962946bb05b8a20a0f19dd294eb3b3056142.tar.bz2
gnuradio-c1ab962946bb05b8a20a0f19dd294eb3b3056142.zip
This splits the rate into a fractional an integer value, which allows the loop to adjust the fractional rate while the integer rate keeps the increments moving properly. Allows the max rate deviation to be independent of the integer rate. Scaling of the differential taps also allows alpha and beta to operate independent of the rate when fractional samples per symbol are used. Slightly more tolerant to large signal values, but they still should be close to +/-1.
Diffstat (limited to 'gnuradio-core/src')
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc20
-rw-r--r--gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h2
2 files changed, 18 insertions, 4 deletions
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
index 43412f25b..433b7d613 100644
--- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc
@@ -68,6 +68,8 @@ gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float gain,
set_beta(0.25*gain*gain);
d_k = init_phase;
d_rate = (sps-floor(sps))*(double)d_nfilters;
+ d_rate_i = (int)floor(d_rate);
+ d_rate_f = d_rate - (float)d_rate_i;
d_filtnum = (int)floor(d_k);
d_filters = std::vector<gr_fir_ccf*>(d_nfilters);
@@ -137,13 +139,23 @@ void
gr_pfb_clock_sync_ccf::create_diff_taps(const std::vector<float> &newtaps,
std::vector<float> &difftaps)
{
+ float maxtap = 1e-20;
difftaps.clear();
difftaps.push_back(0); //newtaps[0]);
for(unsigned int i = 1; i < newtaps.size()-1; i++) {
float tap = newtaps[i+1] - newtaps[i-1];
difftaps.push_back(tap);
+ if(tap > maxtap) {
+ maxtap = tap;
+ }
}
difftaps.push_back(0);//-newtaps[newtaps.size()-1]);
+
+ // Scale the differential taps; helps scale error term to better update state
+ // FIXME: should this be scaled this way or use the same gain as the taps?
+ for(unsigned int i = 0; i < difftaps.size(); i++) {
+ difftaps[i] /= maxtap;
+ }
}
void
@@ -250,18 +262,18 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items,
error = (error_i + error_r) / 2.0; // average error from I&Q channel
// Run the control loop to update the current phase (k) and tracking rate
- d_k = d_k + d_alpha*error + d_rate;
- d_rate = d_rate + d_beta*error;
+ d_k = d_k + d_alpha*error + d_rate_i + d_rate_f;
+ d_rate_f = d_rate_f + d_beta*error;
// Keep our rate within a good range
- d_rate = gr_branchless_clip(d_rate, d_max_dev);
+ d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev);
i++;
count += (int)floor(d_sps);
if(output_items.size() > 2) {
err[i] = error;
- outrate[i] = d_rate;
+ outrate[i] = d_rate_f;
outk[i] = d_k;
}
}
diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
index 778db59e5..a07192a7f 100644
--- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
+++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h
@@ -69,6 +69,8 @@ class gr_pfb_clock_sync_ccf : public gr_block
std::vector< std::vector<float> > d_dtaps;
float d_k;
float d_rate;
+ float d_rate_i;
+ float d_rate_f;
float d_max_dev;
int d_filtnum;
int d_taps_per_filter;