aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/dboard
diff options
context:
space:
mode:
authormattprost <matt.prost@ni.com>2020-07-22 12:13:59 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2020-08-04 15:46:02 -0500
commitd1799df5a43eb350a8d11f3b225a33254abb0401 (patch)
treec73c47a355ab3aa78f7930b0ba3863a9631ee24a /host/lib/usrp/dboard
parent18aeb2077b8c6a339f833fb53d90171a359175be (diff)
downloaduhd-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/dboard')
-rw-r--r--host/lib/usrp/dboard/db_ubx.cpp18
-rw-r--r--host/lib/usrp/dboard/db_ubx.hpp57
-rw-r--r--host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp51
3 files changed, 89 insertions, 37 deletions
diff --git a/host/lib/usrp/dboard/db_ubx.cpp b/host/lib/usrp/dboard/db_ubx.cpp
index 8ac96a2fe..733a4b8e2 100644
--- a/host/lib/usrp/dboard/db_ubx.cpp
+++ b/host/lib/usrp/dboard/db_ubx.cpp
@@ -7,6 +7,7 @@
/***********************************************************************
* Included Files and Libraries
**********************************************************************/
+#include "db_ubx.hpp"
#include <uhd/types/device_addr.hpp>
#include <uhd/types/dict.hpp>
#include <uhd/types/direction.hpp>
@@ -30,6 +31,7 @@
using namespace uhd;
using namespace uhd::usrp;
+using namespace uhd::usrp::dboard::ubx;
/***********************************************************************
* UBX Data Structures
@@ -134,22 +136,6 @@ enum spi_dest_t {
* UBX Constants
**********************************************************************/
#define fMHz (1000000.0)
-static const dboard_id_t UBX_PROTO_V3_TX_ID(0x73);
-static const dboard_id_t UBX_PROTO_V3_RX_ID(0x74);
-static const dboard_id_t UBX_PROTO_V4_TX_ID(0x75);
-static const dboard_id_t UBX_PROTO_V4_RX_ID(0x76);
-static const dboard_id_t UBX_V1_40MHZ_TX_ID(0x77);
-static const dboard_id_t UBX_V1_40MHZ_RX_ID(0x78);
-static const dboard_id_t UBX_V1_160MHZ_TX_ID(0x79);
-static const dboard_id_t UBX_V1_160MHZ_RX_ID(0x7A);
-static const dboard_id_t UBX_V2_40MHZ_TX_ID(0x7B);
-static const dboard_id_t UBX_V2_40MHZ_RX_ID(0x7C);
-static const dboard_id_t UBX_V2_160MHZ_TX_ID(0x7D);
-static const dboard_id_t UBX_V2_160MHZ_RX_ID(0x7E);
-static const dboard_id_t UBX_LP_160MHZ_TX_ID(0x0200);
-static const dboard_id_t UBX_LP_160MHZ_RX_ID(0x0201);
-static const dboard_id_t UBX_TDD_160MHZ_TX_ID(0x0202);
-static const dboard_id_t UBX_TDD_160MHZ_RX_ID(0x0203);
static const freq_range_t ubx_freq_range(10e6, 6.0e9);
static const gain_range_t ubx_tx_gain_range(0, 31.5, double(0.5));
static const gain_range_t ubx_rx_gain_range(0, 31.5, double(0.5));
diff --git a/host/lib/usrp/dboard/db_ubx.hpp b/host/lib/usrp/dboard/db_ubx.hpp
new file mode 100644
index 000000000..246a89eb0
--- /dev/null
+++ b/host/lib/usrp/dboard/db_ubx.hpp
@@ -0,0 +1,57 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#pragma once
+
+#include <uhd/usrp/dboard_base.hpp>
+
+using namespace uhd;
+using namespace uhd::usrp;
+
+namespace uhd { namespace usrp { namespace dboard { namespace ubx {
+
+static const dboard_id_t UBX_PROTO_V3_TX_ID(0x73);
+static const dboard_id_t UBX_PROTO_V3_RX_ID(0x74);
+static const dboard_id_t UBX_PROTO_V4_TX_ID(0x75);
+static const dboard_id_t UBX_PROTO_V4_RX_ID(0x76);
+static const dboard_id_t UBX_V1_40MHZ_TX_ID(0x77);
+static const dboard_id_t UBX_V1_40MHZ_RX_ID(0x78);
+static const dboard_id_t UBX_V1_160MHZ_TX_ID(0x79);
+static const dboard_id_t UBX_V1_160MHZ_RX_ID(0x7A);
+static const dboard_id_t UBX_V2_40MHZ_TX_ID(0x7B);
+static const dboard_id_t UBX_V2_40MHZ_RX_ID(0x7C);
+static const dboard_id_t UBX_V2_160MHZ_TX_ID(0x7D);
+static const dboard_id_t UBX_V2_160MHZ_RX_ID(0x7E);
+static const dboard_id_t UBX_LP_160MHZ_TX_ID(0x0200);
+static const dboard_id_t UBX_LP_160MHZ_RX_ID(0x0201);
+static const dboard_id_t UBX_TDD_160MHZ_TX_ID(0x0202);
+static const dboard_id_t UBX_TDD_160MHZ_RX_ID(0x0203);
+static const std::vector<dboard_id_t> ubx_ids{UBX_PROTO_V3_TX_ID,
+ UBX_PROTO_V4_TX_ID,
+ UBX_V1_40MHZ_TX_ID,
+ UBX_V1_160MHZ_TX_ID,
+ UBX_V2_40MHZ_TX_ID,
+ UBX_V2_160MHZ_TX_ID,
+ UBX_LP_160MHZ_TX_ID,
+ UBX_TDD_160MHZ_TX_ID,
+ UBX_PROTO_V3_RX_ID,
+ UBX_PROTO_V4_RX_ID,
+ UBX_V1_40MHZ_RX_ID,
+ UBX_V1_160MHZ_RX_ID,
+ UBX_V2_40MHZ_RX_ID,
+ UBX_V2_160MHZ_RX_ID,
+ UBX_LP_160MHZ_RX_ID,
+ UBX_TDD_160MHZ_RX_ID};
+
+static UHD_INLINE double get_max_pfd_freq(dboard_id_t dboard_id)
+{
+ if ((dboard_id == UBX_PROTO_V3_TX_ID) || (dboard_id == UBX_PROTO_V3_RX_ID)) {
+ return 25e6;
+ }
+ return 50e6;
+}
+
+}}}}; // namespace uhd::usrp::dboard::ubx
diff --git a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp
index 3752a2e70..3686f4348 100644
--- a/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp
+++ b/host/lib/usrp/dboard/twinrx/twinrx_ctrl.cpp
@@ -13,6 +13,7 @@
#include <uhdlib/usrp/common/adf535x.hpp>
#include <uhdlib/utils/narrow.hpp>
#include <chrono>
+#include <cmath>
#include <thread>
using namespace uhd;
@@ -29,10 +30,9 @@ inline uint32_t bool2bin(bool x)
return x ? 1 : 0;
}
-const double TWINRX_DESIRED_REFERENCE_FREQ = 50e6;
-const double TWINRX_REV_AB_PFD_FREQ = 6.25e6;
-const double TWINRX_REV_C_PFD_FREQ = 12.5e6;
-const double TWINRX_SPI_CLOCK_FREQ = 3e6;
+const double TWINRX_REV_AB_PFD_FREQ = 6.25e6;
+const double TWINRX_REV_C_PFD_FREQ = 12.5e6;
+const double TWINRX_SPI_CLOCK_FREQ = 3e6;
} // namespace
class twinrx_ctrl_impl : public twinrx_ctrl
@@ -49,22 +49,29 @@ public:
_spi_config.divider = uhd::narrow_cast<size_t>(std::ceil(
_db_iface->get_codec_rate(dboard_iface::UNIT_TX) / TWINRX_SPI_CLOCK_FREQ));
- // Initialize dboard clocks
- bool found_rate = false;
- for (double rate : _db_iface->get_clock_rates(dboard_iface::UNIT_TX)) {
- found_rate |=
- uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ);
- }
- for (double rate : _db_iface->get_clock_rates(dboard_iface::UNIT_RX)) {
- found_rate |=
- uhd::math::frequencies_are_equal(rate, TWINRX_DESIRED_REFERENCE_FREQ);
- }
- if (not found_rate) {
- throw uhd::runtime_error("TwinRX not supported on this motherboard");
+ // Daughterboard clock rates must be a multiple of the pfd frequency
+ if (rx_id == twinrx::TWINRX_REV_C_ID) {
+ if (fmod(_db_iface->get_clock_rate(dboard_iface::UNIT_RX),
+ TWINRX_REV_C_PFD_FREQ)
+ != 0) {
+ throw uhd::value_error(
+ str(boost::format(
+ "TwinRX clock rate %f is not a multiple of the pfd freq %f.")
+ % _db_iface->get_clock_rate(dboard_iface::UNIT_RX)
+ % TWINRX_REV_C_PFD_FREQ));
+ }
+ } else {
+ if (fmod(_db_iface->get_clock_rate(dboard_iface::UNIT_RX),
+ TWINRX_REV_AB_PFD_FREQ)
+ != 0) {
+ throw uhd::value_error(
+ str(boost::format(
+ "TwinRX clock rate %f is not a multiple of the pfd freq %f.")
+ % _db_iface->get_clock_rate(dboard_iface::UNIT_RX)
+ % TWINRX_REV_AB_PFD_FREQ));
+ }
}
- _db_iface->set_clock_rate(dboard_iface::UNIT_TX, TWINRX_DESIRED_REFERENCE_FREQ);
- _db_iface->set_clock_rate(dboard_iface::UNIT_RX, TWINRX_DESIRED_REFERENCE_FREQ);
-
+ // Initialize dboard clocks
_db_iface->set_clock_enabled(dboard_iface::UNIT_TX, true);
_db_iface->set_clock_enabled(dboard_iface::UNIT_RX, true);
@@ -126,7 +133,8 @@ public:
_lo1_iface[i]->set_pfd_freq(TWINRX_REV_AB_PFD_FREQ);
}
_lo1_iface[i]->set_output_power(adf535x_iface::OUTPUT_POWER_5DBM);
- _lo1_iface[i]->set_reference_freq(TWINRX_DESIRED_REFERENCE_FREQ);
+ _lo1_iface[i]->set_reference_freq(
+ _db_iface->get_clock_rate(dboard_iface::UNIT_TX));
_lo1_iface[i]->set_muxout_mode(adf535x_iface::MUXOUT_DLD);
_lo1_iface[i]->set_frequency(3e9, 1.0e3);
@@ -137,7 +145,8 @@ public:
});
_lo2_iface[i]->set_feedback_select(adf435x_iface::FB_SEL_DIVIDED);
_lo2_iface[i]->set_output_power(adf435x_iface::OUTPUT_POWER_5DBM);
- _lo2_iface[i]->set_reference_freq(TWINRX_DESIRED_REFERENCE_FREQ);
+ _lo2_iface[i]->set_reference_freq(
+ _db_iface->get_clock_rate(dboard_iface::UNIT_RX));
_lo2_iface[i]->set_muxout_mode(adf435x_iface::MUXOUT_DLD);
_lo2_iface[i]->set_tuning_mode(adf435x_iface::TUNING_MODE_LOW_SPUR);
_lo2_iface[i]->set_prescaler(adf435x_iface::PRESCALER_8_9);