diff options
Diffstat (limited to 'host/lib/usrp/dboard/db_wbx_version3.cpp')
-rw-r--r-- | host/lib/usrp/dboard/db_wbx_version3.cpp | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/host/lib/usrp/dboard/db_wbx_version3.cpp b/host/lib/usrp/dboard/db_wbx_version3.cpp index 7ef47edd4..1f67b37c9 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,15 +228,14 @@ 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; + double vco_freq = target_freq; while (vco_freq < 2.2e9) { vco_freq *= 2; RFdiv *= 2; } //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, @@ -241,7 +243,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 @@ -260,7 +262,7 @@ double wbx_base::wbx_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; @@ -275,7 +277,7 @@ double wbx_base::wbx_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 @@ -285,14 +287,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); 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 +303,9 @@ 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; + 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; |