diff options
Diffstat (limited to 'gr-digital/lib/digital_costas_loop_cc.cc')
-rw-r--r-- | gr-digital/lib/digital_costas_loop_cc.cc | 138 |
1 files changed, 121 insertions, 17 deletions
diff --git a/gr-digital/lib/digital_costas_loop_cc.cc b/gr-digital/lib/digital_costas_loop_cc.cc index 5d98bde4c4..be914486f2 100644 --- a/gr-digital/lib/digital_costas_loop_cc.cc +++ b/gr-digital/lib/digital_costas_loop_cc.cc @@ -33,28 +33,29 @@ #define M_TWOPI (2*M_PI) digital_costas_loop_cc_sptr -digital_make_costas_loop_cc (float damping, float nat_freq, - int order +digital_make_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument) { - return gnuradio::get_initial_sptr(new digital_costas_loop_cc (damping, - nat_freq, - order)); + return gnuradio::get_initial_sptr(new digital_costas_loop_cc + (loop_bw, order)); } -digital_costas_loop_cc::digital_costas_loop_cc (float damping, float nat_freq, - int order +digital_costas_loop_cc::digital_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument) : gr_sync_block ("costas_loop_cc", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature2 (1, 2, sizeof (gr_complex), sizeof(float))), - d_max_freq(1.0), d_min_freq(-1.0), d_phase(0), d_freq(0.0), - d_nat_freq(nat_freq), d_damping(damping), + d_max_freq(1.0), d_min_freq(-1.0), + d_loop_bw(loop_bw), d_order(order), d_phase_detector(NULL) { - // initialize gains from the natural freq and damping factors - update_gains(); + // Set the damping factor for a critically damped system + d_damping = sqrtf(2.0f)/2.0f; + + // Set the bandwidth, which will then call update_gains() + set_loop_bandwidth(loop_bw); + // Set up the phase detector to use based on the constellation order switch(d_order) { case 2: d_phase_detector = &digital_costas_loop_cc::phase_detector_2; @@ -72,6 +73,10 @@ digital_costas_loop_cc::digital_costas_loop_cc (float damping, float nat_freq, throw std::invalid_argument("order must be 2, 4, or 8"); break; } + + // Initialize loop values + d_freq = 0; + d_phase = 0; } float @@ -115,25 +120,124 @@ digital_costas_loop_cc::phase_detector_2(gr_complex sample) const return (sample.real()*sample.imag()); } +/******************************************************************* + SET FUNCTIONS +*******************************************************************/ + void -digital_costas_loop_cc::set_natural_freq(float w) +digital_costas_loop_cc::set_loop_bandwidth(float bw) { - d_nat_freq = w; + if(bw < 0) { + throw std::out_of_range ("digital_costas_loop_cc: invalid bandwidth. Must be >= 0."); + } + + d_loop_bw = bw; update_gains(); } void -digital_costas_loop_cc::set_damping_factor(float eta) +digital_costas_loop_cc::set_damping_factor(float df) { - d_damping = eta; + if(df < 0 || df > 1.0) { + throw std::out_of_range ("digital_costas_loop_cc: invalid damping factor. Must be in [0,1]."); + } + + d_damping = df; update_gains(); } void +digital_costas_loop_cc::set_alpha(float alpha) +{ + if(alpha < 0 || alpha > 1.0) { + throw std::out_of_range ("digital_costas_loop_cc: invalid alpha. Must be in [0,1]."); + } + d_alpha = alpha; +} + +void +digital_costas_loop_cc::set_beta(float beta) +{ + if(beta < 0 || beta > 1.0) { + throw std::out_of_range ("digital_costas_loop_cc: invalid beta. Must be in [0,1]."); + } + d_beta = beta; +} + +void +digital_costas_loop_cc::set_frequency(float freq) +{ + if(freq > d_max_freq) + d_freq = d_min_freq; + else if(freq < d_min_freq) + d_freq = d_max_freq; + else + d_freq = freq; +} + +void +digital_costas_loop_cc::set_phase(float phase) +{ + d_phase = phase; + while(d_phase>M_TWOPI) + d_phase -= M_TWOPI; + while(d_phase<-M_TWOPI) + d_phase += M_TWOPI; +} + + +/******************************************************************* + GET FUNCTIONS +*******************************************************************/ + + +float +digital_costas_loop_cc::get_loop_bandwidth() const +{ + return d_loop_bw; +} + +float +digital_costas_loop_cc::get_damping_factor() const +{ + return d_damping; +} + +float +digital_costas_loop_cc::get_alpha() const +{ + return d_alpha; +} + +float +digital_costas_loop_cc::get_beta() const +{ + return d_beta; +} + +float +digital_costas_loop_cc::get_frequency() const +{ + return d_freq; +} + +float +digital_costas_loop_cc::get_phase() const +{ + return d_phase; +} + + +/******************************************************************* +*******************************************************************/ + + +void digital_costas_loop_cc::update_gains() { - d_beta = d_nat_freq*d_nat_freq; - d_alpha = 2*d_damping*d_nat_freq; + float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw); + d_alpha = (4*d_damping*d_loop_bw) / denom; + d_beta = (4*d_loop_bw*d_loop_bw) / denom; } int |