From 5eb35d758f7bf08b821479d11a8784689eef239c Mon Sep 17 00:00:00 2001 From: jcorgan Date: Wed, 31 Dec 2008 22:19:48 +0000 Subject: [PATCH] For USRP2, implement auto scaling of TX pipeline such that [-1.0 1.0] input to usrp2.sink_32fc results in full-scale DAC outputs, regardless of interpolation rate. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10182 221aa14e-8319-0410-a670-987f0aec2ac5 --- gr-usrp2/src/usrp2.i | 13 ++++++++++- gr-usrp2/src/usrp2_sink_base.cc | 6 ++++++ gr-usrp2/src/usrp2_sink_base.h | 5 +++++ usrp2/host/include/usrp2/usrp2.h | 5 +++++ usrp2/host/lib/usrp2.cc | 6 ++++++ usrp2/host/lib/usrp2_impl.cc | 37 +++++++++++++++++++++++++++----- usrp2/host/lib/usrp2_impl.h | 1 + 7 files changed, 67 insertions(+), 6 deletions(-) diff --git a/gr-usrp2/src/usrp2.i b/gr-usrp2/src/usrp2.i index e85de208..28944e67 100644 --- a/gr-usrp2/src/usrp2.i +++ b/gr-usrp2/src/usrp2.i @@ -137,6 +137,8 @@ public: bool set_interp(int interp_factor); bool set_scale_iq(int scale_i, int scale_q); int interp(); + %rename(_real_default_tx_scale_iq) default_scale_iq; + void default_scale_iq(int interp, int *scale_i, int *scale_q); %rename(_real_dac_rate) dac_rate; bool dac_rate(long *rate); double gain_min(); @@ -257,7 +259,7 @@ def __freq_range(self): self.freq_max()] def __daughterboard_id(self): - dbid = make_int_ptr(); + dbid = make_int_ptr() r = self._real_daughterboard_id(dbid) if r: result = deref_int_ptr(dbid) @@ -266,6 +268,12 @@ def __daughterboard_id(self): free_int_ptr(dbid) return result +def __default_tx_scale_iq(self, interp): + scale_i = make_int_ptr() + scale_q = make_int_ptr() + self._real_default_tx_scale_iq(interp, scale_i, scale_q) + return (deref_int_ptr(scale_i), deref_int_ptr(scale_q)) + usrp2_source_32fc_sptr.set_center_freq = __set_center_freq usrp2_source_16sc_sptr.set_center_freq = __set_center_freq usrp2_sink_32fc_sptr.set_center_freq = __set_center_freq @@ -296,4 +304,7 @@ usrp2_source_16sc_sptr.daughterboard_id = __daughterboard_id usrp2_sink_32fc_sptr.daughterboard_id = __daughterboard_id usrp2_sink_16sc_sptr.daughterboard_id = __daughterboard_id +usrp2_sink_32fc_sptr.default_scale_iq = __default_tx_scale_iq +usrp2_sink_16sc_sptr.default_scale_iq = __default_tx_scale_iq + %} diff --git a/gr-usrp2/src/usrp2_sink_base.cc b/gr-usrp2/src/usrp2_sink_base.cc index c04914ee..579aaaa4 100644 --- a/gr-usrp2/src/usrp2_sink_base.cc +++ b/gr-usrp2/src/usrp2_sink_base.cc @@ -64,6 +64,12 @@ usrp2_sink_base::set_interp(int interp_factor) return d_u2->set_tx_interp(interp_factor); } +void +usrp2_sink_base::default_scale_iq(int interp_factor, int *scale_i, int *scale_q) +{ + return d_u2->default_tx_scale_iq(interp_factor, scale_i, scale_q); +} + bool usrp2_sink_base::set_scale_iq(int scale_i, int scale_q) { diff --git a/gr-usrp2/src/usrp2_sink_base.h b/gr-usrp2/src/usrp2_sink_base.h index 0c4fe72c..fad96562 100644 --- a/gr-usrp2/src/usrp2_sink_base.h +++ b/gr-usrp2/src/usrp2_sink_base.h @@ -55,6 +55,11 @@ public: */ bool set_interp(int interp_factor); + /*! + * \brief Calculate default scale_iq for given interpolation factor + */ + void default_scale_iq(int interpolation_factor, int *scale_i, int *scale_q); + /*! * \brief Set transmit IQ scale factors */ diff --git a/usrp2/host/include/usrp2/usrp2.h b/usrp2/host/include/usrp2/usrp2.h index 82b1c644..39da63aa 100644 --- a/usrp2/host/include/usrp2/usrp2.h +++ b/usrp2/host/include/usrp2/usrp2.h @@ -219,6 +219,11 @@ namespace usrp2 { //! Return current interpolation factor int tx_interp(); + /* + * \brief Calculate default scale_iq for given interpolation rate + */ + void default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q); + /*! * Set transmit IQ magnitude scaling */ diff --git a/usrp2/host/lib/usrp2.cc b/usrp2/host/lib/usrp2.cc index 2a7fe596..90a31b22 100644 --- a/usrp2/host/lib/usrp2.cc +++ b/usrp2/host/lib/usrp2.cc @@ -309,6 +309,12 @@ namespace usrp2 { return d_impl->tx_interp(); } + void + usrp2::default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q) + { + d_impl->default_tx_scale_iq(interpolation_factor, scale_i, scale_q); + } + bool usrp2::set_tx_scale_iq(int scale_i, int scale_q) { diff --git a/usrp2/host/lib/usrp2_impl.cc b/usrp2/host/lib/usrp2_impl.cc index 04f50f48..2aa43013 100644 --- a/usrp2/host/lib/usrp2_impl.cc +++ b/usrp2/host/lib/usrp2_impl.cc @@ -46,7 +46,6 @@ #endif static const int DEFAULT_RX_SCALE = 1024; -static const int DEFAULT_TX_SCALE = 3000; namespace usrp2 { @@ -187,9 +186,6 @@ namespace usrp2 { // set workable defaults for scaling if (!set_rx_scale_iq(DEFAULT_RX_SCALE, DEFAULT_RX_SCALE)) std::cerr << "usrp2::ctor set_rx_scale_iq failed\n"; - - if (!set_tx_scale_iq(DEFAULT_TX_SCALE, DEFAULT_TX_SCALE)) - std::cerr << "usrp2::ctor set_tx_scale_iq failed\n"; } usrp2::impl::~impl() @@ -768,11 +764,42 @@ namespace usrp2 { return false; bool success = (ntohx(reply.ok) == 1); - if (success) + if (success) { d_tx_interp = interpolation_factor; + + // Auto-set TX scaling based on interpolation rate + int scale_i, scale_q; + default_tx_scale_iq(d_tx_interp, &scale_i, &scale_q); + return set_tx_scale_iq(scale_i, scale_q); + } + return success; } + void + usrp2::impl::default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q) + { + // Calculate CIC interpolation (i.e., without halfband interpolators) + int i = interpolation_factor; + if (i > 128) + i = i >> 1; + if (i > 128) + i = i >> 1; + + // Calculate dsp_core_tx gain absent scale multipliers + float gain = (1.65*i*i*i)/(4096*pow(2, ceil(log2(i*i*i)))); + + // Calculate closest multiplier constant to reverse gain + int scale = (int)rint(1.0/gain); + // fprintf(stderr, "if=%i i=%i gain=%f scale=%i\n", interpolation_factor, i, gain, scale); + + // Both I and Q are identical in this case + if (scale_i) + *scale_i = scale; + if (scale_q) + *scale_q = scale; + } + bool usrp2::impl::set_tx_scale_iq(int scale_i, int scale_q) { diff --git a/usrp2/host/lib/usrp2_impl.h b/usrp2/host/lib/usrp2_impl.h index 0400a108..b332d65d 100644 --- a/usrp2/host/lib/usrp2_impl.h +++ b/usrp2/host/lib/usrp2_impl.h @@ -146,6 +146,7 @@ namespace usrp2 { double tx_freq_max() { return d_tx_db_info.freq_max; } bool set_tx_interp(int interpolation_factor); int tx_interp() { return d_tx_interp; } + void default_tx_scale_iq(int interpolation_factor, int *scale_i, int *scale_q); bool set_tx_scale_iq(int scale_i, int scale_q); bool tx_32fc(unsigned int channel, -- 2.30.2