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_cbx.cpp6
-rw-r--r--host/lib/usrp/dboard/db_sbx_version3.cpp8
-rw-r--r--host/lib/usrp/dboard/db_sbx_version4.cpp8
-rw-r--r--host/lib/usrp/dboard/db_wbx_version2.cpp33
-rw-r--r--host/lib/usrp/dboard/db_wbx_version3.cpp33
-rw-r--r--host/lib/usrp/dboard/db_wbx_version4.cpp34
6 files changed, 89 insertions, 33 deletions
diff --git a/host/lib/usrp/dboard/db_cbx.cpp b/host/lib/usrp/dboard/db_cbx.cpp
index ae41a7971..78ecd9794 100644
--- a/host/lib/usrp/dboard/db_cbx.cpp
+++ b/host/lib/usrp/dboard/db_cbx.cpp
@@ -18,7 +18,7 @@
#include "max2870_regs.hpp"
#include "db_sbx_common.hpp"
-
+#include <boost/algorithm/string.hpp>
using namespace uhd;
using namespace uhd::usrp;
@@ -47,14 +47,14 @@ double sbx_xcvr::cbx::set_lo_freq(dboard_iface::unit_t unit, double target_freq)
) % (target_freq/1e6) << std::endl;
/*
- * If the user sets 'mode_n=int-n' in the tuning args, the user wishes to
+ * If the user sets 'mode_n=integer' in the tuning args, the user wishes to
* tune in Integer-N mode, which can result in better spur
* performance on some mixers. The default is fractional tuning.
*/
property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree()
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
- bool is_int_n = (tune_args.get("mode_n","") == "int-n");
+ bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
//clip the input
target_freq = cbx_freq_range.clip(target_freq);
diff --git a/host/lib/usrp/dboard/db_sbx_version3.cpp b/host/lib/usrp/dboard/db_sbx_version3.cpp
index ef0126557..463de5e15 100644
--- a/host/lib/usrp/dboard/db_sbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version3.cpp
@@ -20,6 +20,7 @@
#include "db_sbx_common.hpp"
#include "../common/adf435x_common.hpp"
#include <uhd/types/tune_request.hpp>
+#include <boost/algorithm/string.hpp>
using namespace uhd;
using namespace uhd::usrp;
@@ -47,14 +48,14 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
) % (target_freq/1e6) << std::endl;
/*
- * If the user sets 'mode_n=int-n' in the tuning args, the user wishes to
+ * If the user sets 'mode_n=integer' in the tuning args, the user wishes to
* tune in Integer-N mode, which can result in better spur
* performance on some mixers. The default is fractional tuning.
*/
property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree()
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
- bool is_int_n = (tune_args.get("mode_n","") == "int-n");
+ bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
//clip the input
target_freq = sbx_freq_range.clip(target_freq);
@@ -84,6 +85,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
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;
double actual_freq;
adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
@@ -102,7 +104,7 @@ double sbx_xcvr::sbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
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_settings.feedback_after_divider ?
+ 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;
diff --git a/host/lib/usrp/dboard/db_sbx_version4.cpp b/host/lib/usrp/dboard/db_sbx_version4.cpp
index 6c0cebb4b..ff4e19163 100644
--- a/host/lib/usrp/dboard/db_sbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_sbx_version4.cpp
@@ -20,6 +20,7 @@
#include "db_sbx_common.hpp"
#include "../common/adf435x_common.hpp"
#include <uhd/types/tune_request.hpp>
+#include <boost/algorithm/string.hpp>
using namespace uhd;
using namespace uhd::usrp;
@@ -48,14 +49,14 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
) % (target_freq/1e6) << std::endl;
/*
- * If the user sets 'mode_n=int-n' in the tuning args, the user wishes to
+ * If the user sets 'mode_n=integer' in the tuning args, the user wishes to
* tune in Integer-N mode, which can result in better spur
* performance on some mixers. The default is fractional tuning.
*/
property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree()
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
- bool is_int_n = (tune_args.get("mode_n","") == "int-n");
+ bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
//clip the input
target_freq = sbx_freq_range.clip(target_freq);
@@ -87,6 +88,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
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(
@@ -105,7 +107,7 @@ double sbx_xcvr::sbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
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_settings.feedback_after_divider ?
+ 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;
diff --git a/host/lib/usrp/dboard/db_wbx_version2.cpp b/host/lib/usrp/dboard/db_wbx_version2.cpp
index 2afdce4cd..c5945483d 100644
--- a/host/lib/usrp/dboard/db_wbx_version2.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version2.cpp
@@ -30,6 +30,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/math/special_functions/round.hpp>
+#include <boost/algorithm/string.hpp>
using namespace uhd;
using namespace uhd::usrp;
@@ -169,14 +170,14 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
) % (target_freq/1e6) << std::endl;
/*
- * If the user sets 'mode_n=int-n' in the tuning args, the user wishes to
+ * If the user sets 'mode_n=integer' in the tuning args, the user wishes to
* tune in Integer-N mode, which can result in better spur
* performance on some mixers. The default is fractional tuning.
*/
property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree()
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
- bool is_int_n = (tune_args.get("mode_n","") == "int-n");
+ bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
//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
@@ -193,7 +194,15 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
(16, adf4350_regs_t::RF_DIVIDER_SELECT_DIV16)
;
- adf4350_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
+ 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;
@@ -202,11 +211,17 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
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);
+ //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;
- double actual_freq;
+ double synth_actual_freq = 0;
adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- target_freq, self_base->get_iface()->get_clock_rate(unit),
- tuning_constraints, actual_freq);
+ synth_target_freq, reference_freq, tuning_constraints, synth_actual_freq);
+
+ //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;
@@ -222,10 +237,12 @@ double wbx_base::wbx_version2::set_lo_freq(dboard_iface::unit_t unit, double tar
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_settings.feedback_after_divider ?
+ 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.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 ?
diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp
index e30d6c665..80ecb426b 100644
--- a/host/lib/usrp/dboard/db_wbx_version3.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version3.cpp
@@ -29,6 +29,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/math/special_functions/round.hpp>
+#include <boost/algorithm/string.hpp>
using namespace uhd;
using namespace uhd::usrp;
@@ -200,14 +201,14 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
) % (target_freq/1e6) << std::endl;
/*
- * If the user sets 'mode_n=int-n' in the tuning args, the user wishes to
+ * If the user sets 'mode_n=integer' in the tuning args, the user wishes to
* tune in Integer-N mode, which can result in better spur
* performance on some mixers. The default is fractional tuning.
*/
property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree()
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
- bool is_int_n = (tune_args.get("mode_n","") == "int-n");
+ bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
//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
@@ -224,7 +225,15 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
(16, adf4350_regs_t::RF_DIVIDER_SELECT_DIV16)
;
- adf4350_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5;
+ 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;
@@ -233,11 +242,17 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
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);
+ //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;
- double actual_freq;
+ double synth_actual_freq = 0;
adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- target_freq, self_base->get_iface()->get_clock_rate(unit),
- tuning_constraints, actual_freq);
+ synth_target_freq, reference_freq, tuning_constraints, synth_actual_freq);
+
+ //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;
@@ -253,10 +268,12 @@ double wbx_base::wbx_version3::set_lo_freq(dboard_iface::unit_t unit, double tar
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_settings.feedback_after_divider ?
+ 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.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 ?
diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp
index dc1ae4df8..80ff3f998 100644
--- a/host/lib/usrp/dboard/db_wbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version4.cpp
@@ -29,6 +29,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/math/special_functions/round.hpp>
+#include <boost/algorithm/string.hpp>
using namespace uhd;
using namespace uhd::usrp;
@@ -208,14 +209,14 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
) % (target_freq/1e6) << std::endl;
/*
- * If the user sets 'mode_n=int-n' in the tuning args, the user wishes to
+ * If the user sets 'mode_n=integer' in the tuning args, the user wishes to
* tune in Integer-N mode, which can result in better spur
* performance on some mixers. The default is fractional tuning.
*/
property_tree::sptr subtree = (unit == dboard_iface::UNIT_RX) ? self_base->get_rx_subtree()
: self_base->get_tx_subtree();
device_addr_t tune_args = subtree->access<device_addr_t>("tune_args").get();
- bool is_int_n = (tune_args.get("mode_n","") == "int-n");
+ bool is_int_n = boost::iequals(tune_args.get("mode_n",""), "integer");
//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
@@ -234,7 +235,15 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
(64, adf4351_regs_t::RF_DIVIDER_SELECT_DIV64)
;
- adf4351_regs_t::prescaler_t prescaler = target_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
+ 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);
+
+ adf4351_regs_t::prescaler_t prescaler =
+ synth_target_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
adf435x_tuning_constraints tuning_constraints;
tuning_constraints.force_frac0 = is_int_n;
@@ -243,11 +252,17 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
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);
+ //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;
- double actual_freq;
+ double synth_actual_freq = 0;
adf435x_tuning_settings tuning_settings = tune_adf435x_synth(
- target_freq, self_base->get_iface()->get_clock_rate(unit),
- tuning_constraints, actual_freq);
+ synth_target_freq, reference_freq, tuning_constraints, synth_actual_freq);
+
+ //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;
@@ -263,10 +278,12 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
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_settings.feedback_after_divider ?
+ 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.clock_div_mode = div_resync_enabled ?
+ 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 ?
@@ -307,5 +324,6 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
UHD_LOGV(often) << boost::format(
"%s tune: actual frequency %f Mhz"
) % board_name.c_str() % (actual_freq/1e6) << std::endl;
+
return actual_freq;
}