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.cpp19
1 files changed, 12 insertions, 7 deletions
diff --git a/host/lib/usrp/dboard/db_wbx_version4.cpp b/host/lib/usrp/dboard/db_wbx_version4.cpp
index dd6c3c9ef..057cdb6ce 100644
--- a/host/lib/usrp/dboard/db_wbx_version4.cpp
+++ b/host/lib/usrp/dboard/db_wbx_version4.cpp
@@ -211,14 +211,16 @@ 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
+ 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 = target_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
+ adf4351_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4351_regs_t::PRESCALER_8_9 : adf4351_regs_t::PRESCALER_4_5;
/*
* The goal here is to loop though possible R dividers,
@@ -245,7 +247,7 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
if (pfd_freq > 25e6) continue;
//ignore fractional part of tuning
- N = int(std::floor(target_freq/pfd_freq));
+ N = int(std::floor(vco_freq/pfd_freq));
//keep N > minimum int divider requirement
if (N < prescaler_to_min_int_div[prescaler]) continue;
@@ -260,7 +262,7 @@ double wbx_base::wbx_version4::set_lo_freq(dboard_iface::unit_t unit, double tar
//Fractional-N calculation
MOD = 4095; //max fractional accuracy
- FRAC = int((target_freq/pfd_freq - N)*MOD);
+ FRAC = int((vco_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
@@ -270,7 +272,7 @@ 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)))/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
@@ -286,9 +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;
- 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;
+ 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;