summaryrefslogtreecommitdiff
path: root/gr-digital/lib
diff options
context:
space:
mode:
authorTom Rondeau <trondeau@vt.edu>2011-08-14 22:32:01 -0400
committerTom Rondeau <trondeau@vt.edu>2011-08-14 22:32:01 -0400
commited564be6c78a3e22b3c98862834192f8b20bc551 (patch)
treec566277b3a39699669eb684156d09aedae1925be /gr-digital/lib
parent7e47bddafc6b27c623137c6d76f460e608952fcc (diff)
digital: cleaned up Costas loop code by switching over to the gri_control_loop class to handle the inner loop. Had to add it to digital_swig.i to properly wrap the parent functions into Python.
Diffstat (limited to 'gr-digital/lib')
-rw-r--r--gr-digital/lib/digital_costas_loop_cc.cc167
-rw-r--r--gr-digital/lib/digital_costas_loop_cc.h143
2 files changed, 10 insertions, 300 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);