diff options
author | mattprost <matt.prost@ni.com> | 2020-07-22 12:13:59 -0500 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-08-04 15:46:02 -0500 |
commit | d1799df5a43eb350a8d11f3b225a33254abb0401 (patch) | |
tree | c73c47a355ab3aa78f7930b0ba3863a9631ee24a /host/lib/usrp/x300 | |
parent | 18aeb2077b8c6a339f833fb53d90171a359175be (diff) | |
download | uhd-d1799df5a43eb350a8d11f3b225a33254abb0401.tar.gz uhd-d1799df5a43eb350a8d11f3b225a33254abb0401.tar.bz2 uhd-d1799df5a43eb350a8d11f3b225a33254abb0401.zip |
x300: change default dboard clock rate from 50 to 100 MHz
This sets the reference clock for X300 daughterboards (other than UBX)
to 100 MHz by default to improve RF performance.
Note: The UBX daughterboard requires a clock rate of no more than the
max pfd frequency (50 or 25 MHz depending on the hardware rev) in
order to maintain phase synchronization. If a UBX daughterboard is
present on the X300, the clock rate for all daughterboards will be set
to the pfd frequency by default. This is because of the limitation on
X300 that requires the daughterboards to use the same clock rate.
Signed-off-by: mattprost <matt.prost@ni.com>
Diffstat (limited to 'host/lib/usrp/x300')
-rw-r--r-- | host/lib/usrp/x300/x300_device_args.hpp | 7 | ||||
-rw-r--r-- | host/lib/usrp/x300/x300_impl.cpp | 62 |
2 files changed, 64 insertions, 5 deletions
diff --git a/host/lib/usrp/x300/x300_device_args.hpp b/host/lib/usrp/x300/x300_device_args.hpp index 6c6680c4f..7e17c36ce 100644 --- a/host/lib/usrp/x300/x300_device_args.hpp +++ b/host/lib/usrp/x300/x300_device_args.hpp @@ -197,12 +197,11 @@ private: if (dev_args.has_key(_dboard_clock_rate.key())) { _dboard_clock_rate.parse(dev_args[_dboard_clock_rate.key()]); } else { - // Some daughterboards may require other rates, but this default - // works best for all newer daughterboards (i.e. CBX, WBX, SBX, - // UBX, and TwinRX). + // This default clock rate works best for most daughterboards (i.e. DBSRX2, + // WBX, SBX, CBX, and TwinRX). if (_master_clock_rate.get() >= MIN_TICK_RATE && _master_clock_rate.get() <= MAX_TICK_RATE) { - _dboard_clock_rate.set(_master_clock_rate.get() / 4); + _dboard_clock_rate.set(_master_clock_rate.get() / 2); } else { throw uhd::value_error("Can't infer daughterboard clock rate. Specify " "dboard_clk_rate in the device args."); diff --git a/host/lib/usrp/x300/x300_impl.cpp b/host/lib/usrp/x300/x300_impl.cpp index a414fd0f1..fa8425fac 100644 --- a/host/lib/usrp/x300/x300_impl.cpp +++ b/host/lib/usrp/x300/x300_impl.cpp @@ -7,6 +7,7 @@ // #include "x300_impl.hpp" +#include "../dboard/db_ubx.hpp" #include "x300_claim.hpp" #include "x300_eth_mgr.hpp" #include "x300_mb_controller.hpp" @@ -15,6 +16,8 @@ #include "x300_mboard_type.hpp" #include "x300_pcie_mgr.hpp" #include <uhd/transport/if_addrs.hpp> +#include <uhd/usrp/dboard_eeprom.hpp> +#include <uhd/usrp/dboard_id.hpp> #include <uhd/utils/log.hpp> #include <uhd/utils/paths.hpp> #include <uhd/utils/safe_call.hpp> @@ -141,6 +144,31 @@ device_addrs_t x300_find(const device_addr_t& hint_) } /*********************************************************************** + * Daughterboard detection before initialization in software + **********************************************************************/ +static std::vector<dboard_id_t> get_dboard_ids(uhd::i2c_iface& zpu_i2c) +{ + std::vector<dboard_id_t> dboard_ids; + // Read dboard ids from the EEPROM + constexpr size_t BASE_ADDR = 0x50; + constexpr size_t RX_EEPROM_ADDR = 0x5; + constexpr size_t TX_EEPROM_ADDR = 0x4; + static const std::vector<size_t> DB_OFFSETS{0x0, 0x2}; + static const std::vector<size_t> EEPROM_ADDRS{RX_EEPROM_ADDR, TX_EEPROM_ADDR}; + for (size_t eeprom_addr : EEPROM_ADDRS) { + for (size_t db_offset : DB_OFFSETS) { + const size_t addr = eeprom_addr + db_offset; + // Load EEPROM + std::unordered_map<size_t, usrp::dboard_eeprom_t> db_eeproms; + db_eeproms[addr].load(zpu_i2c, BASE_ADDR | addr); + uint16_t dboard_id = db_eeproms[addr].id.to_uint16(); + dboard_ids.push_back(static_cast<dboard_id_t>(dboard_id)); + } + } + return dboard_ids; +} + +/*********************************************************************** * Make **********************************************************************/ static device::sptr x300_make(const device_addr_t& device_addr) @@ -331,13 +359,45 @@ void x300_impl::setup_mb(const size_t mb_i, const uhd::device_addr_t& dev_addr) // create clock control objects //////////////////////////////////////////////////////////////////// UHD_LOGGER_DEBUG("X300") << "Setting up RF frontend clocking..."; + + // The default daughterboard clock rate may have to be overridden. This is due to the + // limitation on X300 devices where both daughterboards must use the same clock rate. + // The daughterboards that require specific clock rates are UBX and TwinRX. TwinRX + // requires a clock rate of 100 MHz for the best RF performance. UBX daughterboards + // require a clock rate of no more than the max pfd frequency to maintain phase + // synchronization. If there is no UBX, the default daughterboard clock rate is half + // of the master clock rate for X300. + const double x300_dboard_clock_rate = [this, dev_addr, mb]() -> double { + // Do not override use-specified dboard clock rates + if (dev_addr.has_key("dboard_clock_rate")) { + return mb.args.get_dboard_clock_rate(); + } + const double mcr = mb.args.get_master_clock_rate(); + double dboard_clock_rate = mb.args.get_dboard_clock_rate(); + // Check for UBX daughterboards + std::vector<dboard_id_t> dboard_ids = get_dboard_ids(*mb.zpu_i2c); + for (dboard_id_t dboard_id : dboard_ids) { + if (std::find( + dboard::ubx::ubx_ids.begin(), dboard::ubx::ubx_ids.end(), dboard_id) + != dboard::ubx::ubx_ids.end()) { + double ubx_clock_rate = mcr; + for (int i = 2; ubx_clock_rate > dboard::ubx::get_max_pfd_freq(dboard_id); + i++) { + ubx_clock_rate = mcr / i; + } + dboard_clock_rate = std::min(dboard_clock_rate, ubx_clock_rate); + } + } + return dboard_clock_rate; + }(); + // Initialize clock control registers. // NOTE: This does not configure the LMK yet. mb.clock = x300_clock_ctrl::make(mb.zpu_spi, 1 /*slaveno*/, mb.hw_rev, mb.args.get_master_clock_rate(), - mb.args.get_dboard_clock_rate(), + x300_dboard_clock_rate, mb.args.get_system_ref_rate()); //////////////////////////////////////////////////////////////////// |