aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/dboard
diff options
context:
space:
mode:
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);