From 052e7a2c880edbc0dd55dc05d2758d3730cf9cb8 Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Mon, 17 Aug 2009 23:30:01 -0700
Subject: Initial compile of wbxng, properly sets db IDs

---
 usrp/host/apps/burn-db-eeprom      |   1 +
 usrp/host/include/usrp/Makefile.am |   1 +
 usrp/host/include/usrp/db_wbxng.h  |  92 +++++
 usrp/host/lib/Makefile.am          |   1 +
 usrp/host/lib/db_boards.cc         |   8 +
 usrp/host/lib/db_wbxng.cc          | 809 +++++++++++++++++++++++++++++++++++++
 usrp/host/lib/usrp_dbid.dat        |   3 +
 7 files changed, 915 insertions(+)
 create mode 100644 usrp/host/include/usrp/db_wbxng.h
 create mode 100644 usrp/host/lib/db_wbxng.cc

(limited to 'usrp')

diff --git a/usrp/host/apps/burn-db-eeprom b/usrp/host/apps/burn-db-eeprom
index 34f4c7015..195c4e897 100755
--- a/usrp/host/apps/burn-db-eeprom
+++ b/usrp/host/apps/burn-db-eeprom
@@ -69,6 +69,7 @@ daughterboards = {
     'lftx'            : ((LF_TX, 0x0000),           None),
     'lfrx'            : (None,                      (LF_RX, 0x0000)),
     'wbx_lo'          : ((WBX_LO_TX, 0x0000),       (WBX_LO_RX, 0x0000)),
+    'wbx_ng'          : ((WBX_NG_TX, 0x0000),       (WBX_NG_RX, 0x0000)),
     'xcvr2450'        : ((XCVR2450_TX, 0x0000),       (XCVR2450_RX, 0x0000)),
     'experimental_tx' : ((EXPERIMENTAL_TX, 0x0000), None),
     'experimental_rx' : (None,                      (EXPERIMENTAL_RX, 0x0000)),
diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am
index 769acc774..83e86da7e 100644
--- a/usrp/host/include/usrp/Makefile.am
+++ b/usrp/host/include/usrp/Makefile.am
@@ -33,6 +33,7 @@ usrpinclude_HEADERS = \
 	db_flexrf_mimo.h \
 	db_tv_rx.h \
  	db_tv_rx_mimo.h	\
+	db_wbxng.h \
 	db_xcvr2450.h \
 	libusb_types.h \
 	usrp_basic.h \
diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h
new file mode 100644
index 000000000..b255cf91c
--- /dev/null
+++ b/usrp/host/include/usrp/db_wbxng.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*- */
+//
+// Copyright 2008,2009 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+// 
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef DB_WBXNG_H
+#define DB_WBXNG_H
+
+#include <usrp/db_base.h>
+#include <boost/shared_ptr.hpp>
+
+class wbxng;
+typedef boost::shared_ptr<wbxng> wbxng_sptr;
+
+
+/******************************************************************************/
+
+
+class db_wbxng_base: public db_base
+{
+  /*
+   * Abstract base class for all wbxng boards.
+   * 
+   * Derive board specific subclasses from db_wbxng_base_{tx,rx}
+   */
+public:
+  db_wbxng_base(usrp_basic_sptr usrp, int which);
+  ~db_wbxng_base();
+  struct freq_result_t set_freq(double target_freq);
+  bool is_quadrature();
+  double freq_min();
+  double freq_max();
+
+protected:
+  wbxng_sptr d_wbxng;
+  void shutdown_common();
+};
+
+
+/******************************************************************************/
+
+
+class db_wbxng_tx : public db_wbxng_base
+{
+protected:
+  void shutdown();
+
+public:
+  db_wbxng_tx(usrp_basic_sptr usrp, int which);
+  ~db_wbxng_tx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool  set_gain(float gain);
+  bool  i_and_q_swapped();
+};
+
+class db_wbxng_rx : public db_wbxng_base
+{
+protected:
+  void shutdown();
+
+public:
+  db_wbxng_rx(usrp_basic_sptr usrp, int which);
+  ~db_wbxng_rx();
+
+  float gain_min();
+  float gain_max();
+  float gain_db_per_step();
+  bool  set_gain(float gain);
+};
+
+
+
+#endif
diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am
index 2f8cbe6de..4b889993b 100644
--- a/usrp/host/lib/Makefile.am
+++ b/usrp/host/lib/Makefile.am
@@ -130,6 +130,7 @@ libusrp_la_common_SOURCES = 		\
 	db_flexrf.cc			\
 	db_flexrf_mimo.cc		\
 	db_dbs_rx.cc			\
+	db_wbxng.cc			\
 	db_xcvr2450.cc			\
 	db_dtt754.cc			\
 	db_dtt768.cc			\
diff --git a/usrp/host/lib/db_boards.cc b/usrp/host/lib/db_boards.cc
index 8ef5bac8b..53304bd1a 100644
--- a/usrp/host/lib/db_boards.cc
+++ b/usrp/host/lib/db_boards.cc
@@ -32,6 +32,7 @@
 #include <usrp/db_dbs_rx.h>
 #include <usrp/db_flexrf.h>
 #include <usrp/db_flexrf_mimo.h>
+#include <usrp/db_wbxng.h>
 #include <usrp/db_xcvr2450.h>
 #include <usrp/db_dtt754.h>
 #include <usrp/db_dtt768.h>
@@ -194,6 +195,13 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side)
     break;
 #endif
 
+  case(USRP_DBID_WBX_NG_TX):
+    db.push_back(db_base_sptr(new db_wbxng_tx(usrp, which_side)));
+    break;
+  case(USRP_DBID_WBX_NG_RX):
+    db.push_back(db_base_sptr(new db_wbxng_rx(usrp, which_side)));
+    break;
+
   case(USRP_DBID_DTT754):
     db.push_back(db_base_sptr(new db_dtt754(usrp, which_side)));
     break;
diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
new file mode 100644
index 000000000..53ec27afc
--- /dev/null
+++ b/usrp/host/lib/db_wbxng.cc
@@ -0,0 +1,809 @@
+//
+// Copyright 2008,2009 Free Software Foundation, Inc.
+// 
+// This file is part of GNU Radio
+// 
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+// 
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#include <usrp/db_wbxng.h>
+#include <db_base_impl.h>
+#include <cmath>
+#include <boost/thread.hpp>
+#include <boost/weak_ptr.hpp>
+#include <cstdio>
+
+#if 0
+#define LO_OFFSET 4.25e6
+#else
+#define LO_OFFSET 0
+#define NO_LO_OFFSET
+#endif
+
+
+/* ------------------------------------------------------------------------
+ *  **** TODO ****
+ *    Fix the comment below to reflect WBX NG
+ */
+
+/* ------------------------------------------------------------------------
+ *  A few comments about the XCVR2450:
+ *
+ * It is half-duplex.  I.e., transmit and receive are mutually exclusive.
+ * There is a single LO for both the Tx and Rx sides.
+ * For our purposes the board is always either receiving or transmitting.
+ *
+ * Each board is uniquely identified by the *USRP hardware* instance and side
+ * This dictionary holds a weak reference to existing board controller so it
+ * can be created or retrieved as needed.
+ */
+
+
+
+// TX IO Pins
+#define HB_PA_OFF      (1 << 15)    // 5GHz PA, 1 = off, 0 = on
+#define LB_PA_OFF      (1 << 14)    // 2.4GHz PA, 1 = off, 0 = on
+#define ANTSEL_TX1_RX2 (1 << 13)    // 1 = Ant 1 to TX, Ant 2 to RX
+#define ANTSEL_TX2_RX1 (1 << 12)    // 1 = Ant 2 to TX, Ant 1 to RX
+#define TX_EN          (1 << 11)    // 1 = TX on, 0 = TX off
+#define AD9515DIV      (1 << 4)     // 1 = Div  by 3, 0 = Div by 2
+
+#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV
+#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV
+
+// RX IO Pins
+#define LOCKDET (1 << 15)           // This is an INPUT!!!
+#define EN      (1 << 14)
+#define RX_EN   (1 << 13)           // 1 = RX on, 0 = RX off
+#define RX_HP   (1 << 12)
+#define RX_OE_MASK EN|RX_EN|RX_HP
+#define RX_SAFE_IO EN
+
+struct wbxng_key {
+  std::string serial_no;
+  int which;
+
+  bool operator==(const wbxng_key &x){
+    return x.serial_no ==serial_no && x.which == which;
+  }
+};
+
+class wbxng
+{
+private:
+  usrp_basic *d_raw_usrp;
+  int d_which;
+
+  bool d_is_shutdown;
+  int d_spi_format, d_spi_enable;
+  
+  int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig;
+  int d_cp_current, d_ref_div, d_rssi_hbw;
+  int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser;
+  int d_rssi_range, d_rssi_mode, d_rssi_mux;
+  int d_rx_hp_pin, d_rx_hpf, d_rx_ant;
+  int d_tx_ant, d_txvga_ser, d_tx_driver_lin;
+  int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain;
+  int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain;
+  int d_rx_rf_gain, d_rx_bb_gain;
+
+  int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll;
+  int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain;
+  int d_reg_pabias, d_reg_rxgain, d_reg_txgain;
+
+  int d_ad9515_div;
+
+  void _set_rfagc(float gain);
+  void _set_ifagc(float gain);
+  void _set_pga(float pga_gain);
+
+public:
+  usrp_basic *usrp(){
+    return d_raw_usrp;
+  }
+
+  wbxng(usrp_basic_sptr usrp, int which);
+  ~wbxng();
+  void shutdown();
+
+  void set_reg_standby();
+  
+  // Integer-Divider Ratio (3)
+  void set_reg_int_divider();
+  
+  // Fractional-Divider Ratio (4)
+  void set_reg_frac_divider();
+  
+  // Band Select and PLL (5)
+  void set_reg_bandselpll();
+  
+  // Calibration (6)
+  void set_reg_cal();
+
+  // Lowpass Filter (7)
+  void set_reg_lpf();
+  
+  // Rx Control/RSSI (8)
+  void set_reg_rxrssi_ctrl();
+  
+  // Tx Linearity/Baseband Gain (9)
+  void set_reg_txlin_gain();
+  
+  // PA Bias DAC (10)
+  void set_reg_pabias();
+  
+  // Rx Gain (11)
+  void set_reg_rxgain();
+  
+  // Tx Gain (12)
+  void set_reg_txgain();
+  
+  // Send register write to SPI
+  void send_reg(int v);
+
+  void set_gpio();
+  bool lock_detect();
+  bool set_rx_gain(float gain);
+  bool set_tx_gain(float gain);
+
+  struct freq_result_t set_freq(double target_freq);
+};
+
+
+/*****************************************************************************/
+
+
+wbxng::wbxng(usrp_basic_sptr _usrp, int which)
+  : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false)
+{
+  // Handler for WBX NG daughterboards.
+  // 
+  // @param usrp: instance of usrp.source_c
+  // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+
+  // Use MSB with no header
+  d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_RX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_RX_B;
+  }
+
+  // Sane defaults
+  d_mimo = 1;          // 0 = OFF, 1 = ON
+  d_int_div = 192;     // 128 = min, 255 = max
+  d_frac_div = 0;      // 0 = min, 65535 = max
+  d_highband = 0;      // 0 = freq <= 5.4e9, 1 = freq > 5.4e9
+  d_five_gig = 0;      // 0 = freq <= 3.e9, 1 = freq > 3e9
+  d_cp_current = 1;    // 0 = 2mA, 1 = 4mA
+  d_ref_div = 1;       // 1 to 7
+  d_rssi_hbw = 0;      // 0 = 2 MHz, 1 = 6 MHz
+  d_txlpf_bw = 1;      // 1 = 12 MHz, 2 = 18 MHz, 3 = 24 MHz
+  d_rxlpf_bw = 1;      // 0 = 7.5 MHz, 1 = 9.5 MHz, 2 = 14 MHz, 3 = 18 MHz
+  d_rxlpf_fine = 2;    // 0 = 90%, 1 = 95%, 2 = 100%, 3 = 105%, 4 = 110%
+  d_rxvga_ser = 1;     // 0 = RXVGA controlled by B7:1, 1=controlled serially
+  d_rssi_range = 1;    // 0 = low range (datasheet typo), 1=high range (0.5V - 2.0V) 
+  d_rssi_mode = 1;     // 0 = enable follows RXHP, 1 = enabled
+  d_rssi_mux = 0;      // 0 = RSSI, 1 = TEMP
+  d_rx_hp_pin = 0;     // 0 = Fc set by rx_hpf, 1 = 600 KHz
+  d_rx_hpf = 0;        // 0 = 100Hz, 1 = 30KHz
+  d_rx_ant = 0;        // 0 = Ant. #1, 1 = Ant. #2
+  d_tx_ant = 0;        // 0 = Ant. #1, 1 = Ant. #2
+  d_txvga_ser = 1;     // 0 = TXVGA controlled by B6:1, 1=controlled serially
+  d_tx_driver_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+  d_tx_vga_lin = 2;    // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+  d_tx_upconv_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
+  d_tx_bb_gain = 3;    // 0=maxgain-5dB, 1=max-3dB, 2=max-1.5dB, 3=max
+  d_pabias_delay = 15; // 0 = 0, 15 = 7uS
+  d_pabias = 0;        // 0 = 0 uA, 63 = 315uA
+  d_rx_rf_gain = 0;    // 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB
+  d_rx_bb_gain = 16;   // 0 = min, 31 = max (0 - 62 dB)
+
+  d_txgain = 63;       // 0 = min, 63 = max
+
+  /*
+  // Initialize GPIO and ATR  
+  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
+  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
+  usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
+  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
+
+  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
+  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
+  usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
+  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
+
+  // Initialize chipset
+  // TODO: perform reset sequence to ensure power up defaults
+  set_reg_standby();
+  set_reg_bandselpll();
+  set_reg_cal();
+  set_reg_lpf();
+  set_reg_rxrssi_ctrl();
+  set_reg_txlin_gain();
+  set_reg_pabias();
+  set_reg_rxgain();
+  set_reg_txgain();
+  //FIXME: set_freq(2.45e9);
+  */
+}
+
+wbxng::~wbxng()
+{
+  //printf("wbxng::destructor\n");
+  shutdown();
+}
+
+void
+wbxng::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    /*
+    usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
+    usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
+    usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
+    usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
+    */
+  }
+}
+
+
+void
+wbxng::set_reg_standby()
+{
+  d_reg_standby = ((d_mimo<<17) | 
+		   (1<<16)      | 
+		   (1<<6)       | 
+		   (1<<5)       | 
+		   (1<<4)       | 2);
+  //send_reg(d_reg_standby);
+}
+
+void
+wbxng::set_reg_int_divider()
+{
+  d_reg_int_divider = (((d_frac_div & 0x03)<<16) | 
+		       (d_int_div<<4)            | 3);
+  //send_reg(d_reg_int_divider);
+}
+
+void
+wbxng::set_reg_frac_divider()
+{
+  d_reg_frac_divider = ((d_frac_div & 0xfffc)<<2) | 4;
+  //send_reg(d_reg_frac_divider);
+}
+        
+void
+wbxng::set_reg_bandselpll()
+{
+  d_reg_bandselpll = ((d_mimo<<17)      |
+		      (1<<16)           |
+		      (1<<15)           |
+		      (0<<11)           |
+		      (d_highband<<10)  |
+		      (d_cp_current<<9) |
+		      (d_ref_div<<5)    |
+		      (d_five_gig<<4)   | 5);
+  //send_reg(d_reg_bandselpll);
+  d_reg_bandselpll = ((d_mimo<<17)      |
+		      (1<<16)           |
+		      (1<<15)           |
+		      (1<<11)           |
+		      (d_highband<<10)  |
+		      (d_cp_current<<9) |
+		      (d_ref_div<<5)    |
+		      (d_five_gig<<4)   | 5);
+  //send_reg(d_reg_bandselpll);
+}
+     
+void
+wbxng::set_reg_cal()
+{
+  // FIXME do calibration
+  d_reg_cal = (1<<14)|6;
+  //send_reg(d_reg_cal);
+}
+
+void
+wbxng::set_reg_lpf()
+{
+  d_reg_lpf = (
+	     (d_rssi_hbw<<15)  |
+	     (d_txlpf_bw<<10)  |
+	     (d_rxlpf_bw<<9)   |
+	     (d_rxlpf_fine<<4) | 7);
+  //send_reg(d_reg_lpf);
+}
+
+void
+wbxng::set_reg_rxrssi_ctrl()
+{
+  d_reg_rxrssi_ctrl = ((d_rxvga_ser<<16)  |
+		       (d_rssi_range<<15) |
+		       (d_rssi_mode<<14)  |
+		       (d_rssi_mux<<12)   |
+		       (1<<9)             |
+		       (d_rx_hpf<<6)      |
+		       (1<<4) 		  | 8);
+  //send_reg(d_reg_rxrssi_ctrl);
+}
+
+void
+wbxng::set_reg_txlin_gain()
+{
+  d_reg_txlin_gain = ((d_txvga_ser<<14)     |
+		      (d_tx_driver_lin<<12) |
+		      (d_tx_vga_lin<<10)    |
+		      (d_tx_upconv_lin<<6)  |
+		      (d_tx_bb_gain<<4)     | 9);
+  //send_reg(d_reg_txlin_gain);
+}
+
+void
+wbxng::set_reg_pabias()
+{
+  d_reg_pabias = (
+		  (d_pabias_delay<<10) |
+		  (d_pabias<<4)        | 10);
+  //send_reg(d_reg_pabias);
+}
+
+void
+wbxng::set_reg_rxgain()
+{
+  d_reg_rxgain = (
+		  (d_rx_rf_gain<<9) |
+		  (d_rx_bb_gain<<4) | 11);
+  //send_reg(d_reg_rxgain);
+}
+
+void
+wbxng::set_reg_txgain()
+{
+  d_reg_txgain = (d_txgain<<4) | 12;
+  //send_reg(d_reg_txgain);
+}
+
+void
+wbxng::send_reg(int v)
+{
+  // Send 24 bits, it keeps last 18 clocked in
+  char c[3];
+  c[0] = (char)((v >> 16) & 0xff);
+  c[1] = (char)((v >>  8) & 0xff);
+  c[2] = (char)((v & 0xff));
+  std::string s(c, 3);
+  
+  //usrp()->_write_spi(0, d_spi_enable, d_spi_format, s);
+  //printf("wbxng: Setting reg %d to %X\n", (v&15), v);
+}
+
+// ----------------------------------------------------------------
+
+void
+wbxng::set_gpio()
+{
+  // We calculate four values:
+  //
+  // io_rx_while_rx: what to drive onto io_rx_* when receiving
+  // io_rx_while_tx: what to drive onto io_rx_* when transmitting
+  // io_tx_while_rx: what to drive onto io_tx_* when receiving
+  // io_tx_while_tx: what to drive onto io_tx_* when transmitting
+  //
+  // B1-B7 is ignored as gain is set serially for now.
+  
+  int rx_hp, tx_antsel, rx_antsel, tx_pa_sel;
+  if(d_rx_hp_pin)
+    rx_hp = RX_HP;
+  else
+    rx_hp = 0;
+  
+  if(d_tx_ant)
+    tx_antsel = ANTSEL_TX2_RX1;
+  else
+    tx_antsel = ANTSEL_TX1_RX2;
+
+  if(d_rx_ant)
+    rx_antsel = ANTSEL_TX2_RX1;
+  else
+    rx_antsel = ANTSEL_TX1_RX2;
+
+  if(d_five_gig)
+    tx_pa_sel = LB_PA_OFF;
+  else
+    tx_pa_sel = HB_PA_OFF;
+ 
+  /*
+  // Reset GPIO and ATR
+  // FIXME: dont set io, oe, atr mask once basic code stops overriding our settings
+  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
+  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_TX, d_which, tx_pa_sel|tx_antsel|TX_EN|AD9515DIV);
+  usrp()->common_write_atr_rxval(C_TX, d_which, HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV);
+  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
+
+  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
+  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
+  usrp()->common_write_atr_txval(C_RX, d_which, EN|rx_hp);
+  usrp()->common_write_atr_rxval(C_RX, d_which, EN|rx_hp|RX_EN);
+  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
+  */
+
+  //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X\n",
+  //       io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx);
+}
+  
+
+struct freq_result_t
+wbxng::set_freq(double target_freq)
+{
+  struct freq_result_t args = {false, 0};
+
+  double scaler;
+
+  if(target_freq > 3e9) {
+    d_five_gig = 1;
+    d_ad9515_div = 3;
+    scaler = 4.0/5.0;
+  }
+  else {
+    d_five_gig = 0;
+    d_ad9515_div = 3;
+    scaler = 4.0/3.0;
+  }
+
+  if(target_freq > 5.408e9) {
+    d_highband = 1;
+  }
+  else {
+    d_highband = 0;
+  }
+
+  double vco_freq = target_freq*scaler;
+  double sys_clk = usrp()->fpga_master_clock_freq();  // Usually 64e6 
+  double ref_clk = sys_clk / d_ad9515_div;
+        
+  double phdet_freq = ref_clk/d_ref_div;
+  double div = vco_freq/phdet_freq;
+  d_int_div = int(floor(div));
+  d_frac_div = int((div-d_int_div)*65536.0);
+  // double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler;
+  
+  //printf("RF=%f VCO=%f R=%d PHD=%f DIV=%3.5f I=%3d F=%5d ACT=%f\n",
+  //	 target_freq, vco_freq, d_ref_div, phdet_freq,
+  //	 div, d_int_div, d_frac_div, actual_freq);
+
+  args.ok = lock_detect();
+
+  /*
+  set_gpio();
+  set_reg_int_divider();
+  set_reg_frac_divider();
+  set_reg_bandselpll();
+
+  args.ok = lock_detect();
+#ifdef NO_LO_OFFSET
+  args.baseband_freq = target_freq;
+#else
+  args.baseband_freq = actual_freq;
+#endif
+  */
+
+  if(!args.ok){
+    printf("Fail %f\n", target_freq);
+  }
+  return args;
+}
+
+bool
+wbxng::lock_detect()
+{
+  /*
+    @returns: the value of the VCO/PLL lock detect bit.
+    @rtype: 0 or 1
+  */
+  /*
+  if(usrp()->common_read_io(C_RX, d_which) & LOCKDET) {
+    return true;
+  }
+  else {      // Give it a second chance
+    if(usrp()->common_read_io(C_RX, d_which) & LOCKDET)
+      return true;
+    else
+      return false;
+  }
+  */
+  return true;
+}
+
+bool
+wbxng::set_rx_gain(float gain)
+{
+  if(gain < 0.0) 
+    gain = 0.0;
+  if(gain > 92.0)
+    gain = 92.0;
+
+  // Split the gain between RF and baseband
+  // This is experimental, not prescribed
+  if(gain < 31.0) {
+    d_rx_rf_gain = 0;		           // 0 dB RF gain
+    rx_bb_gain = int(gain/2.0);
+  }
+  
+  if(gain >= 30.0 and gain < 60.5) {
+    d_rx_rf_gain = 2;                    // 15 dB RF gain
+    d_rx_bb_gain = int((gain-15.0)/2.0);
+  }
+  
+  if(gain >= 60.5) {
+    d_rx_rf_gain = 3;			   // 30.5 dB RF gain
+    d_rx_bb_gain = int((gain-30.5)/2.0);
+  }
+  
+  //set_reg_rxgain();
+  
+  return true;
+}
+
+bool
+wbxng::set_tx_gain(float gain)
+{
+  if(gain < 0.0) {
+    gain = 0.0;
+  }
+  if(gain > 30.0) {
+    gain = 30.0;
+  }
+  
+  d_txgain = int((gain/30.0)*63);
+  //set_reg_txgain();
+
+  return true;
+}
+
+
+/*****************************************************************************/
+
+
+struct wbxng_table_entry {
+  wbxng_key 			key;
+  boost::weak_ptr<wbxng>	value;
+
+  wbxng_table_entry(const wbxng_key &_key, boost::weak_ptr<wbxng> _value)
+    : key(_key), value(_value) {}
+};
+
+typedef std::vector<wbxng_table_entry> wbxng_table;
+
+static boost::mutex s_table_mutex;
+static wbxng_table s_table;
+
+static wbxng_sptr
+_get_or_make_wbxng(usrp_basic_sptr usrp, int which)
+{
+  wbxng_key key = {usrp->serial_number(), which};
+
+  boost::mutex::scoped_lock	guard(s_table_mutex);
+
+  for (wbxng_table::iterator p = s_table.begin(); p != s_table.end();){
+    if (p->value.expired())	// weak pointer is now dead
+      p = s_table.erase(p);	// erase it
+    else {
+      if (key == p->key){	// found it
+	return wbxng_sptr(p->value);
+      }
+      else		        
+	++p;			// keep looking
+    }
+  }
+
+  // We don't have the wbxng we're looking for
+
+  // create a new one and stick it in the table.
+  wbxng_sptr r(new wbxng(usrp, which));
+  wbxng_table_entry t(key, r);
+  s_table.push_back(t);
+
+  return r;
+}
+
+
+/*****************************************************************************/
+
+
+db_wbxng_base::db_wbxng_base(usrp_basic_sptr usrp, int which)
+  : db_base(usrp, which)
+{
+  /*
+   * Abstract base class for all wbxng boards.
+   * 
+   * Derive board specific subclasses from db_wbxng_base_{tx,rx}
+   *
+   * @param usrp: instance of usrp.source_c
+   * @param which: which side: 0 or 1 corresponding to side A or B respectively
+   * @type which: int
+   */
+  
+  d_wbxng = _get_or_make_wbxng(usrp, which);
+}
+
+db_wbxng_base::~db_wbxng_base()
+{
+}
+
+void
+db_wbxng_base::shutdown_common()
+{
+  // If the usrp_basic in the wbxng is the same as the usrp_basic
+  // in the daughterboard, shutdown the wbxng now (when only one of Tx
+  // and Rx is open, this is always true).
+
+  if (d_wbxng->usrp() == usrp()){
+    //std::cerr << "db_wbxng_base::shutdown_common: same -> shutting down\n";
+    d_wbxng->shutdown();
+  }
+  else {
+    //std::cerr << "db_wbxng_base::shutdown_common: different -> ignoring\n";
+  }
+}
+
+struct freq_result_t
+db_wbxng_base::set_freq(double target_freq)
+{
+  /*
+   * @returns (ok, actual_baseband_freq) where:
+   * ok is True or False and indicates success or failure,
+   * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
+   */
+  return d_wbxng->set_freq(target_freq+d_lo_offset);
+}
+
+bool
+db_wbxng_base::is_quadrature()
+{
+  /*
+   * Return True if this board requires both I & Q analog channels.
+   *
+   * This bit of info is useful when setting up the USRP Rx mux register.
+   */
+   return true;
+}
+
+double
+db_wbxng_base::freq_min()
+{
+  return 2.4e9;
+}
+
+double
+db_wbxng_base::freq_max()
+{
+  return 6.0e9;
+}
+
+
+/******************************************************************************/
+
+
+db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr usrp, int which)
+  : db_wbxng_base(usrp, which)
+{
+  set_lo_offset(LO_OFFSET);
+  //printf("db_wbxng_tx::db_wbxng_tx\n");
+}
+
+db_wbxng_tx::~db_wbxng_tx()
+{
+  shutdown();
+}
+
+void
+db_wbxng_tx::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    shutdown_common();
+  }
+}
+
+float
+db_wbxng_tx::gain_min()
+{
+  return 0;
+}
+
+float
+db_wbxng_tx::gain_max()
+{
+  return 30;
+}
+
+float
+db_wbxng_tx::gain_db_per_step()
+{
+  return (30.0/63.0);
+}
+
+bool
+db_wbxng_tx::set_gain(float gain)
+{
+  return d_wbxng->set_tx_gain(gain);
+}
+
+bool
+db_wbxng_tx::i_and_q_swapped()
+{
+  return true;
+}
+
+
+/******************************************************************************/
+
+
+db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which)
+  : db_wbxng_base(usrp, which)
+{
+  /*
+   * @param usrp: instance of usrp.source_c
+   * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+   */
+  set_lo_offset(LO_OFFSET);
+  //printf("db_wbxng_rx:d_wbxng_rx\n");
+}
+
+db_wbxng_rx::~db_wbxng_rx()
+{
+  shutdown();
+}
+
+void
+db_wbxng_rx::shutdown()
+{
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    shutdown_common();
+  }
+}
+
+float
+db_wbxng_rx::gain_min()
+{
+  return 0.0;
+}
+
+float
+db_wbxng_rx::gain_max()
+{
+  return 92.0;
+}
+
+float
+db_wbxng_rx::gain_db_per_step()
+{
+  return 1;
+}
+
+bool
+db_wbxng_rx::set_gain(float gain)
+{
+  return d_wbxng->set_rx_gain(gain);
+}
diff --git a/usrp/host/lib/usrp_dbid.dat b/usrp/host/lib/usrp_dbid.dat
index 6bad9a298..1df28802e 100644
--- a/usrp/host/lib/usrp_dbid.dat
+++ b/usrp/host/lib/usrp_dbid.dat
@@ -78,6 +78,9 @@
 "WBX LO TX"		0x0050
 "WBX LO RX"		0x0051
 
+"WBX NG TX"		0x0052
+"WBX NG RX"		0x0053
+
 "XCVR2450 Tx"		0x0060
 "XCVR2450 Rx"		0x0061
 
-- 
cgit 


From ba4f8351cc3b74895f3f0a880ad25f51652cd94b Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Fri, 21 Aug 2009 10:08:44 -0700
Subject: Clean build

---
 usrp/host/include/usrp/Makefile.am             |    2 +
 usrp/host/include/usrp/db_wbxng.h              |  108 ++-
 usrp/host/include/usrp/db_wbxng_adf4350.h      |   37 +
 usrp/host/include/usrp/db_wbxng_adf4350_regs.h |   65 ++
 usrp/host/lib/Makefile.am                      |    2 +
 usrp/host/lib/db_wbxng.cc                      | 1061 ++++++++++--------------
 usrp/host/lib/db_wbxng_adf4350.cc              |  156 ++++
 usrp/host/lib/db_wbxng_adf4350_regs.cc         |  106 +++
 8 files changed, 888 insertions(+), 649 deletions(-)
 create mode 100644 usrp/host/include/usrp/db_wbxng_adf4350.h
 create mode 100644 usrp/host/include/usrp/db_wbxng_adf4350_regs.h
 create mode 100644 usrp/host/lib/db_wbxng_adf4350.cc
 create mode 100644 usrp/host/lib/db_wbxng_adf4350_regs.cc

(limited to 'usrp')

diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am
index 83e86da7e..7c868e061 100644
--- a/usrp/host/include/usrp/Makefile.am
+++ b/usrp/host/include/usrp/Makefile.am
@@ -33,6 +33,8 @@ usrpinclude_HEADERS = \
 	db_flexrf_mimo.h \
 	db_tv_rx.h \
  	db_tv_rx_mimo.h	\
+	db_wbxng_adf4350.h \
+	db_wbxng_adf4350_regs.h \
 	db_wbxng.h \
 	db_xcvr2450.h \
 	libusb_types.h \
diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h
index b255cf91c..1ded1b5dc 100644
--- a/usrp/host/include/usrp/db_wbxng.h
+++ b/usrp/host/include/usrp/db_wbxng.h
@@ -23,70 +23,118 @@
 #define DB_WBXNG_H
 
 #include <usrp/db_base.h>
-#include <boost/shared_ptr.hpp>
+#include <cmath>
 
-class wbxng;
-typedef boost::shared_ptr<wbxng> wbxng_sptr;
+//debug_using_gui = true                // Must be set to True or False
+#define debug_using_gui false           // Must be set to True or False
 
+class adf4350;
 
-/******************************************************************************/
-
-
-class db_wbxng_base: public db_base
+class wbxng_base : public db_base
 {
-  /*
-   * Abstract base class for all wbxng boards.
-   * 
-   * Derive board specific subclasses from db_wbxng_base_{tx,rx}
-   */
 public:
-  db_wbxng_base(usrp_basic_sptr usrp, int which);
-  ~db_wbxng_base();
-  struct freq_result_t set_freq(double target_freq);
-  bool is_quadrature();
+  wbxng_base(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~wbxng_base();
+
+  struct freq_result_t set_freq(double freq);
+
+  bool  is_quadrature();
   double freq_min();
   double freq_max();
 
 protected:
-  wbxng_sptr d_wbxng;
-  void shutdown_common();
+  void _write_all(int R, int control, int N);
+  void _write_control(int control);
+  void _write_R(int R);
+  void _write_N(int N);
+  void _write_it(int v);
+  bool _lock_detect();
+
+  virtual bool _compute_regs(double freq, int &retR, int &retcontrol, 
+			     int &retN, double &retfreq);
+  int  _compute_control_reg();
+  int _refclk_divisor();
+  double _refclk_freq();
+
+  bool _set_pga(float pga_gain);
+
+  int power_on() { return d_power_on; }
+  int power_off() { return 0; }
+
+  bool d_first;
+  int  d_spi_format;
+  int  d_spi_enable;
+  int  d_power_on;
+  int  d_PD;
+
+  adf4350 *d_common;
 };
 
+// ----------------------------------------------------------------
 
-/******************************************************************************/
-
-
-class db_wbxng_tx : public db_wbxng_base
+class wbxng_base_tx : public wbxng_base
 {
 protected:
   void shutdown();
 
 public:
-  db_wbxng_tx(usrp_basic_sptr usrp, int which);
-  ~db_wbxng_tx();
+  wbxng_base_tx(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~wbxng_base_tx();
 
+  //*** TODO *** Fix comment
+  // All RFX tx d'boards have fixed gain
   float gain_min();
   float gain_max();
   float gain_db_per_step();
-  bool  set_gain(float gain);
-  bool  i_and_q_swapped();
+
+  bool set_auto_tr(bool on);
+  bool set_enable(bool on);
+  bool set_gain(float gain);
 };
 
-class db_wbxng_rx : public db_wbxng_base
+class wbxng_base_rx : public wbxng_base
 {
 protected:
   void shutdown();
 
+public:
+  wbxng_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0);
+  ~wbxng_base_rx();
+    
+  bool set_auto_tr(bool on);
+  bool select_rx_antenna(int which_antenna);
+  bool select_rx_antenna(const std::string &which_antenna);
+  bool set_gain(float gain);
+
+};
+
+// ----------------------------------------------------------------
+
+class db_wbxng_tx : public wbxng_base_tx
+{
+ public:
+  db_wbxng_tx(usrp_basic_sptr usrp, int which);
+  ~db_wbxng_tx();
+
+  // Wrapper calls to d_common functions
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+		     int &retN, double &retfreq);
+};
+
+class db_wbxng_rx : public wbxng_base_rx
+{
 public:
   db_wbxng_rx(usrp_basic_sptr usrp, int which);
   ~db_wbxng_rx();
-
+  
   float gain_min();
   float gain_max();
   float gain_db_per_step();
-  bool  set_gain(float gain);
-};
+  bool i_and_q_swapped();
 
+  bool _compute_regs(double freq, int &retR, int &retcontrol,
+		     int &retN, double &retfreq);
+};
 
 
 #endif
diff --git a/usrp/host/include/usrp/db_wbxng_adf4350.h b/usrp/host/include/usrp/db_wbxng_adf4350.h
new file mode 100644
index 000000000..a5ebe646e
--- /dev/null
+++ b/usrp/host/include/usrp/db_wbxng_adf4350.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2009 Ettus Research LLC
+ */
+
+#ifndef ADF4350_H
+#define ADF4350_H
+
+#include <usrp/db_wbxng_adf4350_regs.h>
+#include <usrp/db_base.h>
+#include <stdint.h>
+
+typedef uint32_t freq_t;
+class adf4350_regs;
+
+class adf4350
+{
+public:
+    adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable);
+    ~adf4350();
+    void _update();
+    bool _get_locked();
+    void _enable(bool enable);
+    void _write(uint8_t addr, uint32_t data);
+    bool _set_freq(freq_t freq);
+    freq_t _get_freq();
+    freq_t _get_max_freq();
+    freq_t _get_min_freq();
+
+protected:
+    usrp_basic_sptr d_usrp;
+    int d_which;
+    int d_spi_enable;
+    int d_spi_format;
+    adf4350_regs *d_regs;
+};
+
+#endif /* ADF4350_H */
diff --git a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h
new file mode 100644
index 000000000..ec78a9fa5
--- /dev/null
+++ b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2009 Ettus Research LLC
+ */
+
+#ifndef ADF4350_REGS_H
+#define ADF4350_REGS_H
+
+#include <usrp/db_wbxng_adf4350.h>
+#include <usrp/db_base.h>
+#include <stdint.h>
+
+class adf4350;
+
+class adf4350_regs
+{
+public:
+    adf4350_regs(adf4350* _adf4350);
+    ~adf4350_regs();
+
+    adf4350* d_adf4350;
+
+    uint32_t _reg_shift(uint32_t data, uint32_t shift);
+    void _load_register(uint8_t addr);
+
+    /* reg 0 */
+    uint16_t _int;
+    uint16_t _frac;
+    /* reg 1 */
+    static uint8_t _prescaler;
+    static uint16_t _phase;
+    uint16_t _mod;
+    /* reg 2 */
+    static uint8_t _low_noise_and_low_spur_modes;
+    static uint8_t _muxout;
+    static uint8_t _reference_doubler;
+    static uint8_t _rdiv2;
+    uint16_t _10_bit_r_counter;
+    static uint8_t _double_buff;
+    static uint8_t _charge_pump_setting;
+    static uint8_t _ldf;
+    static uint8_t _ldp;
+    static uint8_t _pd_polarity;
+    static uint8_t _power_down;
+    static uint8_t _cp_three_state;
+    static uint8_t _counter_reset;
+    /* reg 3 */
+    static uint8_t _csr;
+    static uint8_t _clk_div_mode;
+    static uint16_t _12_bit_clock_divider_value;
+    /* reg 4 */
+    static uint8_t _feedback_select;
+    uint8_t _divider_select;
+    uint8_t _8_bit_band_select_clock_divider_value;
+    static uint8_t _vco_power_down;
+    static uint8_t _mtld;
+    static uint8_t _aux_output_select;
+    static uint8_t _aux_output_enable;
+    static uint8_t _aux_output_power;
+    static uint8_t _rf_output_enable;
+    static uint8_t _output_power;
+    /* reg 5 */
+    static uint8_t _ld_pin_mode;
+};
+
+#endif /* ADF4350_REGS_H */
diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am
index 4b889993b..13f25d69b 100644
--- a/usrp/host/lib/Makefile.am
+++ b/usrp/host/lib/Makefile.am
@@ -122,6 +122,8 @@ libusrp_la_common_SOURCES = 		\
 	usrp_local_sighandler.cc	\
 	usrp_prims_common.cc		\
 	usrp_standard.cc		\
+	db_wbxng_adf4350.cc			\
+	db_wbxng_adf4350_regs.cc			\
 	db_boards.cc			\
 	db_base.cc			\
 	db_basic.cc			\
diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index 53ec27afc..e911c9d03 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -1,5 +1,5 @@
 //
-// Copyright 2008,2009 Free Software Foundation, Inc.
+// Copyright 2008 Free Software Foundation, Inc.
 // 
 // This file is part of GNU Radio
 // 
@@ -19,791 +19,614 @@
 // Boston, MA 02110-1301, USA.
 
 #include <usrp/db_wbxng.h>
+#include <usrp/db_wbxng_adf4350.h>
 #include <db_base_impl.h>
-#include <cmath>
-#include <boost/thread.hpp>
-#include <boost/weak_ptr.hpp>
-#include <cstdio>
-
-#if 0
-#define LO_OFFSET 4.25e6
-#else
-#define LO_OFFSET 0
-#define NO_LO_OFFSET
-#endif
-
-
-/* ------------------------------------------------------------------------
- *  **** TODO ****
- *    Fix the comment below to reflect WBX NG
- */
-
-/* ------------------------------------------------------------------------
- *  A few comments about the XCVR2450:
- *
- * It is half-duplex.  I.e., transmit and receive are mutually exclusive.
- * There is a single LO for both the Tx and Rx sides.
- * For our purposes the board is always either receiving or transmitting.
- *
- * Each board is uniquely identified by the *USRP hardware* instance and side
- * This dictionary holds a weak reference to existing board controller so it
- * can be created or retrieved as needed.
- */
-
-
-
-// TX IO Pins
-#define HB_PA_OFF      (1 << 15)    // 5GHz PA, 1 = off, 0 = on
-#define LB_PA_OFF      (1 << 14)    // 2.4GHz PA, 1 = off, 0 = on
-#define ANTSEL_TX1_RX2 (1 << 13)    // 1 = Ant 1 to TX, Ant 2 to RX
-#define ANTSEL_TX2_RX1 (1 << 12)    // 1 = Ant 2 to TX, Ant 1 to RX
-#define TX_EN          (1 << 11)    // 1 = TX on, 0 = TX off
-#define AD9515DIV      (1 << 4)     // 1 = Div  by 3, 0 = Div by 2
-
-#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV
-#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV
-
-// RX IO Pins
-#define LOCKDET (1 << 15)           // This is an INPUT!!!
-#define EN      (1 << 14)
-#define RX_EN   (1 << 13)           // 1 = RX on, 0 = RX off
-#define RX_HP   (1 << 12)
-#define RX_OE_MASK EN|RX_EN|RX_HP
-#define RX_SAFE_IO EN
-
-struct wbxng_key {
-  std::string serial_no;
-  int which;
-
-  bool operator==(const wbxng_key &x){
-    return x.serial_no ==serial_no && x.which == which;
-  }
-};
-
-class wbxng
-{
-private:
-  usrp_basic *d_raw_usrp;
-  int d_which;
-
-  bool d_is_shutdown;
-  int d_spi_format, d_spi_enable;
-  
-  int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig;
-  int d_cp_current, d_ref_div, d_rssi_hbw;
-  int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser;
-  int d_rssi_range, d_rssi_mode, d_rssi_mux;
-  int d_rx_hp_pin, d_rx_hpf, d_rx_ant;
-  int d_tx_ant, d_txvga_ser, d_tx_driver_lin;
-  int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain;
-  int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain;
-  int d_rx_rf_gain, d_rx_bb_gain;
-
-  int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll;
-  int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain;
-  int d_reg_pabias, d_reg_rxgain, d_reg_txgain;
-
-  int d_ad9515_div;
-
-  void _set_rfagc(float gain);
-  void _set_ifagc(float gain);
-  void _set_pga(float pga_gain);
-
-public:
-  usrp_basic *usrp(){
-    return d_raw_usrp;
-  }
-
-  wbxng(usrp_basic_sptr usrp, int which);
-  ~wbxng();
-  void shutdown();
-
-  void set_reg_standby();
-  
-  // Integer-Divider Ratio (3)
-  void set_reg_int_divider();
-  
-  // Fractional-Divider Ratio (4)
-  void set_reg_frac_divider();
-  
-  // Band Select and PLL (5)
-  void set_reg_bandselpll();
-  
-  // Calibration (6)
-  void set_reg_cal();
-
-  // Lowpass Filter (7)
-  void set_reg_lpf();
-  
-  // Rx Control/RSSI (8)
-  void set_reg_rxrssi_ctrl();
-  
-  // Tx Linearity/Baseband Gain (9)
-  void set_reg_txlin_gain();
-  
-  // PA Bias DAC (10)
-  void set_reg_pabias();
-  
-  // Rx Gain (11)
-  void set_reg_rxgain();
-  
-  // Tx Gain (12)
-  void set_reg_txgain();
-  
-  // Send register write to SPI
-  void send_reg(int v);
-
-  void set_gpio();
-  bool lock_detect();
-  bool set_rx_gain(float gain);
-  bool set_tx_gain(float gain);
-
-  struct freq_result_t set_freq(double target_freq);
-};
-
-
-/*****************************************************************************/
 
-
-wbxng::wbxng(usrp_basic_sptr _usrp, int which)
-  : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false)
+// d'board i/o pin defs
+// Tx and Rx have shared defs, but different i/o regs
+#define ENABLE_5        (1 << 7)         // enables 5.0V power supply
+#define ENABLE_33       (1 << 6)         // enables 3.3V supply
+#define RX_TXN          (1 << 5)         // Tx only: T/R antenna switch for TX/RX port
+#define RX2_RX1N        (1 << 5)         // Rx only: antenna switch between RX2 and TX/RX port
+#define BBAMP_EN        (1 << 4)
+#define PLL_CE          (1 << 3)
+#define PLL_PDBRF       (1 << 2)
+#define PLL_MUXOUT      (1 << 1)
+#define PLL_LOCK_DETECT (1 << 0)
+
+wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on)
+  : db_base(_usrp, which), d_power_on(_power_on)
 {
-  // Handler for WBX NG daughterboards.
-  // 
-  // @param usrp: instance of usrp.source_c
-  // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively
+  /*
+    @param usrp: instance of usrp.source_c
+    @param which: which side: 0 or 1 corresponding to side A or B respectively
+    @type which: int
+  */
 
-  // Use MSB with no header
+  d_first = true;
   d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
 
-  if(which == 0) {
-    d_spi_enable = SPI_ENABLE_RX_A;
-  }
-  else {
-    d_spi_enable = SPI_ENABLE_RX_B;
-  }
-
-  // Sane defaults
-  d_mimo = 1;          // 0 = OFF, 1 = ON
-  d_int_div = 192;     // 128 = min, 255 = max
-  d_frac_div = 0;      // 0 = min, 65535 = max
-  d_highband = 0;      // 0 = freq <= 5.4e9, 1 = freq > 5.4e9
-  d_five_gig = 0;      // 0 = freq <= 3.e9, 1 = freq > 3e9
-  d_cp_current = 1;    // 0 = 2mA, 1 = 4mA
-  d_ref_div = 1;       // 1 to 7
-  d_rssi_hbw = 0;      // 0 = 2 MHz, 1 = 6 MHz
-  d_txlpf_bw = 1;      // 1 = 12 MHz, 2 = 18 MHz, 3 = 24 MHz
-  d_rxlpf_bw = 1;      // 0 = 7.5 MHz, 1 = 9.5 MHz, 2 = 14 MHz, 3 = 18 MHz
-  d_rxlpf_fine = 2;    // 0 = 90%, 1 = 95%, 2 = 100%, 3 = 105%, 4 = 110%
-  d_rxvga_ser = 1;     // 0 = RXVGA controlled by B7:1, 1=controlled serially
-  d_rssi_range = 1;    // 0 = low range (datasheet typo), 1=high range (0.5V - 2.0V) 
-  d_rssi_mode = 1;     // 0 = enable follows RXHP, 1 = enabled
-  d_rssi_mux = 0;      // 0 = RSSI, 1 = TEMP
-  d_rx_hp_pin = 0;     // 0 = Fc set by rx_hpf, 1 = 600 KHz
-  d_rx_hpf = 0;        // 0 = 100Hz, 1 = 30KHz
-  d_rx_ant = 0;        // 0 = Ant. #1, 1 = Ant. #2
-  d_tx_ant = 0;        // 0 = Ant. #1, 1 = Ant. #2
-  d_txvga_ser = 1;     // 0 = TXVGA controlled by B6:1, 1=controlled serially
-  d_tx_driver_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
-  d_tx_vga_lin = 2;    // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
-  d_tx_upconv_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin)
-  d_tx_bb_gain = 3;    // 0=maxgain-5dB, 1=max-3dB, 2=max-1.5dB, 3=max
-  d_pabias_delay = 15; // 0 = 0, 15 = 7uS
-  d_pabias = 0;        // 0 = 0 uA, 63 = 315uA
-  d_rx_rf_gain = 0;    // 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB
-  d_rx_bb_gain = 16;   // 0 = min, 31 = max (0 - 62 dB)
-
-  d_txgain = 63;       // 0 = min, 63 = max
+  usrp()->_write_oe(d_which, 0, 0xffff);   // turn off all outputs
+  _enable_refclk(false);                // disable refclk
 
-  /*
-  // Initialize GPIO and ATR  
-  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
-  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
-  usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
-  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
-
-  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
-  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
-  usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
-  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
-
-  // Initialize chipset
-  // TODO: perform reset sequence to ensure power up defaults
-  set_reg_standby();
-  set_reg_bandselpll();
-  set_reg_cal();
-  set_reg_lpf();
-  set_reg_rxrssi_ctrl();
-  set_reg_txlin_gain();
-  set_reg_pabias();
-  set_reg_rxgain();
-  set_reg_txgain();
-  //FIXME: set_freq(2.45e9);
-  */
+  set_auto_tr(false);
 }
 
-wbxng::~wbxng()
+wbxng_base::~wbxng_base()
 {
-  //printf("wbxng::destructor\n");
-  shutdown();
+  delete d_common;
 }
 
 void
-wbxng::shutdown()
+wbxng_base::_write_all(int R, int control, int N)
 {
-  if (!d_is_shutdown){
-    d_is_shutdown = true;
-    /*
-    usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO);
-    usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO);
-    usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO);
-    usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO);
-    */
+  /*
+    Write R counter latch, control latch and N counter latch to VCO.
+    
+    Adds 10ms delay between writing control and N if this is first call.
+    This is the required power-up sequence.
+    
+    @param R: 24-bit R counter latch
+    @type R: int
+    @param control: 24-bit control latch
+    @type control: int
+    @param N: 24-bit N counter latch
+    @type N: int
+  */
+  timespec t;
+  t.tv_sec = 0;
+  t.tv_nsec = 10000000;
+
+  /*
+  _write_R(R);
+  _write_control(control);
+  if(d_first) {
+    //time.sleep(0.010);
+    nanosleep(&t, NULL);
+    d_first = false;
   }
+  _write_N(N);
+  */
 }
 
-
 void
-wbxng::set_reg_standby()
+wbxng_base::_write_control(int control)
 {
-  d_reg_standby = ((d_mimo<<17) | 
-		   (1<<16)      | 
-		   (1<<6)       | 
-		   (1<<5)       | 
-		   (1<<4)       | 2);
-  //send_reg(d_reg_standby);
+  //_write_it((control & ~0x3) | 0);
 }
 
 void
-wbxng::set_reg_int_divider()
+wbxng_base::_write_R(int R)
 {
-  d_reg_int_divider = (((d_frac_div & 0x03)<<16) | 
-		       (d_int_div<<4)            | 3);
-  //send_reg(d_reg_int_divider);
+  //_write_it((R & ~0x3) | 1);
 }
 
 void
-wbxng::set_reg_frac_divider()
-{
-  d_reg_frac_divider = ((d_frac_div & 0xfffc)<<2) | 4;
-  //send_reg(d_reg_frac_divider);
-}
-        
-void
-wbxng::set_reg_bandselpll()
-{
-  d_reg_bandselpll = ((d_mimo<<17)      |
-		      (1<<16)           |
-		      (1<<15)           |
-		      (0<<11)           |
-		      (d_highband<<10)  |
-		      (d_cp_current<<9) |
-		      (d_ref_div<<5)    |
-		      (d_five_gig<<4)   | 5);
-  //send_reg(d_reg_bandselpll);
-  d_reg_bandselpll = ((d_mimo<<17)      |
-		      (1<<16)           |
-		      (1<<15)           |
-		      (1<<11)           |
-		      (d_highband<<10)  |
-		      (d_cp_current<<9) |
-		      (d_ref_div<<5)    |
-		      (d_five_gig<<4)   | 5);
-  //send_reg(d_reg_bandselpll);
-}
-     
-void
-wbxng::set_reg_cal()
+wbxng_base::_write_N(int N)
 {
-  // FIXME do calibration
-  d_reg_cal = (1<<14)|6;
-  //send_reg(d_reg_cal);
+  //_write_it((N & ~0x3) | 2);
 }
 
 void
-wbxng::set_reg_lpf()
+wbxng_base::_write_it(int v)
 {
-  d_reg_lpf = (
-	     (d_rssi_hbw<<15)  |
-	     (d_txlpf_bw<<10)  |
-	     (d_rxlpf_bw<<9)   |
-	     (d_rxlpf_fine<<4) | 7);
-  //send_reg(d_reg_lpf);
+  char s[3];
+  s[0] = (char)((v >> 16) & 0xff);
+  s[1] = (char)((v >>  8) & 0xff);
+  s[2] = (char)(v & 0xff);
+  std::string str(s, 3);
+  //usrp()->_write_spi(0, d_spi_enable, d_spi_format, str);
 }
-
-void
-wbxng::set_reg_rxrssi_ctrl()
+        
+bool
+wbxng_base::_lock_detect()
 {
-  d_reg_rxrssi_ctrl = ((d_rxvga_ser<<16)  |
-		       (d_rssi_range<<15) |
-		       (d_rssi_mode<<14)  |
-		       (d_rssi_mux<<12)   |
-		       (1<<9)             |
-		       (d_rx_hpf<<6)      |
-		       (1<<4) 		  | 8);
-  //send_reg(d_reg_rxrssi_ctrl);
+  /*
+    @returns: the value of the VCO/PLL lock detect bit.
+    @rtype: 0 or 1
+  */
+  /*
+  if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
+    return true;
+  }
+  else {      // Give it a second chance
+    // FIXME: make portable sleep
+    timespec t;
+    t.tv_sec = 0;
+    t.tv_nsec = 100000000;
+    nanosleep(&t, NULL);
+    
+    if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+  */
+  throw std::runtime_error("_lock_detect called from wbxng_base\n");
 }
 
-void
-wbxng::set_reg_txlin_gain()
-{
-  d_reg_txlin_gain = ((d_txvga_ser<<14)     |
-		      (d_tx_driver_lin<<12) |
-		      (d_tx_vga_lin<<10)    |
-		      (d_tx_upconv_lin<<6)  |
-		      (d_tx_bb_gain<<4)     | 9);
-  //send_reg(d_reg_txlin_gain);
+/*
+bool
+wbxng_base::_compute_regs(double freq, int &retR, int &retcontrol,
+			   int &retN, double &retfreq)
+{
+  **COMMENT**
+    Determine values of R, control, and N registers, along with actual freq.
+    
+    @param freq: target frequency in Hz
+    @type freq: float
+    @returns: (R, control, N, actual_freq)
+    @rtype: tuple(int, int, int, float)
+    
+    Override this in derived classes.
+  **COMMENT**
+  
+  //raise NotImplementedError;
+  throw std::runtime_error("_compute_regs called from wbxng_base\n");
 }
+*/
 
-void
-wbxng::set_reg_pabias()
+int
+wbxng_base::_compute_control_reg()
 {
-  d_reg_pabias = (
-		  (d_pabias_delay<<10) |
-		  (d_pabias<<4)        | 10);
-  //send_reg(d_reg_pabias);
+  throw std::runtime_error("_compute_control_reg called from wbxng_base\n");
+  //return d_common->_compute_control_reg();
 }
 
-void
-wbxng::set_reg_rxgain()
+int
+wbxng_base::_refclk_divisor()
 {
-  d_reg_rxgain = (
-		  (d_rx_rf_gain<<9) |
-		  (d_rx_bb_gain<<4) | 11);
-  //send_reg(d_reg_rxgain);
+  throw std::runtime_error("_refclk_divisor called from wbxng_base\n");
+  //return d_common->_refclk_divisor();
 }
 
-void
-wbxng::set_reg_txgain()
+double
+wbxng_base::_refclk_freq()
 {
-  d_reg_txgain = (d_txgain<<4) | 12;
-  //send_reg(d_reg_txgain);
-}
-
-void
-wbxng::send_reg(int v)
-{
-  // Send 24 bits, it keeps last 18 clocked in
-  char c[3];
-  c[0] = (char)((v >> 16) & 0xff);
-  c[1] = (char)((v >>  8) & 0xff);
-  c[2] = (char)((v & 0xff));
-  std::string s(c, 3);
-  
-  //usrp()->_write_spi(0, d_spi_enable, d_spi_format, s);
-  //printf("wbxng: Setting reg %d to %X\n", (v&15), v);
+  throw std::runtime_error("_refclk_divisor called from wbxng_base\n");
+  // *** TODO *** Magic Number 64e6?
+  //return 64e6/_refclk_divisor();
 }
 
-// ----------------------------------------------------------------
-
-void
-wbxng::set_gpio()
-{
-  // We calculate four values:
-  //
-  // io_rx_while_rx: what to drive onto io_rx_* when receiving
-  // io_rx_while_tx: what to drive onto io_rx_* when transmitting
-  // io_tx_while_rx: what to drive onto io_tx_* when receiving
-  // io_tx_while_tx: what to drive onto io_tx_* when transmitting
-  //
-  // B1-B7 is ignored as gain is set serially for now.
-  
-  int rx_hp, tx_antsel, rx_antsel, tx_pa_sel;
-  if(d_rx_hp_pin)
-    rx_hp = RX_HP;
-  else
-    rx_hp = 0;
-  
-  if(d_tx_ant)
-    tx_antsel = ANTSEL_TX2_RX1;
-  else
-    tx_antsel = ANTSEL_TX1_RX2;
-
-  if(d_rx_ant)
-    rx_antsel = ANTSEL_TX2_RX1;
-  else
-    rx_antsel = ANTSEL_TX1_RX2;
-
-  if(d_five_gig)
-    tx_pa_sel = LB_PA_OFF;
-  else
-    tx_pa_sel = HB_PA_OFF;
- 
+struct freq_result_t
+wbxng_base::set_freq(double freq)
+{
   /*
-  // Reset GPIO and ATR
-  // FIXME: dont set io, oe, atr mask once basic code stops overriding our settings
-  usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK);
-  usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_TX, d_which, tx_pa_sel|tx_antsel|TX_EN|AD9515DIV);
-  usrp()->common_write_atr_rxval(C_TX, d_which, HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV);
-  usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK);
-
-  usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK);
-  usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff);
-  usrp()->common_write_atr_txval(C_RX, d_which, EN|rx_hp);
-  usrp()->common_write_atr_rxval(C_RX, d_which, EN|rx_hp|RX_EN);
-  usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK);
+    @returns (ok, actual_baseband_freq) where:
+    ok is True or False and indicates success or failure,
+    actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
   */
 
-  //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X\n",
-  //       io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx);
-}
-  
-
-struct freq_result_t
-wbxng::set_freq(double target_freq)
-{
   struct freq_result_t args = {false, 0};
 
-  double scaler;
-
-  if(target_freq > 3e9) {
-    d_five_gig = 1;
-    d_ad9515_div = 3;
-    scaler = 4.0/5.0;
-  }
-  else {
-    d_five_gig = 0;
-    d_ad9515_div = 3;
-    scaler = 4.0/3.0;
-  }
-
-  if(target_freq > 5.408e9) {
-    d_highband = 1;
-  }
-  else {
-    d_highband = 0;
-  }
-
-  double vco_freq = target_freq*scaler;
-  double sys_clk = usrp()->fpga_master_clock_freq();  // Usually 64e6 
-  double ref_clk = sys_clk / d_ad9515_div;
-        
-  double phdet_freq = ref_clk/d_ref_div;
-  double div = vco_freq/phdet_freq;
-  d_int_div = int(floor(div));
-  d_frac_div = int((div-d_int_div)*65536.0);
-  // double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler;
+  // Offsetting the LO helps get the Tx carrier leakage out of the way.
+  // This also ensures that on Rx, we're not getting hosed by the
+  // FPGA's DC removal loop's time constant.  We were seeing a
+  // problem when running with discontinuous transmission.
+  // Offsetting the LO made the problem go away.
+  freq += d_lo_offset;
   
-  //printf("RF=%f VCO=%f R=%d PHD=%f DIV=%3.5f I=%3d F=%5d ACT=%f\n",
-  //	 target_freq, vco_freq, d_ref_div, phdet_freq,
-  //	 div, d_int_div, d_frac_div, actual_freq);
-
-  args.ok = lock_detect();
-
-  /*
-  set_gpio();
-  set_reg_int_divider();
-  set_reg_frac_divider();
-  set_reg_bandselpll();
-
-  args.ok = lock_detect();
-#ifdef NO_LO_OFFSET
-  args.baseband_freq = target_freq;
-#else
-  args.baseband_freq = actual_freq;
-#endif
-  */
-
-  if(!args.ok){
-    printf("Fail %f\n", target_freq);
-  }
+  //int R, control, N;
+  //double actual_freq;
+  //_compute_regs(freq, R, control, N, actual_freq);
+
+  //if(R==0) {
+  //  return args;
+  //}
+   
+  //_write_all(R, control, N);
+  //args.ok = _lock_detect();
+  //args.baseband_freq = actual_freq;
   return args;
 }
 
 bool
-wbxng::lock_detect()
+wbxng_base::_set_pga(float pga_gain)
 {
   /*
-    @returns: the value of the VCO/PLL lock detect bit.
-    @rtype: 0 or 1
-  */
-  /*
-  if(usrp()->common_read_io(C_RX, d_which) & LOCKDET) {
-    return true;
+  if(d_which == 0) {
+    usrp()->set_pga(0, pga_gain);
+    usrp()->set_pga(1, pga_gain);
   }
-  else {      // Give it a second chance
-    if(usrp()->common_read_io(C_RX, d_which) & LOCKDET)
-      return true;
-    else
-      return false;
+  else {
+    usrp()->set_pga(2, pga_gain);
+    usrp()->set_pga(3, pga_gain);
   }
   */
   return true;
 }
 
 bool
-wbxng::set_rx_gain(float gain)
-{
-  if(gain < 0.0) 
-    gain = 0.0;
-  if(gain > 92.0)
-    gain = 92.0;
-
-  // Split the gain between RF and baseband
-  // This is experimental, not prescribed
-  if(gain < 31.0) {
-    d_rx_rf_gain = 0;		           // 0 dB RF gain
-    rx_bb_gain = int(gain/2.0);
-  }
-  
-  if(gain >= 30.0 and gain < 60.5) {
-    d_rx_rf_gain = 2;                    // 15 dB RF gain
-    d_rx_bb_gain = int((gain-15.0)/2.0);
-  }
-  
-  if(gain >= 60.5) {
-    d_rx_rf_gain = 3;			   // 30.5 dB RF gain
-    d_rx_bb_gain = int((gain-30.5)/2.0);
-  }
-  
-  //set_reg_rxgain();
-  
+wbxng_base::is_quadrature()
+{
+  /*
+    Return True if this board requires both I & Q analog channels.
+    
+    This bit of info is useful when setting up the USRP Rx mux register.
+  */
   return true;
 }
 
-bool
-wbxng::set_tx_gain(float gain)
+double
+wbxng_base::freq_min()
 {
-  if(gain < 0.0) {
-    gain = 0.0;
-  }
-  if(gain > 30.0) {
-    gain = 30.0;
-  }
-  
-  d_txgain = int((gain/30.0)*63);
-  //set_reg_txgain();
-
-  return true;
+  throw std::runtime_error("freq_min called from wbxng_base\n");
+  //return d_common->freq_min();
 }
 
-
-/*****************************************************************************/
-
-
-struct wbxng_table_entry {
-  wbxng_key 			key;
-  boost::weak_ptr<wbxng>	value;
-
-  wbxng_table_entry(const wbxng_key &_key, boost::weak_ptr<wbxng> _value)
-    : key(_key), value(_value) {}
-};
-
-typedef std::vector<wbxng_table_entry> wbxng_table;
-
-static boost::mutex s_table_mutex;
-static wbxng_table s_table;
-
-static wbxng_sptr
-_get_or_make_wbxng(usrp_basic_sptr usrp, int which)
+double
+wbxng_base::freq_max()
 {
-  wbxng_key key = {usrp->serial_number(), which};
+  throw std::runtime_error("freq_max called from wbxng_base\n");
+  //return d_common->freq_max();
+}
 
-  boost::mutex::scoped_lock	guard(s_table_mutex);
+// ----------------------------------------------------------------
 
-  for (wbxng_table::iterator p = s_table.begin(); p != s_table.end();){
-    if (p->value.expired())	// weak pointer is now dead
-      p = s_table.erase(p);	// erase it
-    else {
-      if (key == p->key){	// found it
-	return wbxng_sptr(p->value);
-      }
-      else		        
-	++p;			// keep looking
-    }
+wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
+  : wbxng_base(_usrp, which, _power_on)
+{
+  /*
+    @param usrp: instance of usrp.sink_c
+    @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
+  */
+  
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_TX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_TX_B;
   }
 
-  // We don't have the wbxng we're looking for
+  d_common = new adf4350(_usrp, d_which, d_spi_enable);
+  
+  // power up the transmit side, but don't enable the mixer
+  /*
+  usrp()->_write_oe(d_which,(POWER_UP|RX_TXN|ENABLE), 0xffff);
+  usrp()->write_io(d_which, (power_on()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
+  set_lo_offset(4e6);
 
-  // create a new one and stick it in the table.
-  wbxng_sptr r(new wbxng(usrp, which));
-  wbxng_table_entry t(key, r);
-  s_table.push_back(t);
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+  */
+}
 
-  return r;
+wbxng_base_tx::~wbxng_base_tx()
+{
+  shutdown();
 }
 
 
-/*****************************************************************************/
+void
+wbxng_base_tx::shutdown()
+{
+  // fprintf(stderr, "wbxng_base_tx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
 
+  if (!d_is_shutdown){
+    d_is_shutdown = true;
+    // do whatever there is to do to shutdown
 
-db_wbxng_base::db_wbxng_base(usrp_basic_sptr usrp, int which)
-  : db_base(usrp, which)
-{
-  /*
-   * Abstract base class for all wbxng boards.
-   * 
-   * Derive board specific subclasses from db_wbxng_base_{tx,rx}
-   *
-   * @param usrp: instance of usrp.source_c
-   * @param which: which side: 0 or 1 corresponding to side A or B respectively
-   * @type which: int
-   */
+    // Power down and leave the T/R switch in the R position
+    //usrp()->write_io(d_which, (power_off()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
+
+    // Power down VCO/PLL
+    d_PD = 3;
   
-  d_wbxng = _get_or_make_wbxng(usrp, which);
+    _write_control(_compute_control_reg());
+    _enable_refclk(false);                       // turn off refclk
+    set_auto_tr(false);
+  }
 }
 
-db_wbxng_base::~db_wbxng_base()
+bool
+wbxng_base_tx::set_auto_tr(bool on)
 {
+  bool ok = true;
+  /*
+  if(on) {
+    ok &= set_atr_mask (RX_TXN | ENABLE);
+    ok &= set_atr_txval(0      | ENABLE);
+    ok &= set_atr_rxval(RX_TXN | 0);
+  }
+  else {
+    ok &= set_atr_mask (0);
+    ok &= set_atr_txval(0);
+    ok &= set_atr_rxval(0);
+  }
+  */
+  return ok;
 }
 
-void
-db_wbxng_base::shutdown_common()
+bool
+wbxng_base_tx::set_enable(bool on)
 {
-  // If the usrp_basic in the wbxng is the same as the usrp_basic
-  // in the daughterboard, shutdown the wbxng now (when only one of Tx
-  // and Rx is open, this is always true).
+  /*
+    Enable transmitter if on is true
+  */
 
-  if (d_wbxng->usrp() == usrp()){
-    //std::cerr << "db_wbxng_base::shutdown_common: same -> shutting down\n";
-    d_wbxng->shutdown();
+  int v;
+  //int mask = RX_TXN | ENABLE_5 | ENABLE_33;
+  if(on) {
+    v = ENABLE_5 | ENABLE_33;
   }
   else {
-    //std::cerr << "db_wbxng_base::shutdown_common: different -> ignoring\n";
+    v = RX_TXN;
   }
+  throw std::runtime_error("set_enable called from wbxng_base_tx\n");
+  //return usrp()->write_io(d_which, v, mask);
 }
 
-struct freq_result_t
-db_wbxng_base::set_freq(double target_freq)
+float
+wbxng_base_tx::gain_min()
 {
-  /*
-   * @returns (ok, actual_baseband_freq) where:
-   * ok is True or False and indicates success or failure,
-   * actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
-   */
-  return d_wbxng->set_freq(target_freq+d_lo_offset);
+  return usrp()->pga_max();
 }
 
-bool
-db_wbxng_base::is_quadrature()
+float
+wbxng_base_tx::gain_max()
 {
-  /*
-   * Return True if this board requires both I & Q analog channels.
-   *
-   * This bit of info is useful when setting up the USRP Rx mux register.
-   */
-   return true;
+  return usrp()->pga_max();
 }
 
-double
-db_wbxng_base::freq_min()
+float
+wbxng_base_tx::gain_db_per_step()
 {
-  return 2.4e9;
+  return 1;
 }
 
-double
-db_wbxng_base::freq_max()
+bool
+wbxng_base_tx::set_gain(float gain)
 {
-  return 6.0e9;
+  /*
+    Set the gain.
+    
+    @param gain:  gain in decibels
+    @returns True/False
+  */
+  return _set_pga(usrp()->pga_max());
 }
 
 
-/******************************************************************************/
+/**************************************************************************/
 
 
-db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr usrp, int which)
-  : db_wbxng_base(usrp, which)
+wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
+  : wbxng_base(_usrp, which, _power_on)
 {
-  set_lo_offset(LO_OFFSET);
-  //printf("db_wbxng_tx::db_wbxng_tx\n");
+  /*
+    @param usrp: instance of usrp.source_c
+    @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
+  */
+
+  if(which == 0) {
+    d_spi_enable = SPI_ENABLE_RX_A;
+  }
+  else {
+    d_spi_enable = SPI_ENABLE_RX_B;
+  }
+
+  d_common = new adf4350(_usrp, d_which, d_spi_enable);
+
+  /*  
+  usrp()->_write_oe(d_which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff);
+  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE), 
+		   (POWER_UP|RX2_RX1N|ENABLE));
+  
+  // set up for RX on TX/RX port
+  select_rx_antenna("TX/RX");
+  
+  bypass_adc_buffers(true);
+
+  set_lo_offset(-4e6);
+  */
 }
 
-db_wbxng_tx::~db_wbxng_tx()
+wbxng_base_rx::~wbxng_base_rx()
 {
   shutdown();
 }
 
 void
-db_wbxng_tx::shutdown()
+wbxng_base_rx::shutdown()
 {
+  // fprintf(stderr, "wbxng_base_rx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
+
   if (!d_is_shutdown){
     d_is_shutdown = true;
-    shutdown_common();
+    // do whatever there is to do to shutdown
+
+    // Power down
+    //usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE));
+
+    // Power down VCO/PLL
+    d_PD = 3;
+  
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  before _write_control\n");
+    //_write_control(_compute_control_reg());
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  before _enable_refclk\n");
+    //_enable_refclk(false);                       // turn off refclk
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  before set_auto_tr\n");
+    //set_auto_tr(false);
+
+    // fprintf(stderr, "wbxng_base_rx::shutdown  after set_auto_tr\n");
   }
 }
 
-float
-db_wbxng_tx::gain_min()
+bool
+wbxng_base_rx::set_auto_tr(bool on)
 {
-  return 0;
+  //bool ok = true;
+  /*
+  if(on) {
+    ok &= set_atr_mask (ENABLE);
+    ok &= set_atr_txval(     0);
+    ok &= set_atr_rxval(ENABLE);
+  }
+  else {
+    ok &= set_atr_mask (0);
+    ok &= set_atr_txval(0);
+    ok &= set_atr_rxval(0);
+  }
+  */
+  return true;
 }
 
-float
-db_wbxng_tx::gain_max()
+/* *** TODO *** Defined select_rx_antenna twice?
+bool
+wbxng_base_rx::select_rx_antenna(int which_antenna)
 {
-  return 30;
-}
+  **COMMENT**
+    Specify which antenna port to use for reception.
+    @param which_antenna: either 'TX/RX' or 'RX2'
+  **COMMENT**
 
-float
-db_wbxng_tx::gain_db_per_step()
-{
-  return (30.0/63.0);
+  if(which_antenna == 0) {
+    usrp()->write_io(d_which, 0,RX2_RX1N);
+  }
+  else if(which_antenna == 1) {
+    usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+  }
+  else {
+    return false;
+    // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+  }
+  return true;
 }
+*/
 
 bool
-db_wbxng_tx::set_gain(float gain)
+wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
 {
-  return d_wbxng->set_tx_gain(gain);
+  /*
+    Specify which antenna port to use for reception.
+    @param which_antenna: either 'TX/RX' or 'RX2'
+  */
+
+  /*
+  if(which_antenna == "TX/RX") {
+    usrp()->write_io(d_which, 0, RX2_RX1N);
+  }
+  else if(which_antenna == "RX2") {
+    usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
+  }
+  else {
+    // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
+    return false;
+  }
+  */
+  return true;
 }
 
 bool
-db_wbxng_tx::i_and_q_swapped()
+wbxng_base_rx::set_gain(float gain)
 {
-  return true;
+  /*
+    Set the gain.
+    
+    @param gain:  gain in decibels
+    @returns True/False
+  */
+  
+  /*
+  // clamp gain
+  gain = std::max(gain_min(), std::min(gain, gain_max()));
+
+  float pga_gain, agc_gain;
+  float V_maxgain, V_mingain, V_fullscale, dac_value;
+
+  float maxgain = gain_max() - usrp()->pga_max();
+  float mingain = gain_min();
+  if(gain > maxgain) {
+    pga_gain = gain-maxgain;
+    assert(pga_gain <= usrp()->pga_max());
+    agc_gain = maxgain;
+  }
+  else {
+    pga_gain = 0;
+    agc_gain = gain;
+  }
+  
+  V_maxgain = .2;
+  V_mingain = 1.2;
+  V_fullscale = 3.3;
+  dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+  assert(dac_value>=0 && dac_value<4096);
+
+  return (usrp()->write_aux_dac(d_which, 0, int(dac_value))
+	  && _set_pga(int(pga_gain)));
+  */
+  return false;
 }
 
+// ----------------------------------------------------------------
 
-/******************************************************************************/
+db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr usrp, int which)
+  : wbxng_base_tx(usrp, which)
+{
+}
 
+db_wbxng_tx::~db_wbxng_tx()
+{
+}
 
-db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which)
-  : db_wbxng_base(usrp, which)
+/*
+bool
+db_wbxng_tx::_compute_regs(double freq, int &retR, int &retcontrol,
+				 int &retN, double &retfreq)
 {
-  /*
-   * @param usrp: instance of usrp.source_c
-   * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
-   */
-  set_lo_offset(LO_OFFSET);
-  //printf("db_wbxng_rx:d_wbxng_rx\n");
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+				 retcontrol, retN, retfreq);
 }
+*/
 
-db_wbxng_rx::~db_wbxng_rx()
+
+db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which)
+  : wbxng_base_rx(usrp, which)
 {
-  shutdown();
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
 }
 
-void
-db_wbxng_rx::shutdown()
+db_wbxng_rx::~db_wbxng_rx()
 {
-  if (!d_is_shutdown){
-    d_is_shutdown = true;
-    shutdown_common();
-  }
 }
 
 float
 db_wbxng_rx::gain_min()
 {
-  return 0.0;
+  return usrp()->pga_min();
 }
 
 float
 db_wbxng_rx::gain_max()
 {
-  return 92.0;
+  return usrp()->pga_max()+70;
 }
 
 float
 db_wbxng_rx::gain_db_per_step()
 {
-  return 1;
+  return 0.05;
+}
+
+
+bool
+db_wbxng_rx::i_and_q_swapped()
+{
+  return true;
 }
 
+/*
 bool
-db_wbxng_rx::set_gain(float gain)
+db_wbxng_rx::_compute_regs(double freq, int &retR, int &retcontrol,
+				 int &retN, double &retfreq)
 {
-  return d_wbxng->set_rx_gain(gain);
+  return d_common->_compute_regs(_refclk_freq(), freq, retR,
+				 retcontrol, retN, retfreq);
 }
+*/
+
diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc
new file mode 100644
index 000000000..22262be33
--- /dev/null
+++ b/usrp/host/lib/db_wbxng_adf4350.cc
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2009 Ettus Research LLC
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <usrp/db_wbxng_adf4350.h>
+#include <usrp/db_wbxng_adf4350_regs.h>
+#include <db_base_impl.h>
+#include <stdio.h>
+//#include "io.h"
+//#include "spi.h"
+
+#define INPUT_REF_FREQ FREQ_C(10e6)
+#define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom))
+#define FREQ_C(freq) ((uint32_t)DIV_ROUND(freq, (uint32_t)1000))
+#define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ)                            /* input ref freq with doubler turned on */
+#define MIN_INT_DIV uint16_t(23)                                        /* minimum int divider, prescaler 4/5 only */
+#define MAX_RF_DIV uint8_t(16)                                          /* max rf divider, divides rf output */
+#define MIN_VCO_FREQ FREQ_C(2.2e9)                                      /* minimum vco freq */
+#define MAX_VCO_FREQ FREQ_C(4.4e9)                                      /* minimum vco freq */
+#define MAX_FREQ MAX_VCO_FREQ                                           /* upper bound freq (rf div = 1) */
+#define MIN_FREQ DIV_ROUND(MIN_VCO_FREQ, MAX_RF_DIV)                    /* calculated lower bound freq */
+
+#define CE_PIN        (1 << 3)
+#define PDB_RF_PIN    (1 << 2)
+#define MUX_PIN       (1 << 1)
+#define LD_PIN        (1 << 0)
+
+adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){
+	/* Initialize the pin directions. */
+
+    d_usrp = _usrp;
+    d_which = _which;
+    d_spi_enable = _spi_enable;
+    d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
+
+    d_regs = new adf4350_regs(this);
+
+    /* Outputs */
+    d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), 0xffff);
+
+	/* Initialize the pin levels. */
+	_enable(true);
+	/* Initialize the registers. */
+	d_regs->_load_register(5);
+	d_regs->_load_register(4);
+	d_regs->_load_register(3);
+	d_regs->_load_register(2);
+	d_regs->_load_register(1);
+	d_regs->_load_register(0);
+}
+
+adf4350::~adf4350(){
+    delete d_regs;
+}
+
+freq_t 
+adf4350::_get_max_freq(void){
+	return MAX_FREQ;
+}
+
+freq_t 
+adf4350::_get_min_freq(void){
+	return MIN_FREQ;
+}
+
+bool 
+adf4350::_get_locked(void){
+    return d_usrp->read_io(d_which) & LD_PIN;
+}
+
+void 
+adf4350::_enable(bool enable){
+	if (enable){ /* chip enable */
+        d_usrp->write_io(d_which, 1, CE_PIN);
+	}else{
+        d_usrp->write_io(d_which, 0, CE_PIN);
+	}
+}
+
+void 
+adf4350::_write(uint8_t addr, uint32_t data){
+	data |= addr;
+
+    // create str from data here
+    char s[4];
+    s[0] = (char)((data >> 24) & 0xff);
+    s[1] = (char)((data >> 16) & 0xff);
+    s[2] = (char)((data >>  8) & 0xff);
+    s[3] = (char)(data & 0xff);
+    std::string str(s, 3);
+
+    d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str);
+	/* pulse latch */
+    //d_usrp->write_io(d_which, 1, LE_PIN);
+    //d_usrp->write_io(d_which, 0, LE_PIN);
+}
+
+bool 
+adf4350::_set_freq(freq_t freq){
+	/* Set the frequency by setting int, frac, mod, r, div */
+	if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
+	/* Ramp up the RF divider until the VCO is within range. */
+	d_regs->_divider_select = 0;
+	while (freq < MIN_VCO_FREQ){
+		freq <<= 1; //double the freq
+		d_regs->_divider_select++; //double the divider
+	}
+	/* Ramp up the R divider until the N divider is at least the minimum. */
+	d_regs->_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq;
+	uint64_t n_mod;
+	do{
+		d_regs->_10_bit_r_counter++;
+		n_mod = freq;
+		n_mod *= d_regs->_10_bit_r_counter;
+		n_mod *= d_regs->_mod;
+		n_mod /= INPUT_REF_FREQ_2X;
+		/* calculate int and frac */
+		d_regs->_int = n_mod/d_regs->_mod;
+		d_regs->_frac = (n_mod - (freq_t)d_regs->_int*d_regs->_mod) & uint16_t(0xfff);
+		/*printf(
+			"VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
+			freq, d_regs->_int, d_regs->_frac,
+			d_regs->_mod, d_regs->_10_bit_r_counter, (1 << d_regs->_divider_select)
+		);*/
+	}while(d_regs->_int < MIN_INT_DIV);
+	/* calculate the band select so PFD is under 125 KHz */
+	d_regs->_8_bit_band_select_clock_divider_value = \
+		INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->_10_bit_r_counter) + 1;
+	/* load involved registers */
+	d_regs->_load_register(2);
+	d_regs->_load_register(4);
+	d_regs->_load_register(0); /* register 0 must be last */
+	return true;
+}
+
+freq_t 
+adf4350::_get_freq(void){
+	/* Calculate the freq from int, frac, mod, ref, r, div:
+	 *  freq = (int + frac/mod) * (ref/r)
+	 * Keep precision by doing multiplies first:
+	 *  freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
+	 */
+	uint64_t temp;
+	temp = d_regs->_int;
+	temp *= d_regs->_mod;
+	temp += d_regs->_frac;
+	temp *= INPUT_REF_FREQ_2X;
+	temp /= d_regs->_mod;
+	temp /= d_regs->_10_bit_r_counter;
+	temp /= (1 << d_regs->_divider_select);
+	return temp;
+}
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc
new file mode 100644
index 000000000..b320e8bbf
--- /dev/null
+++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2009 Ettus Research LLC
+ */
+
+#include <usrp/db_wbxng_adf4350_regs.h>
+#include <usrp/db_wbxng_adf4350.h>
+//#include "cal_div.h"
+
+adf4350_regs::adf4350_regs(adf4350* _adf4350){
+    d_adf4350 = _adf4350;
+
+    /* reg 0 */
+    _int = uint16_t(100);
+    _frac = 0;
+    /* reg 1 */
+    _prescaler = 1;                        /* 8/9 */
+    _phase = 0;                           /* 0 */
+    _mod = uint16_t(0xfff);                      /* max fractional accuracy */
+    /* reg 2 */
+    _low_noise_and_low_spur_modes = 0;     /* low noise mode */
+    _muxout = 6;                           /* digital lock detect */
+    _reference_doubler = 1;                /* enabled */
+    _rdiv2 = 0;                            /* disabled */
+    _10_bit_r_counter = uint16_t(1);
+    _double_buff = 0;                      /* disabled */
+    _charge_pump_setting = 7;              /* 2.50 mA */
+    _ldf = 0;                              /* frac-n */
+    _ldp = 0;                              /* 10 ns */
+    _pd_polarity = 1;                      /* positive */
+    _power_down = 0;                       /* disabled */
+    _cp_three_state = 0;                   /* disabled */
+    _counter_reset = 0;                    /* disabled */
+    /* reg 3 */
+    _csr = 0;                              /* disabled */
+    _clk_div_mode = 0;                     /* clock divider off */
+    _12_bit_clock_divider_value = 0;      /* 0 */
+    /* reg 4 */
+    _feedback_select = 1;                  /* fundamental */
+    _divider_select = 0;
+    _8_bit_band_select_clock_divider_value = 0;
+    _vco_power_down = 0;                   /* vco powered up */
+    _mtld = 0;                             /* mute disabled */
+    _aux_output_select = 0;                /* divided output */
+    _aux_output_enable = 0;                /* disabled */
+    _aux_output_power = 0;                 /* -4 */
+    _rf_output_enable = 1;                 /* enabled */
+    _output_power = 1;                     /* -1 */
+    /* reg 5 */
+    _ld_pin_mode = 1;                      /* digital lock detect */
+}
+
+adf4350_regs::~adf4350_regs(void){
+}
+
+uint32_t 
+adf4350_regs::_reg_shift(uint32_t data, uint32_t shift){
+        return data << shift;
+    }
+
+void 
+adf4350_regs::_load_register(uint8_t addr){
+	uint32_t data;
+	switch (addr){
+		case 0: data = (
+			_reg_shift(_int, 15)                           |
+			_reg_shift(_frac, 3)); break;
+		case 1: data = (
+			_reg_shift(_prescaler, 27)                     |
+			_reg_shift(_phase, 15)                         |
+			_reg_shift(_mod, 3)); break;
+		case 2: data = (
+			_reg_shift(_low_noise_and_low_spur_modes, 29)  |
+			_reg_shift(_muxout, 26)                        |
+			_reg_shift(_reference_doubler, 25)             |
+			_reg_shift(_rdiv2, 24)                         |
+			_reg_shift(_10_bit_r_counter, 14)              |
+			_reg_shift(_double_buff, 13)                   |
+			_reg_shift(_charge_pump_setting, 9)            |
+			_reg_shift(_ldf, 8)                            |
+			_reg_shift(_ldp, 7)                            |
+			_reg_shift(_pd_polarity, 6)                    |
+			_reg_shift(_power_down, 5)                     |
+			_reg_shift(_cp_three_state, 4)                 |
+			_reg_shift(_counter_reset, 3)); break;
+		case 3: data = (
+			_reg_shift(_csr, 18)                           |
+			_reg_shift(_clk_div_mode, 15)                  |
+			_reg_shift(_12_bit_clock_divider_value, 3)); break;
+		case 4: data = (
+			_reg_shift(_feedback_select, 23)               |
+			_reg_shift(_divider_select, 20)                |
+			_reg_shift(_8_bit_band_select_clock_divider_value, 12) |
+			_reg_shift(_vco_power_down, 11)                |
+			_reg_shift(_mtld, 10)                          |
+			_reg_shift(_aux_output_select, 9)              |
+			_reg_shift(_aux_output_enable, 8)              |
+			_reg_shift(_aux_output_power, 6)               |
+			_reg_shift(_rf_output_enable, 5)               |
+			_reg_shift(_output_power, 3)); break;
+		case 5: data = (
+			_reg_shift(_ld_pin_mode, 22)); break;
+		default: return;
+	}
+	/* write the data out to spi */
+	d_adf4350->_write(addr, data);
+}
-- 
cgit 


From 16951928760f44b729f3f67e3c6c279c3fef28c1 Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Fri, 21 Aug 2009 15:16:18 -0700
Subject: twiddling gpio successfully

---
 usrp/host/include/usrp/db_wbxng.h              |   9 +-
 usrp/host/include/usrp/db_wbxng_adf4350.h      |   2 +-
 usrp/host/include/usrp/db_wbxng_adf4350_regs.h |  64 ++++++------
 usrp/host/lib/db_wbxng.cc                      |  75 +++++++-------
 usrp/host/lib/db_wbxng_adf4350.cc              |  38 +++----
 usrp/host/lib/db_wbxng_adf4350_regs.cc         | 135 +++++++++++++------------
 6 files changed, 164 insertions(+), 159 deletions(-)

(limited to 'usrp')

diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h
index 1ded1b5dc..0d03e4297 100644
--- a/usrp/host/include/usrp/db_wbxng.h
+++ b/usrp/host/include/usrp/db_wbxng.h
@@ -50,8 +50,7 @@ protected:
   void _write_it(int v);
   bool _lock_detect();
 
-  virtual bool _compute_regs(double freq, int &retR, int &retcontrol, 
-			     int &retN, double &retfreq);
+  //virtual bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
   int  _compute_control_reg();
   int _refclk_divisor();
   double _refclk_freq();
@@ -117,8 +116,7 @@ class db_wbxng_tx : public wbxng_base_tx
   ~db_wbxng_tx();
 
   // Wrapper calls to d_common functions
-  bool _compute_regs(double freq, int &retR, int &retcontrol,
-		     int &retN, double &retfreq);
+  //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
 };
 
 class db_wbxng_rx : public wbxng_base_rx
@@ -132,8 +130,7 @@ public:
   float gain_db_per_step();
   bool i_and_q_swapped();
 
-  bool _compute_regs(double freq, int &retR, int &retcontrol,
-		     int &retN, double &retfreq);
+  //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
 };
 
 
diff --git a/usrp/host/include/usrp/db_wbxng_adf4350.h b/usrp/host/include/usrp/db_wbxng_adf4350.h
index a5ebe646e..d7b8dd99b 100644
--- a/usrp/host/include/usrp/db_wbxng_adf4350.h
+++ b/usrp/host/include/usrp/db_wbxng_adf4350.h
@@ -9,7 +9,7 @@
 #include <usrp/db_base.h>
 #include <stdint.h>
 
-typedef uint32_t freq_t;
+typedef uint64_t freq_t;
 class adf4350_regs;
 
 class adf4350
diff --git a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h
index ec78a9fa5..6a5b77a4b 100644
--- a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h
+++ b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h
@@ -23,43 +23,43 @@ public:
     void _load_register(uint8_t addr);
 
     /* reg 0 */
-    uint16_t _int;
-    uint16_t _frac;
+    uint16_t d_int;
+    uint16_t d_frac;
     /* reg 1 */
-    static uint8_t _prescaler;
-    static uint16_t _phase;
-    uint16_t _mod;
+    static const uint8_t s_prescaler;
+    static const uint16_t s_phase;
+    uint16_t d_mod;
     /* reg 2 */
-    static uint8_t _low_noise_and_low_spur_modes;
-    static uint8_t _muxout;
-    static uint8_t _reference_doubler;
-    static uint8_t _rdiv2;
-    uint16_t _10_bit_r_counter;
-    static uint8_t _double_buff;
-    static uint8_t _charge_pump_setting;
-    static uint8_t _ldf;
-    static uint8_t _ldp;
-    static uint8_t _pd_polarity;
-    static uint8_t _power_down;
-    static uint8_t _cp_three_state;
-    static uint8_t _counter_reset;
+    static const uint8_t s_low_noise_and_low_spur_modes;
+    static const uint8_t s_muxout;
+    static const uint8_t s_reference_doubler;
+    static const uint8_t s_rdiv2;
+    uint16_t d_10_bit_r_counter;
+    static const uint8_t s_double_buff;
+    static const uint8_t s_charge_pump_setting;
+    static const uint8_t s_ldf;
+    static const uint8_t s_ldp;
+    static const uint8_t s_pd_polarity;
+    static const uint8_t s_power_down;
+    static const uint8_t s_cp_three_state;
+    static const uint8_t s_counter_reset;
     /* reg 3 */
-    static uint8_t _csr;
-    static uint8_t _clk_div_mode;
-    static uint16_t _12_bit_clock_divider_value;
+    static const uint8_t s_csr;
+    static const uint8_t s_clk_div_mode;
+    static const uint16_t s_12_bit_clock_divider_value;
     /* reg 4 */
-    static uint8_t _feedback_select;
-    uint8_t _divider_select;
-    uint8_t _8_bit_band_select_clock_divider_value;
-    static uint8_t _vco_power_down;
-    static uint8_t _mtld;
-    static uint8_t _aux_output_select;
-    static uint8_t _aux_output_enable;
-    static uint8_t _aux_output_power;
-    static uint8_t _rf_output_enable;
-    static uint8_t _output_power;
+    static const uint8_t s_feedback_select;
+    uint8_t d_divider_select;
+    uint8_t d_8_bit_band_select_clock_divider_value;
+    static const uint8_t s_vco_power_down;
+    static const uint8_t s_mtld;
+    static const uint8_t s_aux_output_select;
+    static const uint8_t s_aux_output_enable;
+    static const uint8_t s_aux_output_power;
+    static const uint8_t s_rf_output_enable;
+    static const uint8_t s_output_power;
     /* reg 5 */
-    static uint8_t _ld_pin_mode;
+    static const uint8_t s_ld_pin_mode;
 };
 
 #endif /* ADF4350_REGS_H */
diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index e911c9d03..ccad3cb41 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -46,7 +46,7 @@ wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on)
   d_first = true;
   d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
 
-  usrp()->_write_oe(d_which, 0, 0xffff);   // turn off all outputs
+  usrp()->_write_oe(d_which, 1, 0xffff);   // turn off all outputs
   _enable_refclk(false);                // disable refclk
 
   set_auto_tr(false);
@@ -125,11 +125,13 @@ wbxng_base::_lock_detect()
     @returns: the value of the VCO/PLL lock detect bit.
     @rtype: 0 or 1
   */
-  /*
-  if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
+  
+  if(d_common->_get_locked()){
     return true;
   }
   else {      // Give it a second chance
+    return false;
+    /*
     // FIXME: make portable sleep
     timespec t;
     t.tv_sec = 0;
@@ -142,8 +144,9 @@ wbxng_base::_lock_detect()
     else {
       return false;
     }
+    */
   }
-  */
+ 
   throw std::runtime_error("_lock_detect called from wbxng_base\n");
 }
 
@@ -199,14 +202,17 @@ wbxng_base::set_freq(double freq)
     actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
   */
 
-  struct freq_result_t args = {false, 0};
+  freq_t int_freq = (freq_t) freq;
+  bool ok = d_common->_set_freq(int_freq);
+  double freq_result = (double) d_common->_get_freq();
+  struct freq_result_t args = {ok, freq_result};
 
   // Offsetting the LO helps get the Tx carrier leakage out of the way.
   // This also ensures that on Rx, we're not getting hosed by the
   // FPGA's DC removal loop's time constant.  We were seeing a
   // problem when running with discontinuous transmission.
   // Offsetting the LO made the problem go away.
-  freq += d_lo_offset;
+  //freq += d_lo_offset;
   
   //int R, control, N;
   //double actual_freq;
@@ -252,15 +258,13 @@ wbxng_base::is_quadrature()
 double
 wbxng_base::freq_min()
 {
-  throw std::runtime_error("freq_min called from wbxng_base\n");
-  //return d_common->freq_min();
+  return (double) d_common->_get_min_freq();
 }
 
 double
 wbxng_base::freq_max()
 {
-  throw std::runtime_error("freq_max called from wbxng_base\n");
-  //return d_common->freq_max();
+  return (double) d_common->_get_max_freq();
 }
 
 // ----------------------------------------------------------------
@@ -283,13 +287,11 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
   
   // power up the transmit side, but don't enable the mixer
-  /*
-  usrp()->_write_oe(d_which,(POWER_UP|RX_TXN|ENABLE), 0xffff);
-  usrp()->write_io(d_which, (power_on()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
-  set_lo_offset(4e6);
+  usrp()->_write_oe(d_which,(RX_TXN|ENABLE_33|ENABLE_5), 0xffff);
+  usrp()->write_io(d_which, (power_on()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
+  //set_lo_offset(4e6);
 
-  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
-  */
+  //set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
 }
 
 wbxng_base_tx::~wbxng_base_tx()
@@ -308,12 +310,14 @@ wbxng_base_tx::shutdown()
     // do whatever there is to do to shutdown
 
     // Power down and leave the T/R switch in the R position
-    //usrp()->write_io(d_which, (power_off()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
+    usrp()->write_io(d_which, (power_off()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
 
+    /*
     // Power down VCO/PLL
     d_PD = 3;
   
     _write_control(_compute_control_reg());
+    */
     _enable_refclk(false);                       // turn off refclk
     set_auto_tr(false);
   }
@@ -325,8 +329,8 @@ wbxng_base_tx::set_auto_tr(bool on)
   bool ok = true;
   /*
   if(on) {
-    ok &= set_atr_mask (RX_TXN | ENABLE);
-    ok &= set_atr_txval(0      | ENABLE);
+    ok &= set_atr_mask (RX_TXN | ENABLE_33 | ENABLE_5);
+    ok &= set_atr_txval(0      | ENABLE_33 | ENABLE_5);
     ok &= set_atr_rxval(RX_TXN | 0);
   }
   else {
@@ -346,15 +350,14 @@ wbxng_base_tx::set_enable(bool on)
   */
 
   int v;
-  //int mask = RX_TXN | ENABLE_5 | ENABLE_33;
+  int mask = RX_TXN | ENABLE_5 | ENABLE_33;
   if(on) {
     v = ENABLE_5 | ENABLE_33;
   }
   else {
     v = RX_TXN;
   }
-  throw std::runtime_error("set_enable called from wbxng_base_tx\n");
-  //return usrp()->write_io(d_which, v, mask);
+  return usrp()->write_io(d_which, v, mask);
 }
 
 float
@@ -408,16 +411,16 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
 
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
 
-  /*  
-  usrp()->_write_oe(d_which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff);
-  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE), 
-		   (POWER_UP|RX2_RX1N|ENABLE));
+  usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), 0xffff);
+  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), 
+		   (RX2_RX1N|ENABLE_33|ENABLE_5));
   
   // set up for RX on TX/RX port
   select_rx_antenna("TX/RX");
   
   bypass_adc_buffers(true);
 
+  /*  
   set_lo_offset(-4e6);
   */
 }
@@ -437,7 +440,7 @@ wbxng_base_rx::shutdown()
     // do whatever there is to do to shutdown
 
     // Power down
-    //usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE));
+    usrp()->common_write_io(C_RX, d_which, power_off(), (ENABLE_33|ENABLE_5));
 
     // Power down VCO/PLL
     d_PD = 3;
@@ -447,10 +450,10 @@ wbxng_base_rx::shutdown()
     //_write_control(_compute_control_reg());
 
     // fprintf(stderr, "wbxng_base_rx::shutdown  before _enable_refclk\n");
-    //_enable_refclk(false);                       // turn off refclk
+    _enable_refclk(false);                       // turn off refclk
 
     // fprintf(stderr, "wbxng_base_rx::shutdown  before set_auto_tr\n");
-    //set_auto_tr(false);
+    set_auto_tr(false);
 
     // fprintf(stderr, "wbxng_base_rx::shutdown  after set_auto_tr\n");
   }
@@ -462,9 +465,9 @@ wbxng_base_rx::set_auto_tr(bool on)
   //bool ok = true;
   /*
   if(on) {
-    ok &= set_atr_mask (ENABLE);
+    ok &= set_atr_mask (ENABLE_33|ENABLE_5);
     ok &= set_atr_txval(     0);
-    ok &= set_atr_rxval(ENABLE);
+    ok &= set_atr_rxval(ENABLE_33|ENABLE_5);
   }
   else {
     ok &= set_atr_mask (0);
@@ -475,14 +478,13 @@ wbxng_base_rx::set_auto_tr(bool on)
   return true;
 }
 
-/* *** TODO *** Defined select_rx_antenna twice?
 bool
 wbxng_base_rx::select_rx_antenna(int which_antenna)
 {
-  **COMMENT**
+  /*
     Specify which antenna port to use for reception.
     @param which_antenna: either 'TX/RX' or 'RX2'
-  **COMMENT**
+  */
 
   if(which_antenna == 0) {
     usrp()->write_io(d_which, 0,RX2_RX1N);
@@ -496,7 +498,6 @@ wbxng_base_rx::select_rx_antenna(int which_antenna)
   }
   return true;
 }
-*/
 
 bool
 wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
@@ -506,7 +507,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
     @param which_antenna: either 'TX/RX' or 'RX2'
   */
 
-  /*
+  
   if(which_antenna == "TX/RX") {
     usrp()->write_io(d_which, 0, RX2_RX1N);
   }
@@ -517,7 +518,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
     // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
     return false;
   }
-  */
+  
   return true;
 }
 
diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc
index 22262be33..a1f024b4f 100644
--- a/usrp/host/lib/db_wbxng_adf4350.cc
+++ b/usrp/host/lib/db_wbxng_adf4350.cc
@@ -104,32 +104,32 @@ adf4350::_set_freq(freq_t freq){
 	/* Set the frequency by setting int, frac, mod, r, div */
 	if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
 	/* Ramp up the RF divider until the VCO is within range. */
-	d_regs->_divider_select = 0;
+	d_regs->d_divider_select = 0;
 	while (freq < MIN_VCO_FREQ){
 		freq <<= 1; //double the freq
-		d_regs->_divider_select++; //double the divider
+		d_regs->d_divider_select++; //double the divider
 	}
 	/* Ramp up the R divider until the N divider is at least the minimum. */
-	d_regs->_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq;
+	d_regs->d_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq;
 	uint64_t n_mod;
 	do{
-		d_regs->_10_bit_r_counter++;
+		d_regs->d_10_bit_r_counter++;
 		n_mod = freq;
-		n_mod *= d_regs->_10_bit_r_counter;
-		n_mod *= d_regs->_mod;
+		n_mod *= d_regs->d_10_bit_r_counter;
+		n_mod *= d_regs->d_mod;
 		n_mod /= INPUT_REF_FREQ_2X;
 		/* calculate int and frac */
-		d_regs->_int = n_mod/d_regs->_mod;
-		d_regs->_frac = (n_mod - (freq_t)d_regs->_int*d_regs->_mod) & uint16_t(0xfff);
+		d_regs->d_int = n_mod/d_regs->d_mod;
+		d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff);
 		/*printf(
 			"VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
-			freq, d_regs->_int, d_regs->_frac,
-			d_regs->_mod, d_regs->_10_bit_r_counter, (1 << d_regs->_divider_select)
+			freq, d_regs->d_int, d_regs->d_frac,
+			d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select)
 		);*/
-	}while(d_regs->_int < MIN_INT_DIV);
+	}while(d_regs->d_int < MIN_INT_DIV);
 	/* calculate the band select so PFD is under 125 KHz */
-	d_regs->_8_bit_band_select_clock_divider_value = \
-		INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->_10_bit_r_counter) + 1;
+	d_regs->d_8_bit_band_select_clock_divider_value = \
+		INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1;
 	/* load involved registers */
 	d_regs->_load_register(2);
 	d_regs->_load_register(4);
@@ -145,12 +145,12 @@ adf4350::_get_freq(void){
 	 *  freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
 	 */
 	uint64_t temp;
-	temp = d_regs->_int;
-	temp *= d_regs->_mod;
-	temp += d_regs->_frac;
+	temp = d_regs->d_int;
+	temp *= d_regs->d_mod;
+	temp += d_regs->d_frac;
 	temp *= INPUT_REF_FREQ_2X;
-	temp /= d_regs->_mod;
-	temp /= d_regs->_10_bit_r_counter;
-	temp /= (1 << d_regs->_divider_select);
+	temp /= d_regs->d_mod;
+	temp /= d_regs->d_10_bit_r_counter;
+	temp /= (1 << d_regs->d_divider_select);
 	return temp;
 }
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc
index b320e8bbf..3452663c8 100644
--- a/usrp/host/lib/db_wbxng_adf4350_regs.cc
+++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc
@@ -6,47 +6,54 @@
 #include <usrp/db_wbxng_adf4350.h>
 //#include "cal_div.h"
 
+/* reg 0 */
+/* reg 1 */
+const uint8_t adf4350_regs::s_prescaler = 1;
+const uint16_t adf4350_regs::s_phase = 0;
+/* reg 2 */
+const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 0;
+const uint8_t adf4350_regs::s_muxout = 6;
+const uint8_t adf4350_regs::s_reference_doubler = 1;
+const uint8_t adf4350_regs::s_rdiv2 = 0;
+const uint8_t adf4350_regs::s_double_buff = 0;
+const uint8_t adf4350_regs::s_charge_pump_setting = 7;
+const uint8_t adf4350_regs::s_ldf = 0;
+const uint8_t adf4350_regs::s_ldp = 0;
+const uint8_t adf4350_regs::s_pd_polarity = 1;
+const uint8_t adf4350_regs::s_power_down = 0;
+const uint8_t adf4350_regs::s_cp_three_state = 0;
+const uint8_t adf4350_regs::s_counter_reset = 0;
+/* reg 3 */
+const uint8_t adf4350_regs::s_csr = 0;
+const uint8_t adf4350_regs::s_clk_div_mode = 0;
+const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0;
+/* reg 4 */
+const uint8_t adf4350_regs::s_feedback_select = 1;
+const uint8_t adf4350_regs::s_vco_power_down = 0;
+const uint8_t adf4350_regs::s_mtld = 0;
+const uint8_t adf4350_regs::s_aux_output_select = 0;
+const uint8_t adf4350_regs::s_aux_output_enable = 0;
+const uint8_t adf4350_regs::s_aux_output_power = 0;
+const uint8_t adf4350_regs::s_rf_output_enable = 1;
+const uint8_t adf4350_regs::s_output_power = 1;
+/* reg 5 */
+const uint8_t adf4350_regs::s_ld_pin_mode = 1;
+
 adf4350_regs::adf4350_regs(adf4350* _adf4350){
     d_adf4350 = _adf4350;
 
     /* reg 0 */
-    _int = uint16_t(100);
-    _frac = 0;
+    d_int = uint16_t(100);
+    d_frac = 0;
     /* reg 1 */
-    _prescaler = 1;                        /* 8/9 */
-    _phase = 0;                           /* 0 */
-    _mod = uint16_t(0xfff);                      /* max fractional accuracy */
+    d_mod = uint16_t(0xfff);                      /* max fractional accuracy */
     /* reg 2 */
-    _low_noise_and_low_spur_modes = 0;     /* low noise mode */
-    _muxout = 6;                           /* digital lock detect */
-    _reference_doubler = 1;                /* enabled */
-    _rdiv2 = 0;                            /* disabled */
-    _10_bit_r_counter = uint16_t(1);
-    _double_buff = 0;                      /* disabled */
-    _charge_pump_setting = 7;              /* 2.50 mA */
-    _ldf = 0;                              /* frac-n */
-    _ldp = 0;                              /* 10 ns */
-    _pd_polarity = 1;                      /* positive */
-    _power_down = 0;                       /* disabled */
-    _cp_three_state = 0;                   /* disabled */
-    _counter_reset = 0;                    /* disabled */
+    d_10_bit_r_counter = uint16_t(1);
     /* reg 3 */
-    _csr = 0;                              /* disabled */
-    _clk_div_mode = 0;                     /* clock divider off */
-    _12_bit_clock_divider_value = 0;      /* 0 */
     /* reg 4 */
-    _feedback_select = 1;                  /* fundamental */
-    _divider_select = 0;
-    _8_bit_band_select_clock_divider_value = 0;
-    _vco_power_down = 0;                   /* vco powered up */
-    _mtld = 0;                             /* mute disabled */
-    _aux_output_select = 0;                /* divided output */
-    _aux_output_enable = 0;                /* disabled */
-    _aux_output_power = 0;                 /* -4 */
-    _rf_output_enable = 1;                 /* enabled */
-    _output_power = 1;                     /* -1 */
+    d_divider_select = 0;
+    d_8_bit_band_select_clock_divider_value = 0;
     /* reg 5 */
-    _ld_pin_mode = 1;                      /* digital lock detect */
 }
 
 adf4350_regs::~adf4350_regs(void){
@@ -62,43 +69,43 @@ adf4350_regs::_load_register(uint8_t addr){
 	uint32_t data;
 	switch (addr){
 		case 0: data = (
-			_reg_shift(_int, 15)                           |
-			_reg_shift(_frac, 3)); break;
+			_reg_shift(d_int, 15)                           |
+			_reg_shift(d_frac, 3)); break;
 		case 1: data = (
-			_reg_shift(_prescaler, 27)                     |
-			_reg_shift(_phase, 15)                         |
-			_reg_shift(_mod, 3)); break;
+			_reg_shift(s_prescaler, 27)                     |
+			_reg_shift(s_phase, 15)                         |
+			_reg_shift(d_mod, 3)); break;
 		case 2: data = (
-			_reg_shift(_low_noise_and_low_spur_modes, 29)  |
-			_reg_shift(_muxout, 26)                        |
-			_reg_shift(_reference_doubler, 25)             |
-			_reg_shift(_rdiv2, 24)                         |
-			_reg_shift(_10_bit_r_counter, 14)              |
-			_reg_shift(_double_buff, 13)                   |
-			_reg_shift(_charge_pump_setting, 9)            |
-			_reg_shift(_ldf, 8)                            |
-			_reg_shift(_ldp, 7)                            |
-			_reg_shift(_pd_polarity, 6)                    |
-			_reg_shift(_power_down, 5)                     |
-			_reg_shift(_cp_three_state, 4)                 |
-			_reg_shift(_counter_reset, 3)); break;
+			_reg_shift(s_low_noise_and_low_spur_modes, 29)  |
+			_reg_shift(s_muxout, 26)                        |
+			_reg_shift(s_reference_doubler, 25)             |
+			_reg_shift(s_rdiv2, 24)                         |
+			_reg_shift(d_10_bit_r_counter, 14)              |
+			_reg_shift(s_double_buff, 13)                   |
+			_reg_shift(s_charge_pump_setting, 9)            |
+			_reg_shift(s_ldf, 8)                            |
+			_reg_shift(s_ldp, 7)                            |
+			_reg_shift(s_pd_polarity, 6)                    |
+			_reg_shift(s_power_down, 5)                     |
+			_reg_shift(s_cp_three_state, 4)                 |
+			_reg_shift(s_counter_reset, 3)); break;
 		case 3: data = (
-			_reg_shift(_csr, 18)                           |
-			_reg_shift(_clk_div_mode, 15)                  |
-			_reg_shift(_12_bit_clock_divider_value, 3)); break;
+			_reg_shift(s_csr, 18)                           |
+			_reg_shift(s_clk_div_mode, 15)                  |
+			_reg_shift(s_12_bit_clock_divider_value, 3)); break;
 		case 4: data = (
-			_reg_shift(_feedback_select, 23)               |
-			_reg_shift(_divider_select, 20)                |
-			_reg_shift(_8_bit_band_select_clock_divider_value, 12) |
-			_reg_shift(_vco_power_down, 11)                |
-			_reg_shift(_mtld, 10)                          |
-			_reg_shift(_aux_output_select, 9)              |
-			_reg_shift(_aux_output_enable, 8)              |
-			_reg_shift(_aux_output_power, 6)               |
-			_reg_shift(_rf_output_enable, 5)               |
-			_reg_shift(_output_power, 3)); break;
+			_reg_shift(s_feedback_select, 23)               |
+			_reg_shift(d_divider_select, 20)                |
+			_reg_shift(d_8_bit_band_select_clock_divider_value, 12) |
+			_reg_shift(s_vco_power_down, 11)                |
+			_reg_shift(s_mtld, 10)                          |
+			_reg_shift(s_aux_output_select, 9)              |
+			_reg_shift(s_aux_output_enable, 8)              |
+			_reg_shift(s_aux_output_power, 6)               |
+			_reg_shift(s_rf_output_enable, 5)               |
+			_reg_shift(s_output_power, 3)); break;
 		case 5: data = (
-			_reg_shift(_ld_pin_mode, 22)); break;
+			_reg_shift(s_ld_pin_mode, 22)); break;
 		default: return;
 	}
 	/* write the data out to spi */
-- 
cgit 


From e4b5ce36f60652dba15ff4124b347c9a8b725d05 Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Sun, 23 Aug 2009 17:40:43 -0700
Subject: Able to tune RX VCO, observe R and N divider output on MUXOUT

---
 usrp/host/lib/db_wbxng.cc              | 23 ++++++++++---------
 usrp/host/lib/db_wbxng_adf4350.cc      | 40 ++++++++++++++++++++++------------
 usrp/host/lib/db_wbxng_adf4350_regs.cc | 20 ++++++++---------
 3 files changed, 49 insertions(+), 34 deletions(-)

(limited to 'usrp')

diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index ccad3cb41..1c7b23265 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -43,10 +43,11 @@ wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on)
     @type which: int
   */
 
+  usrp()->_write_oe(d_which, 0, 0xffff);   // turn off all outputs
+
   d_first = true;
   d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
 
-  usrp()->_write_oe(d_which, 1, 0xffff);   // turn off all outputs
   _enable_refclk(false);                // disable refclk
 
   set_auto_tr(false);
@@ -202,11 +203,14 @@ wbxng_base::set_freq(double freq)
     actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
   */
 
-  freq_t int_freq = (freq_t) freq;
+  freq_t int_freq = (freq_t) (freq/1000);
   bool ok = d_common->_set_freq(int_freq);
-  double freq_result = (double) d_common->_get_freq();
+  double freq_result = (double) d_common->_get_freq()*1000;
   struct freq_result_t args = {ok, freq_result};
 
+  fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", 
+          int_freq*1000, freq_result, _lock_detect());
+
   // Offsetting the LO helps get the Tx carrier leakage out of the way.
   // This also ensures that on Rx, we're not getting hosed by the
   // FPGA's DC removal loop's time constant.  We were seeing a
@@ -287,8 +291,8 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
   
   // power up the transmit side, but don't enable the mixer
-  usrp()->_write_oe(d_which,(RX_TXN|ENABLE_33|ENABLE_5), 0xffff);
-  usrp()->write_io(d_which, (power_on()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
+  usrp()->_write_oe(d_which,(PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which, (power_on()|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
   //set_lo_offset(4e6);
 
   //set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
@@ -310,7 +314,7 @@ wbxng_base_tx::shutdown()
     // do whatever there is to do to shutdown
 
     // Power down and leave the T/R switch in the R position
-    usrp()->write_io(d_which, (power_off()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
+    usrp()->write_io(d_which, (power_off()|RX_TXN), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
 
     /*
     // Power down VCO/PLL
@@ -352,7 +356,7 @@ wbxng_base_tx::set_enable(bool on)
   int v;
   int mask = RX_TXN | ENABLE_5 | ENABLE_33;
   if(on) {
-    v = ENABLE_5 | ENABLE_33;
+    v = PLL_CE | ENABLE_5 | ENABLE_33;
   }
   else {
     v = RX_TXN;
@@ -411,9 +415,8 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
 
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
 
-  usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), 0xffff);
-  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), 
-		   (RX2_RX1N|ENABLE_33|ENABLE_5));
+  usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5));
   
   // set up for RX on TX/RX port
   select_rx_antenna("TX/RX");
diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc
index a1f024b4f..6e74bf0c1 100644
--- a/usrp/host/lib/db_wbxng_adf4350.cc
+++ b/usrp/host/lib/db_wbxng_adf4350.cc
@@ -13,11 +13,11 @@
 //#include "io.h"
 //#include "spi.h"
 
-#define INPUT_REF_FREQ FREQ_C(10e6)
+#define INPUT_REF_FREQ FREQ_C(32e6)
 #define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom))
-#define FREQ_C(freq) ((uint32_t)DIV_ROUND(freq, (uint32_t)1000))
+#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000))
 #define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ)                            /* input ref freq with doubler turned on */
-#define MIN_INT_DIV uint16_t(23)                                        /* minimum int divider, prescaler 4/5 only */
+#define MIN_INT_DIV uint16_t(300)                                        /* minimum int divider, prescaler 4/5 only */
 #define MAX_RF_DIV uint8_t(16)                                          /* max rf divider, divides rf output */
 #define MIN_VCO_FREQ FREQ_C(2.2e9)                                      /* minimum vco freq */
 #define MAX_VCO_FREQ FREQ_C(4.4e9)                                      /* minimum vco freq */
@@ -40,12 +40,23 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){
     d_regs = new adf4350_regs(this);
 
     /* Outputs */
-    d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), 0xffff);
+    d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
+    d_usrp->write_io(d_which, (CE_PIN), (CE_PIN | PDB_RF_PIN));
 
 	/* Initialize the pin levels. */
 	_enable(true);
 	/* Initialize the registers. */
-	d_regs->_load_register(5);
+    /*
+    timespec t;
+    t.tv_sec = 1;
+    t.tv_nsec = 0;
+    while (1) {
+    */
+    d_regs->_load_register(5);
+    /*
+        nanosleep(&t, NULL);
+    }
+    */
 	d_regs->_load_register(4);
 	d_regs->_load_register(3);
 	d_regs->_load_register(2);
@@ -75,9 +86,9 @@ adf4350::_get_locked(void){
 void 
 adf4350::_enable(bool enable){
 	if (enable){ /* chip enable */
-        d_usrp->write_io(d_which, 1, CE_PIN);
+        d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
 	}else{
-        d_usrp->write_io(d_which, 0, CE_PIN);
+        d_usrp->write_io(d_which, 0, (CE_PIN | PDB_RF_PIN));
 	}
 }
 
@@ -91,9 +102,10 @@ adf4350::_write(uint8_t addr, uint32_t data){
     s[1] = (char)((data >> 16) & 0xff);
     s[2] = (char)((data >>  8) & 0xff);
     s[3] = (char)(data & 0xff);
-    std::string str(s, 3);
+    std::string str(s, 4);
 
     d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str);
+    fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data);
 	/* pulse latch */
     //d_usrp->write_io(d_which, 1, LE_PIN);
     //d_usrp->write_io(d_which, 0, LE_PIN);
@@ -110,26 +122,26 @@ adf4350::_set_freq(freq_t freq){
 		d_regs->d_divider_select++; //double the divider
 	}
 	/* Ramp up the R divider until the N divider is at least the minimum. */
-	d_regs->d_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq;
+	d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq;
 	uint64_t n_mod;
 	do{
 		d_regs->d_10_bit_r_counter++;
 		n_mod = freq;
 		n_mod *= d_regs->d_10_bit_r_counter;
 		n_mod *= d_regs->d_mod;
-		n_mod /= INPUT_REF_FREQ_2X;
+		n_mod /= INPUT_REF_FREQ;
 		/* calculate int and frac */
 		d_regs->d_int = n_mod/d_regs->d_mod;
 		d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff);
-		/*printf(
+		fprintf(stderr,
 			"VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
 			freq, d_regs->d_int, d_regs->d_frac,
 			d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select)
-		);*/
+		);
 	}while(d_regs->d_int < MIN_INT_DIV);
 	/* calculate the band select so PFD is under 125 KHz */
 	d_regs->d_8_bit_band_select_clock_divider_value = \
-		INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1;
+		INPUT_REF_FREQ/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1;
 	/* load involved registers */
 	d_regs->_load_register(2);
 	d_regs->_load_register(4);
@@ -148,7 +160,7 @@ adf4350::_get_freq(void){
 	temp = d_regs->d_int;
 	temp *= d_regs->d_mod;
 	temp += d_regs->d_frac;
-	temp *= INPUT_REF_FREQ_2X;
+	temp *= INPUT_REF_FREQ;
 	temp /= d_regs->d_mod;
 	temp /= d_regs->d_10_bit_r_counter;
 	temp /= (1 << d_regs->d_divider_select);
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc
index 3452663c8..bf39c73ca 100644
--- a/usrp/host/lib/db_wbxng_adf4350_regs.cc
+++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc
@@ -8,13 +8,13 @@
 
 /* reg 0 */
 /* reg 1 */
-const uint8_t adf4350_regs::s_prescaler = 1;
+const uint8_t adf4350_regs::s_prescaler = 0;
 const uint16_t adf4350_regs::s_phase = 0;
 /* reg 2 */
 const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 0;
-const uint8_t adf4350_regs::s_muxout = 6;
-const uint8_t adf4350_regs::s_reference_doubler = 1;
-const uint8_t adf4350_regs::s_rdiv2 = 0;
+const uint8_t adf4350_regs::s_muxout = 3;
+const uint8_t adf4350_regs::s_reference_doubler = 0;
+const uint8_t adf4350_regs::s_rdiv2 = 1;
 const uint8_t adf4350_regs::s_double_buff = 0;
 const uint8_t adf4350_regs::s_charge_pump_setting = 7;
 const uint8_t adf4350_regs::s_ldf = 0;
@@ -31,11 +31,11 @@ const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0;
 const uint8_t adf4350_regs::s_feedback_select = 1;
 const uint8_t adf4350_regs::s_vco_power_down = 0;
 const uint8_t adf4350_regs::s_mtld = 0;
-const uint8_t adf4350_regs::s_aux_output_select = 0;
-const uint8_t adf4350_regs::s_aux_output_enable = 0;
-const uint8_t adf4350_regs::s_aux_output_power = 0;
-const uint8_t adf4350_regs::s_rf_output_enable = 1;
-const uint8_t adf4350_regs::s_output_power = 1;
+const uint8_t adf4350_regs::s_aux_output_select = 1;
+const uint8_t adf4350_regs::s_aux_output_enable = 1;
+const uint8_t adf4350_regs::s_aux_output_power = 1;
+const uint8_t adf4350_regs::s_rf_output_enable = 0;
+const uint8_t adf4350_regs::s_output_power = 0;
 /* reg 5 */
 const uint8_t adf4350_regs::s_ld_pin_mode = 1;
 
@@ -48,7 +48,7 @@ adf4350_regs::adf4350_regs(adf4350* _adf4350){
     /* reg 1 */
     d_mod = uint16_t(0xfff);                      /* max fractional accuracy */
     /* reg 2 */
-    d_10_bit_r_counter = uint16_t(1);
+    d_10_bit_r_counter = uint16_t(2);
     /* reg 3 */
     /* reg 4 */
     d_divider_select = 0;
-- 
cgit 


From a85e0396f5adf1c4d72d81cbbead02e139a6d5af Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Mon, 24 Aug 2009 16:20:03 -0700
Subject: Locking, controllable synthesizer on TX and RX

    set Charge Pump Current (Icp) per design guide on schem
    set R divider to 3, so that PFD inputs are ~21MHz
    set RF output enable even when looking for AUX
---
 usrp/host/lib/db_wbxng.cc              | 22 ++++++++++++++--------
 usrp/host/lib/db_wbxng_adf4350.cc      | 28 ++++++++++++++++++++++------
 usrp/host/lib/db_wbxng_adf4350_regs.cc | 14 +++++++-------
 3 files changed, 43 insertions(+), 21 deletions(-)

(limited to 'usrp')

diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index 1c7b23265..970d8efd6 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -203,13 +203,19 @@ wbxng_base::set_freq(double freq)
     actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
   */
 
-  freq_t int_freq = (freq_t) (freq/1000);
+  freq_t int_freq = freq_t(freq);
   bool ok = d_common->_set_freq(int_freq);
-  double freq_result = (double) d_common->_get_freq()*1000;
+  double freq_result = (double) d_common->_get_freq();
   struct freq_result_t args = {ok, freq_result};
 
+  /* Wait before reading Lock Detect*/
+  timespec t;
+  t.tv_sec = 0;
+  t.tv_nsec = 10000000;
+  nanosleep(&t, NULL);
+
   fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", 
-          int_freq*1000, freq_result, _lock_detect());
+          int_freq, freq_result, _lock_detect());
 
   // Offsetting the LO helps get the Tx carrier leakage out of the way.
   // This also ensures that on Rx, we're not getting hosed by the
@@ -291,8 +297,8 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
   
   // power up the transmit side, but don't enable the mixer
-  usrp()->_write_oe(d_which,(PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
-  usrp()->write_io(d_which, (power_on()|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
+  usrp()->_write_oe(d_which,(PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which, (power_on()|PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
   //set_lo_offset(4e6);
 
   //set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
@@ -314,7 +320,7 @@ wbxng_base_tx::shutdown()
     // do whatever there is to do to shutdown
 
     // Power down and leave the T/R switch in the R position
-    usrp()->write_io(d_which, (power_off()|RX_TXN), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
+    usrp()->write_io(d_which, (power_off()|RX_TXN), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
 
     /*
     // Power down VCO/PLL
@@ -354,9 +360,9 @@ wbxng_base_tx::set_enable(bool on)
   */
 
   int v;
-  int mask = RX_TXN | ENABLE_5 | ENABLE_33;
+  int mask = PLL_PDBRF | PLL_PDBRF | RX_TXN | ENABLE_5 | ENABLE_33;
   if(on) {
-    v = PLL_CE | ENABLE_5 | ENABLE_33;
+    v = PLL_PDBRF | PLL_CE | ENABLE_5 | ENABLE_33;
   }
   else {
     v = RX_TXN;
diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc
index 6e74bf0c1..1facfd882 100644
--- a/usrp/host/lib/db_wbxng_adf4350.cc
+++ b/usrp/host/lib/db_wbxng_adf4350.cc
@@ -13,11 +13,12 @@
 //#include "io.h"
 //#include "spi.h"
 
-#define INPUT_REF_FREQ FREQ_C(32e6)
+#define INPUT_REF_FREQ FREQ_C(64e6)
 #define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom))
-#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000))
+//#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000))
+#define FREQ_C(freq) uint64_t(freq)
 #define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ)                            /* input ref freq with doubler turned on */
-#define MIN_INT_DIV uint16_t(300)                                        /* minimum int divider, prescaler 4/5 only */
+#define MIN_INT_DIV uint16_t(23)                                        /* minimum int divider, prescaler 4/5 only */
 #define MAX_RF_DIV uint8_t(16)                                          /* max rf divider, divides rf output */
 #define MIN_VCO_FREQ FREQ_C(2.2e9)                                      /* minimum vco freq */
 #define MAX_VCO_FREQ FREQ_C(4.4e9)                                      /* minimum vco freq */
@@ -41,7 +42,7 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){
 
     /* Outputs */
     d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
-    d_usrp->write_io(d_which, (CE_PIN), (CE_PIN | PDB_RF_PIN));
+    d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
 
 	/* Initialize the pin levels. */
 	_enable(true);
@@ -104,7 +105,14 @@ adf4350::_write(uint8_t addr, uint32_t data){
     s[3] = (char)(data & 0xff);
     std::string str(s, 4);
 
+    timespec t;
+    t.tv_sec = 0;
+    t.tv_nsec = 5e6;
+
+    nanosleep(&t, NULL);
     d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str);
+    nanosleep(&t, NULL);
+
     fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data);
 	/* pulse latch */
     //d_usrp->write_io(d_which, 1, LE_PIN);
@@ -122,7 +130,8 @@ adf4350::_set_freq(freq_t freq){
 		d_regs->d_divider_select++; //double the divider
 	}
 	/* Ramp up the R divider until the N divider is at least the minimum. */
-	d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq;
+	//d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq;
+	d_regs->d_10_bit_r_counter = 2;
 	uint64_t n_mod;
 	do{
 		d_regs->d_10_bit_r_counter++;
@@ -141,7 +150,14 @@ adf4350::_set_freq(freq_t freq){
 	}while(d_regs->d_int < MIN_INT_DIV);
 	/* calculate the band select so PFD is under 125 KHz */
 	d_regs->d_8_bit_band_select_clock_divider_value = \
-		INPUT_REF_FREQ/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1;
+		INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1;
+    fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", 
+        d_regs->d_8_bit_band_select_clock_divider_value, 
+		INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1
+    );
+	d_regs->_load_register(5);
+	d_regs->_load_register(3);
+	d_regs->_load_register(1);
 	/* load involved registers */
 	d_regs->_load_register(2);
 	d_regs->_load_register(4);
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc
index bf39c73ca..2c1660f56 100644
--- a/usrp/host/lib/db_wbxng_adf4350_regs.cc
+++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc
@@ -12,11 +12,11 @@ const uint8_t adf4350_regs::s_prescaler = 0;
 const uint16_t adf4350_regs::s_phase = 0;
 /* reg 2 */
 const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 0;
-const uint8_t adf4350_regs::s_muxout = 3;
+const uint8_t adf4350_regs::s_muxout = 6;
 const uint8_t adf4350_regs::s_reference_doubler = 0;
-const uint8_t adf4350_regs::s_rdiv2 = 1;
+const uint8_t adf4350_regs::s_rdiv2 = 0;
 const uint8_t adf4350_regs::s_double_buff = 0;
-const uint8_t adf4350_regs::s_charge_pump_setting = 7;
+const uint8_t adf4350_regs::s_charge_pump_setting = 5;
 const uint8_t adf4350_regs::s_ldf = 0;
 const uint8_t adf4350_regs::s_ldp = 0;
 const uint8_t adf4350_regs::s_pd_polarity = 1;
@@ -31,11 +31,11 @@ const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0;
 const uint8_t adf4350_regs::s_feedback_select = 1;
 const uint8_t adf4350_regs::s_vco_power_down = 0;
 const uint8_t adf4350_regs::s_mtld = 0;
-const uint8_t adf4350_regs::s_aux_output_select = 1;
+const uint8_t adf4350_regs::s_aux_output_select = 0;
 const uint8_t adf4350_regs::s_aux_output_enable = 1;
-const uint8_t adf4350_regs::s_aux_output_power = 1;
-const uint8_t adf4350_regs::s_rf_output_enable = 0;
-const uint8_t adf4350_regs::s_output_power = 0;
+const uint8_t adf4350_regs::s_aux_output_power = 3;
+const uint8_t adf4350_regs::s_rf_output_enable = 1;
+const uint8_t adf4350_regs::s_output_power = 3;
 /* reg 5 */
 const uint8_t adf4350_regs::s_ld_pin_mode = 1;
 
-- 
cgit 


From 9aff67eeedcaf7c0fcca0fe2410ec2a3dbd4ea02 Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Fri, 18 Sep 2009 18:28:02 -0700
Subject: First Functional TX modulator

---
 usrp/host/lib/db_wbxng.cc         |  35 ++++-----
 usrp/host/lib/db_wbxng_adf4350.cc | 156 ++++++++++++++++++--------------------
 2 files changed, 91 insertions(+), 100 deletions(-)

(limited to 'usrp')

diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index 970d8efd6..8a03cfbac 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -21,6 +21,7 @@
 #include <usrp/db_wbxng.h>
 #include <usrp/db_wbxng_adf4350.h>
 #include <db_base_impl.h>
+#include <stdio.h>
 
 // d'board i/o pin defs
 // Tx and Rx have shared defs, but different i/o regs
@@ -28,7 +29,7 @@
 #define ENABLE_33       (1 << 6)         // enables 3.3V supply
 #define RX_TXN          (1 << 5)         // Tx only: T/R antenna switch for TX/RX port
 #define RX2_RX1N        (1 << 5)         // Rx only: antenna switch between RX2 and TX/RX port
-#define BBAMP_EN        (1 << 4)
+#define TXMOD_EN        (1 << 4)
 #define PLL_CE          (1 << 3)
 #define PLL_PDBRF       (1 << 2)
 #define PLL_MUXOUT      (1 << 1)
@@ -204,8 +205,8 @@ wbxng_base::set_freq(double freq)
   */
 
   freq_t int_freq = freq_t(freq);
-  bool ok = d_common->_set_freq(int_freq);
-  double freq_result = (double) d_common->_get_freq();
+  bool ok = d_common->_set_freq(int_freq*2);
+  double freq_result = (double) d_common->_get_freq()/2.0;
   struct freq_result_t args = {ok, freq_result};
 
   /* Wait before reading Lock Detect*/
@@ -268,13 +269,13 @@ wbxng_base::is_quadrature()
 double
 wbxng_base::freq_min()
 {
-  return (double) d_common->_get_min_freq();
+  return (double) d_common->_get_min_freq()/2.0;
 }
 
 double
 wbxng_base::freq_max()
 {
-  return (double) d_common->_get_max_freq();
+  return (double) d_common->_get_max_freq()/2.0;
 }
 
 // ----------------------------------------------------------------
@@ -297,8 +298,9 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
   
   // power up the transmit side, but don't enable the mixer
-  usrp()->_write_oe(d_which,(PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
-  usrp()->write_io(d_which, (power_on()|PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
+  usrp()->_write_oe(d_which,(RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which, (power_on()|RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5));
+  fprintf(stderr,"Setting WBXNG TXMOD on"); 
   //set_lo_offset(4e6);
 
   //set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
@@ -320,12 +322,12 @@ wbxng_base_tx::shutdown()
     // do whatever there is to do to shutdown
 
     // Power down and leave the T/R switch in the R position
-    usrp()->write_io(d_which, (power_off()|RX_TXN), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5));
+    usrp()->write_io(d_which, (power_off()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5));
 
-    /*
     // Power down VCO/PLL
-    d_PD = 3;
+    d_common->_enable(false);
   
+    /*
     _write_control(_compute_control_reg());
     */
     _enable_refclk(false);                       // turn off refclk
@@ -337,7 +339,6 @@ bool
 wbxng_base_tx::set_auto_tr(bool on)
 {
   bool ok = true;
-  /*
   if(on) {
     ok &= set_atr_mask (RX_TXN | ENABLE_33 | ENABLE_5);
     ok &= set_atr_txval(0      | ENABLE_33 | ENABLE_5);
@@ -348,7 +349,6 @@ wbxng_base_tx::set_auto_tr(bool on)
     ok &= set_atr_txval(0);
     ok &= set_atr_rxval(0);
   }
-  */
   return ok;
 }
 
@@ -360,9 +360,9 @@ wbxng_base_tx::set_enable(bool on)
   */
 
   int v;
-  int mask = PLL_PDBRF | PLL_PDBRF | RX_TXN | ENABLE_5 | ENABLE_33;
+  int mask = RX_TXN | ENABLE_5 | ENABLE_33;
   if(on) {
-    v = PLL_PDBRF | PLL_CE | ENABLE_5 | ENABLE_33;
+    v = ENABLE_5 | ENABLE_33;
   }
   else {
     v = RX_TXN;
@@ -452,8 +452,7 @@ wbxng_base_rx::shutdown()
     usrp()->common_write_io(C_RX, d_which, power_off(), (ENABLE_33|ENABLE_5));
 
     // Power down VCO/PLL
-    d_PD = 3;
-  
+    d_common->_enable(false);
 
     // fprintf(stderr, "wbxng_base_rx::shutdown  before _write_control\n");
     //_write_control(_compute_control_reg());
@@ -471,8 +470,7 @@ wbxng_base_rx::shutdown()
 bool
 wbxng_base_rx::set_auto_tr(bool on)
 {
-  //bool ok = true;
-  /*
+  bool ok = true;
   if(on) {
     ok &= set_atr_mask (ENABLE_33|ENABLE_5);
     ok &= set_atr_txval(     0);
@@ -483,7 +481,6 @@ wbxng_base_rx::set_auto_tr(bool on)
     ok &= set_atr_txval(0);
     ok &= set_atr_rxval(0);
   }
-  */
   return true;
 }
 
diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc
index 1facfd882..73485d90c 100644
--- a/usrp/host/lib/db_wbxng_adf4350.cc
+++ b/usrp/host/lib/db_wbxng_adf4350.cc
@@ -31,7 +31,7 @@
 #define LD_PIN        (1 << 0)
 
 adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){
-	/* Initialize the pin directions. */
+    /* Initialize the pin directions. */
 
     d_usrp = _usrp;
     d_which = _which;
@@ -42,27 +42,17 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){
 
     /* Outputs */
     d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
-    d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
+    d_usrp->write_io(d_which, (0), (CE_PIN | PDB_RF_PIN));
 
-	/* Initialize the pin levels. */
-	_enable(true);
-	/* Initialize the registers. */
-    /*
-    timespec t;
-    t.tv_sec = 1;
-    t.tv_nsec = 0;
-    while (1) {
-    */
+    /* Initialize the pin levels. */
+    _enable(true);
+    /* Initialize the registers. */
     d_regs->_load_register(5);
-    /*
-        nanosleep(&t, NULL);
-    }
-    */
-	d_regs->_load_register(4);
-	d_regs->_load_register(3);
-	d_regs->_load_register(2);
-	d_regs->_load_register(1);
-	d_regs->_load_register(0);
+    d_regs->_load_register(4);
+    d_regs->_load_register(3);
+    d_regs->_load_register(2);
+    d_regs->_load_register(1);
+    d_regs->_load_register(0);
 }
 
 adf4350::~adf4350(){
@@ -71,12 +61,12 @@ adf4350::~adf4350(){
 
 freq_t 
 adf4350::_get_max_freq(void){
-	return MAX_FREQ;
+    return MAX_FREQ;
 }
 
 freq_t 
 adf4350::_get_min_freq(void){
-	return MIN_FREQ;
+    return MIN_FREQ;
 }
 
 bool 
@@ -86,16 +76,16 @@ adf4350::_get_locked(void){
 
 void 
 adf4350::_enable(bool enable){
-	if (enable){ /* chip enable */
+    if (enable){ /* chip enable */
         d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
-	}else{
+    }else{
         d_usrp->write_io(d_which, 0, (CE_PIN | PDB_RF_PIN));
-	}
+    }
 }
 
 void 
 adf4350::_write(uint8_t addr, uint32_t data){
-	data |= addr;
+    data |= addr;
 
     // create str from data here
     char s[4];
@@ -113,72 +103,76 @@ adf4350::_write(uint8_t addr, uint32_t data){
     d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str);
     nanosleep(&t, NULL);
 
-    fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data);
-	/* pulse latch */
+    //fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data);
+    /* pulse latch */
     //d_usrp->write_io(d_which, 1, LE_PIN);
     //d_usrp->write_io(d_which, 0, LE_PIN);
 }
 
 bool 
 adf4350::_set_freq(freq_t freq){
-	/* Set the frequency by setting int, frac, mod, r, div */
-	if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
-	/* Ramp up the RF divider until the VCO is within range. */
-	d_regs->d_divider_select = 0;
-	while (freq < MIN_VCO_FREQ){
-		freq <<= 1; //double the freq
-		d_regs->d_divider_select++; //double the divider
-	}
-	/* Ramp up the R divider until the N divider is at least the minimum. */
-	//d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq;
-	d_regs->d_10_bit_r_counter = 2;
-	uint64_t n_mod;
-	do{
-		d_regs->d_10_bit_r_counter++;
-		n_mod = freq;
-		n_mod *= d_regs->d_10_bit_r_counter;
-		n_mod *= d_regs->d_mod;
-		n_mod /= INPUT_REF_FREQ;
-		/* calculate int and frac */
-		d_regs->d_int = n_mod/d_regs->d_mod;
-		d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff);
-		fprintf(stderr,
-			"VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
-			freq, d_regs->d_int, d_regs->d_frac,
-			d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select)
-		);
-	}while(d_regs->d_int < MIN_INT_DIV);
-	/* calculate the band select so PFD is under 125 KHz */
-	d_regs->d_8_bit_band_select_clock_divider_value = \
-		INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1;
+    /* Set the frequency by setting int, frac, mod, r, div */
+    if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
+    /* Ramp up the RF divider until the VCO is within range. */
+    d_regs->d_divider_select = 0;
+    while (freq < MIN_VCO_FREQ){
+        freq <<= 1; //double the freq
+        d_regs->d_divider_select++; //double the divider
+    }
+    /* Ramp up the R divider until the N divider is at least the minimum. */
+    //d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq;
+    d_regs->d_10_bit_r_counter = 2;
+    uint64_t n_mod;
+    do{
+        d_regs->d_10_bit_r_counter++;
+        n_mod = freq;
+        n_mod *= d_regs->d_10_bit_r_counter;
+        n_mod *= d_regs->d_mod;
+        n_mod /= INPUT_REF_FREQ;
+        /* calculate int and frac */
+        d_regs->d_int = n_mod/d_regs->d_mod;
+        d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff);
+        /*
+        fprintf(stderr,
+            "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n",
+            freq, d_regs->d_int, d_regs->d_frac,
+            d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select)
+        );
+        */
+    }while(d_regs->d_int < MIN_INT_DIV);
+    /* calculate the band select so PFD is under 125 KHz */
+    d_regs->d_8_bit_band_select_clock_divider_value = \
+        INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1;
+    /*
     fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", 
         d_regs->d_8_bit_band_select_clock_divider_value, 
-		INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1
+        INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1
     );
-	d_regs->_load_register(5);
-	d_regs->_load_register(3);
-	d_regs->_load_register(1);
-	/* load involved registers */
-	d_regs->_load_register(2);
-	d_regs->_load_register(4);
-	d_regs->_load_register(0); /* register 0 must be last */
-	return true;
+    */
+    d_regs->_load_register(5);
+    d_regs->_load_register(3);
+    d_regs->_load_register(1);
+    /* load involved registers */
+    d_regs->_load_register(2);
+    d_regs->_load_register(4);
+    d_regs->_load_register(0); /* register 0 must be last */
+    return true;
 }
 
 freq_t 
 adf4350::_get_freq(void){
-	/* Calculate the freq from int, frac, mod, ref, r, div:
-	 *  freq = (int + frac/mod) * (ref/r)
-	 * Keep precision by doing multiplies first:
-	 *  freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
-	 */
-	uint64_t temp;
-	temp = d_regs->d_int;
-	temp *= d_regs->d_mod;
-	temp += d_regs->d_frac;
-	temp *= INPUT_REF_FREQ;
-	temp /= d_regs->d_mod;
-	temp /= d_regs->d_10_bit_r_counter;
-	temp /= (1 << d_regs->d_divider_select);
-	return temp;
+    /* Calculate the freq from int, frac, mod, ref, r, div:
+     *  freq = (int + frac/mod) * (ref/r)
+     * Keep precision by doing multiplies first:
+     *  freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div)
+     */
+    uint64_t temp;
+    temp = d_regs->d_int;
+    temp *= d_regs->d_mod;
+    temp += d_regs->d_frac;
+    temp *= INPUT_REF_FREQ;
+    temp /= d_regs->d_mod;
+    temp /= d_regs->d_10_bit_r_counter;
+    temp /= (1 << d_regs->d_divider_select);
+    return temp;
 }
-- 
cgit 


From 48e2124c1eac6806d3259964d80348ad1d64214c Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Tue, 22 Sep 2009 14:07:42 -0700
Subject: Enabled RX Baseband

---
 usrp/host/lib/db_wbxng.cc | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'usrp')

diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index 8a03cfbac..aa61012e7 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -29,6 +29,7 @@
 #define ENABLE_33       (1 << 6)         // enables 3.3V supply
 #define RX_TXN          (1 << 5)         // Tx only: T/R antenna switch for TX/RX port
 #define RX2_RX1N        (1 << 5)         // Rx only: antenna switch between RX2 and TX/RX port
+#define RXBB_EN         (1 << 4)
 #define TXMOD_EN        (1 << 4)
 #define PLL_CE          (1 << 3)
 #define PLL_PDBRF       (1 << 2)
@@ -421,8 +422,9 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
 
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
 
-  usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5));
-  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5));
+  usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5));
+  fprintf(stderr,"Setting WBXNG RXBB on"); 
   
   // set up for RX on TX/RX port
   select_rx_antenna("TX/RX");
-- 
cgit 


From bf0bbd9daf5360b5d1fb5f36dcb968d6bcd0fd60 Mon Sep 17 00:00:00 2001
From: Jason Abele
Date: Thu, 24 Sep 2009 16:12:26 -0700
Subject: Integrated gain control for TX and RX of wbxng

---
 usrp/host/include/usrp/db_wbxng.h |  1 +
 usrp/host/lib/db_wbxng.cc         | 69 +++++++++++++++++++++++++++------------
 2 files changed, 49 insertions(+), 21 deletions(-)

(limited to 'usrp')

diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h
index 0d03e4297..fb5c8da71 100644
--- a/usrp/host/include/usrp/db_wbxng.h
+++ b/usrp/host/include/usrp/db_wbxng.h
@@ -95,6 +95,7 @@ class wbxng_base_rx : public wbxng_base
 {
 protected:
   void shutdown();
+  bool _set_attn(float attn);
 
 public:
   wbxng_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0);
diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index aa61012e7..0dd8b0d38 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -36,6 +36,10 @@
 #define PLL_MUXOUT      (1 << 1)
 #define PLL_LOCK_DETECT (1 << 0)
 
+// RX Attenuator constants
+#define ATTN_SHIFT	8
+#define ATTN_MASK	(63 << ATTN_SHIFT)
+
 wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on)
   : db_base(_usrp, which), d_power_on(_power_on)
 {
@@ -243,7 +247,6 @@ wbxng_base::set_freq(double freq)
 bool
 wbxng_base::_set_pga(float pga_gain)
 {
-  /*
   if(d_which == 0) {
     usrp()->set_pga(0, pga_gain);
     usrp()->set_pga(1, pga_gain);
@@ -252,7 +255,6 @@ wbxng_base::_set_pga(float pga_gain)
     usrp()->set_pga(2, pga_gain);
     usrp()->set_pga(3, pga_gain);
   }
-  */
   return true;
 }
 
@@ -304,7 +306,7 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
   fprintf(stderr,"Setting WBXNG TXMOD on"); 
   //set_lo_offset(4e6);
 
-  //set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
+  set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
 }
 
 wbxng_base_tx::~wbxng_base_tx()
@@ -380,7 +382,7 @@ wbxng_base_tx::gain_min()
 float
 wbxng_base_tx::gain_max()
 {
-  return usrp()->pga_max();
+  return usrp()->pga_max() + 25.0;
 }
 
 float
@@ -398,7 +400,35 @@ wbxng_base_tx::set_gain(float gain)
     @param gain:  gain in decibels
     @returns True/False
   */
-  return _set_pga(usrp()->pga_max());
+  
+  // clamp gain
+  gain = std::max(gain_min(), std::min(gain, gain_max()));
+
+  float pga_gain, agc_gain;
+  float V_maxgain, V_mingain, V_fullscale, dac_value;
+
+  float maxgain = gain_max() - usrp()->pga_max();
+  float mingain = gain_min();
+  if(gain > maxgain) {
+    pga_gain = gain-maxgain;
+    assert(pga_gain <= usrp()->pga_max());
+    agc_gain = maxgain;
+  }
+  else {
+    pga_gain = 0;
+    agc_gain = gain;
+  }
+  
+  V_maxgain = 0.7;
+  V_mingain = 1.4;
+  V_fullscale = 3.3;
+  dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
+
+  fprintf(stderr, "TXGAIN: %f dB, Dac Code: %d, Voltage: %f\n", gain, int(dac_value), float((dac_value/4096.0)*V_fullscale));
+  assert(dac_value>=0 && dac_value<4096);
+
+  return (usrp()->write_aux_dac(d_which, 0, int(dac_value))
+	  && _set_pga(int(pga_gain)));
 }
 
 
@@ -422,8 +452,8 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
 
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
 
-  usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5));
-  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5));
+  usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5));
+  usrp()->write_io(d_which,  (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5));
   fprintf(stderr,"Setting WBXNG RXBB on"); 
   
   // set up for RX on TX/RX port
@@ -540,12 +570,10 @@ wbxng_base_rx::set_gain(float gain)
     @returns True/False
   */
   
-  /*
   // clamp gain
   gain = std::max(gain_min(), std::min(gain, gain_max()));
 
   float pga_gain, agc_gain;
-  float V_maxgain, V_mingain, V_fullscale, dac_value;
 
   float maxgain = gain_max() - usrp()->pga_max();
   float mingain = gain_min();
@@ -559,17 +587,16 @@ wbxng_base_rx::set_gain(float gain)
     agc_gain = gain;
   }
   
-  V_maxgain = .2;
-  V_mingain = 1.2;
-  V_fullscale = 3.3;
-  dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
-
-  assert(dac_value>=0 && dac_value<4096);
+  return _set_attn(maxgain-agc_gain) && _set_pga(int(pga_gain));
+}
 
-  return (usrp()->write_aux_dac(d_which, 0, int(dac_value))
-	  && _set_pga(int(pga_gain)));
-  */
-  return false;
+bool
+wbxng_base_rx::_set_attn(float attn)
+{
+  int attn_code = int(floor(attn/0.5));
+  unsigned int iobits = (~attn_code) << ATTN_SHIFT;
+  fprintf(stderr, "Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x \n", attn, attn_code, iobits & ATTN_MASK, ATTN_MASK);
+  return usrp()->write_io(d_which, iobits, ATTN_MASK);
 }
 
 // ----------------------------------------------------------------
@@ -613,7 +640,7 @@ db_wbxng_rx::gain_min()
 float
 db_wbxng_rx::gain_max()
 {
-  return usrp()->pga_max()+70;
+  return usrp()->pga_max()+30.5;
 }
 
 float
@@ -626,7 +653,7 @@ db_wbxng_rx::gain_db_per_step()
 bool
 db_wbxng_rx::i_and_q_swapped()
 {
-  return true;
+  return false;
 }
 
 /*
-- 
cgit 


From 69caa7dce5a58b39614b1aba99c2dd71b38af322 Mon Sep 17 00:00:00 2001
From: Johnathan Corgan
Date: Tue, 6 Oct 2009 17:50:59 -0700
Subject: Clean up for work-in-progress

Copyright updates
Trailing whitespace cleanup
Move private headers out of install
Use standard include guards
Code cleanup
---
 usrp/host/apps/burn-db-eeprom                  |  18 +-
 usrp/host/include/usrp/Makefile.am             |  14 +-
 usrp/host/include/usrp/db_wbxng.h              |  37 ++--
 usrp/host/include/usrp/db_wbxng_adf4350.h      |  37 ----
 usrp/host/include/usrp/db_wbxng_adf4350_regs.h |  65 -------
 usrp/host/lib/Makefile.am                      |  12 +-
 usrp/host/lib/db_boards.cc                     |  14 +-
 usrp/host/lib/db_wbxng.cc                      | 227 ++++---------------------
 usrp/host/lib/db_wbxng_adf4350.cc              |  73 +++++---
 usrp/host/lib/db_wbxng_adf4350.h               |  53 ++++++
 usrp/host/lib/db_wbxng_adf4350_regs.cc         |   9 +-
 usrp/host/lib/db_wbxng_adf4350_regs.h          |  64 +++++++
 usrp/host/lib/usrp_dbid.dat                    |   8 +-
 13 files changed, 241 insertions(+), 390 deletions(-)
 delete mode 100644 usrp/host/include/usrp/db_wbxng_adf4350.h
 delete mode 100644 usrp/host/include/usrp/db_wbxng_adf4350_regs.h
 create mode 100644 usrp/host/lib/db_wbxng_adf4350.h
 create mode 100644 usrp/host/lib/db_wbxng_adf4350_regs.h

(limited to 'usrp')

diff --git a/usrp/host/apps/burn-db-eeprom b/usrp/host/apps/burn-db-eeprom
index 195c4e897..7ff1e9736 100755
--- a/usrp/host/apps/burn-db-eeprom
+++ b/usrp/host/apps/burn-db-eeprom
@@ -1,24 +1,24 @@
 #!/usr/bin/env python
 #
-# Copyright 2005,2007 Free Software Foundation, Inc.
-# 
+# Copyright 2005,2007,2009 Free Software Foundation, Inc.
+#
 # This file is part of GNU Radio
-# 
+#
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 3, or (at your option)
 # any later version.
-# 
+#
 # GNU Radio is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with GNU Radio; see the file COPYING.  If not, write to
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
-# 
+#
 
 from usrpm.usrp_prims import *
 from optparse import OptionParser
@@ -105,11 +105,11 @@ def init_eeprom(u, slot_name, force, dbid, oe):
     if not e:
         print "%s: no d'board, skipped" % (slot_name,)
         return True
-    
+
     if not force and (sum (map (ord, e)) & 0xff) == 0 and ord (e[0]) == 0xDB:
         print "%s: already initialized, skipped" % (slot_name,)
         return True
-        
+
     if not write_dboard_eeprom (u, i2c_addr, dbid, oe):
         print "%s: failed to write d'board EEPROM" % (slot_name,)
         return False
@@ -169,4 +169,4 @@ and at least one side using -A and/or -B."""
 
 if __name__ == "__main__":
     main ()
-    
+
diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am
index 7c868e061..cfce51443 100644
--- a/usrp/host/include/usrp/Makefile.am
+++ b/usrp/host/include/usrp/Makefile.am
@@ -1,23 +1,23 @@
 #
 # Copyright 2009 Free Software Foundation, Inc.
-# 
+#
 # This file is part of GNU Radio
-# 
+#
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 3, or (at your option)
 # any later version.
-# 
+#
 # GNU Radio is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with GNU Radio; see the file COPYING.  If not, write to
 # the Free Software Foundation, Inc., 51 Franklin Street,
 # Boston, MA 02110-1301, USA.
-# 
+#
 
 include $(top_srcdir)/Makefile.common
 
@@ -32,9 +32,7 @@ usrpinclude_HEADERS = \
 	db_flexrf.h \
 	db_flexrf_mimo.h \
 	db_tv_rx.h \
- 	db_tv_rx_mimo.h	\
-	db_wbxng_adf4350.h \
-	db_wbxng_adf4350_regs.h \
+	db_tv_rx_mimo.h	\
 	db_wbxng.h \
 	db_xcvr2450.h \
 	libusb_types.h \
diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h
index fb5c8da71..2158face2 100644
--- a/usrp/host/include/usrp/db_wbxng.h
+++ b/usrp/host/include/usrp/db_wbxng.h
@@ -1,33 +1,30 @@
 /* -*- c++ -*- */
 //
-// Copyright 2008,2009 Free Software Foundation, Inc.
-// 
+// Copyright 2009 Free Software Foundation, Inc.
+//
 // This file is part of GNU Radio
-// 
+//
 // GNU Radio is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation; either asversion 3, or (at your option)
 // any later version.
-// 
+//
 // GNU Radio is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
-// 
+//
 // You should have received a copy of the GNU General Public License
 // along with GNU Radio; see the file COPYING.  If not, write to
 // the Free Software Foundation, Inc., 51 Franklin Street,
 // Boston, MA 02110-1301, USA.
 
-#ifndef DB_WBXNG_H
-#define DB_WBXNG_H
+#ifndef INCLUDED_DB_WBXNG_H
+#define INCLUDED_DB_WBXNG_H
 
 #include <usrp/db_base.h>
 #include <cmath>
 
-//debug_using_gui = true                // Must be set to True or False
-#define debug_using_gui false           // Must be set to True or False
-
 class adf4350;
 
 class wbxng_base : public db_base
@@ -43,11 +40,6 @@ public:
   double freq_max();
 
 protected:
-  void _write_all(int R, int control, int N);
-  void _write_control(int control);
-  void _write_R(int R);
-  void _write_N(int N);
-  void _write_it(int v);
   bool _lock_detect();
 
   //virtual bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
@@ -80,8 +72,6 @@ public:
   wbxng_base_tx(usrp_basic_sptr usrp, int which, int _power_on=0);
   ~wbxng_base_tx();
 
-  //*** TODO *** Fix comment
-  // All RFX tx d'boards have fixed gain
   float gain_min();
   float gain_max();
   float gain_db_per_step();
@@ -100,12 +90,11 @@ protected:
 public:
   wbxng_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0);
   ~wbxng_base_rx();
-    
+
   bool set_auto_tr(bool on);
   bool select_rx_antenna(int which_antenna);
   bool select_rx_antenna(const std::string &which_antenna);
   bool set_gain(float gain);
-
 };
 
 // ----------------------------------------------------------------
@@ -115,9 +104,6 @@ class db_wbxng_tx : public wbxng_base_tx
  public:
   db_wbxng_tx(usrp_basic_sptr usrp, int which);
   ~db_wbxng_tx();
-
-  // Wrapper calls to d_common functions
-  //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
 };
 
 class db_wbxng_rx : public wbxng_base_rx
@@ -125,14 +111,11 @@ class db_wbxng_rx : public wbxng_base_rx
 public:
   db_wbxng_rx(usrp_basic_sptr usrp, int which);
   ~db_wbxng_rx();
-  
+
   float gain_min();
   float gain_max();
   float gain_db_per_step();
   bool i_and_q_swapped();
-
-  //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq);
 };
 
-
-#endif
+#endif /* INCLUDED_DB_WBXNG_H */
diff --git a/usrp/host/include/usrp/db_wbxng_adf4350.h b/usrp/host/include/usrp/db_wbxng_adf4350.h
deleted file mode 100644
index d7b8dd99b..000000000
--- a/usrp/host/include/usrp/db_wbxng_adf4350.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2009 Ettus Research LLC
- */
-
-#ifndef ADF4350_H
-#define ADF4350_H
-
-#include <usrp/db_wbxng_adf4350_regs.h>
-#include <usrp/db_base.h>
-#include <stdint.h>
-
-typedef uint64_t freq_t;
-class adf4350_regs;
-
-class adf4350
-{
-public:
-    adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable);
-    ~adf4350();
-    void _update();
-    bool _get_locked();
-    void _enable(bool enable);
-    void _write(uint8_t addr, uint32_t data);
-    bool _set_freq(freq_t freq);
-    freq_t _get_freq();
-    freq_t _get_max_freq();
-    freq_t _get_min_freq();
-
-protected:
-    usrp_basic_sptr d_usrp;
-    int d_which;
-    int d_spi_enable;
-    int d_spi_format;
-    adf4350_regs *d_regs;
-};
-
-#endif /* ADF4350_H */
diff --git a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h
deleted file mode 100644
index 6a5b77a4b..000000000
--- a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2009 Ettus Research LLC
- */
-
-#ifndef ADF4350_REGS_H
-#define ADF4350_REGS_H
-
-#include <usrp/db_wbxng_adf4350.h>
-#include <usrp/db_base.h>
-#include <stdint.h>
-
-class adf4350;
-
-class adf4350_regs
-{
-public:
-    adf4350_regs(adf4350* _adf4350);
-    ~adf4350_regs();
-
-    adf4350* d_adf4350;
-
-    uint32_t _reg_shift(uint32_t data, uint32_t shift);
-    void _load_register(uint8_t addr);
-
-    /* reg 0 */
-    uint16_t d_int;
-    uint16_t d_frac;
-    /* reg 1 */
-    static const uint8_t s_prescaler;
-    static const uint16_t s_phase;
-    uint16_t d_mod;
-    /* reg 2 */
-    static const uint8_t s_low_noise_and_low_spur_modes;
-    static const uint8_t s_muxout;
-    static const uint8_t s_reference_doubler;
-    static const uint8_t s_rdiv2;
-    uint16_t d_10_bit_r_counter;
-    static const uint8_t s_double_buff;
-    static const uint8_t s_charge_pump_setting;
-    static const uint8_t s_ldf;
-    static const uint8_t s_ldp;
-    static const uint8_t s_pd_polarity;
-    static const uint8_t s_power_down;
-    static const uint8_t s_cp_three_state;
-    static const uint8_t s_counter_reset;
-    /* reg 3 */
-    static const uint8_t s_csr;
-    static const uint8_t s_clk_div_mode;
-    static const uint16_t s_12_bit_clock_divider_value;
-    /* reg 4 */
-    static const uint8_t s_feedback_select;
-    uint8_t d_divider_select;
-    uint8_t d_8_bit_band_select_clock_divider_value;
-    static const uint8_t s_vco_power_down;
-    static const uint8_t s_mtld;
-    static const uint8_t s_aux_output_select;
-    static const uint8_t s_aux_output_enable;
-    static const uint8_t s_aux_output_power;
-    static const uint8_t s_rf_output_enable;
-    static const uint8_t s_output_power;
-    /* reg 5 */
-    static const uint8_t s_ld_pin_mode;
-};
-
-#endif /* ADF4350_REGS_H */
diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am
index 13f25d69b..72312ebbb 100644
--- a/usrp/host/lib/Makefile.am
+++ b/usrp/host/lib/Makefile.am
@@ -1,22 +1,22 @@
 #
 #  USRP - Universal Software Radio Peripheral
-# 
+#
 #  Copyright (C) 2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc.
-# 
+#
 #  This program is free software; you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation; either version 3 of the License, or
 #  (at your option) any later version.
-# 
+#
 #  This program is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
-# 
+#
 #  You should have received a copy of the GNU General Public License
 #  along with this program; if not, write to the Free Software
 #  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
-# 
+#
 
 include $(top_srcdir)/Makefile.common
 
@@ -168,6 +168,8 @@ noinst_HEADERS =			\
 	db_base_impl.h			\
 	db_boards.h			\
 	db_util.h			\
+	db_wbxng_adf4350.h		\
+	db_wbxng_adf4350_regs.h		\
 	fusb.h				\
 	fusb_darwin.h			\
 	fusb_generic.h			\
diff --git a/usrp/host/lib/db_boards.cc b/usrp/host/lib/db_boards.cc
index 53304bd1a..590d8132d 100644
--- a/usrp/host/lib/db_boards.cc
+++ b/usrp/host/lib/db_boards.cc
@@ -1,19 +1,19 @@
 /* -*- c++ -*- */
 //
 // Copyright 2008,2009 Free Software Foundation, Inc.
-// 
+//
 // This file is part of GNU Radio
-// 
+//
 // GNU Radio is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation; either asversion 3, or (at your option)
 // any later version.
-// 
+//
 // GNU Radio is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
-// 
+//
 // You should have received a copy of the GNU General Public License
 // along with GNU Radio; see the file COPYING.  If not, write to
 // the Free Software Foundation, Inc., 51 Franklin Street,
@@ -64,7 +64,7 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side)
     db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 1)));
     db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 2)));
     break;
-    
+
   case(USRP_DBID_DBS_RX):
     db.push_back(db_base_sptr(new db_dbs_rx(usrp, which_side)));
     break;
@@ -185,7 +185,7 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side)
   case(USRP_DBID_XCVR2450_RX):
     db.push_back(db_base_sptr(new db_xcvr2450_rx(usrp, which_side)));
     break;
-  
+
 #if 0	// FIXME wbx doesn't compile
   case(USRP_DBID_WBX_LO_TX):
     db.push_back(db_base_sptr(new db_wbx_lo_tx(usrp, which_side)));
@@ -218,7 +218,7 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side)
       db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1)));
     }
     break;
-  
+
   case(-2):
   default:
     if (boost::dynamic_pointer_cast<usrp_basic_tx>(usrp)){
diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc
index 0dd8b0d38..c23fc47ed 100644
--- a/usrp/host/lib/db_wbxng.cc
+++ b/usrp/host/lib/db_wbxng.cc
@@ -1,25 +1,25 @@
 //
-// Copyright 2008 Free Software Foundation, Inc.
-// 
+// Copyright 2008,2009 Free Software Foundation, Inc.
+//
 // This file is part of GNU Radio
-// 
+//
 // GNU Radio is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
 // the Free Software Foundation; either asversion 3, or (at your option)
 // any later version.
-// 
+//
 // GNU Radio is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
-// 
+//
 // You should have received a copy of the GNU General Public License
 // along with GNU Radio; see the file COPYING.  If not, write to
 // the Free Software Foundation, Inc., 51 Franklin Street,
 // Boston, MA 02110-1301, USA.
 
 #include <usrp/db_wbxng.h>
-#include <usrp/db_wbxng_adf4350.h>
+#include "db_wbxng_adf4350.h"
 #include <db_base_impl.h>
 #include <stdio.h>
 
@@ -61,143 +61,8 @@ wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on)
 
 wbxng_base::~wbxng_base()
 {
-  delete d_common;
-}
-
-void
-wbxng_base::_write_all(int R, int control, int N)
-{
-  /*
-    Write R counter latch, control latch and N counter latch to VCO.
-    
-    Adds 10ms delay between writing control and N if this is first call.
-    This is the required power-up sequence.
-    
-    @param R: 24-bit R counter latch
-    @type R: int
-    @param control: 24-bit control latch
-    @type control: int
-    @param N: 24-bit N counter latch
-    @type N: int
-  */
-  timespec t;
-  t.tv_sec = 0;
-  t.tv_nsec = 10000000;
-
-  /*
-  _write_R(R);
-  _write_control(control);
-  if(d_first) {
-    //time.sleep(0.010);
-    nanosleep(&t, NULL);
-    d_first = false;
-  }
-  _write_N(N);
-  */
-}
-
-void
-wbxng_base::_write_control(int control)
-{
-  //_write_it((control & ~0x3) | 0);
-}
-
-void
-wbxng_base::_write_R(int R)
-{
-  //_write_it((R & ~0x3) | 1);
-}
-
-void
-wbxng_base::_write_N(int N)
-{
-  //_write_it((N & ~0x3) | 2);
-}
-
-void
-wbxng_base::_write_it(int v)
-{
-  char s[3];
-  s[0] = (char)((v >> 16) & 0xff);
-  s[1] = (char)((v >>  8) & 0xff);
-  s[2] = (char)(v & 0xff);
-  std::string str(s, 3);
-  //usrp()->_write_spi(0, d_spi_enable, d_spi_format, str);
-}
-        
-bool
-wbxng_base::_lock_detect()
-{
-  /*
-    @returns: the value of the VCO/PLL lock detect bit.
-    @rtype: 0 or 1
-  */
-  
-  if(d_common->_get_locked()){
-    return true;
-  }
-  else {      // Give it a second chance
-    return false;
-    /*
-    // FIXME: make portable sleep
-    timespec t;
-    t.tv_sec = 0;
-    t.tv_nsec = 100000000;
-    nanosleep(&t, NULL);
-    
-    if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
-      return true;
-    }
-    else {
-      return false;
-    }
-    */
-  }
- 
-  throw std::runtime_error("_lock_detect called from wbxng_base\n");
-}
-
-/*
-bool
-wbxng_base::_compute_regs(double freq, int &retR, int &retcontrol,
-			   int &retN, double &retfreq)
-{
-  **COMMENT**
-    Determine values of R, control, and N registers, along with actual freq.
-    
-    @param freq: target frequency in Hz
-    @type freq: float
-    @returns: (R, control, N, actual_freq)
-    @rtype: tuple(int, int, int, float)
-    
-    Override this in derived classes.
-  **COMMENT**
-  
-  //raise NotImplementedError;
-  throw std::runtime_error("_compute_regs called from wbxng_base\n");
-}
-*/
-
-int
-wbxng_base::_compute_control_reg()
-{
-  throw std::runtime_error("_compute_control_reg called from wbxng_base\n");
-  //return d_common->_compute_control_reg();
-}
-
-int
-wbxng_base::_refclk_divisor()
-{
-  throw std::runtime_error("_refclk_divisor called from wbxng_base\n");
-  //return d_common->_refclk_divisor();
-}
-
-double
-wbxng_base::_refclk_freq()
-{
-  throw std::runtime_error("_refclk_divisor called from wbxng_base\n");
-  // *** TODO *** Magic Number 64e6?
-  //return 64e6/_refclk_divisor();
+  if (d_common)
+    delete d_common;
 }
 
 struct freq_result_t
@@ -220,27 +85,17 @@ wbxng_base::set_freq(double freq)
   t.tv_nsec = 10000000;
   nanosleep(&t, NULL);
 
-  fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", 
+  fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n",
           int_freq, freq_result, _lock_detect());
 
+  // FIXME
   // Offsetting the LO helps get the Tx carrier leakage out of the way.
   // This also ensures that on Rx, we're not getting hosed by the
   // FPGA's DC removal loop's time constant.  We were seeing a
   // problem when running with discontinuous transmission.
   // Offsetting the LO made the problem go away.
   //freq += d_lo_offset;
-  
-  //int R, control, N;
-  //double actual_freq;
-  //_compute_regs(freq, R, control, N, actual_freq);
-
-  //if(R==0) {
-  //  return args;
-  //}
-   
-  //_write_all(R, control, N);
-  //args.ok = _lock_detect();
-  //args.baseband_freq = actual_freq;
+
   return args;
 }
 
@@ -263,7 +118,7 @@ wbxng_base::is_quadrature()
 {
   /*
     Return True if this board requires both I & Q analog channels.
-    
+
     This bit of info is useful when setting up the USRP Rx mux register.
   */
   return true;
@@ -290,7 +145,7 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
     @param usrp: instance of usrp.sink_c
     @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
   */
-  
+
   if(which == 0) {
     d_spi_enable = SPI_ENABLE_TX_A;
   }
@@ -299,11 +154,11 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
   }
 
   d_common = new adf4350(_usrp, d_which, d_spi_enable);
-  
-  // power up the transmit side, but don't enable the mixer
+
+  // FIXME: power up the transmit side, but don't enable the mixer
   usrp()->_write_oe(d_which,(RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5));
   usrp()->write_io(d_which, (power_on()|RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5));
-  fprintf(stderr,"Setting WBXNG TXMOD on"); 
+  fprintf(stderr,"Setting WBXNG TXMOD on");
   //set_lo_offset(4e6);
 
   set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
@@ -329,7 +184,7 @@ wbxng_base_tx::shutdown()
 
     // Power down VCO/PLL
     d_common->_enable(false);
-  
+
     /*
     _write_control(_compute_control_reg());
     */
@@ -396,11 +251,11 @@ wbxng_base_tx::set_gain(float gain)
 {
   /*
     Set the gain.
-    
+
     @param gain:  gain in decibels
     @returns True/False
   */
-  
+
   // clamp gain
   gain = std::max(gain_min(), std::min(gain, gain_max()));
 
@@ -418,7 +273,7 @@ wbxng_base_tx::set_gain(float gain)
     pga_gain = 0;
     agc_gain = gain;
   }
-  
+
   V_maxgain = 0.7;
   V_mingain = 1.4;
   V_fullscale = 3.3;
@@ -454,14 +309,14 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
 
   usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5));
   usrp()->write_io(d_which,  (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5));
-  fprintf(stderr,"Setting WBXNG RXBB on"); 
-  
+  fprintf(stderr,"Setting WBXNG RXBB on");
+
   // set up for RX on TX/RX port
   select_rx_antenna("TX/RX");
-  
+
   bypass_adc_buffers(true);
 
-  /*  
+  /*
   set_lo_offset(-4e6);
   */
 }
@@ -532,7 +387,6 @@ wbxng_base_rx::select_rx_antenna(int which_antenna)
   }
   else {
     return false;
-    // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
   }
   return true;
 }
@@ -545,7 +399,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
     @param which_antenna: either 'TX/RX' or 'RX2'
   */
 
-  
+
   if(which_antenna == "TX/RX") {
     usrp()->write_io(d_which, 0, RX2_RX1N);
   }
@@ -553,10 +407,9 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna)
     usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
   }
   else {
-    // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
     return false;
   }
-  
+
   return true;
 }
 
@@ -565,11 +418,11 @@ wbxng_base_rx::set_gain(float gain)
 {
   /*
     Set the gain.
-    
+
     @param gain:  gain in decibels
     @returns True/False
   */
-  
+
   // clamp gain
   gain = std::max(gain_min(), std::min(gain, gain_max()));
 
@@ -586,7 +439,7 @@ wbxng_base_rx::set_gain(float gain)
     pga_gain = 0;
     agc_gain = gain;
   }
-  
+
   return _set_attn(maxgain-agc_gain) && _set_pga(int(pga_gain));
 }
 
@@ -610,17 +463,6 @@ db_wbxng_tx::~db_wbxng_tx()
 {
 }
 
-/*
-bool
-db_wbxng_tx::_compute_regs(double freq, int &retR, int &retcontrol,
-				 int &retN, double &retfreq)
-{
-  return d_common->_compute_regs(_refclk_freq(), freq, retR,
-				 retcontrol, retN, retfreq);
-}
-*/
-
-
 db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which)
   : wbxng_base_rx(usrp, which)
 {
@@ -655,14 +497,3 @@ db_wbxng_rx::i_and_q_swapped()
 {
   return false;
 }
-
-/*
-bool
-db_wbxng_rx::_compute_regs(double freq, int &retR, int &retcontrol,
-				 int &retN, double &retfreq)
-{
-  return d_common->_compute_regs(_refclk_freq(), freq, retR,
-				 retcontrol, retN, retfreq);
-}
-*/
-
diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc
index 73485d90c..af4eac573 100644
--- a/usrp/host/lib/db_wbxng_adf4350.cc
+++ b/usrp/host/lib/db_wbxng_adf4350.cc
@@ -1,21 +1,33 @@
-/*
- * Copyright 2009 Ettus Research LLC
- */
+//
+// Copyright 2009 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-#include <usrp/db_wbxng_adf4350.h>
-#include <usrp/db_wbxng_adf4350_regs.h>
+#include "db_wbxng_adf4350.h"
 #include <db_base_impl.h>
 #include <stdio.h>
-//#include "io.h"
-//#include "spi.h"
 
 #define INPUT_REF_FREQ FREQ_C(64e6)
 #define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom))
-//#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000))
 #define FREQ_C(freq) uint64_t(freq)
 #define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ)                            /* input ref freq with doubler turned on */
 #define MIN_INT_DIV uint16_t(23)                                        /* minimum int divider, prescaler 4/5 only */
@@ -30,7 +42,8 @@
 #define MUX_PIN       (1 << 1)
 #define LD_PIN        (1 << 0)
 
-adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){
+adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable)
+{
     /* Initialize the pin directions. */
 
     d_usrp = _usrp;
@@ -55,27 +68,32 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){
     d_regs->_load_register(0);
 }
 
-adf4350::~adf4350(){
+adf4350::~adf4350()
+{
     delete d_regs;
 }
 
-freq_t 
-adf4350::_get_max_freq(void){
+freq_t
+adf4350::_get_max_freq(void)
+{
     return MAX_FREQ;
 }
 
-freq_t 
-adf4350::_get_min_freq(void){
+freq_t
+adf4350::_get_min_freq(void)
+{
     return MIN_FREQ;
 }
 
-bool 
-adf4350::_get_locked(void){
+bool
+adf4350::_get_locked(void)
+{
     return d_usrp->read_io(d_which) & LD_PIN;
 }
 
-void 
-adf4350::_enable(bool enable){
+void
+adf4350::_enable(bool enable)
+{
     if (enable){ /* chip enable */
         d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN));
     }else{
@@ -83,8 +101,9 @@ adf4350::_enable(bool enable){
     }
 }
 
-void 
-adf4350::_write(uint8_t addr, uint32_t data){
+void
+adf4350::_write(uint8_t addr, uint32_t data)
+{
     data |= addr;
 
     // create str from data here
@@ -109,8 +128,9 @@ adf4350::_write(uint8_t addr, uint32_t data){
     //d_usrp->write_io(d_which, 0, LE_PIN);
 }
 
-bool 
-adf4350::_set_freq(freq_t freq){
+bool
+adf4350::_set_freq(freq_t freq)
+{
     /* Set the frequency by setting int, frac, mod, r, div */
     if (freq > MAX_FREQ || freq < MIN_FREQ) return false;
     /* Ramp up the RF divider until the VCO is within range. */
@@ -144,8 +164,8 @@ adf4350::_set_freq(freq_t freq){
     d_regs->d_8_bit_band_select_clock_divider_value = \
         INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1;
     /*
-    fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", 
-        d_regs->d_8_bit_band_select_clock_divider_value, 
+    fprintf(stderr, "Band Selection: Div %u, Freq %lu\n",
+        d_regs->d_8_bit_band_select_clock_divider_value,
         INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1
     );
     */
@@ -159,8 +179,9 @@ adf4350::_set_freq(freq_t freq){
     return true;
 }
 
-freq_t 
-adf4350::_get_freq(void){
+freq_t
+adf4350::_get_freq(void)
+{
     /* Calculate the freq from int, frac, mod, ref, r, div:
      *  freq = (int + frac/mod) * (ref/r)
      * Keep precision by doing multiplies first:
diff --git a/usrp/host/lib/db_wbxng_adf4350.h b/usrp/host/lib/db_wbxng_adf4350.h
new file mode 100644
index 000000000..2b0783c20
--- /dev/null
+++ b/usrp/host/lib/db_wbxng_adf4350.h
@@ -0,0 +1,53 @@
+//
+// Copyright 2009 Free Software Foundation, Inc.
+//
+// This file is part of GNU Radio
+//
+// GNU Radio is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either asversion 3, or (at your option)
+// any later version.
+//
+// GNU Radio is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GNU Radio; see the file COPYING.  If not, write to
+// the Free Software Foundation, Inc., 51 Franklin Street,
+// Boston, MA 02110-1301, USA.
+
+#ifndef INCLUDED_ADF4350_H
+#define INCLUDED_ADF4350_H
+
+#include "db_wbxng_adf4350_regs.h"
+#include <usrp/db_base.h>
+#include <stdint.h>
+
+typedef uint64_t freq_t;
+class adf4350_regs;
+
+class adf4350
+{
+public:
+    adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable);
+    ~adf4350();
+    void _update();
+    bool _get_locked();
+    void _enable(bool enable);
+    void _write(uint8_t addr, uint32_t data);
+    bool _set_freq(freq_t freq);
+    freq_t _get_freq();
+    freq_t _get_max_freq();
+    freq_t _get_min_freq();
+
+protected:
+    usrp_basic_sptr d_usrp;
+    int d_which;
+    int d_spi_enable;
+    int d_spi_format;
+    adf4350_regs *d_regs;
+};
+
+#endif /* INCLUDED_ADF4350_H */
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc
index 2c1660f56..11dcf8816 100644
--- a/usrp/host/lib/db_wbxng_adf4350_regs.cc
+++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc
@@ -2,8 +2,9 @@
  * Copyright 2009 Ettus Research LLC
  */
 
-#include <usrp/db_wbxng_adf4350_regs.h>
-#include <usrp/db_wbxng_adf4350.h>
+#include "db_wbxng_adf4350_regs.h"
+#include "db_wbxng_adf4350.h"
+
 //#include "cal_div.h"
 
 /* reg 0 */
@@ -59,12 +60,12 @@ adf4350_regs::adf4350_regs(adf4350* _adf4350){
 adf4350_regs::~adf4350_regs(void){
 }
 
-uint32_t 
+uint32_t
 adf4350_regs::_reg_shift(uint32_t data, uint32_t shift){
         return data << shift;
     }
 
-void 
+void
 adf4350_regs::_load_register(uint8_t addr){
 	uint32_t data;
 	switch (addr){
diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.h b/usrp/host/lib/db_wbxng_adf4350_regs.h
new file mode 100644
index 000000000..dc941ee87
--- /dev/null
+++ b/usrp/host/lib/db_wbxng_adf4350_regs.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2009 Ettus Research LLC
+ */
+
+#ifndef ADF4350_REGS_H
+#define ADF4350_REGS_H
+
+#include <usrp/db_base.h>
+#include <stdint.h>
+
+class adf4350;
+
+class adf4350_regs
+{
+public:
+    adf4350_regs(adf4350* _adf4350);
+    ~adf4350_regs();
+
+    adf4350* d_adf4350;
+
+    uint32_t _reg_shift(uint32_t data, uint32_t shift);
+    void _load_register(uint8_t addr);
+
+    /* reg 0 */
+    uint16_t d_int;
+    uint16_t d_frac;
+    /* reg 1 */
+    static const uint8_t s_prescaler;
+    static const uint16_t s_phase;
+    uint16_t d_mod;
+    /* reg 2 */
+    static const uint8_t s_low_noise_and_low_spur_modes;
+    static const uint8_t s_muxout;
+    static const uint8_t s_reference_doubler;
+    static const uint8_t s_rdiv2;
+    uint16_t d_10_bit_r_counter;
+    static const uint8_t s_double_buff;
+    static const uint8_t s_charge_pump_setting;
+    static const uint8_t s_ldf;
+    static const uint8_t s_ldp;
+    static const uint8_t s_pd_polarity;
+    static const uint8_t s_power_down;
+    static const uint8_t s_cp_three_state;
+    static const uint8_t s_counter_reset;
+    /* reg 3 */
+    static const uint8_t s_csr;
+    static const uint8_t s_clk_div_mode;
+    static const uint16_t s_12_bit_clock_divider_value;
+    /* reg 4 */
+    static const uint8_t s_feedback_select;
+    uint8_t d_divider_select;
+    uint8_t d_8_bit_band_select_clock_divider_value;
+    static const uint8_t s_vco_power_down;
+    static const uint8_t s_mtld;
+    static const uint8_t s_aux_output_select;
+    static const uint8_t s_aux_output_enable;
+    static const uint8_t s_aux_output_power;
+    static const uint8_t s_rf_output_enable;
+    static const uint8_t s_output_power;
+    /* reg 5 */
+    static const uint8_t s_ld_pin_mode;
+};
+
+#endif /* ADF4350_REGS_H */
diff --git a/usrp/host/lib/usrp_dbid.dat b/usrp/host/lib/usrp_dbid.dat
index 1df28802e..7d1e18714 100644
--- a/usrp/host/lib/usrp_dbid.dat
+++ b/usrp/host/lib/usrp_dbid.dat
@@ -1,18 +1,18 @@
 #
 # Copyright 2005,2009 Free Software Foundation, Inc.
-# 
+#
 # This file is part of GNU Radio
-# 
+#
 # GNU Radio is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 3, or (at your option)
 # any later version.
-# 
+#
 # GNU Radio is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License along
 # with this program; if not, write to the Free Software Foundation, Inc.,
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-- 
cgit