diff options
-rw-r--r-- | gr-digital/lib/digital_costas_loop_cc.cc | 167 | ||||
-rw-r--r-- | gr-digital/lib/digital_costas_loop_cc.h | 143 | ||||
-rw-r--r-- | gr-digital/swig/digital_costas_loop_cc.i | 18 | ||||
-rw-r--r-- | gr-digital/swig/digital_swig.i | 2 |
4 files changed, 13 insertions, 317 deletions
diff --git a/gr-digital/lib/digital_costas_loop_cc.cc b/gr-digital/lib/digital_costas_loop_cc.cc index af9e20ac83..370dc7e5c1 100644 --- a/gr-digital/lib/digital_costas_loop_cc.cc +++ b/gr-digital/lib/digital_costas_loop_cc.cc @@ -30,8 +30,6 @@ #include <gr_sincos.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) - digital_costas_loop_cc_sptr digital_make_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument) @@ -45,15 +43,9 @@ digital_costas_loop_cc::digital_costas_loop_cc (float loop_bw, int order : 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), + gri_control_loop(loop_bw, 1.0, -1.0), d_order(order), d_phase_detector(NULL) { - // 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: @@ -72,10 +64,6 @@ digital_costas_loop_cc::digital_costas_loop_cc (float loop_bw, int order throw std::invalid_argument("order must be 2, 4, or 8"); break; } - - // Initialize loop values - d_freq = 0; - d_phase = 0; } float @@ -119,126 +107,6 @@ digital_costas_loop_cc::phase_detector_2(gr_complex sample) const return (sample.real()*sample.imag()); } -/******************************************************************* - SET FUNCTIONS -*******************************************************************/ - -void -digital_costas_loop_cc::set_loop_bandwidth(float bw) -{ - 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 df) -{ - 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() -{ - 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 digital_costas_loop_cc::work (int noutput_items, gr_vector_const_void_star &input_items, @@ -262,18 +130,9 @@ digital_costas_loop_cc::work (int noutput_items, error = (*this.*d_phase_detector)(optr[i]); error = gr_branchless_clip(error, 1.0); - d_freq = d_freq + d_beta * error; - d_phase = d_phase + d_freq + d_alpha * error; - - while(d_phase>M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase<-M_TWOPI) - d_phase += M_TWOPI; - - if (d_freq > d_max_freq) - d_freq = d_min_freq; - else if (d_freq < d_min_freq) - d_freq = d_max_freq; + advance_loop(error); + phase_wrap(); + frequency_limit(); foptr[i] = d_freq; } @@ -284,20 +143,10 @@ digital_costas_loop_cc::work (int noutput_items, error = (*this.*d_phase_detector)(optr[i]); error = gr_branchless_clip(error, 1.0); - - d_freq = d_freq + d_beta * error; - d_phase = d_phase + d_freq + d_alpha * error; - - while(d_phase>M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase<-M_TWOPI) - d_phase += M_TWOPI; - - if (d_freq > d_max_freq) - d_freq = d_min_freq; - else if (d_freq < d_min_freq) - d_freq = d_max_freq; - + + advance_loop(error); + phase_wrap(); + frequency_limit(); } } return noutput_items; diff --git a/gr-digital/lib/digital_costas_loop_cc.h b/gr-digital/lib/digital_costas_loop_cc.h index 83edded194..7b2cd6dad7 100644 --- a/gr-digital/lib/digital_costas_loop_cc.h +++ b/gr-digital/lib/digital_costas_loop_cc.h @@ -25,6 +25,7 @@ #define INCLUDED_DIGITAL_COSTAS_LOOP_CC_H #include <gr_sync_block.h> +#include <gri_control_loop.h> #include <stdexcept> #include <fstream> @@ -72,36 +73,17 @@ digital_make_costas_loop_cc (float loop_bw, int order * * \p order must be 2 or 4. */ -class digital_costas_loop_cc : public gr_sync_block +class digital_costas_loop_cc : public gr_sync_block, public gri_control_loop { friend digital_costas_loop_cc_sptr digital_make_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument); - float d_max_freq; - float d_min_freq; int d_order; - float d_loop_bw; - float d_damping; - float d_alpha; - float d_beta; - - float d_phase; - float d_freq; - digital_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument); - /*! \brief update the system gains from the loop bandwidth and damping factor - * - * This function updates the system gains based on the loop - * bandwidth and damping factor of the system. - * These two factors can be set separately through their own - * set functions. - */ - void update_gains(); - /*! \brief the phase detector circuit for 8th-order PSK loops * \param sample complex sample * \return the phase error @@ -125,127 +107,6 @@ class digital_costas_loop_cc : public gr_sync_block public: - /******************************************************************* - SET FUNCTIONS - *******************************************************************/ - - /*! - * \brief Set the loop bandwidth - * - * Set the loop filter's bandwidth to \p bw. This should be between - * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive - * number. - * - * When a new damping factor is set, the gains, alpha and beta, of the loop - * are recalculated by a call to update_gains(). - * - * \param bw (float) new bandwidth - * - */ - void set_loop_bandwidth(float bw); - - /*! - * \brief Set the loop damping factor - * - * Set the loop filter's damping factor to \p df. The damping factor - * should be sqrt(2)/2.0 for critically damped systems. - * Set it to anything else only if you know what you are doing. It must - * be a number between 0 and 1. - * - * When a new damping factor is set, the gains, alpha and beta, of the loop - * are recalculated by a call to update_gains(). - * - * \param df (float) new damping factor - * - */ - void set_damping_factor(float df); - - /*! - * \brief Set the loop gain alpha - * - * Set's the loop filter's alpha gain parameter. - * - * This value should really only be set by adjusting the loop bandwidth - * and damping factor. - * - * \param alpha (float) new alpha gain - * - */ - void set_alpha(float alpha); - - /*! - * \brief Set the loop gain beta - * - * Set's the loop filter's beta gain parameter. - * - * This value should really only be set by adjusting the loop bandwidth - * and damping factor. - * - * \param beta (float) new beta gain - * - */ - void set_beta(float beta); - - /*! - * \brief Set the Costas loop's frequency. - * - * Set's the Costas Loop's frequency. While this is normally updated by the - * inner loop of the algorithm, it could be useful to manually initialize, - * set, or reset this under certain circumstances. - * - * \param freq (float) new frequency - * - */ - void set_frequency(float freq); - - /*! - * \brief Set the Costas loop's phase. - * - * Set's the Costas Loop's phase. While this is normally updated by the - * inner loop of the algorithm, it could be useful to manually initialize, - * set, or reset this under certain circumstances. - * - * \param phase (float) new phase - * - */ - void set_phase(float phase); - - - /******************************************************************* - GET FUNCTIONS - *******************************************************************/ - - /*! - * \brief Returns the loop bandwidth - */ - float get_loop_bandwidth() const; - - /*! - * \brief Returns the loop damping factor - */ - float get_damping_factor() const; - - /*! - * \brief Returns the loop gain alpha - */ - float get_alpha() const; - - /*! - * \brief Returns the loop gain beta - */ - float get_beta() const; - - /*! - * \brief Get the Costas loop's frequency estimate - */ - float get_frequency() const; - - /*! - * \brief Get the Costas loop's phase estimate - */ - float get_phase() const; - - int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/gr-digital/swig/digital_costas_loop_cc.i b/gr-digital/swig/digital_costas_loop_cc.i index f6e2765626..ab09200a0a 100644 --- a/gr-digital/swig/digital_costas_loop_cc.i +++ b/gr-digital/swig/digital_costas_loop_cc.i @@ -26,24 +26,8 @@ digital_costas_loop_cc_sptr digital_make_costas_loop_cc (float loop_bw, int order ) throw (std::invalid_argument); - -class digital_costas_loop_cc : public gr_sync_block +class digital_costas_loop_cc : public gr_sync_block, public gri_control_loop { private: digital_costas_loop_cc (float loop_bw, int order); - - public: - void set_loop_bandwidth(float bw); - void set_damping_factor(float df); - void set_alpha(float alpha); - void set_beta(float beta); - void set_frequency(float freq); - void set_phase(float phase); - - float get_loop_bandwidth() const; - float get_damping_factor() const; - float get_alpha() const; - float get_beta() const; - float get_frequency() const; - float get_phase() const; }; diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i index 9703aeeda8..0328ca2fcc 100644 --- a/gr-digital/swig/digital_swig.i +++ b/gr-digital/swig/digital_swig.i @@ -21,6 +21,8 @@ %include "gnuradio.i" +%include <gri_control_loop.i> + %{ #include "digital_binary_slicer_fb.h" #include "digital_clock_recovery_mm_cc.h" |