aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/dboard/db_wbx_version4.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/dboard/db_wbx_version4.cpp')
-rw-r--r--host/lib/usrp/dboard/db_wbx_version4.cpp32
1 files changed, 23 insertions, 9 deletions
diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp
index 3a85826cd..58a5e5f3e 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))
@@ -179,6 +179,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
@@ -208,12 +211,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;
@@ -268,14 +272,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;
@@ -285,6 +288,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;
@@ -322,6 +331,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;