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.cpp30
-rw-r--r--host/lib/usrp/dboard/db_dbsrx.cpp2
-rw-r--r--host/lib/usrp/dboard/db_dbsrx2.cpp4
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp24
-rw-r--r--host/lib/usrp/dboard/db_sbx_version3.cpp25
-rw-r--r--host/lib/usrp/dboard/db_sbx_version4.cpp23
-rw-r--r--host/lib/usrp/dboard/db_tvrx.cpp4
-rw-r--r--host/lib/usrp/dboard/db_tvrx2.cpp4
-rw-r--r--host/lib/usrp/dboard/db_wbx_common.cpp3
-rw-r--r--host/lib/usrp/dboard/db_wbx_simple.cpp9
-rw-r--r--host/lib/usrp/dboard/db_wbx_version2.cpp34
-rw-r--r--host/lib/usrp/dboard/db_wbx_version3.cpp34
-rw-r--r--host/lib/usrp/dboard/db_wbx_version4.cpp32
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp4
14 files changed, 158 insertions, 74 deletions
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp
index fc42a73d5..2b30dab52 100644
--- a/host/lib/usrp/dboard/db_basic_and_lf.cpp
+++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -108,11 +108,17 @@ basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args){
////////////////////////////////////////////////////////////////////
// Register properties
////////////////////////////////////////////////////////////////////
- this->get_rx_subtree()->create<std::string>("name").set(
- std::string(str(boost::format("%s - %s")
- % get_rx_id().to_pp_string()
- % get_subdev_name()
+ if(get_rx_id() == 0x0001){
+ this->get_rx_subtree()->create<std::string>("name").set(
+ std::string(str(boost::format("BasicRX (%s)") % get_subdev_name()
)));
+ }
+ else{
+ this->get_rx_subtree()->create<std::string>("name").set(
+ std::string(str(boost::format("LFRX (%s)") % get_subdev_name()
+ )));
+ }
+
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);
@@ -157,11 +163,17 @@ basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args){
////////////////////////////////////////////////////////////////////
// Register properties
////////////////////////////////////////////////////////////////////
- this->get_tx_subtree()->create<std::string>("name").set(
- std::string(str(boost::format("%s - %s")
- % get_tx_id().to_pp_string()
- % get_subdev_name()
+ if(get_tx_id() == 0x0000){
+ this->get_tx_subtree()->create<std::string>("name").set(
+ std::string(str(boost::format("BasicTX (%s)") % get_subdev_name()
)));
+ }
+ else{
+ this->get_tx_subtree()->create<std::string>("name").set(
+ std::string(str(boost::format("LFTX (%s)") % get_subdev_name()
+ )));
+ }
+
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);
diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp
index 95c5c5d4d..b1cee4aa7 100644
--- a/host/lib/usrp/dboard/db_dbsrx.cpp
+++ b/host/lib/usrp/dboard/db_dbsrx.cpp
@@ -202,7 +202,7 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){
// Register properties
////////////////////////////////////////////////////////////////////
this->get_rx_subtree()->create<std::string>("name")
- .set(get_rx_id().to_pp_string());
+ .set("DBSRX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&dbsrx::get_locked, this));
BOOST_FOREACH(const std::string &name, dbsrx_gain_ranges.keys()){
diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp
index 517b7b183..013f3178a 100644
--- a/host/lib/usrp/dboard/db_dbsrx2.cpp
+++ b/host/lib/usrp/dboard/db_dbsrx2.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -189,7 +189,7 @@ dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args){
// Register properties
////////////////////////////////////////////////////////////////////
this->get_rx_subtree()->create<std::string>("name")
- .set(get_rx_id().to_pp_string());
+ .set("DBSRX2");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&dbsrx2::get_locked, this));
BOOST_FOREACH(const std::string &name, dbsrx2_gain_ranges.keys()){
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 32aa3fe04..cf3b29ddc 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -174,7 +174,14 @@ rfx_xcvr::rfx_xcvr(
////////////////////////////////////////////////////////////////////
// Register RX properties
////////////////////////////////////////////////////////////////////
- this->get_rx_subtree()->create<std::string>("name").set("RFX RX");
+ if(get_rx_id() == 0x0024) this->get_rx_subtree()->create<std::string>("name").set("RFX400 RX");
+ else if(get_rx_id() == 0x0025) this->get_rx_subtree()->create<std::string>("name").set("RFX900 RX");
+ else if(get_rx_id() == 0x0034) this->get_rx_subtree()->create<std::string>("name").set("RFX1800 RX");
+ else if(get_rx_id() == 0x0026) this->get_rx_subtree()->create<std::string>("name").set("RFX1200 RX");
+ else if(get_rx_id() == 0x002c) this->get_rx_subtree()->create<std::string>("name").set("RFX2200 RX");
+ else if(get_rx_id() == 0x0027) this->get_rx_subtree()->create<std::string>("name").set("RFX2400 RX");
+ 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));
BOOST_FOREACH(const std::string &name, _rx_gain_ranges.keys()){
@@ -203,7 +210,14 @@ rfx_xcvr::rfx_xcvr(
////////////////////////////////////////////////////////////////////
// Register TX properties
////////////////////////////////////////////////////////////////////
- this->get_tx_subtree()->create<std::string>("name").set("RFX TX");
+ if(get_tx_id() == 0x0028) this->get_tx_subtree()->create<std::string>("name").set("RFX400 TX");
+ else if(get_tx_id() == 0x0029) this->get_tx_subtree()->create<std::string>("name").set("RFX900 TX");
+ else if(get_tx_id() == 0x0035) this->get_tx_subtree()->create<std::string>("name").set("RFX1800 TX");
+ else if(get_tx_id() == 0x002a) this->get_tx_subtree()->create<std::string>("name").set("RFX1200 TX");
+ else if(get_tx_id() == 0x002d) this->get_tx_subtree()->create<std::string>("name").set("RFX2200 TX");
+ else if(get_tx_id() == 0x002b) this->get_tx_subtree()->create<std::string>("name").set("RFX2400 TX");
+ 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));
this->get_tx_subtree()->create<int>("gains"); //phony property so this dir exists
@@ -258,7 +272,7 @@ 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_DIS);
+ 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 );
}
@@ -358,7 +372,7 @@ double rfx_xcvr::set_lo_freq(
* The goal here to to loop though possible R dividers,
* band select clock dividers, and prescaler values.
* Calculate the A and B counters for each set of values.
- * The loop exists when it meets all of the constraints.
+ * The loop exits when it meets all of the constraints.
* The resulting loop values are loaded into the registers.
*
* fvco = [P*B + A] * fref/R
diff --git a/host/lib/usrp/dboard/db_sbx_version3.cpp b/host/lib/usrp/dboard/db_sbx_version3.cpp
index 6e20d5882..2765d530c 100644
--- a/host/lib/usrp/dboard/db_sbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version3.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -75,7 +75,6 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED;
//increase RF divider until acceptable VCO frequency
- //start with target_freq*2 because mixer has divide by 2
double vco_freq = target_freq;
while (vco_freq < 2.2e9) {
vco_freq *= 2;
@@ -83,7 +82,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
- adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
+ adf4350_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
/*
* The goal here is to loop though possible R dividers,
@@ -91,7 +90,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
* (frac) dividers.
*
* Calculate the N and F dividers for each set of values.
- * The loop exists when it meets all of the constraints.
+ * The loop exits when it meets all of the constraints.
* The resulting loop values are loaded into the registers.
*
* from pg.21
@@ -110,7 +109,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
if (pfd_freq > 25e6) continue;
//ignore fractional part of tuning
- N = int(std::floor(vco_freq/pfd_freq));
+ N = int(std::floor(target_freq/pfd_freq));
//keep N > minimum int divider requirement
if (N < prescaler_to_min_int_div[prescaler]) continue;
@@ -125,7 +124,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
//Fractional-N calculation
MOD = 4095; //max fractional accuracy
- FRAC = int((vco_freq/pfd_freq - N)*MOD);
+ FRAC = int((target_freq/pfd_freq - N)*MOD);
//Reference divide-by-2 for 50% duty cycle
// if R even, move one divide by 2 to to regs.reference_divide_by_2
@@ -135,12 +134,12 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//actual frequency calculation
- actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv);
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T))));
UHD_LOGV(often)
<< boost::format("SBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
- << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
- ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl
+ << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
<< boost::format("SBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
@@ -155,6 +154,9 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
regs.frac_12_bit = FRAC;
regs.int_16_bit = N;
regs.mod_12_bit = MOD;
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = adf4350_regs_t::FEEDBACK_SELECT_DIVIDED;
+ regs.clock_div_mode = adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
regs.prescaler = prescaler;
regs.r_counter_10_bit = R;
regs.reference_divide_by_2 = T;
@@ -163,6 +165,11 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv));
regs.rf_divider_select = rfdivsel_to_enum[RFdiv];
+ //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;
diff --git a/host/lib/usrp/dboard/db_sbx_version4.cpp b/host/lib/usrp/dboard/db_sbx_version4.cpp
index c8128d5f4..27fd68b05 100644
--- a/host/lib/usrp/dboard/db_sbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version4.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -78,7 +78,6 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
if(ref_freq <= 12.5e6) D = adf4351_regs_t::REFERENCE_DOUBLER_ENABLED;
//increase RF divider until acceptable VCO frequency
- //start with target_freq*2 because mixer has divide by 2
double vco_freq = target_freq;
while (vco_freq < 2.2e9) {
vco_freq *= 2;
@@ -86,7 +85,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
- adf4351_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
+ adf4351_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
/*
* The goal here is to loop though possible R dividers,
@@ -94,7 +93,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
* (frac) dividers.
*
* Calculate the N and F dividers for each set of values.
- * The loop exists when it meets all of the constraints.
+ * The loop exits when it meets all of the constraints.
* The resulting loop values are loaded into the registers.
*
* from pg.21
@@ -128,7 +127,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
//Fractional-N calculation
MOD = 4095; //max fractional accuracy
- FRAC = int((vco_freq/pfd_freq - N)*MOD);
+ FRAC = int((target_freq/pfd_freq - N)*MOD);
//Reference divide-by-2 for 50% duty cycle
// if R even, move one divide by 2 to to regs.reference_divide_by_2
@@ -138,12 +137,12 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//actual frequency calculation
- actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv);
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T))));
UHD_LOGV(often)
<< boost::format("SBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
- << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
- ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl
+ << boost::format("SBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
<< boost::format("SBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
@@ -158,6 +157,9 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
regs.frac_12_bit = FRAC;
regs.int_16_bit = N;
regs.mod_12_bit = MOD;
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = adf4351_regs_t::FEEDBACK_SELECT_DIVIDED;
+ regs.clock_div_mode = adf4351_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
regs.prescaler = prescaler;
regs.r_counter_10_bit = R;
regs.reference_divide_by_2 = T;
@@ -166,6 +168,11 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
UHD_ASSERT_THROW(rfdivsel_to_enum.has_key(RFdiv));
regs.rf_divider_select = rfdivsel_to_enum[RFdiv];
+ //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;
diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp
index fd86d5b83..edee46cd5 100644
--- a/host/lib/usrp/dboard/db_tvrx.cpp
+++ b/host/lib/usrp/dboard/db_tvrx.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 Ettus Research LLC
+// Copyright 2010-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -186,7 +186,7 @@ tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){
// Register properties
////////////////////////////////////////////////////////////////////
this->get_rx_subtree()->create<std::string>("name")
- .set(get_rx_id().to_pp_string());
+ .set("TVRX");
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")
diff --git a/host/lib/usrp/dboard/db_tvrx2.cpp b/host/lib/usrp/dboard/db_tvrx2.cpp
index 628221527..0bfa5229a 100644
--- a/host/lib/usrp/dboard/db_tvrx2.cpp
+++ b/host/lib/usrp/dboard/db_tvrx2.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010 Ettus Research LLC
+// Copyright 2010,2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -955,7 +955,7 @@ tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args){
// Register properties
////////////////////////////////////////////////////////////////////
this->get_rx_subtree()->create<std::string>("name")
- .set(get_rx_id().to_pp_string());
+ .set("TVRX2");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&tvrx2::get_locked, this));
this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi")
diff --git a/host/lib/usrp/dboard/db_wbx_common.cpp b/host/lib/usrp/dboard/db_wbx_common.cpp
index 58ce03d79..503e5aabf 100644
--- a/host/lib/usrp/dboard/db_wbx_common.cpp
+++ b/host/lib/usrp/dboard/db_wbx_common.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -16,7 +16,6 @@
//
#include "db_wbx_common.hpp"
-#include "adf4350_regs.hpp"
#include <uhd/types/dict.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/types/sensors.hpp>
diff --git a/host/lib/usrp/dboard/db_wbx_simple.cpp b/host/lib/usrp/dboard/db_wbx_simple.cpp
index 3d633a672..4ba30255d 100644
--- a/host/lib/usrp/dboard/db_wbx_simple.cpp
+++ b/host/lib/usrp/dboard/db_wbx_simple.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -81,8 +81,10 @@ wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){
////////////////////////////////////////////////////////////////////
// Register RX properties
////////////////////////////////////////////////////////////////////
+
this->get_rx_subtree()->access<std::string>("name").set(
- this->get_rx_subtree()->access<std::string>("name").get() + " + Simple GDB");
+ 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))
.set("RX2");
@@ -93,7 +95,8 @@ wbx_simple::wbx_simple(ctor_args_t args) : wbx_base(args){
// Register TX properties
////////////////////////////////////////////////////////////////////
this->get_tx_subtree()->access<std::string>("name").set(
- this->get_tx_subtree()->access<std::string>("name").get() + " + Simple GDB");
+ 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))
.set(wbx_tx_antennas.at(0));
diff --git a/host/lib/usrp/dboard/db_wbx_version2.cpp b/host/lib/usrp/dboard/db_wbx_version2.cpp
index ad31339e7..5f6118a91 100644
--- a/host/lib/usrp/dboard/db_wbx_version2.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version2.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -78,7 +78,7 @@ wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) {
////////////////////////////////////////////////////////////////////
// Register RX properties
////////////////////////////////////////////////////////////////////
- this->get_rx_subtree()->create<std::string>("name").set("WBX RX v2");
+ 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((wbx_v2_freq_range.start() + wbx_v2_freq_range.stop())/2.0);
@@ -87,7 +87,7 @@ wbx_base::wbx_version2::wbx_version2(wbx_base *_self_wbx_base) {
////////////////////////////////////////////////////////////////////
// Register TX properties
////////////////////////////////////////////////////////////////////
- this->get_tx_subtree()->create<std::string>("name").set("WBX TX v2");
+ 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))
@@ -166,6 +166,9 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
"WBX tune: target frequency %f Mhz"
) % (target_freq/1e6) << std::endl;
+ //start with target_freq*2 because mixer has divide by 2
+ target_freq *= 2;
+
//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
@@ -193,12 +196,13 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED;
//increase RF divider until acceptable VCO frequency
- //start with target_freq*2 because mixer has divide by 2
- double vco_freq = target_freq*2;
+ const bool do_sync = (target_freq/2 > ref_freq);
+ double vco_freq = target_freq;
while (vco_freq < 2.2e9) {
vco_freq *= 2;
RFdiv *= 2;
}
+ if (do_sync) vco_freq = target_freq;
//use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
@@ -209,7 +213,7 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
* (frac) dividers.
*
* Calculate the N and F dividers for each set of values.
- * The loop exists when it meets all of the constraints.
+ * The loop exits when it meets all of the constraints.
* The resulting loop values are loaded into the registers.
*
* from pg.21
@@ -253,14 +257,13 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//actual frequency calculation
- actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv/2);
-
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/2/(vco_freq/target_freq));
UHD_LOGV(often)
<< boost::format("WBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
- << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
- ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl
+ << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
<< boost::format("WBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
@@ -270,6 +273,12 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
regs.frac_12_bit = FRAC;
regs.int_16_bit = N;
regs.mod_12_bit = MOD;
+ if (do_sync)
+ {
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = adf4350_regs_t::FEEDBACK_SELECT_DIVIDED;
+ regs.clock_div_mode = adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
+ }
regs.prescaler = prescaler;
regs.r_counter_10_bit = R;
regs.reference_divide_by_2 = T;
@@ -307,6 +316,11 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
}
+ //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;
diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp
index 7ef47edd4..3e8fc8095 100644
--- a/host/lib/usrp/dboard/db_wbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version3.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -84,7 +84,7 @@ wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) {
////////////////////////////////////////////////////////////////////
// Register RX properties
////////////////////////////////////////////////////////////////////
- this->get_rx_subtree()->create<std::string>("name").set("WBX RX v3");
+ 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((wbx_v3_freq_range.start() + wbx_v3_freq_range.stop())/2.0);
@@ -93,7 +93,7 @@ wbx_base::wbx_version3::wbx_version3(wbx_base *_self_wbx_base) {
////////////////////////////////////////////////////////////////////
// Register TX properties
////////////////////////////////////////////////////////////////////
- this->get_tx_subtree()->create<std::string>("name").set("WBX TX v3");
+ 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))
@@ -198,6 +198,9 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
"WBX tune: target frequency %f Mhz"
) % (target_freq/1e6) << std::endl;
+ //start with target_freq*2 because mixer has divide by 2
+ target_freq *= 2;
+
//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
@@ -225,12 +228,13 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED;
//increase RF divider until acceptable VCO frequency
- //start with target_freq*2 because mixer has divide by 2
- double vco_freq = target_freq*2;
+ const bool do_sync = (target_freq/2 > ref_freq);
+ double vco_freq = target_freq;
while (vco_freq < 2.2e9) {
vco_freq *= 2;
RFdiv *= 2;
}
+ if (do_sync) vco_freq = target_freq;
//use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
@@ -241,7 +245,7 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
* (frac) dividers.
*
* Calculate the N and F dividers for each set of values.
- * The loop exists when it meets all of the constraints.
+ * The loop exits when it meets all of the constraints.
* The resulting loop values are loaded into the registers.
*
* from pg.21
@@ -285,14 +289,13 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//actual frequency calculation
- actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv/2);
-
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/2/(vco_freq/target_freq));
UHD_LOGV(often)
<< boost::format("WBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
- << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
- ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl
+ << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
<< boost::format("WBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
@@ -302,6 +305,12 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
regs.frac_12_bit = FRAC;
regs.int_16_bit = N;
regs.mod_12_bit = MOD;
+ if (do_sync)
+ {
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = adf4350_regs_t::FEEDBACK_SELECT_DIVIDED;
+ regs.clock_div_mode = adf4350_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
+ }
regs.prescaler = prescaler;
regs.r_counter_10_bit = R;
regs.reference_divide_by_2 = T;
@@ -339,6 +348,11 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
}
+ //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;
diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp
index 40bf90527..1feea2c0b 100644
--- a/host/lib/usrp/dboard/db_wbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version4.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2011 Ettus Research LLC
+// Copyright 2011-2012 Ettus Research LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -85,7 +85,7 @@ wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
////////////////////////////////////////////////////////////////////
// Register RX properties
////////////////////////////////////////////////////////////////////
- this->get_rx_subtree()->create<std::string>("name").set("WBX RX v4");
+ this->get_rx_subtree()->create<std::string>("name").set("WBXv4 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((wbx_v4_freq_range.start() + wbx_v4_freq_range.stop())/2.0);
@@ -94,7 +94,7 @@ wbx_base::wbx_version4::wbx_version4(wbx_base *_self_wbx_base) {
////////////////////////////////////////////////////////////////////
// Register TX properties
////////////////////////////////////////////////////////////////////
- this->get_tx_subtree()->create<std::string>("name").set("WBX TX v4");
+ this->get_tx_subtree()->create<std::string>("name").set("WBXv4 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))
@@ -200,6 +200,9 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
"WBX tune: target frequency %f Mhz"
) % (target_freq/1e6) << std::endl;
+ //start with target_freq*2 because mixer has divide by 2
+ target_freq *= 2;
+
//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
@@ -229,12 +232,13 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
if(ref_freq <= 12.5e6) D = adf4351_regs_t::REFERENCE_DOUBLER_ENABLED;
//increase RF divider until acceptable VCO frequency
- //start with target_freq*2 because mixer has divide by 2
- double vco_freq = target_freq*2;
+ const bool do_sync = (target_freq/2 > ref_freq);
+ double vco_freq = target_freq;
while (vco_freq < 2.2e9) {
vco_freq *= 2;
RFdiv *= 2;
}
+ if (do_sync) vco_freq = target_freq;
//use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler)
adf4351_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
@@ -289,14 +293,13 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
}
//actual frequency calculation
- actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv/2);
-
+ actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/2/(vco_freq/target_freq));
UHD_LOGV(often)
<< boost::format("WBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl
- << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%s"
- ) % R % BS % N % FRAC % MOD % T % D % RFdiv % self_base->get_locked(unit).to_pp_string() << std::endl
+ << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d"
+ ) % R % BS % N % FRAC % MOD % T % D % RFdiv << std::endl
<< boost::format("WBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f"
) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl;
@@ -306,6 +309,12 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
regs.frac_12_bit = FRAC;
regs.int_16_bit = N;
regs.mod_12_bit = MOD;
+ if (do_sync)
+ {
+ regs.clock_divider_12_bit = std::max(1, int(std::ceil(400e-6*pfd_freq/MOD)));
+ regs.feedback_select = adf4351_regs_t::FEEDBACK_SELECT_DIVIDED;
+ regs.clock_div_mode = adf4351_regs_t::CLOCK_DIV_MODE_RESYNC_ENABLE;
+ }
regs.prescaler = prescaler;
regs.r_counter_10_bit = R;
regs.reference_divide_by_2 = T;
@@ -343,6 +352,11 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
}
+ //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;
diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp
index 108a85161..50c67991a 100644
--- a/host/lib/usrp/dboard/db_xcvr2450.cpp
+++ b/host/lib/usrp/dboard/db_xcvr2450.cpp
@@ -229,7 +229,7 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){
// Register RX properties
////////////////////////////////////////////////////////////////////
this->get_rx_subtree()->create<std::string>("name")
- .set(get_rx_id().to_pp_string());
+ .set("XCVR2450 RX");
this->get_rx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&xcvr2450::get_locked, this));
this->get_rx_subtree()->create<sensor_value_t>("sensors/rssi")
@@ -267,7 +267,7 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){
// Register TX properties
////////////////////////////////////////////////////////////////////
this->get_tx_subtree()->create<std::string>("name")
- .set(get_tx_id().to_pp_string());
+ .set("XCVR2450 TX");
this->get_tx_subtree()->create<sensor_value_t>("sensors/lo_locked")
.publish(boost::bind(&xcvr2450::get_locked, this));
BOOST_FOREACH(const std::string &name, xcvr_tx_gain_ranges.keys()){