For USRP2, implement auto scaling of TX pipeline such that [-1.0 1.0] input to
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 31 Dec 2008 22:19:48 +0000 (22:19 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Wed, 31 Dec 2008 22:19:48 +0000 (22:19 +0000)
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
gr-usrp2/src/usrp2_sink_base.cc
gr-usrp2/src/usrp2_sink_base.h
usrp2/host/include/usrp2/usrp2.h
usrp2/host/lib/usrp2.cc
usrp2/host/lib/usrp2_impl.cc
usrp2/host/lib/usrp2_impl.h

index e85de20823dfce38874645a98e7f2eb80930bf8a..28944e67618ff5a866adde51aa3828738265fb5d 100644 (file)
@@ -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
+
 %}
index c04914eedf5c45bf69467fccda093d0e4f5c90f2..579aaaa4c58e6613f5d087158fe81801040a0306 100644 (file)
@@ -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)
 {
index 0c4fe72c66c006f1a046c56ef4ef9d41fcf09630..fad965623a6d81fb7f7d264e8171cb38fc19c676 100644 (file)
@@ -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
    */
index 82b1c6449ffd2a1e20791ddc776399244fd69336..39da63aa5d8bc6da455772f33f768fbf7fe987e7 100644 (file)
@@ -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
      */
index 2a7fe5963a4b5ffd954f297a70f83e7b2f84b756..90a31b220515f635b7fabc7be27017cb5dd2aea1 100644 (file)
@@ -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)
   {
index 04f50f480434052accc0a3b6530e36500daab110..2aa43013833d85337d8b070ffd3e6e358b38b86d 100644 (file)
@@ -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)
   {
index 0400a108b864a55c287603214403a618debc7300..b332d65d26fdf381ca0dd464f863ca9ed76b9d9d 100644 (file)
@@ -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,