aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/dboard
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/dboard')
-rw-r--r--host/lib/usrp/dboard/db_basic_and_lf.cpp8
-rw-r--r--host/lib/usrp/dboard/db_dbsrx.cpp10
-rw-r--r--host/lib/usrp/dboard/db_dbsrx2.cpp10
-rw-r--r--host/lib/usrp/dboard/db_e3x0.cpp4
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp50
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.cpp78
-rw-r--r--host/lib/usrp/dboard/db_sbx_common.hpp25
-rw-r--r--host/lib/usrp/dboard/db_sbx_version3.cpp111
-rw-r--r--host/lib/usrp/dboard/db_sbx_version4.cpp122
-rw-r--r--host/lib/usrp/dboard/db_tvrx.cpp6
-rw-r--r--host/lib/usrp/dboard/db_tvrx2.cpp16
-rw-r--r--host/lib/usrp/dboard/db_ubx.cpp175
-rw-r--r--host/lib/usrp/dboard/db_wbx_common.cpp14
-rw-r--r--host/lib/usrp/dboard/db_wbx_common.hpp20
-rw-r--r--host/lib/usrp/dboard/db_wbx_simple.cpp42
-rw-r--r--host/lib/usrp/dboard/db_wbx_version2.cpp140
-rw-r--r--host/lib/usrp/dboard/db_wbx_version3.cpp142
-rw-r--r--host/lib/usrp/dboard/db_wbx_version4.cpp140
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp46
19 files changed, 428 insertions, 731 deletions
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp
index 2b30dab52..941a80ea4 100644
--- a/host/lib/usrp/dboard/db_basic_and_lf.cpp
+++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp
@@ -50,7 +50,7 @@ static const uhd::dict<std::string, double> subdev_bandwidth_scalar = map_list_o
class basic_rx : public rx_dboard_base{
public:
basic_rx(ctor_args_t args, double max_freq);
- ~basic_rx(void);
+ virtual ~basic_rx(void);
private:
double _max_freq;
@@ -59,7 +59,7 @@ private:
class basic_tx : public tx_dboard_base{
public:
basic_tx(ctor_args_t args, double max_freq);
- ~basic_tx(void);
+ virtual ~basic_tx(void);
private:
double _max_freq;
@@ -121,7 +121,7 @@ basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args){
this->get_rx_subtree()->create<int>("gains"); //phony property so this dir exists
this->get_rx_subtree()->create<double>("freq/value")
- .publish(&always_zero_freq);
+ .set_publisher(&always_zero_freq);
this->get_rx_subtree()->create<meta_range_t>("freq/range")
.set(freq_range_t(-_max_freq, +_max_freq));
this->get_rx_subtree()->create<std::string>("antenna/value")
@@ -176,7 +176,7 @@ basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args){
this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists
this->get_tx_subtree()->create<double>("freq/value")
- .publish(&always_zero_freq);
+ .set_publisher(&always_zero_freq);
this->get_tx_subtree()->create<meta_range_t>("freq/range")
.set(freq_range_t(-_max_freq, +_max_freq));
this->get_tx_subtree()->create<std::string>("antenna/value")
diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp
index 9d04d8e16..6e1846fb8 100644
--- a/host/lib/usrp/dboard/db_dbsrx.cpp
+++ b/host/lib/usrp/dboard/db_dbsrx.cpp
@@ -66,7 +66,7 @@ static const double usrp1_gpio_clock_rate_limit = 4e6;
class dbsrx : public rx_dboard_base{
public:
dbsrx(ctor_args_t args);
- ~dbsrx(void);
+ virtual ~dbsrx(void);
private:
double _lo_freq;
@@ -204,16 +204,16 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){
this->get_rx_subtree()->create<std::string>("name")
.set("DBSRX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&dbsrx::get_locked, this));
+ .set_publisher(boost::bind(&dbsrx::get_locked, this));
BOOST_FOREACH(const std::string &name, dbsrx_gain_ranges.keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&dbsrx::set_gain, this, _1, name))
+ .set_coercer(boost::bind(&dbsrx::set_gain, this, _1, name))
.set(dbsrx_gain_ranges[name].start());
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(dbsrx_gain_ranges[name]);
}
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&dbsrx::set_lo_freq, this, _1));
+ .set_coercer(boost::bind(&dbsrx::set_lo_freq, this, _1));
this->get_rx_subtree()->create<meta_range_t>("freq/range")
.set(dbsrx_freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
@@ -227,7 +227,7 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){
this->get_rx_subtree()->create<bool>("use_lo_offset")
.set(false);
this->get_rx_subtree()->create<double>("bandwidth/value")
- .coerce(boost::bind(&dbsrx::set_bandwidth, this, _1));
+ .set_coercer(boost::bind(&dbsrx::set_bandwidth, this, _1));
this->get_rx_subtree()->create<meta_range_t>("bandwidth/range")
.set(dbsrx_bandwidth_range);
diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp
index 1debe3c8f..11d706ed6 100644
--- a/host/lib/usrp/dboard/db_dbsrx2.cpp
+++ b/host/lib/usrp/dboard/db_dbsrx2.cpp
@@ -60,7 +60,7 @@ static const uhd::dict<std::string, gain_range_t> dbsrx2_gain_ranges = map_list_
class dbsrx2 : public rx_dboard_base{
public:
dbsrx2(ctor_args_t args);
- ~dbsrx2(void);
+ virtual ~dbsrx2(void);
private:
double _lo_freq;
@@ -191,16 +191,16 @@ dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args){
this->get_rx_subtree()->create<std::string>("name")
.set("DBSRX2");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&dbsrx2::get_locked, this));
+ .set_publisher(boost::bind(&dbsrx2::get_locked, this));
BOOST_FOREACH(const std::string &name, dbsrx2_gain_ranges.keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&dbsrx2::set_gain, this, _1, name))
+ .set_coercer(boost::bind(&dbsrx2::set_gain, this, _1, name))
.set(dbsrx2_gain_ranges[name].start());
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(dbsrx2_gain_ranges[name]);
}
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&dbsrx2::set_lo_freq, this, _1))
+ .set_coercer(boost::bind(&dbsrx2::set_lo_freq, this, _1))
.set(dbsrx2_freq_range.start());
this->get_rx_subtree()->create<meta_range_t>("freq/range")
.set(dbsrx2_freq_range);
@@ -218,7 +218,7 @@ dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args){
double codec_rate = this->get_iface()->get_codec_rate(dboard_iface::UNIT_RX);
this->get_rx_subtree()->create<double>("bandwidth/value")
- .coerce(boost::bind(&dbsrx2::set_bandwidth, this, _1))
+ .set_coercer(boost::bind(&dbsrx2::set_bandwidth, this, _1))
.set(2.0*(0.8*codec_rate/2.0)); //bandwidth in lowpass, convert to complex bandpass
//default to anti-alias at different codec_rate
this->get_rx_subtree()->create<meta_range_t>("bandwidth/range")
diff --git a/host/lib/usrp/dboard/db_e3x0.cpp b/host/lib/usrp/dboard/db_e3x0.cpp
index 523927d49..c7cc52d73 100644
--- a/host/lib/usrp/dboard/db_e3x0.cpp
+++ b/host/lib/usrp/dboard/db_e3x0.cpp
@@ -29,7 +29,7 @@ class e310_dboard : public xcvr_dboard_base{
public:
e310_dboard(ctor_args_t args) : xcvr_dboard_base(args) {}
- ~e310_dboard(void) {}
+ virtual ~e310_dboard(void) {}
};
/***********************************************************************
@@ -40,7 +40,7 @@ class e300_dboard : public xcvr_dboard_base{
public:
e300_dboard(ctor_args_t args) : xcvr_dboard_base(args) {}
- ~e300_dboard(void) {}
+ virtual ~e300_dboard(void) {}
};
/***********************************************************************
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 1342c913d..dbb1600ec 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -78,7 +78,7 @@ public:
const freq_range_t &freq_range,
bool rx_div2, bool tx_div2
);
- ~rfx_xcvr(void);
+ virtual ~rfx_xcvr(void);
private:
const freq_range_t _freq_range;
@@ -183,20 +183,20 @@ rfx_xcvr::rfx_xcvr(
else this->get_rx_subtree()->create<std::string>("name").set("RFX RX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_RX));
+ .set_publisher(boost::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_RX));
BOOST_FOREACH(const std::string &name, _rx_gain_ranges.keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&rfx_xcvr::set_rx_gain, this, _1, name))
+ .set_coercer(boost::bind(&rfx_xcvr::set_rx_gain, this, _1, name))
.set(_rx_gain_ranges[name].start());
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(_rx_gain_ranges[name]);
}
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
+ .set_coercer(boost::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
.set((_freq_range.start() + _freq_range.stop())/2.0);
this->get_rx_subtree()->create<meta_range_t>("freq/range").set(_freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&rfx_xcvr::set_rx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&rfx_xcvr::set_rx_ant, this, _1))
.set("RX2");
this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(rfx_rx_antennas);
@@ -219,14 +219,14 @@ rfx_xcvr::rfx_xcvr(
else this->get_tx_subtree()->create<std::string>("name").set("RFX TX");
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_TX));
+ .set_publisher(boost::bind(&rfx_xcvr::get_locked, this, dboard_iface::UNIT_TX));
this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists
this->get_tx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
+ .set_coercer(boost::bind(&rfx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
.set((_freq_range.start() + _freq_range.stop())/2.0);
this->get_tx_subtree()->create<meta_range_t>("freq/range").set(_freq_range);
this->get_tx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&rfx_xcvr::set_tx_ant, this, _1)).set(rfx_tx_antennas.at(0));
+ .add_coerced_subscriber(boost::bind(&rfx_xcvr::set_tx_ant, this, _1)).set(rfx_tx_antennas.at(0));
this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(rfx_tx_antennas);
this->get_tx_subtree()->create<std::string>("connection").set("IQ");
@@ -248,15 +248,15 @@ rfx_xcvr::rfx_xcvr(
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, output_enables);
//setup the tx atr (this does not change with antenna)
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _power_up | ANT_RX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
//setup the rx atr (this does not change with antenna)
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
}
rfx_xcvr::~rfx_xcvr(void){
@@ -272,14 +272,14 @@ void rfx_xcvr::set_rx_ant(const std::string &ant){
//set the rx atr regs that change with antenna setting
if (ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_TXRX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_TXRX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | ANT_TXRX );
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TXRX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TXRX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB | ANT_TXRX );
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, _power_up | MIXER_ENB |
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_XX | MIXER_DIS);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX2| MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _power_up | MIXER_ENB |
((ant == "TX/RX")? ANT_TXRX : ANT_RX2));
}
@@ -292,12 +292,12 @@ void rfx_xcvr::set_tx_ant(const std::string &ant){
//set the tx atr regs that change with antenna setting
if (ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_RX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_RX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_RX | MIXER_ENB);
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _power_up | ANT_TX | MIXER_ENB);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _power_up | ANT_TX | MIXER_ENB);
}
}
diff --git a/host/lib/usrp/dboard/db_sbx_common.cpp b/host/lib/usrp/dboard/db_sbx_common.cpp
index ce5166c4c..be02cf77a 100644
--- a/host/lib/usrp/dboard/db_sbx_common.cpp
+++ b/host/lib/usrp/dboard/db_sbx_common.cpp
@@ -159,20 +159,20 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
else this->get_rx_subtree()->create<std::string>("name").set("SBX/CBX RX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_RX));
+ .set_publisher(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_RX));
BOOST_FOREACH(const std::string &name, sbx_rx_gain_ranges.keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&sbx_xcvr::set_rx_gain, this, _1, name))
+ .set_coercer(boost::bind(&sbx_xcvr::set_rx_gain, this, _1, name))
.set(sbx_rx_gain_ranges[name].start());
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(sbx_rx_gain_ranges[name]);
}
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
+ .set_coercer(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
.set((freq_range.start() + freq_range.stop())/2.0);
this->get_rx_subtree()->create<meta_range_t>("freq/range").set(freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&sbx_xcvr::set_rx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&sbx_xcvr::set_rx_ant, this, _1))
.set("RX2");
this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(sbx_rx_antennas);
@@ -200,20 +200,20 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
else this->get_tx_subtree()->create<std::string>("name").set("SBX/CBX TX");
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_TX));
+ .set_publisher(boost::bind(&sbx_xcvr::get_locked, this, dboard_iface::UNIT_TX));
BOOST_FOREACH(const std::string &name, sbx_tx_gain_ranges.keys()){
this->get_tx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&sbx_xcvr::set_tx_gain, this, _1, name))
+ .set_coercer(boost::bind(&sbx_xcvr::set_tx_gain, this, _1, name))
.set(sbx_tx_gain_ranges[name].start());
this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(sbx_tx_gain_ranges[name]);
}
this->get_tx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
+ .set_coercer(boost::bind(&sbx_xcvr::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
.set((freq_range.start() + freq_range.stop())/2.0);
this->get_tx_subtree()->create<meta_range_t>("freq/range").set(freq_range);
this->get_tx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&sbx_xcvr::set_tx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&sbx_xcvr::set_tx_ant, this, _1))
.set(sbx_tx_antennas.at(0));
this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(sbx_tx_antennas);
@@ -237,8 +237,8 @@ sbx_xcvr::sbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
- //flash LEDs
- flash_leds();
+ //Initialize ATR registers after direction and pin ctrl configuration
+ update_atr();
UHD_LOGV(often) << boost::format(
"SBX GPIO Direction: RX: 0x%08x, TX: 0x%08x"
@@ -265,39 +265,39 @@ void sbx_xcvr::update_atr(void){
//setup the tx atr (this does not change with antenna)
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_IDLE, 0 | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_IDLE, 0 | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | ANT_XX | TX_MIXER_DIS);
//setup the rx atr (this does not change with antenna)
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_IDLE, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_IDLE, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | ANT_XX | RX_MIXER_DIS);
//set the RX atr regs that change with antenna setting
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_RX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_RX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \
| ((_rx_ant != "RX2")? ANT_TXRX : ANT_RX2));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_TX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_TX_ONLY, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_DIS \
| ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, rx_pga0_iobits | rx_lo_lpf_en \
+ gpio_atr::ATR_REG_FULL_DUPLEX, rx_pga0_iobits | rx_lo_lpf_en \
| rx_ld_led | rx_ant_led | RX_POWER_UP | RX_MIXER_ENB \
| ((_rx_ant == "CAL")? ANT_TXRX : ANT_RX2));
//set the TX atr regs that change with antenna setting
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_RX_ONLY, 0 | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_RX_ONLY, 0 | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_DIS \
| ((_rx_ant != "RX2")? ANT_RX : ANT_TX));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_TX_ONLY, tx_pga0_iobits | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_TX_ONLY, tx_pga0_iobits | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \
| ((_tx_ant == "CAL")? ANT_RX : ANT_TX));
this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, tx_pga0_iobits | tx_lo_lpf_en \
+ gpio_atr::ATR_REG_FULL_DUPLEX, tx_pga0_iobits | tx_lo_lpf_en \
| tx_ld_led | tx_ant_led | TX_POWER_UP | TX_MIXER_ENB \
| ((_tx_ant == "CAL")? ANT_RX : ANT_TX));
}
@@ -352,45 +352,3 @@ sensor_value_t sbx_xcvr::get_locked(dboard_iface::unit_t unit) {
return sensor_value_t("LO", locked, "locked", "unlocked");
}
-
-
-void sbx_xcvr::flash_leds(void) {
- //Remove LED gpios from ATR control temporarily and set to outputs
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, TXIO_MASK);
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, RXIO_MASK);
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|RX_LED_IO));
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_LD, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, \
- TX_LED_TXRX|TX_LED_LD, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_LD, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, \
- RX_LED_RX1RX2|RX_LED_LD, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, RX_LED_LD, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, 0, RX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, TX_LED_LD, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- this->get_iface()->set_gpio_out(dboard_iface::UNIT_TX, 0, TX_LED_IO);
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
-
- //Put LED gpios back in ATR control and update atr
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
- this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, (TXIO_MASK|TX_LED_IO));
- this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, (RXIO_MASK|RX_LED_IO));
-}
-
diff --git a/host/lib/usrp/dboard/db_sbx_common.hpp b/host/lib/usrp/dboard/db_sbx_common.hpp
index 4800bbd83..c0e29f263 100644
--- a/host/lib/usrp/dboard/db_sbx_common.hpp
+++ b/host/lib/usrp/dboard/db_sbx_common.hpp
@@ -16,10 +16,15 @@
//
#include <uhd/types/device_addr.hpp>
-
-#include "adf435x_common.hpp"
+#include "adf435x.hpp"
#include "max287x.hpp"
+// LO Related
+#define ADF435X_CE (1 << 3)
+#define ADF435X_PDBRF (1 << 2)
+#define ADF435X_MUXOUT (1 << 1) // INPUT!!!
+#define LOCKDET_MASK (1 << 0) // INPUT!!!
+
// Common IO Pins
#define LO_LPF_EN (1 << 15)
@@ -36,6 +41,8 @@
#define RX_LED_LD (1 << 6) // LED for RX Lock Detect
#define DIS_POWER_RX (1 << 5) // on UNIT_RX, 0 powers up RX
#define RX_DISABLE (1 << 4) // on UNIT_RX, 1 disables RX Mixer and Baseband
+#define RX_ATTN_SHIFT 8 //lsb of RX Attenuator Control
+#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) //valid bits of RX Attenuator Control
// TX Attenuator Pins
#define TX_ATTN_SHIFT 8 // lsb of TX Attenuator Control
@@ -184,12 +191,16 @@ protected:
class sbx_version3 : public sbx_versionx {
public:
sbx_version3(sbx_xcvr *_self_sbx_xcvr);
- ~sbx_version3(void);
+ virtual ~sbx_version3(void);
double set_lo_freq(dboard_iface::unit_t unit, double target_freq);
/*! This is the registered instance of the wrapper class, sbx_base. */
sbx_xcvr *self_base;
+ private:
+ adf435x_iface::sptr _txlo;
+ adf435x_iface::sptr _rxlo;
+ void write_lo_regs(dboard_iface::unit_t unit, const std::vector<boost::uint32_t> &regs);
};
/*!
@@ -200,12 +211,16 @@ protected:
class sbx_version4 : public sbx_versionx {
public:
sbx_version4(sbx_xcvr *_self_sbx_xcvr);
- ~sbx_version4(void);
+ virtual ~sbx_version4(void);
double set_lo_freq(dboard_iface::unit_t unit, double target_freq);
/*! This is the registered instance of the wrapper class, sbx_base. */
sbx_xcvr *self_base;
+ private:
+ adf435x_iface::sptr _txlo;
+ adf435x_iface::sptr _rxlo;
+ void write_lo_regs(dboard_iface::unit_t unit, const std::vector<boost::uint32_t> &regs);
};
/*!
@@ -218,7 +233,7 @@ protected:
class cbx : public sbx_versionx {
public:
cbx(sbx_xcvr *_self_sbx_xcvr);
- ~cbx(void);
+ virtual ~cbx(void);
double set_lo_freq(dboard_iface::unit_t unit, double target_freq);
diff --git a/host/lib/usrp/dboard/db_sbx_version3.cpp b/host/lib/usrp/dboard/db_sbx_version3.cpp
index b848097d1..76ad7b04f 100644
--- a/host/lib/usrp/dboard/db_sbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version3.cpp
@@ -16,9 +16,7 @@
//
-#include "adf4350_regs.hpp"
#include "db_sbx_common.hpp"
-#include "../common/adf435x_common.hpp"
#include <uhd/types/tune_request.hpp>
#include <boost/algorithm/string.hpp>
@@ -32,12 +30,21 @@ using namespace boost::assign;
sbx_xcvr::sbx_version3::sbx_version3(sbx_xcvr *_self_sbx_xcvr) {
//register the handle to our base SBX class
self_base = _self_sbx_xcvr;
+ _txlo = adf435x_iface::make_adf4350(boost::bind(&sbx_xcvr::sbx_version3::write_lo_regs, this, dboard_iface::UNIT_TX, _1));
+ _rxlo = adf435x_iface::make_adf4350(boost::bind(&sbx_xcvr::sbx_version3::write_lo_regs, this, dboard_iface::UNIT_RX, _1));
}
sbx_xcvr::sbx_version3::~sbx_version3(void){
/* NOP */
}
+void sbx_xcvr::sbx_version3::write_lo_regs(dboard_iface::unit_t unit, const std::vector<boost::uint32_t> &regs)
+{
+ BOOST_FOREACH(boost::uint32_t reg, regs)
+ {
+ self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32);
+ }
+}
/***********************************************************************
* Tuning
@@ -57,95 +64,27 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
- //clip the input
- target_freq = sbx_freq_range.clip(target_freq);
-
- //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)
- static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of
- (0,23) //adf4350_regs_t::PRESCALER_4_5
- (1,75) //adf4350_regs_t::PRESCALER_8_9
- ;
-
- //map rf divider select output dividers to enums
- static const uhd::dict<int, adf4350_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
- (1, adf4350_regs_t::RF_DIVIDER_SELECT_DIV1)
- (2, adf4350_regs_t::RF_DIVIDER_SELECT_DIV2)
- (4, adf4350_regs_t::RF_DIVIDER_SELECT_DIV4)
- (8, adf4350_regs_t::RF_DIVIDER_SELECT_DIV8)
- (16, adf4350_regs_t::RF_DIVIDER_SELECT_DIV16)
- ;
-
- //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
- adf4350_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
-
- adf435x_tuning_constraints tuning_constraints;
- tuning_constraints.force_frac0 = is_int_n;
- tuning_constraints.band_sel_freq_max = 100e3;
- tuning_constraints.ref_doubler_threshold = 12.5e6;
- tuning_constraints.int_range = uhd::range_t(prescaler_to_min_int_div[prescaler], 4095); //INT is a 12-bit field
- tuning_constraints.pfd_freq_max = 25e6;
- tuning_constraints.rf_divider_range = uhd::range_t(1, 16);
- tuning_constraints.feedback_after_divider = true;
+ //Select the LO
+ adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo;
+ lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED);
+ lo_iface->set_reference_freq(self_base->get_iface()->get_clock_rate(unit));
- double actual_freq;
- adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- target_freq, self_base->get_iface()->get_clock_rate(unit),
- tuning_constraints, actual_freq);
+ //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
+ lo_iface->set_prescaler(target_freq > 3e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5);
- //load the register values
- adf4350_regs_t regs;
+ //Configure the LO
+ double actual_freq = 0.0;
+ actual_freq = lo_iface->set_frequency(sbx_freq_range.clip(target_freq), is_int_n);
- if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq)))
- regs.output_power = adf4350_regs_t::OUTPUT_POWER_2DBM;
- else
- regs.output_power = adf4350_regs_t::OUTPUT_POWER_5DBM;
-
- regs.frac_12_bit = tuning_settings.frac_12_bit;
- regs.int_16_bit = tuning_settings.int_16_bit;
- regs.mod_12_bit = tuning_settings.mod_12_bit;
- regs.clock_divider_12_bit = tuning_settings.clock_divider_12_bit;
- regs.feedback_select = tuning_constraints.feedback_after_divider ?
- adf4350_regs_t::FEEDBACK_SELECT_DIVIDED :
- adf4350_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
- regs.clock_div_mode = adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
- regs.prescaler = prescaler;
- regs.r_counter_10_bit = tuning_settings.r_counter_10_bit;
- regs.reference_divide_by_2 = tuning_settings.r_divide_by_2_en ?
- adf4350_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED :
- adf4350_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- regs.reference_doubler = tuning_settings.r_doubler_en ?
- adf4350_regs_t::REFERENCE_DOUBLER_ENABLED :
- adf4350_regs_t::REFERENCE_DOUBLER_DISABLED;
- regs.band_select_clock_div = tuning_settings.band_select_clock_div;
- UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(tuning_settings.rf_divider));
- regs.rf_divider_select = rfdivsel_to_enum[tuning_settings.rf_divider];
- regs.ldf = is_int_n ?
- adf4350_regs_t::LDF_INT_N :
- adf4350_regs_t::LDF_FRAC_N;
-
- //reset the N and R counter
- regs.counter_reset = adf4350_regs_t::COUNTER_RESET_ENABLED;
- self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, regs.get_reg(2), 32);
- regs.counter_reset = adf4350_regs_t::COUNTER_RESET_DISABLED;
-
- //write the registers
- //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
- int addr;
-
- for(addr=5; addr>=0; addr--){
- UHD_LOGV(often) << boost::format(
- "SBX SPI Reg (0x%02x): 0x%08x"
- ) % addr % regs.get_reg(addr) << std::endl;
- self_base->get_iface()->write_spi(
- unit, spi_config_t::EDGE_RISE,
- regs.get_reg(addr), 32
- );
+ if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) {
+ lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_2DBM);
+ } else {
+ lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM);
}
- //return the actual frequency
- UHD_LOGV(often) << boost::format(
- "SBX tune: actual frequency %f MHz"
- ) % (actual_freq/1e6) << std::endl;
+ //Write to hardware
+ lo_iface->commit();
+
return actual_freq;
}
diff --git a/host/lib/usrp/dboard/db_sbx_version4.cpp b/host/lib/usrp/dboard/db_sbx_version4.cpp
index 8f7e747bc..639bce250 100644
--- a/host/lib/usrp/dboard/db_sbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version4.cpp
@@ -16,9 +16,7 @@
//
-#include "adf4351_regs.hpp"
#include "db_sbx_common.hpp"
-#include "../common/adf435x_common.hpp"
#include <uhd/types/tune_request.hpp>
#include <boost/algorithm/string.hpp>
@@ -32,6 +30,8 @@ using namespace boost::assign;
sbx_xcvr::sbx_version4::sbx_version4(sbx_xcvr *_self_sbx_xcvr) {
//register the handle to our base SBX class
self_base = _self_sbx_xcvr;
+ _txlo = adf435x_iface::make_adf4351(boost::bind(&sbx_xcvr::sbx_version4::write_lo_regs, this, dboard_iface::UNIT_TX, _1));
+ _rxlo = adf435x_iface::make_adf4351(boost::bind(&sbx_xcvr::sbx_version4::write_lo_regs, this, dboard_iface::UNIT_RX, _1));
}
@@ -39,6 +39,14 @@ sbx_xcvr::sbx_version4::~sbx_version4(void){
/* NOP */
}
+void sbx_xcvr::sbx_version4::write_lo_regs(dboard_iface::unit_t unit, const std::vector<boost::uint32_t> &regs)
+{
+ BOOST_FOREACH(boost::uint32_t reg, regs)
+ {
+ self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32);
+ }
+}
+
/***********************************************************************
* Tuning
@@ -58,99 +66,27 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
- //clip the input
- target_freq = sbx_freq_range.clip(target_freq);
-
- //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)
- static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of
- (0,23) //adf4351_regs_t::PRESCALER_4_5
- (1,75) //adf4351_regs_t::PRESCALER_8_9
- ;
-
- //map rf divider select output dividers to enums
- static const uhd::dict<int, adf4351_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
- (1, adf4351_regs_t::RF_DIVIDER_SELECT_DIV1)
- (2, adf4351_regs_t::RF_DIVIDER_SELECT_DIV2)
- (4, adf4351_regs_t::RF_DIVIDER_SELECT_DIV4)
- (8, adf4351_regs_t::RF_DIVIDER_SELECT_DIV8)
- (16, adf4351_regs_t::RF_DIVIDER_SELECT_DIV16)
- (32, adf4351_regs_t::RF_DIVIDER_SELECT_DIV32)
- (64, adf4351_regs_t::RF_DIVIDER_SELECT_DIV64)
- ;
-
- //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
- adf4351_regs_t::prescaler_t prescaler = target_freq > 3.6e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
-
- adf435x_tuning_constraints tuning_constraints;
- tuning_constraints.force_frac0 = is_int_n;
- tuning_constraints.band_sel_freq_max = 100e3;
- tuning_constraints.ref_doubler_threshold = 12.5e6;
- tuning_constraints.int_range = uhd::range_t(prescaler_to_min_int_div[prescaler], 4095); //INT is a 12-bit field
- tuning_constraints.pfd_freq_max = 25e6;
- tuning_constraints.rf_divider_range = uhd::range_t(1, 64);
- tuning_constraints.feedback_after_divider = true;
-
- double actual_freq;
- adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- target_freq, self_base->get_iface()->get_clock_rate(unit),
- tuning_constraints, actual_freq);
-
- //load the register values
- adf4351_regs_t regs;
-
- if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq)))
- regs.output_power = adf4351_regs_t::OUTPUT_POWER_2DBM;
- else
- regs.output_power = adf4351_regs_t::OUTPUT_POWER_5DBM;
-
- regs.frac_12_bit = tuning_settings.frac_12_bit;
- regs.int_16_bit = tuning_settings.int_16_bit;
- regs.mod_12_bit = tuning_settings.mod_12_bit;
- regs.clock_divider_12_bit = tuning_settings.clock_divider_12_bit;
- regs.feedback_select = tuning_constraints.feedback_after_divider ?
- adf4351_regs_t::FEEDBACK_SELECT_DIVIDED :
- adf4351_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
- regs.clock_div_mode = adf4351_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
- regs.prescaler = prescaler;
- regs.r_counter_10_bit = tuning_settings.r_counter_10_bit;
- regs.reference_divide_by_2 = tuning_settings.r_divide_by_2_en ?
- adf4351_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED :
- adf4351_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- regs.reference_doubler = tuning_settings.r_doubler_en ?
- adf4351_regs_t::REFERENCE_DOUBLER_ENABLED :
- adf4351_regs_t::REFERENCE_DOUBLER_DISABLED;
- regs.band_select_clock_div = tuning_settings.band_select_clock_div;
- UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(tuning_settings.rf_divider));
- regs.rf_divider_select = rfdivsel_to_enum[tuning_settings.rf_divider];
- regs.ldf = is_int_n ?
- adf4351_regs_t::LDF_INT_N :
- adf4351_regs_t::LDF_FRAC_N;
-
- //reset the N and R counter
- regs.counter_reset = adf4351_regs_t::COUNTER_RESET_ENABLED;
- self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, regs.get_reg(2), 32);
- regs.counter_reset = adf4351_regs_t::COUNTER_RESET_DISABLED;
-
- //write the registers
- //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
- int addr;
-
- boost::uint16_t rx_id = self_base->get_rx_id().to_uint16();
- std::string board_name = (rx_id == 0x0083) ? "SBX-120" : "SBX";
- for(addr=5; addr>=0; addr--){
- UHD_LOGV(often) << boost::format(
- "%s SPI Reg (0x%02x): 0x%08x"
- ) % board_name.c_str() % addr % regs.get_reg(addr) << std::endl;
- self_base->get_iface()->write_spi(
- unit, spi_config_t::EDGE_RISE,
- regs.get_reg(addr), 32
- );
+ //Select the LO
+ adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo;
+ lo_iface->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED);
+ lo_iface->set_reference_freq(self_base->get_iface()->get_clock_rate(unit));
+
+ //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
+ lo_iface->set_prescaler(target_freq > 3.6e9 ? adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5);
+
+ //Configure the LO
+ double actual_freq = 0.0;
+ actual_freq = lo_iface->set_frequency(sbx_freq_range.clip(target_freq), is_int_n);
+
+ if ((unit == dboard_iface::UNIT_TX) and (actual_freq == sbx_tx_lo_2dbm.clip(actual_freq))) {
+ lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_2DBM);
+ } else {
+ lo_iface->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM);
}
- //return the actual frequency
- UHD_LOGV(often) << boost::format(
- "%s tune: actual frequency %f MHz"
- ) % board_name.c_str() % (actual_freq/1e6) << std::endl;
+ //Write to hardware
+ lo_iface->commit();
+
return actual_freq;
}
diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp
index e9f60f765..0f84cd68a 100644
--- a/host/lib/usrp/dboard/db_tvrx.cpp
+++ b/host/lib/usrp/dboard/db_tvrx.cpp
@@ -134,7 +134,7 @@ static const double reference_freq = 4.0e6;
class tvrx : public rx_dboard_base{
public:
tvrx(ctor_args_t args);
- ~tvrx(void);
+ virtual ~tvrx(void);
private:
uhd::dict<std::string, double> _gains;
@@ -190,12 +190,12 @@ tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){
this->get_rx_subtree()->create<int>("sensors"); //phony property so this dir exists
BOOST_FOREACH(const std::string &name, get_tvrx_gain_ranges().keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&tvrx::set_gain, this, _1, name));
+ .set_coercer(boost::bind(&tvrx::set_gain, this, _1, name));
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(get_tvrx_gain_ranges()[name]);
}
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&tvrx::set_freq, this, _1));
+ .set_coercer(boost::bind(&tvrx::set_freq, this, _1));
this->get_rx_subtree()->create<meta_range_t>("freq/range")
.set(tvrx_freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
diff --git a/host/lib/usrp/dboard/db_tvrx2.cpp b/host/lib/usrp/dboard/db_tvrx2.cpp
index ccbac0b5d..6f0604f72 100644
--- a/host/lib/usrp/dboard/db_tvrx2.cpp
+++ b/host/lib/usrp/dboard/db_tvrx2.cpp
@@ -751,7 +751,7 @@ static const uhd::dict<std::string, gain_range_t> tvrx2_gain_ranges = map_list_o
class tvrx2 : public rx_dboard_base{
public:
tvrx2(ctor_args_t args);
- ~tvrx2(void);
+ virtual ~tvrx2(void);
private:
double _freq_scalar;
@@ -957,19 +957,19 @@ tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args){
this->get_rx_subtree()->create<std::string>("name")
.set("TVRX2");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&tvrx2::get_locked, this));
+ .set_publisher(boost::bind(&tvrx2::get_locked, this));
this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi")
- .publish(boost::bind(&tvrx2::get_rssi, this));
+ .set_publisher(boost::bind(&tvrx2::get_rssi, this));
this->get_rx_subtree()->create<sensor_value_t>("sensors/temperature")
- .publish(boost::bind(&tvrx2::get_temp, this));
+ .set_publisher(boost::bind(&tvrx2::get_temp, this));
BOOST_FOREACH(const std::string &name, tvrx2_gain_ranges.keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&tvrx2::set_gain, this, _1, name));
+ .set_coercer(boost::bind(&tvrx2::set_gain, this, _1, name));
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(tvrx2_gain_ranges[name]);
}
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&tvrx2::set_lo_freq, this, _1));
+ .set_coercer(boost::bind(&tvrx2::set_lo_freq, this, _1));
this->get_rx_subtree()->create<meta_range_t>("freq/range")
.set(tvrx2_freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
@@ -979,12 +979,12 @@ tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args){
this->get_rx_subtree()->create<std::string>("connection")
.set(tvrx2_sd_name_to_conn[get_subdev_name()]);
this->get_rx_subtree()->create<bool>("enabled")
- .coerce(boost::bind(&tvrx2::set_enabled, this, _1))
+ .set_coercer(boost::bind(&tvrx2::set_enabled, this, _1))
.set(_enabled);
this->get_rx_subtree()->create<bool>("use_lo_offset")
.set(false);
this->get_rx_subtree()->create<double>("bandwidth/value")
- .coerce(boost::bind(&tvrx2::set_bandwidth, this, _1))
+ .set_coercer(boost::bind(&tvrx2::set_bandwidth, this, _1))
.set(_bandwidth);
this->get_rx_subtree()->create<meta_range_t>("bandwidth/range")
.set(tvrx2_bandwidth_range);
diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp
index 15a4d17a9..be3bdd17d 100644
--- a/host/lib/usrp/dboard/db_ubx.cpp
+++ b/host/lib/usrp/dboard/db_ubx.cpp
@@ -27,7 +27,9 @@
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/utils/assert_has.hpp>
#include <uhd/utils/log.hpp>
+#include <uhd/utils/msg.hpp>
#include <uhd/utils/static.hpp>
+#include <uhd/utils/safe_call.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/math/special_functions/round.hpp>
@@ -319,14 +321,14 @@ public:
write_gpio();
// Configure ATR
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, _tx_gpio_reg.atr_idle);
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx);
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx);
- _iface->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, _tx_gpio_reg.atr_full_duplex);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, _rx_gpio_reg.atr_idle);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx);
- _iface->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, _rx_gpio_reg.atr_full_duplex);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, _tx_gpio_reg.atr_idle);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, _tx_gpio_reg.atr_tx);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, _tx_gpio_reg.atr_rx);
+ _iface->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, _tx_gpio_reg.atr_full_duplex);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, _rx_gpio_reg.atr_idle);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, _rx_gpio_reg.atr_tx);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, _rx_gpio_reg.atr_rx);
+ _iface->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, _rx_gpio_reg.atr_full_duplex);
// Engage ATR control (1 is ATR control, 0 is manual control)
_iface->set_pin_ctrl(dboard_iface::UNIT_TX, _tx_gpio_reg.atr_mask);
@@ -385,23 +387,23 @@ public:
get_rx_subtree()->create<std::vector<std::string> >("power_mode/options")
.set(ubx_power_modes);
get_rx_subtree()->create<std::string>("power_mode/value")
- .subscribe(boost::bind(&ubx_xcvr::set_power_mode, this, _1))
+ .add_coerced_subscriber(boost::bind(&ubx_xcvr::set_power_mode, this, _1))
.set("performance");
get_rx_subtree()->create<std::vector<std::string> >("xcvr_mode/options")
.set(ubx_xcvr_modes);
get_rx_subtree()->create<std::string>("xcvr_mode/value")
- .subscribe(boost::bind(&ubx_xcvr::set_xcvr_mode, this, _1))
+ .add_coerced_subscriber(boost::bind(&ubx_xcvr::set_xcvr_mode, this, _1))
.set("FDX");
get_tx_subtree()->create<std::vector<std::string> >("power_mode/options")
.set(ubx_power_modes);
get_tx_subtree()->create<std::string>("power_mode/value")
- .subscribe(boost::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("power_mode/value"), _1))
- .publish(boost::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("power_mode/value")));
+ .add_coerced_subscriber(boost::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("power_mode/value"), _1))
+ .set_publisher(boost::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("power_mode/value")));
get_tx_subtree()->create<std::vector<std::string> >("xcvr_mode/options")
.set(ubx_xcvr_modes);
get_tx_subtree()->create<std::string>("xcvr_mode/value")
- .subscribe(boost::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("xcvr_mode/value"), _1))
- .publish(boost::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("xcvr_mode/value")));
+ .add_coerced_subscriber(boost::bind(&uhd::property<std::string>::set, &get_rx_subtree()->access<std::string>("xcvr_mode/value"), _1))
+ .set_publisher(boost::bind(&uhd::property<std::string>::get, &get_rx_subtree()->access<std::string>("xcvr_mode/value")));
////////////////////////////////////////////////////////////////////
// Register TX properties
@@ -410,20 +412,20 @@ public:
get_tx_subtree()->create<device_addr_t>("tune_args")
.set(device_addr_t());
get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&ubx_xcvr::get_locked, this, "TXLO"));
+ .set_publisher(boost::bind(&ubx_xcvr::get_locked, this, "TXLO"));
get_tx_subtree()->create<double>("gains/PGA0/value")
- .coerce(boost::bind(&ubx_xcvr::set_tx_gain, this, _1)).set(0);
+ .set_coercer(boost::bind(&ubx_xcvr::set_tx_gain, this, _1)).set(0);
get_tx_subtree()->create<meta_range_t>("gains/PGA0/range")
.set(ubx_tx_gain_range);
get_tx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&ubx_xcvr::set_tx_freq, this, _1))
+ .set_coercer(boost::bind(&ubx_xcvr::set_tx_freq, this, _1))
.set(ubx_freq_range.start());
get_tx_subtree()->create<meta_range_t>("freq/range")
.set(ubx_freq_range);
get_tx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(ubx_tx_antennas);
get_tx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&ubx_xcvr::set_tx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&ubx_xcvr::set_tx_ant, this, _1))
.set(ubx_tx_antennas.at(0));
get_tx_subtree()->create<std::string>("connection")
.set("QI");
@@ -436,7 +438,7 @@ public:
get_tx_subtree()->create<meta_range_t>("bandwidth/range")
.set(freq_range_t(bw, bw));
get_tx_subtree()->create<int64_t>("sync_delay")
- .subscribe(boost::bind(&ubx_xcvr::set_sync_delay, this, true, _1))
+ .add_coerced_subscriber(boost::bind(&ubx_xcvr::set_sync_delay, this, true, _1))
.set(-8);
////////////////////////////////////////////////////////////////////
@@ -446,21 +448,21 @@ public:
get_rx_subtree()->create<device_addr_t>("tune_args")
.set(device_addr_t());
get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&ubx_xcvr::get_locked, this, "RXLO"));
+ .set_publisher(boost::bind(&ubx_xcvr::get_locked, this, "RXLO"));
get_rx_subtree()->create<double>("gains/PGA0/value")
- .coerce(boost::bind(&ubx_xcvr::set_rx_gain, this, _1))
+ .set_coercer(boost::bind(&ubx_xcvr::set_rx_gain, this, _1))
.set(0);
get_rx_subtree()->create<meta_range_t>("gains/PGA0/range")
.set(ubx_rx_gain_range);
get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&ubx_xcvr::set_rx_freq, this, _1))
+ .set_coercer(boost::bind(&ubx_xcvr::set_rx_freq, this, _1))
.set(ubx_freq_range.start());
get_rx_subtree()->create<meta_range_t>("freq/range")
.set(ubx_freq_range);
get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(ubx_rx_antennas);
get_rx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&ubx_xcvr::set_rx_ant, this, _1)).set("RX2");
+ .add_coerced_subscriber(boost::bind(&ubx_xcvr::set_rx_ant, this, _1)).set("RX2");
get_rx_subtree()->create<std::string>("connection")
.set("IQ");
get_rx_subtree()->create<bool>("enabled")
@@ -472,35 +474,38 @@ public:
get_rx_subtree()->create<meta_range_t>("bandwidth/range")
.set(freq_range_t(bw, bw));
get_rx_subtree()->create<int64_t>("sync_delay")
- .subscribe(boost::bind(&ubx_xcvr::set_sync_delay, this, false, _1))
+ .add_coerced_subscriber(boost::bind(&ubx_xcvr::set_sync_delay, this, false, _1))
.set(-8);
}
- ~ubx_xcvr(void)
+ virtual ~ubx_xcvr(void)
{
- // Shutdown synthesizers
- _txlo1->shutdown();
- _txlo2->shutdown();
- _rxlo1->shutdown();
- _rxlo2->shutdown();
+ UHD_SAFE_CALL
+ (
+ // Shutdown synthesizers
+ _txlo1->shutdown();
+ _txlo2->shutdown();
+ _rxlo1->shutdown();
+ _rxlo2->shutdown();
- // Reset CPLD values
- _cpld_reg.value = 0;
- write_cpld_reg();
+ // Reset CPLD values
+ _cpld_reg.value = 0;
+ write_cpld_reg();
- // Reset GPIO values
- set_gpio_field(TX_GAIN, 0);
- set_gpio_field(CPLD_RST_N, 0);
- set_gpio_field(RX_ANT, 1);
- set_gpio_field(TX_EN_N, 1);
- set_gpio_field(RX_EN_N, 1);
- set_gpio_field(SPI_ADDR, 0x7);
- set_gpio_field(RX_GAIN, 0);
- set_gpio_field(TXLO1_SYNC, 0);
- set_gpio_field(TXLO2_SYNC, 0);
- set_gpio_field(RXLO1_SYNC, 0);
- set_gpio_field(RXLO1_SYNC, 0);
- write_gpio();
+ // Reset GPIO values
+ set_gpio_field(TX_GAIN, 0);
+ set_gpio_field(CPLD_RST_N, 0);
+ set_gpio_field(RX_ANT, 1);
+ set_gpio_field(TX_EN_N, 1);
+ set_gpio_field(RX_EN_N, 1);
+ set_gpio_field(SPI_ADDR, 0x7);
+ set_gpio_field(RX_GAIN, 0);
+ set_gpio_field(TXLO1_SYNC, 0);
+ set_gpio_field(TXLO2_SYNC, 0);
+ set_gpio_field(RXLO1_SYNC, 0);
+ set_gpio_field(RXLO1_SYNC, 0);
+ write_gpio();
+ )
}
private:
@@ -638,23 +643,23 @@ private:
uint16_t mask = lo1_field_info.mask | lo2_field_info.mask;
dboard_iface::unit_t unit = lo1_field_info.unit;
UHD_ASSERT_THROW(lo1_field_info.unit == lo2_field_info.unit);
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_IDLE, value, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, value, mask);
cmd_time += uhd::time_spec_t(1/pfd_freq);
_iface->set_command_time(cmd_time);
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_TX_ONLY, value, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, value, mask);
cmd_time += uhd::time_spec_t(1/pfd_freq);
_iface->set_command_time(cmd_time);
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_RX_ONLY, value, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, value, mask);
cmd_time += uhd::time_spec_t(1/pfd_freq);
_iface->set_command_time(cmd_time);
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_FULL_DUPLEX, value, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, value, mask);
// De-assert SYNC
// Head of line blocking means the command time does not need to be set.
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_IDLE, 0, mask);
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_TX_ONLY, 0, mask);
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_RX_ONLY, 0, mask);
- _iface->set_atr_reg(unit, dboard_iface::ATR_REG_FULL_DUPLEX, 0, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_IDLE, 0, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_TX_ONLY, 0, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_RX_ONLY, 0, mask);
+ _iface->set_atr_reg(unit, gpio_atr::ATR_REG_FULL_DUPLEX, 0, mask);
}
}
@@ -760,6 +765,20 @@ private:
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
UHD_LOGV(rarely) << boost::format("UBX TX: the requested frequency is %f MHz") % (freq/1e6) << std::endl;
+ double target_pfd_freq = _tx_target_pfd_freq;
+ if (is_int_n and tune_args.has_key("int_n_step"))
+ {
+ target_pfd_freq = tune_args.cast<double>("int_n_step", _tx_target_pfd_freq);
+ if (target_pfd_freq > _tx_target_pfd_freq)
+ {
+ UHD_MSG(warning)
+ << boost::format("Requested int_n_step of %f MHz too large, clipping to %f MHz")
+ % (target_pfd_freq/1e6)
+ % (_tx_target_pfd_freq/1e6)
+ << std::endl;
+ target_pfd_freq = _tx_target_pfd_freq;
+ }
+ }
// Clip the frequency to the valid range
freq = ubx_freq_range.clip(freq);
@@ -796,10 +815,10 @@ private:
set_cpld_field(TXLB_SEL, 1);
set_cpld_field(TXHB_SEL, 0);
// Set LO1 to IF of 2100 MHz (offset from RX IF to reduce leakage)
- freq_lo1 = _txlo1->set_frequency(2100*fMHz, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(2100*fMHz, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
// Set LO2 to IF minus desired frequency
- freq_lo2 = _txlo2->set_frequency(freq_lo1 - freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo2 = _txlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n);
_txlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= (500*fMHz)) && (freq <= (800*fMHz)))
@@ -809,7 +828,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 1);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq > (800*fMHz)) && (freq <= (1000*fMHz)))
@@ -819,7 +838,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 1);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
else if ((freq > (1000*fMHz)) && (freq <= (2200*fMHz)))
@@ -829,7 +848,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 0);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq > (2200*fMHz)) && (freq <= (2500*fMHz)))
@@ -839,7 +858,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 0);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq > (2500*fMHz)) && (freq <= (6000*fMHz)))
@@ -849,7 +868,7 @@ private:
set_cpld_field(TXLO1_FSEL1, 0);
set_cpld_field(TXLB_SEL, 0);
set_cpld_field(TXHB_SEL, 1);
- freq_lo1 = _txlo1->set_frequency(freq, ref_freq, _tx_target_pfd_freq, is_int_n);
+ freq_lo1 = _txlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_txlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
@@ -902,6 +921,20 @@ private:
property_tree::sptr subtree = this->get_rx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
+ double target_pfd_freq = _rx_target_pfd_freq;
+ if (is_int_n and tune_args.has_key("int_n_step"))
+ {
+ target_pfd_freq = tune_args.cast<double>("int_n_step", _rx_target_pfd_freq);
+ if (target_pfd_freq > _rx_target_pfd_freq)
+ {
+ UHD_MSG(warning)
+ << boost::format("Requested int_n_step of %f Mhz too large, clipping to %f MHz")
+ % (target_pfd_freq/1e6)
+ % (_rx_target_pfd_freq/1e6)
+ << std::endl;
+ target_pfd_freq = _rx_target_pfd_freq;
+ }
+ }
// Clip the frequency to the valid range
freq = ubx_freq_range.clip(freq);
@@ -940,10 +973,10 @@ private:
set_cpld_field(RXLB_SEL, 1);
set_cpld_field(RXHB_SEL, 0);
// Set LO1 to IF of 2380 MHz (2440 MHz filter center minus 60 MHz offset to minimize LO leakage)
- freq_lo1 = _rxlo1->set_frequency(2380*fMHz, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(2380*fMHz, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
// Set LO2 to IF minus desired frequency
- freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo2->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 100*fMHz) && (freq < 500*fMHz))
@@ -956,10 +989,10 @@ private:
set_cpld_field(RXLB_SEL, 1);
set_cpld_field(RXHB_SEL, 0);
// Set LO1 to IF of 2440 (center of filter)
- freq_lo1 = _rxlo1->set_frequency(2440*fMHz, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(2440*fMHz, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
// Set LO2 to IF minus desired frequency
- freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo2 = _rxlo2->set_frequency(freq_lo1 - freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 500*fMHz) && (freq < 800*fMHz))
@@ -971,7 +1004,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 1);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 800*fMHz) && (freq < 1000*fMHz))
@@ -983,7 +1016,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 1);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
else if ((freq >= 1000*fMHz) && (freq < 1500*fMHz))
@@ -995,7 +1028,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 1500*fMHz) && (freq < 2200*fMHz))
@@ -1007,7 +1040,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 2200*fMHz) && (freq < 2500*fMHz))
@@ -1019,7 +1052,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_2DBM);
}
else if ((freq >= 2500*fMHz) && (freq <= 6000*fMHz))
@@ -1031,7 +1064,7 @@ private:
set_cpld_field(RXLO1_FSEL1, 0);
set_cpld_field(RXLB_SEL, 0);
set_cpld_field(RXHB_SEL, 1);
- freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, _rx_target_pfd_freq, is_int_n);
+ freq_lo1 = _rxlo1->set_frequency(freq, ref_freq, target_pfd_freq, is_int_n);
_rxlo1->set_output_power(max287x_iface::OUTPUT_POWER_5DBM);
}
diff --git a/host/lib/usrp/dboard/db_wbx_common.cpp b/host/lib/usrp/dboard/db_wbx_common.cpp
index 97357bc90..6539e798a 100644
--- a/host/lib/usrp/dboard/db_wbx_common.cpp
+++ b/host/lib/usrp/dboard/db_wbx_common.cpp
@@ -69,17 +69,17 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){
this->get_rx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t());
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_RX));
+ .set_publisher(boost::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_RX));
BOOST_FOREACH(const std::string &name, wbx_rx_gain_ranges.keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&wbx_base::set_rx_gain, this, _1, name))
+ .set_coercer(boost::bind(&wbx_base::set_rx_gain, this, _1, name))
.set(wbx_rx_gain_ranges[name].start());
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(wbx_rx_gain_ranges[name]);
}
this->get_rx_subtree()->create<std::string>("connection").set("IQ");
this->get_rx_subtree()->create<bool>("enabled")
- .subscribe(boost::bind(&wbx_base::set_rx_enabled, this, _1))
+ .add_coerced_subscriber(boost::bind(&wbx_base::set_rx_enabled, this, _1))
.set(true); //start enabled
this->get_rx_subtree()->create<bool>("use_lo_offset").set(false);
@@ -94,7 +94,7 @@ wbx_base::wbx_base(ctor_args_t args) : xcvr_dboard_base(args){
this->get_tx_subtree()->create<device_addr_t>("tune_args").set(device_addr_t());
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_TX));
+ .set_publisher(boost::bind(&wbx_base::get_locked, this, dboard_iface::UNIT_TX));
this->get_tx_subtree()->create<std::string>("connection").set("IQ");
this->get_tx_subtree()->create<bool>("use_lo_offset").set(false);
@@ -156,3 +156,9 @@ sensor_value_t wbx_base::get_locked(dboard_iface::unit_t unit){
const bool locked = (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0;
return sensor_value_t("LO", locked, "locked", "unlocked");
}
+
+void wbx_base::wbx_versionx::write_lo_regs(dboard_iface::unit_t unit, const std::vector<boost::uint32_t> &regs) {
+ BOOST_FOREACH(boost::uint32_t reg, regs) {
+ self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, reg, 32);
+ }
+}
diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp
index 6a4224048..0e339e4a3 100644
--- a/host/lib/usrp/dboard/db_wbx_common.hpp
+++ b/host/lib/usrp/dboard/db_wbx_common.hpp
@@ -19,8 +19,13 @@
#define INCLUDED_LIBUHD_USRP_DBOARD_DB_WBX_COMMON_HPP
#include <uhd/types/device_addr.hpp>
+#include "adf435x.hpp"
-#include "../common/adf435x_common.hpp"
+// LO Related
+#define ADF435X_CE (1 << 3)
+#define ADF435X_PDBRF (1 << 2)
+#define ADF435X_MUXOUT (1 << 1) // INPUT!!!
+#define LOCKDET_MASK (1 << 0) // INPUT!!!
// TX IO Pins
#define TX_PUP_5V (1 << 7) // enables 5.0V power supply
@@ -40,6 +45,9 @@
#define TX_ATTN_1 (1 << 1)
#define TX_ATTN_MASK (TX_ATTN_16|TX_ATTN_8|TX_ATTN_4|TX_ATTN_2|TX_ATTN_1) // valid bits of TX Attenuator Control
+#define RX_ATTN_SHIFT 8 //lsb of RX Attenuator Control
+#define RX_ATTN_MASK (63 << RX_ATTN_SHIFT) //valid bits of RX Attenuator Control
+
// Mixer functions
#define TX_MIXER_ENB (TXMOD_EN|ADF435X_PDBRF) // for v3, TXMOD_EN tied to ADF435X_PDBRF rather than separate
#define TX_MIXER_DIS 0
@@ -142,6 +150,10 @@ protected:
property_tree::sptr get_tx_subtree(void){
return self_base->get_tx_subtree();
}
+
+ adf435x_iface::sptr _txlo;
+ adf435x_iface::sptr _rxlo;
+ void write_lo_regs(dboard_iface::unit_t unit, const std::vector<boost::uint32_t> &regs);
};
@@ -153,7 +165,7 @@ protected:
class wbx_version2 : public wbx_versionx {
public:
wbx_version2(wbx_base *_self_wbx_base);
- ~wbx_version2(void);
+ virtual ~wbx_version2(void);
double set_tx_gain(double gain, const std::string &name);
void set_tx_enabled(bool enb);
@@ -168,7 +180,7 @@ protected:
class wbx_version3 : public wbx_versionx {
public:
wbx_version3(wbx_base *_self_wbx_base);
- ~wbx_version3(void);
+ virtual ~wbx_version3(void);
double set_tx_gain(double gain, const std::string &name);
void set_tx_enabled(bool enb);
@@ -183,7 +195,7 @@ protected:
class wbx_version4 : public wbx_versionx {
public:
wbx_version4(wbx_base *_self_wbx_base);
- ~wbx_version4(void);
+ virtual ~wbx_version4(void);
double set_tx_gain(double gain, const std::string &name);
void set_tx_enabled(bool enb);
diff --git a/host/lib/usrp/dboard/db_wbx_simple.cpp b/host/lib/usrp/dboard/db_wbx_simple.cpp
index c8f2be155..062e1294b 100644
--- a/host/lib/usrp/dboard/db_wbx_simple.cpp
+++ b/host/lib/usrp/dboard/db_wbx_simple.cpp
@@ -46,7 +46,7 @@ static const std::vector<std::string> wbx_rx_antennas = list_of("TX/RX")("RX2")(
class wbx_simple : public wbx_base{
public:
wbx_simple(ctor_args_t args);
- ~wbx_simple(void);
+ virtual ~wbx_simple(void);
private:
void set_rx_ant(const std::string &ant);
@@ -88,7 +88,7 @@ wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){
std::string(str(boost::format("%s+GDB") % this->get_rx_subtree()->access<std::string>("name").get()
)));
this->get_rx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&wbx_simple::set_rx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&wbx_simple::set_rx_ant, this, _1))
.set("RX2");
this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(wbx_rx_antennas);
@@ -100,7 +100,7 @@ wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){
std::string(str(boost::format("%s+GDB") % this->get_tx_subtree()->access<std::string>("name").get()
)));
this->get_tx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&wbx_simple::set_tx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&wbx_simple::set_tx_ant, this, _1))
.set(wbx_tx_antennas.at(0));
this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(wbx_tx_antennas);
@@ -112,14 +112,14 @@ wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){
this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, ANTSW_IO, ANTSW_IO);
//setup ATR for the antenna switches (constant)
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, ANT_RX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
-
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
+
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
}
wbx_simple::~wbx_simple(void){
@@ -138,14 +138,14 @@ void wbx_simple::set_rx_ant(const std::string &ant){
//write the new antenna setting to atr regs
if (_rx_ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TXRX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ANT_TXRX, ANTSW_IO);
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2), ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX2, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2), ANTSW_IO);
}
}
@@ -154,11 +154,11 @@ void wbx_simple::set_tx_ant(const std::string &ant){
//write the new antenna setting to atr regs
if (ant == "CAL") {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_RX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_RX, ANTSW_IO);
}
else {
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, ANT_TX, ANTSW_IO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, ANT_TX, ANTSW_IO);
}
}
diff --git a/host/lib/usrp/dboard/db_wbx_version2.cpp b/host/lib/usrp/dboard/db_wbx_version2.cpp
index 93047fb7a..18dc383b7 100644
--- a/host/lib/usrp/dboard/db_wbx_version2.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version2.cpp
@@ -16,8 +16,6 @@
//
#include "db_wbx_common.hpp"
-#include "adf4350_regs.hpp"
-#include "../common/adf435x_common.hpp"
#include <uhd/types/tune_request.hpp>
#include <uhd/utils/log.hpp>
#include <uhd/types/dict.hpp>
@@ -77,13 +75,15 @@ static double tx_pga0_gain_to_dac_volts(double &gain){
wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) {
//register our handle on the primary wbx_base instance
self_base = _self_wbx_base;
+ _txlo = adf435x_iface::make_adf4350(boost::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, _1));
+ _rxlo = adf435x_iface::make_adf4350(boost::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, _1));
////////////////////////////////////////////////////////////////////
// Register RX properties
////////////////////////////////////////////////////////////////////
this->get_rx_subtree()->create<std::string>("name").set("WBXv2 RX");
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
+ .set_coercer(boost::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
.set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop())/2.0);
this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v2_freq_range);
@@ -93,17 +93,17 @@ wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) {
this->get_tx_subtree()->create<std::string>("name").set("WBXv2 TX");
BOOST_FOREACH(const std::string &name, wbx_v2_tx_gain_ranges.keys()){
self_base->get_tx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&wbx_base::wbx_version2::set_tx_gain, this, _1, name))
+ .set_coercer(boost::bind(&wbx_base::wbx_version2::set_tx_gain, this, _1, name))
.set(wbx_v2_tx_gain_ranges[name].start());
self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(wbx_v2_tx_gain_ranges[name]);
}
this->get_tx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
+ .set_coercer(boost::bind(&wbx_base::wbx_version2::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
.set((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop())/2.0);
this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v2_freq_range);
this->get_tx_subtree()->create<bool>("enabled")
- .subscribe(boost::bind(&wbx_base::wbx_version2::set_tx_enabled, this, _1))
+ .add_coerced_subscriber(boost::bind(&wbx_base::wbx_version2::set_tx_enabled, this, _1))
.set(true); //start enabled
//set attenuator control bits
@@ -117,15 +117,15 @@ wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) {
self_base->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RX_PUP_5V|RX_PUP_3V|ADF435X_CE|RXBB_PDB|ADF435X_PDBRF|RX_ATTN_MASK);
//setup ATR for the mixer enables (always enabled to prevent phase slip between bursts)
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
-
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, v2_tx_mod, TX_MIXER_DIS | v2_tx_mod);
+
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
}
wbx_base::wbx_version2::~wbx_version2(void){
@@ -178,108 +178,42 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
+ double reference_freq = self_base->get_iface()->get_clock_rate(unit);
- //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)
- static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of
- (0,23) //adf4350_regs_t::PRESCALER_4_5
- (1,75) //adf4350_regs_t::PRESCALER_8_9
- ;
-
- //map rf divider select output dividers to enums
- static const uhd::dict<int, adf4350_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
- (1, adf4350_regs_t::RF_DIVIDER_SELECT_DIV1)
- (2, adf4350_regs_t::RF_DIVIDER_SELECT_DIV2)
- (4, adf4350_regs_t::RF_DIVIDER_SELECT_DIV4)
- (8, adf4350_regs_t::RF_DIVIDER_SELECT_DIV8)
- (16, adf4350_regs_t::RF_DIVIDER_SELECT_DIV16)
- ;
+ //Select the LO
+ adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo;
+ lo_iface->set_reference_freq(reference_freq);
- double reference_freq = self_base->get_iface()->get_clock_rate(unit);
//The mixer has a divide-by-2 stage on the LO port so the synthesizer
//frequency must 2x the target frequency
double synth_target_freq = target_freq * 2;
- //TODO: Document why the following has to be true
- bool div_resync_enabled = (target_freq > reference_freq);
-
- adf4350_regs_t::prescaler_t prescaler =
- synth_target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
-
- adf435x_tuning_constraints tuning_constraints;
- tuning_constraints.force_frac0 = is_int_n;
- tuning_constraints.band_sel_freq_max = 100e3;
- tuning_constraints.ref_doubler_threshold = 12.5e6;
- tuning_constraints.int_range = uhd::range_t(prescaler_to_min_int_div[prescaler], 4095);
- tuning_constraints.pfd_freq_max = 25e6;
- tuning_constraints.rf_divider_range = uhd::range_t(1, 16);
+
+ //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
+ lo_iface->set_prescaler(synth_target_freq > 3e9 ?
+ adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5);
+
//When divider resync is enabled, a 180 deg phase error is introduced when syncing
//multiple WBX boards. Switching to fundamental mode works arounds this issue.
- tuning_constraints.feedback_after_divider = div_resync_enabled;
+ //TODO: Document why the following has to be true
+ lo_iface->set_feedback_select((target_freq > reference_freq) ?
+ adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL);
- double synth_actual_freq = 0;
- adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- synth_target_freq, reference_freq, tuning_constraints, synth_actual_freq);
+ double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n);
//The mixer has a divide-by-2 stage on the LO port so the synthesizer
//actual_freq must /2 the synth_actual_freq
double actual_freq = synth_actual_freq / 2;
- //load the register values
- adf4350_regs_t regs;
-
- if (unit == dboard_iface::UNIT_RX)
- regs.output_power = (actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? adf4350_regs_t::OUTPUT_POWER_5DBM
- : adf4350_regs_t::OUTPUT_POWER_2DBM;
- else
- regs.output_power = (actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? adf4350_regs_t::OUTPUT_POWER_5DBM
- : adf4350_regs_t::OUTPUT_POWER_M1DBM;
-
- regs.frac_12_bit = tuning_settings.frac_12_bit;
- regs.int_16_bit = tuning_settings.int_16_bit;
- regs.mod_12_bit = tuning_settings.mod_12_bit;
- regs.clock_divider_12_bit = tuning_settings.clock_divider_12_bit;
- regs.feedback_select = tuning_constraints.feedback_after_divider ?
- adf4350_regs_t::FEEDBACK_SELECT_DIVIDED :
- adf4350_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
- regs.clock_div_mode = div_resync_enabled ?
- adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE :
- adf4350_regs_t::CLOCK_DIV_MODE_FAST_LOCK;
- regs.prescaler = prescaler;
- regs.r_counter_10_bit = tuning_settings.r_counter_10_bit;
- regs.reference_divide_by_2 = tuning_settings.r_divide_by_2_en ?
- adf4350_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED :
- adf4350_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- regs.reference_doubler = tuning_settings.r_doubler_en ?
- adf4350_regs_t::REFERENCE_DOUBLER_ENABLED :
- adf4350_regs_t::REFERENCE_DOUBLER_DISABLED;
- regs.band_select_clock_div = tuning_settings.band_select_clock_div;
- UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(tuning_settings.rf_divider));
- regs.rf_divider_select = rfdivsel_to_enum[tuning_settings.rf_divider];
- regs.ldf = is_int_n ?
- adf4350_regs_t::LDF_INT_N :
- adf4350_regs_t::LDF_FRAC_N;
-
- //reset the N and R counter
- regs.counter_reset = adf4350_regs_t::COUNTER_RESET_ENABLED;
- self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, regs.get_reg(2), 32);
- regs.counter_reset = adf4350_regs_t::COUNTER_RESET_DISABLED;
-
- //write the registers
- //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
- int addr;
-
- for(addr=5; addr>=0; addr--){
- UHD_LOGV(often) << boost::format(
- "WBX SPI Reg (0x%02x): 0x%08x"
- ) % addr % regs.get_reg(addr) << std::endl;
- self_base->get_iface()->write_spi(
- unit, spi_config_t::EDGE_RISE,
- regs.get_reg(addr), 32
- );
+ if (unit == dboard_iface::UNIT_RX) {
+ lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ?
+ adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM);
+ } else {
+ lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ?
+ adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM);
}
- //return the actual frequency
- UHD_LOGV(often) << boost::format(
- "WBX tune: actual frequency %f MHz"
- ) % (actual_freq/1e6) << std::endl;
+ //Write to hardware
+ lo_iface->commit();
+
return actual_freq;
}
diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp
index 6927ae4e4..2add8d25d 100644
--- a/host/lib/usrp/dboard/db_wbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version3.cpp
@@ -16,8 +16,6 @@
//
#include "db_wbx_common.hpp"
-#include "adf4350_regs.hpp"
-#include "../common/adf435x_common.hpp"
#include <uhd/utils/log.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/ranges.hpp>
@@ -82,13 +80,15 @@ static int tx_pga0_gain_to_iobits(double &gain){
wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) {
//register our handle on the primary wbx_base instance
self_base = _self_wbx_base;
+ _txlo = adf435x_iface::make_adf4350(boost::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, _1));
+ _rxlo = adf435x_iface::make_adf4350(boost::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, _1));
////////////////////////////////////////////////////////////////////
// Register RX properties
////////////////////////////////////////////////////////////////////
this->get_rx_subtree()->create<std::string>("name").set("WBXv3 RX");
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
+ .set_coercer(boost::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
.set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop())/2.0);
this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v3_freq_range);
@@ -98,17 +98,17 @@ wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) {
this->get_tx_subtree()->create<std::string>("name").set("WBXv3 TX");
BOOST_FOREACH(const std::string &name, wbx_v3_tx_gain_ranges.keys()){
self_base->get_tx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&wbx_base::wbx_version3::set_tx_gain, this, _1, name))
+ .set_coercer(boost::bind(&wbx_base::wbx_version3::set_tx_gain, this, _1, name))
.set(wbx_v3_tx_gain_ranges[name].start());
self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(wbx_v3_tx_gain_ranges[name]);
}
this->get_tx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
+ .set_coercer(boost::bind(&wbx_base::wbx_version3::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
.set((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop())/2.0);
this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v3_freq_range);
this->get_tx_subtree()->create<bool>("enabled")
- .subscribe(boost::bind(&wbx_base::wbx_version3::set_tx_enabled, this, _1))
+ .add_coerced_subscriber(boost::bind(&wbx_base::wbx_version3::set_tx_enabled, this, _1))
.set(true); //start enabled
//set attenuator control bits
@@ -129,29 +129,29 @@ wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) {
//slip between bursts). set TX gain iobits to min gain (max attenuation)
//when RX_ONLY or IDLE to suppress LO leakage
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_IDLE, v3_tx_mod, \
+ gpio_atr::ATR_REG_IDLE, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_RX_ONLY, v3_tx_mod, \
+ gpio_atr::ATR_REG_RX_ONLY, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_TX_ONLY, v3_tx_mod, \
+ gpio_atr::ATR_REG_TX_ONLY, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, v3_tx_mod, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, v3_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v3_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_IDLE, \
+ gpio_atr::ATR_REG_IDLE, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_TX_ONLY, \
+ gpio_atr::ATR_REG_TX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_RX_ONLY, \
+ gpio_atr::ATR_REG_RX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
}
@@ -181,8 +181,8 @@ double wbx_base::wbx_version3::set_tx_gain(double gain, const std::string &name)
//write the new gain to tx gpio outputs
//Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
}
else UHD_THROW_INVALID_CODE_PATH();
return self_base->_tx_gains[name]; //shadow
@@ -209,108 +209,42 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
+ double reference_freq = self_base->get_iface()->get_clock_rate(unit);
- //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)
- static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of
- (0,23) //adf4350_regs_t::PRESCALER_4_5
- (1,75) //adf4350_regs_t::PRESCALER_8_9
- ;
-
- //map rf divider select output dividers to enums
- static const uhd::dict<int, adf4350_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
- (1, adf4350_regs_t::RF_DIVIDER_SELECT_DIV1)
- (2, adf4350_regs_t::RF_DIVIDER_SELECT_DIV2)
- (4, adf4350_regs_t::RF_DIVIDER_SELECT_DIV4)
- (8, adf4350_regs_t::RF_DIVIDER_SELECT_DIV8)
- (16, adf4350_regs_t::RF_DIVIDER_SELECT_DIV16)
- ;
+ //Select the LO
+ adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo;
+ lo_iface->set_reference_freq(reference_freq);
- double reference_freq = self_base->get_iface()->get_clock_rate(unit);
//The mixer has a divide-by-2 stage on the LO port so the synthesizer
//frequency must 2x the target frequency
double synth_target_freq = target_freq * 2;
- //TODO: Document why the following has to be true
- bool div_resync_enabled = (target_freq > reference_freq);
-
- adf4350_regs_t::prescaler_t prescaler =
- synth_target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
-
- adf435x_tuning_constraints tuning_constraints;
- tuning_constraints.force_frac0 = is_int_n;
- tuning_constraints.band_sel_freq_max = 100e3;
- tuning_constraints.ref_doubler_threshold = 12.5e6;
- tuning_constraints.int_range = uhd::range_t(prescaler_to_min_int_div[prescaler], 4095);
- tuning_constraints.pfd_freq_max = 25e6;
- tuning_constraints.rf_divider_range = uhd::range_t(1, 16);
+
+ //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
+ lo_iface->set_prescaler(synth_target_freq > 3e9 ?
+ adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5);
+
//When divider resync is enabled, a 180 deg phase error is introduced when syncing
//multiple WBX boards. Switching to fundamental mode works arounds this issue.
- tuning_constraints.feedback_after_divider = div_resync_enabled;
+ //TODO: Document why the following has to be true
+ lo_iface->set_feedback_select((target_freq > reference_freq) ?
+ adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL);
- double synth_actual_freq = 0;
- adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- synth_target_freq, reference_freq, tuning_constraints, synth_actual_freq);
+ double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n);
//The mixer has a divide-by-2 stage on the LO port so the synthesizer
//actual_freq must /2 the synth_actual_freq
double actual_freq = synth_actual_freq / 2;
- //load the register values
- adf4350_regs_t regs;
-
- if (unit == dboard_iface::UNIT_RX)
- regs.output_power = (actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? adf4350_regs_t::OUTPUT_POWER_5DBM
- : adf4350_regs_t::OUTPUT_POWER_2DBM;
- else
- regs.output_power = (actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? adf4350_regs_t::OUTPUT_POWER_5DBM
- : adf4350_regs_t::OUTPUT_POWER_M1DBM;
-
- regs.frac_12_bit = tuning_settings.frac_12_bit;
- regs.int_16_bit = tuning_settings.int_16_bit;
- regs.mod_12_bit = tuning_settings.mod_12_bit;
- regs.clock_divider_12_bit = tuning_settings.clock_divider_12_bit;
- regs.feedback_select = tuning_constraints.feedback_after_divider ?
- adf4350_regs_t::FEEDBACK_SELECT_DIVIDED :
- adf4350_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
- regs.clock_div_mode = div_resync_enabled ?
- adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE :
- adf4350_regs_t::CLOCK_DIV_MODE_FAST_LOCK;
- regs.prescaler = prescaler;
- regs.r_counter_10_bit = tuning_settings.r_counter_10_bit;
- regs.reference_divide_by_2 = tuning_settings.r_divide_by_2_en ?
- adf4350_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED :
- adf4350_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- regs.reference_doubler = tuning_settings.r_doubler_en ?
- adf4350_regs_t::REFERENCE_DOUBLER_ENABLED :
- adf4350_regs_t::REFERENCE_DOUBLER_DISABLED;
- regs.band_select_clock_div = tuning_settings.band_select_clock_div;
- UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(tuning_settings.rf_divider));
- regs.rf_divider_select = rfdivsel_to_enum[tuning_settings.rf_divider];
- regs.ldf = is_int_n ?
- adf4350_regs_t::LDF_INT_N :
- adf4350_regs_t::LDF_FRAC_N;
-
- //reset the N and R counter
- regs.counter_reset = adf4350_regs_t::COUNTER_RESET_ENABLED;
- self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, regs.get_reg(2), 32);
- regs.counter_reset = adf4350_regs_t::COUNTER_RESET_DISABLED;
-
- //write the registers
- //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
- int addr;
-
- for(addr=5; addr>=0; addr--){
- UHD_LOGV(often) << boost::format(
- "WBX SPI Reg (0x%02x): 0x%08x"
- ) % addr % regs.get_reg(addr) << std::endl;
- self_base->get_iface()->write_spi(
- unit, spi_config_t::EDGE_RISE,
- regs.get_reg(addr), 32
- );
+ if (unit == dboard_iface::UNIT_RX) {
+ lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ?
+ adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM);
+ } else {
+ lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ?
+ adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM);
}
- //return the actual frequency
- UHD_LOGV(often) << boost::format(
- "WBX tune: actual frequency %f MHz"
- ) % (actual_freq/1e6) << std::endl;
+ //Write to hardware
+ lo_iface->commit();
+
return actual_freq;
}
diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp
index 81cdaefac..dc351af1d 100644
--- a/host/lib/usrp/dboard/db_wbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version4.cpp
@@ -16,8 +16,6 @@
//
#include "db_wbx_common.hpp"
-#include "adf4351_regs.hpp"
-#include "../common/adf435x_common.hpp"
#include <uhd/utils/log.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/ranges.hpp>
@@ -83,6 +81,8 @@ static int tx_pga0_gain_to_iobits(double &gain){
wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
//register our handle on the primary wbx_base instance
self_base = _self_wbx_base;
+ _txlo = adf435x_iface::make_adf4351(boost::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_TX, _1));
+ _rxlo = adf435x_iface::make_adf4351(boost::bind(&wbx_base::wbx_versionx::write_lo_regs, this, dboard_iface::UNIT_RX, _1));
////////////////////////////////////////////////////////////////////
// Register RX properties
@@ -92,7 +92,7 @@ wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
if(rx_id == 0x0063) this->get_rx_subtree()->create<std::string>("name").set("WBXv4 RX");
else if(rx_id == 0x0081) this->get_rx_subtree()->create<std::string>("name").set("WBX-120 RX");
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
+ .set_coercer(boost::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_RX, _1))
.set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0);
this->get_rx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range);
@@ -105,17 +105,17 @@ wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
else if(rx_id == 0x0081) this->get_tx_subtree()->create<std::string>("name").set("WBX-120 TX");
BOOST_FOREACH(const std::string &name, wbx_v4_tx_gain_ranges.keys()){
self_base->get_tx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&wbx_base::wbx_version4::set_tx_gain, this, _1, name))
+ .set_coercer(boost::bind(&wbx_base::wbx_version4::set_tx_gain, this, _1, name))
.set(wbx_v4_tx_gain_ranges[name].start());
self_base->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(wbx_v4_tx_gain_ranges[name]);
}
this->get_tx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
+ .set_coercer(boost::bind(&wbx_base::wbx_version4::set_lo_freq, this, dboard_iface::UNIT_TX, _1))
.set((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0);
this->get_tx_subtree()->create<meta_range_t>("freq/range").set(wbx_v4_freq_range);
this->get_tx_subtree()->create<bool>("enabled")
- .subscribe(boost::bind(&wbx_base::wbx_version4::set_tx_enabled, this, _1))
+ .add_coerced_subscriber(boost::bind(&wbx_base::wbx_version4::set_tx_enabled, this, _1))
.set(true); //start enabled
//set attenuator control bits
@@ -136,29 +136,29 @@ wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
//between bursts) set TX gain iobits to min gain (max attenuation) when
//RX_ONLY or IDLE to suppress LO leakage
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_IDLE, v4_tx_mod, \
+ gpio_atr::ATR_REG_IDLE, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_RX_ONLY, v4_tx_mod, \
+ gpio_atr::ATR_REG_RX_ONLY, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_TX_ONLY, v4_tx_mod, \
+ gpio_atr::ATR_REG_TX_ONLY, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, v4_tx_mod, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, v4_tx_mod, \
TX_ATTN_MASK | TX_MIXER_DIS | v4_tx_mod);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_IDLE, \
+ gpio_atr::ATR_REG_IDLE, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_TX_ONLY, \
+ gpio_atr::ATR_REG_TX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_RX_ONLY, \
+ gpio_atr::ATR_REG_RX_ONLY, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, \
- dboard_iface::ATR_REG_FULL_DUPLEX, \
+ gpio_atr::ATR_REG_FULL_DUPLEX, \
RX_MIXER_ENB, RX_MIXER_DIS | RX_MIXER_ENB);
}
@@ -188,8 +188,8 @@ double wbx_base::wbx_version4::set_tx_gain(double gain, const std::string &name)
//write the new gain to tx gpio outputs
//Update ATR with gain io_bits, only update for TX_ONLY and FULL_DUPLEX ATR states
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
- self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, io_bits, TX_ATTN_MASK);
+ self_base->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, io_bits, TX_ATTN_MASK);
}
else UHD_THROW_INVALID_CODE_PATH();
@@ -217,116 +217,46 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
+ double reference_freq = self_base->get_iface()->get_clock_rate(unit);
- //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)
- static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of
- (adf4351_regs_t::PRESCALER_4_5, 23)
- (adf4351_regs_t::PRESCALER_8_9, 75)
- ;
-
- //map rf divider select output dividers to enums
- static const uhd::dict<int, adf4351_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of
- (1, adf4351_regs_t::RF_DIVIDER_SELECT_DIV1)
- (2, adf4351_regs_t::RF_DIVIDER_SELECT_DIV2)
- (4, adf4351_regs_t::RF_DIVIDER_SELECT_DIV4)
- (8, adf4351_regs_t::RF_DIVIDER_SELECT_DIV8)
- (16, adf4351_regs_t::RF_DIVIDER_SELECT_DIV16)
- (32, adf4351_regs_t::RF_DIVIDER_SELECT_DIV32)
- (64, adf4351_regs_t::RF_DIVIDER_SELECT_DIV64)
- ;
+ //Select the LO
+ adf435x_iface::sptr& lo_iface = unit == dboard_iface::UNIT_RX ? _rxlo : _txlo;
+ lo_iface->set_reference_freq(reference_freq);
- double reference_freq = self_base->get_iface()->get_clock_rate(unit);
//The mixer has a divide-by-2 stage on the LO port so the synthesizer
//frequency must 2x the target frequency. This introduces a 180 degree phase
//ambiguity when trying to synchronize the phase of multiple boards.
double synth_target_freq = target_freq * 2;
- adf4351_regs_t::prescaler_t prescaler =
- synth_target_freq > 3.6e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
+ //Use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
+ lo_iface->set_prescaler(synth_target_freq > 3.6e9 ?
+ adf435x_iface::PRESCALER_8_9 : adf435x_iface::PRESCALER_4_5);
- adf435x_tuning_constraints tuning_constraints;
- tuning_constraints.force_frac0 = is_int_n;
- tuning_constraints.band_sel_freq_max = 100e3;
- tuning_constraints.ref_doubler_threshold = 12.5e6;
- tuning_constraints.int_range = uhd::range_t(prescaler_to_min_int_div[prescaler], 4095);
- tuning_constraints.pfd_freq_max = 25e6;
- tuning_constraints.rf_divider_range = uhd::range_t(1, 64);
//The feedback of the divided frequency must be disabled whenever the target frequency
//divided by the minimum PFD frequency cannot meet the minimum integer divider (N) value.
//If it is disabled, additional phase ambiguity will be introduced. With a minimum PFD
//frequency of 10 MHz, synthesizer frequencies below 230 MHz (LO frequencies below 115 MHz)
//will have too much ambiguity to synchronize.
- tuning_constraints.feedback_after_divider =
- (int(synth_target_freq / 10e6) >= prescaler_to_min_int_div[prescaler]);
+ lo_iface->set_feedback_select(
+ (int(synth_target_freq / 10e6) >= lo_iface->get_int_range().start() ?
+ adf435x_iface::FB_SEL_DIVIDED : adf435x_iface::FB_SEL_FUNDAMENTAL));
- double synth_actual_freq = 0;
- adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- synth_target_freq, reference_freq, tuning_constraints, synth_actual_freq);
+ double synth_actual_freq = lo_iface->set_frequency(synth_target_freq, is_int_n);
//The mixer has a divide-by-2 stage on the LO port so the synthesizer
//actual_freq must /2 the synth_actual_freq
double actual_freq = synth_actual_freq / 2;
- //load the register values
- adf4351_regs_t regs;
-
- if (unit == dboard_iface::UNIT_RX)
- regs.output_power = (actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ? adf4351_regs_t::OUTPUT_POWER_5DBM
- : adf4351_regs_t::OUTPUT_POWER_2DBM;
- else
- regs.output_power = (actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ? adf4351_regs_t::OUTPUT_POWER_5DBM
- : adf4351_regs_t::OUTPUT_POWER_M1DBM;
-
- regs.frac_12_bit = tuning_settings.frac_12_bit;
- regs.int_16_bit = tuning_settings.int_16_bit;
- regs.mod_12_bit = tuning_settings.mod_12_bit;
- regs.clock_divider_12_bit = tuning_settings.clock_divider_12_bit;
- regs.feedback_select = tuning_constraints.feedback_after_divider ?
- adf4351_regs_t::FEEDBACK_SELECT_DIVIDED :
- adf4351_regs_t::FEEDBACK_SELECT_FUNDAMENTAL;
- regs.clock_div_mode = tuning_constraints.feedback_after_divider ?
- adf4351_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE :
- adf4351_regs_t::CLOCK_DIV_MODE_FAST_LOCK;
- regs.prescaler = prescaler;
- regs.r_counter_10_bit = tuning_settings.r_counter_10_bit;
- regs.reference_divide_by_2 = tuning_settings.r_divide_by_2_en ?
- adf4351_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED :
- adf4351_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED;
- regs.reference_doubler = tuning_settings.r_doubler_en ?
- adf4351_regs_t::REFERENCE_DOUBLER_ENABLED :
- adf4351_regs_t::REFERENCE_DOUBLER_DISABLED;
- regs.band_select_clock_div = tuning_settings.band_select_clock_div;
- UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(tuning_settings.rf_divider));
- regs.rf_divider_select = rfdivsel_to_enum[tuning_settings.rf_divider];
- regs.ldf = is_int_n ?
- adf4351_regs_t::LDF_INT_N :
- adf4351_regs_t::LDF_FRAC_N;
-
- //reset the N and R counter
- regs.counter_reset = adf4351_regs_t::COUNTER_RESET_ENABLED;
- self_base->get_iface()->write_spi(unit, spi_config_t::EDGE_RISE, regs.get_reg(2), 32);
- regs.counter_reset = adf4351_regs_t::COUNTER_RESET_DISABLED;
-
- //write the registers
- //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0)
- int addr;
-
- boost::uint16_t rx_id = self_base->get_rx_id().to_uint16();
- std::string board_name = (rx_id == 0x0081) ? "WBX-120" : "WBX";
- for(addr=5; addr>=0; addr--){
- UHD_LOGV(often) << boost::format(
- "%s SPI Reg (0x%02x): 0x%08x"
- ) % board_name.c_str() % addr % regs.get_reg(addr) << std::endl;
- self_base->get_iface()->write_spi(
- unit, spi_config_t::EDGE_RISE,
- regs.get_reg(addr), 32
- );
+ if (unit == dboard_iface::UNIT_RX) {
+ lo_iface->set_output_power((actual_freq == wbx_rx_lo_5dbm.clip(actual_freq)) ?
+ adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_2DBM);
+ } else {
+ lo_iface->set_output_power((actual_freq == wbx_tx_lo_5dbm.clip(actual_freq)) ?
+ adf435x_iface::OUTPUT_POWER_5DBM : adf435x_iface::OUTPUT_POWER_M1DBM);
}
- //return the actual frequency
- UHD_LOGV(often) << boost::format(
- "%s tune: actual frequency %f MHz"
- ) % board_name.c_str() % (actual_freq/1e6) << std::endl;
+ //Write to hardware
+ lo_iface->commit();
return actual_freq;
}
diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp
index 50c67991a..4a3f69f69 100644
--- a/host/lib/usrp/dboard/db_xcvr2450.cpp
+++ b/host/lib/usrp/dboard/db_xcvr2450.cpp
@@ -112,7 +112,7 @@ static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = map_list
class xcvr2450 : public xcvr_dboard_base{
public:
xcvr2450(ctor_args_t args);
- ~xcvr2450(void);
+ virtual ~xcvr2450(void);
private:
double _lo_freq;
@@ -231,23 +231,23 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){
this->get_rx_subtree()->create<std::string>("name")
.set("XCVR2450 RX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&xcvr2450::get_locked, this));
+ .set_publisher(boost::bind(&xcvr2450::get_locked, this));
this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi")
- .publish(boost::bind(&xcvr2450::get_rssi, this));
+ .set_publisher(boost::bind(&xcvr2450::get_rssi, this));
BOOST_FOREACH(const std::string &name, xcvr_rx_gain_ranges.keys()){
this->get_rx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&xcvr2450::set_rx_gain, this, _1, name))
+ .set_coercer(boost::bind(&xcvr2450::set_rx_gain, this, _1, name))
.set(xcvr_rx_gain_ranges[name].start());
this->get_rx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(xcvr_rx_gain_ranges[name]);
}
this->get_rx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&xcvr2450::set_lo_freq, this, _1))
+ .set_coercer(boost::bind(&xcvr2450::set_lo_freq, this, _1))
.set(double(2.45e9));
this->get_rx_subtree()->create<meta_range_t>("freq/range")
.set(xcvr_freq_range);
this->get_rx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&xcvr2450::set_rx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&xcvr2450::set_rx_ant, this, _1))
.set(xcvr_antennas.at(0));
this->get_rx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(xcvr_antennas);
@@ -258,7 +258,7 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){
this->get_rx_subtree()->create<bool>("use_lo_offset")
.set(false);
this->get_rx_subtree()->create<double>("bandwidth/value")
- .coerce(boost::bind(&xcvr2450::set_rx_bandwidth, this, _1)) //complex bandpass bandwidth
+ .set_coercer(boost::bind(&xcvr2450::set_rx_bandwidth, this, _1)) //complex bandpass bandwidth
.set(2.0*_rx_bandwidth); //_rx_bandwidth in lowpass, convert to complex bandpass
this->get_rx_subtree()->create<meta_range_t>("bandwidth/range")
.set(xcvr_rx_bandwidth_range);
@@ -269,21 +269,21 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){
this->get_tx_subtree()->create<std::string>("name")
.set("XCVR2450 TX");
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
- .publish(boost::bind(&xcvr2450::get_locked, this));
+ .set_publisher(boost::bind(&xcvr2450::get_locked, this));
BOOST_FOREACH(const std::string &name, xcvr_tx_gain_ranges.keys()){
this->get_tx_subtree()->create<double>("gains/"+name+"/value")
- .coerce(boost::bind(&xcvr2450::set_tx_gain, this, _1, name))
+ .set_coercer(boost::bind(&xcvr2450::set_tx_gain, this, _1, name))
.set(xcvr_tx_gain_ranges[name].start());
this->get_tx_subtree()->create<meta_range_t>("gains/"+name+"/range")
.set(xcvr_tx_gain_ranges[name]);
}
this->get_tx_subtree()->create<double>("freq/value")
- .coerce(boost::bind(&xcvr2450::set_lo_freq, this, _1))
+ .set_coercer(boost::bind(&xcvr2450::set_lo_freq, this, _1))
.set(double(2.45e9));
this->get_tx_subtree()->create<meta_range_t>("freq/range")
.set(xcvr_freq_range);
this->get_tx_subtree()->create<std::string>("antenna/value")
- .subscribe(boost::bind(&xcvr2450::set_tx_ant, this, _1))
+ .add_coerced_subscriber(boost::bind(&xcvr2450::set_tx_ant, this, _1))
.set(xcvr_antennas.at(1));
this->get_tx_subtree()->create<std::vector<std::string> >("antenna/options")
.set(xcvr_antennas);
@@ -294,7 +294,7 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){
this->get_tx_subtree()->create<bool>("use_lo_offset")
.set(false);
this->get_tx_subtree()->create<double>("bandwidth/value")
- .coerce(boost::bind(&xcvr2450::set_tx_bandwidth, this, _1)) //complex bandpass bandwidth
+ .set_coercer(boost::bind(&xcvr2450::set_tx_bandwidth, this, _1)) //complex bandpass bandwidth
.set(2.0*_tx_bandwidth); //_tx_bandwidth in lowpass, convert to complex bandpass
this->get_tx_subtree()->create<meta_range_t>("bandwidth/range")
.set(xcvr_tx_bandwidth_range);
@@ -315,12 +315,12 @@ xcvr2450::~xcvr2450(void){
void xcvr2450::spi_reset(void){
//spi reset mode: global enable = off, tx and rx enable = on
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, TX_ENB_TXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, TX_ENB_TXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_ENB_RXIO | POWER_DOWN_RXIO);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
//take it back out of spi reset mode and wait a bit
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, RX_DIS_RXIO | POWER_UP_RXIO);
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
}
@@ -337,16 +337,16 @@ void xcvr2450::update_atr(void){
int ad9515div = (_ad9515div == 3)? AD9515DIV_3_TXIO : AD9515DIV_2_TXIO;
//set the tx registers
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE, band_sel | ad9515div | TX_DIS_TXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY, band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY, band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_IDLE, band_sel | ad9515div | TX_DIS_TXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_RX_ONLY, band_sel | ad9515div | TX_DIS_TXIO | rx_ant_sel);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_TX_ONLY, band_sel | ad9515div | TX_ENB_TXIO | tx_ant_sel);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, gpio_atr::ATR_REG_FULL_DUPLEX, band_sel | ad9515div | TX_ENB_TXIO | xx_ant_sel);
//set the rx registers
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO);
- this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, POWER_UP_RXIO | RX_DIS_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_IDLE, POWER_UP_RXIO | RX_DIS_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_RX_ONLY, POWER_UP_RXIO | RX_ENB_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_TX_ONLY, POWER_UP_RXIO | RX_DIS_RXIO);
+ this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, gpio_atr::ATR_REG_FULL_DUPLEX, POWER_UP_RXIO | RX_DIS_RXIO);
}
/***********************************************************************