diff options
author | mattprost <matt.prost@ni.com> | 2020-03-05 10:47:59 -0600 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2020-03-23 09:33:57 -0500 |
commit | 0ac85e4d0186cb63cb98da90363f34947675b3e5 (patch) | |
tree | 0bb25db3a4812d3230866df5cab3957180e4b065 /host/lib/usrp/dboard | |
parent | 5c7237fb407cfccaee205980d97e40ce10768c2a (diff) | |
download | uhd-0ac85e4d0186cb63cb98da90363f34947675b3e5.tar.gz uhd-0ac85e4d0186cb63cb98da90363f34947675b3e5.tar.bz2 uhd-0ac85e4d0186cb63cb98da90363f34947675b3e5.zip |
x300: lf/basic antenna API implementation
This results in a change of operation for LF/Basic Boards on
X300/X310 devices. The RX streaming mode will now be specified
by the antenna rather than the subdev: (AB or BA for complex
streaming, and A or B for real-mode streaming, with AB being
the default antenna value). For real-mode streaming, data is
collected as complex data with zeroed-out values in the
quadrature domain. The subdevs for these boards have been
changed to 0 and 1 for the RX channels, and 0 for the TX
channel, in order to align with subdev specs of other RFNoC
devices.
Note: the old streaming mode paradigm is still in place for
the N210.
Diffstat (limited to 'host/lib/usrp/dboard')
-rw-r--r-- | host/lib/usrp/dboard/db_basic_and_lf.cpp | 189 | ||||
-rw-r--r-- | host/lib/usrp/dboard/db_basic_and_lf.hpp | 35 |
2 files changed, 150 insertions, 74 deletions
diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 5e8ac310e..aaeaff2a6 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later // +#include "db_basic_and_lf.hpp" #include <uhd/types/dict.hpp> #include <uhd/types/ranges.hpp> #include <uhd/usrp/dboard_base.hpp> @@ -17,27 +18,7 @@ using namespace uhd; using namespace uhd::usrp; - -/*********************************************************************** - * Constants - **********************************************************************/ -namespace { -constexpr uint32_t BASIC_TX_PID = 0x0000; -constexpr uint32_t BASIC_RX_PID = 0x0001; -constexpr uint32_t LF_TX_PID = 0x000E; -constexpr uint32_t LF_RX_PID = 0x000F; - -constexpr double BASIC_MAX_BANDWIDTH = 250e6; // Hz -constexpr double LF_MAX_BANDWIDTH = 32e6; // Hz - - -const std::map<std::string, double> subdev_bandwidth_scalar{ - {"A", 1.0}, {"B", 1.0}, {"AB", 2.0}, {"BA", 2.0}}; - -const uhd::dict<std::string, std::string> sd_name_to_conn = - boost::assign::map_list_of("AB", "IQ")("BA", "QI")("A", "I")("B", "Q"); -} // namespace - +using namespace uhd::usrp::dboard::basic_and_lf; /*********************************************************************** * The basic and lf boards: @@ -50,8 +31,6 @@ public: virtual ~basic_rx(void); private: - void set_rx_ant(const std::string& ant); - double _max_freq; }; @@ -91,13 +70,21 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t args) UHD_STATIC_BLOCK(reg_basic_and_lf_dboards) { dboard_manager::register_dboard( - BASIC_TX_PID, &make_basic_tx, "Basic TX", sd_name_to_conn.keys()); + BASIC_TX_PID, &make_basic_tx, "Basic TX", antenna_mode_to_conn.keys()); dboard_manager::register_dboard( - BASIC_RX_PID, &make_basic_rx, "Basic RX", sd_name_to_conn.keys()); + BASIC_RX_PID, &make_basic_rx, "Basic RX", antenna_mode_to_conn.keys()); dboard_manager::register_dboard( - LF_TX_PID, &make_lf_tx, "LF TX", sd_name_to_conn.keys()); + LF_TX_PID, &make_lf_tx, "LF TX", antenna_mode_to_conn.keys()); dboard_manager::register_dboard( - LF_RX_PID, &make_lf_rx, "LF RX", sd_name_to_conn.keys()); + LF_RX_PID, &make_lf_rx, "LF RX", antenna_mode_to_conn.keys()); + dboard_manager::register_dboard( + BASIC_TX_RFNOC_PID, &make_basic_tx, "Basic TX", tx_frontends); + dboard_manager::register_dboard( + BASIC_RX_RFNOC_PID, &make_basic_rx, "Basic RX", rx_frontends); + dboard_manager::register_dboard( + LF_TX_RFNOC_PID, &make_lf_tx, "LF TX", tx_frontends); + dboard_manager::register_dboard( + LF_RX_RFNOC_PID, &make_lf_rx, "LF RX", rx_frontends); } /*********************************************************************** @@ -106,20 +93,30 @@ UHD_STATIC_BLOCK(reg_basic_and_lf_dboards) basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args), _max_freq(max_freq) { + // Examine the frontend to use the RFNoC or the N210 implementation + // (preserves legacy behavior) const std::string fe_name(get_subdev_name()); - const std::string fe_conn(sd_name_to_conn[fe_name]); - const std::string db_name( - str(boost::format("%s (%s)") - % ((get_rx_id() == BASIC_RX_PID) ? "BasicRX" : "LFRX") % fe_name)); + const bool is_rfnoc_dev = std::find(rx_frontends.begin(), rx_frontends.end(), fe_name) + != rx_frontends.end(); + const std::string ant_mode(is_rfnoc_dev ? "AB" : fe_name); + const std::string fe_conn(antenna_mode_to_conn[ant_mode]); + const std::string db_name([this]() { + switch (get_rx_id().to_uint16()) { + case BASIC_RX_PID: + case BASIC_RX_RFNOC_PID: + return str(boost::format("%s (%s)") % "BasicRX" % get_subdev_name()); + case LF_RX_PID: + case LF_RX_RFNOC_PID: + return str(boost::format("%s (%s)") % "LFRX" % get_subdev_name()); + default: + UHD_THROW_INVALID_CODE_PATH(); + } + }()); UHD_LOG_TRACE("BASICRX", - "Initializing driver for: " << db_name << " IQ connection type: " << fe_conn); - const bool has_fe_conn_settings = - get_iface()->has_set_fe_connection(dboard_iface::UNIT_RX); - UHD_LOG_TRACE("BASICRX", - "Access to FE connection settings: " << (has_fe_conn_settings ? "Yes" : "No")); + "Initializing driver for: " << db_name << " IQ connection type: " << ant_mode); + UHD_LOG_TRACE("BASICRX", "Is RFNoC Device: " << (is_rfnoc_dev ? "Yes" : "No")); - std::vector<std::string> antenna_options = - has_fe_conn_settings ? sd_name_to_conn.keys() : std::vector<std::string>(1, ""); + std::vector<std::string> antenna_options = antenna_mode_to_conn.keys(); //////////////////////////////////////////////////////////////////// // Register properties @@ -134,29 +131,43 @@ basic_rx::basic_rx(ctor_args_t args, double max_freq) .set(freq_range_t(-_max_freq, +_max_freq)); this->get_rx_subtree() ->create<std::string>("antenna/value") - .set(has_fe_conn_settings ? fe_name : ""); - if (has_fe_conn_settings) { - this->get_rx_subtree() - ->access<std::string>("antenna/value") - .add_coerced_subscriber( - [this](const std::string& ant) { this->set_rx_ant(ant); }); - } + .set(is_rfnoc_dev ? ant_mode : ""); this->get_rx_subtree() ->create<std::vector<std::string>>("antenna/options") - .set(antenna_options); + .set(is_rfnoc_dev ? antenna_options : std::vector<std::string>(1, "")); this->get_rx_subtree()->create<int>("sensors"); // phony property so this dir exists this->get_rx_subtree() ->create<std::string>("connection") - .set(sd_name_to_conn[get_subdev_name()]); + .set(antenna_mode_to_conn[ant_mode]); this->get_rx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_rx_subtree()->create<bool>("use_lo_offset").set(false); this->get_rx_subtree() ->create<double>("bandwidth/value") - .set(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq); + .set(antenna_mode_bandwidth_scalar.at(ant_mode) * _max_freq); this->get_rx_subtree() ->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq, - subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq)); + .set(freq_range_t(antenna_mode_bandwidth_scalar.at(ant_mode) * _max_freq, + antenna_mode_bandwidth_scalar.at(ant_mode) * _max_freq)); + if (is_rfnoc_dev) { + this->get_rx_subtree() + ->access<std::string>("antenna/value") + .add_coerced_subscriber([this](const std::string& ant) { + this->get_rx_subtree() + ->access<std::string>("connection") + .set(antenna_mode_to_conn[ant]); + this->get_rx_subtree() + ->access<double>("bandwidth/value") + .set(antenna_mode_bandwidth_scalar.at(ant) * _max_freq); + this->get_rx_subtree() + ->access<meta_range_t>("bandwidth/range") + .set(freq_range_t(antenna_mode_bandwidth_scalar.at(ant) * _max_freq, + antenna_mode_bandwidth_scalar.at(ant) * _max_freq)); + UHD_LOG_TRACE("BASICRX", + "Changing antenna mode on channel: " << get_subdev_name() + << " IQ connection type: " + << antenna_mode_to_conn[ant]); + }); + } // disable RX dboard clock by default this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, false); @@ -172,34 +183,40 @@ basic_rx::~basic_rx(void) /* NOP */ } -void basic_rx::set_rx_ant(const std::string& ant) -{ - UHD_ASSERT_THROW(get_iface()->has_set_fe_connection(dboard_iface::UNIT_RX)); - UHD_LOG_TRACE("BASICRX", "Setting antenna value to: " << ant); - get_iface()->set_fe_connection(dboard_iface::UNIT_RX, - get_subdev_name(), - usrp::fe_connection_t(sd_name_to_conn[ant], 0.0 /* IF */)); -} - /*********************************************************************** * Basic and LF TX dboard **********************************************************************/ basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args) { + // Examine the frontend to use the RFNoC or the N210 implementation + // (preserves legacy behavior) + const std::string fe_name(get_subdev_name()); + const bool is_rfnoc_dev = std::find(tx_frontends.begin(), tx_frontends.end(), fe_name) + != tx_frontends.end(); + const std::string ant_mode(is_rfnoc_dev ? "AB" : fe_name); _max_freq = max_freq; - // this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); + const std::string db_name([this]() { + switch (get_tx_id().to_uint16()) { + case BASIC_TX_PID: + case BASIC_TX_RFNOC_PID: + return str(boost::format("%s (%s)") % "BasicTX" % get_subdev_name()); + case LF_TX_PID: + case LF_TX_RFNOC_PID: + return str(boost::format("%s (%s)") % "LFTX" % get_subdev_name()); + default: + UHD_THROW_INVALID_CODE_PATH(); + } + }()); + UHD_LOG_TRACE("BASICTX", + "Initializing driver for: " << db_name << " IQ connection type: " << ant_mode); + UHD_LOG_TRACE("BASICTX", "Is RFNoC Device: " << (is_rfnoc_dev ? "Yes" : "No")); + + std::vector<std::string> antenna_options = antenna_mode_to_conn.keys(); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - if (get_tx_id() == BASIC_TX_PID) { - this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("BasicTX (%s)") % get_subdev_name()))); - } else { - this->get_tx_subtree()->create<std::string>("name").set( - std::string(str(boost::format("LFTX (%s)") % get_subdev_name()))); - } - + this->get_tx_subtree()->create<std::string>("name").set(db_name); this->get_tx_subtree()->create<int>("gains"); // phony property so this dir exists this->get_tx_subtree()->create<double>("freq/value").set_publisher([]() { return 0.0; @@ -207,21 +224,45 @@ basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args) this->get_tx_subtree() ->create<meta_range_t>("freq/range") .set(freq_range_t(-_max_freq, +_max_freq)); - this->get_tx_subtree()->create<std::string>("antenna/value").set(""); - this->get_tx_subtree()->create<std::vector<std::string>>("antenna/options").set({""}); + this->get_tx_subtree() + ->create<std::string>("antenna/value") + .set(is_rfnoc_dev ? ant_mode : ""); + this->get_tx_subtree() + ->create<std::vector<std::string>>("antenna/options") + .set(is_rfnoc_dev ? antenna_options : std::vector<std::string>(1, "")); this->get_tx_subtree()->create<int>("sensors"); // phony property so this dir exists this->get_tx_subtree() ->create<std::string>("connection") - .set(sd_name_to_conn[get_subdev_name()]); + .set(antenna_mode_to_conn[ant_mode]); this->get_tx_subtree()->create<bool>("enabled").set(true); // always enabled this->get_tx_subtree()->create<bool>("use_lo_offset").set(false); this->get_tx_subtree() ->create<double>("bandwidth/value") - .set(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq); + .set(antenna_mode_bandwidth_scalar.at(ant_mode) * _max_freq); this->get_tx_subtree() ->create<meta_range_t>("bandwidth/range") - .set(freq_range_t(subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq, - subdev_bandwidth_scalar.at(get_subdev_name()) * _max_freq)); + .set(freq_range_t(antenna_mode_bandwidth_scalar.at(ant_mode) * _max_freq, + antenna_mode_bandwidth_scalar.at(ant_mode) * _max_freq)); + if (is_rfnoc_dev) { + this->get_tx_subtree() + ->access<std::string>("antenna/value") + .add_coerced_subscriber([this](const std::string& ant) { + this->get_tx_subtree() + ->access<std::string>("connection") + .set(antenna_mode_to_conn[ant]); + this->get_tx_subtree() + ->access<double>("bandwidth/value") + .set(antenna_mode_bandwidth_scalar.at(ant) * _max_freq); + this->get_tx_subtree() + ->access<meta_range_t>("bandwidth/range") + .set(freq_range_t(antenna_mode_bandwidth_scalar.at(ant) * _max_freq, + antenna_mode_bandwidth_scalar.at(ant) * _max_freq)); + UHD_LOG_TRACE("BASICTX", + "Changing antenna mode for channel: " << get_subdev_name() + << " IQ connection type: " + << antenna_mode_to_conn[ant]); + }); + } // disable TX dboard clock by default this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, false); diff --git a/host/lib/usrp/dboard/db_basic_and_lf.hpp b/host/lib/usrp/dboard/db_basic_and_lf.hpp new file mode 100644 index 000000000..c306926eb --- /dev/null +++ b/host/lib/usrp/dboard/db_basic_and_lf.hpp @@ -0,0 +1,35 @@ +// +// Copyright 2020 Ettus Research, a National Instruments Brand +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#include <uhd/types/dict.hpp> +#include <boost/assign/list_of.hpp> + +namespace uhd { namespace usrp { namespace dboard { namespace basic_and_lf { +constexpr uint32_t BASIC_TX_PID = 0x0000; +constexpr uint32_t BASIC_RX_PID = 0x0001; +constexpr uint32_t LF_TX_PID = 0x000E; +constexpr uint32_t LF_RX_PID = 0x000F; +// The PIDs of these dboards are duplicated to support a new operating mode +// on RFNoC devices, while maintaining legacy for the USRP2 +constexpr uint32_t RFNOC_PID_FLAG = 0x6300; +constexpr uint32_t BASIC_TX_RFNOC_PID = BASIC_TX_PID | RFNOC_PID_FLAG; // 0x6300 +constexpr uint32_t BASIC_RX_RFNOC_PID = BASIC_RX_PID | RFNOC_PID_FLAG; // 0x6301 +constexpr uint32_t LF_TX_RFNOC_PID = LF_TX_PID | RFNOC_PID_FLAG; // 0x630E +constexpr uint32_t LF_RX_RFNOC_PID = LF_RX_PID | RFNOC_PID_FLAG; // 0x630F + +constexpr double BASIC_MAX_BANDWIDTH = 250e6; // Hz +constexpr double LF_MAX_BANDWIDTH = 32e6; // Hz + + +static const std::vector<std::string> rx_frontends{"0", "1"}; +static const std::vector<std::string> tx_frontends{"0"}; + +static const std::map<std::string, double> antenna_mode_bandwidth_scalar{ + {"A", 1.0}, {"B", 1.0}, {"AB", 2.0}, {"BA", 2.0}}; + +static const uhd::dict<std::string, std::string> antenna_mode_to_conn = + boost::assign::map_list_of("AB", "IQ")("BA", "QI")("A", "I")("B", "Q"); +}}}}; // namespace uhd::usrp::dboard::basic_and_lf |