From f4b8879064f6090e2233165216e78944070b6a06 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Fri, 4 May 2018 16:35:45 -0700 Subject: basicrx/lfrx: Enable frontend muxing on X3x0 The selection of frontend modes (AB, A, B, BA) is now enabled on X3x0. Unlike older USRPs, switching the frontend is done through the antenna API (e.g., usrp->set_rx_antenna("A")). --- host/docs/dboards.dox | 18 +++++++++- host/lib/usrp/dboard/db_basic_and_lf.cpp | 62 +++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/host/docs/dboards.dox b/host/docs/dboards.dox index 0cb559061..5993501c9 100644 --- a/host/docs/dboards.dox +++ b/host/docs/dboards.dox @@ -11,13 +11,29 @@ of each board as well. \subsection dboards_basicrx Basic RX and LFRX -The Basic RX and LFRX boards have 4 frontends: +The Basic RX and LFRX boards have four modes of operation: - **Frontend A:** real signal on antenna RXA - **Frontend B:** real signal on antenna RXB - **Frontend AB:** quadrature frontend using both antennas (IQ) - **Frontend BA:** quadrature frontend using both antennas (QI) +The way in which you select the mode depends on the USRP type. On the X310, +selecting the mode is done using the antenna API: + +```cpp +auto usrp = uhd::usrp::multi_usrp::make("type=x300"); +usrp->set_rx_antenna("A"); // Disable RXB port +``` + +On the USRP2, the N200 series, the B100 series, the E100, and the USRP1 the mode +depends on the subdev spec applied: + +```cpp +auto usrp = uhd::usrp::multi_usrp::make("type=usrp2"); +usrp->set_rx_subdev_spec("A:A"); // Disable RXB port +``` + The boards have no tunable elements or programmable gains. Through the magic of aliasing, you can down-convert signals greater than the Nyquist rate of the ADC. diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 24051406e..81a7aa534 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -58,6 +58,8 @@ public: virtual ~basic_rx(void); private: + void set_rx_ant(const std::string& ant); + double _max_freq; }; @@ -99,33 +101,49 @@ UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){ /*********************************************************************** * Basic and LF RX dboard **********************************************************************/ -basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args){ - _max_freq = max_freq; - //this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); +basic_rx::basic_rx(ctor_args_t args, double max_freq) + : rx_dboard_base(args), + _max_freq(max_freq) +{ + 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)); + 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")); + + std::vector antenna_options = has_fe_conn_settings + ? sd_name_to_conn.keys() + : std::vector(1, ""); //////////////////////////////////////////////////////////////////// // Register properties //////////////////////////////////////////////////////////////////// - if (get_rx_id() == BASIC_RX_PID) { - this->get_rx_subtree()->create("name").set( - std::string(str(boost::format("BasicRX (%s)") % get_subdev_name() - ))); - } - else{ - this->get_rx_subtree()->create("name").set( - std::string(str(boost::format("LFRX (%s)") % get_subdev_name() - ))); - } - + this->get_rx_subtree()->create("name").set(db_name); this->get_rx_subtree()->create("gains"); //phony property so this dir exists this->get_rx_subtree()->create("freq/value") .set_publisher([](){ return 0.0; }); this->get_rx_subtree()->create("freq/range") .set(freq_range_t(-_max_freq, +_max_freq)); this->get_rx_subtree()->create("antenna/value") - .set(""); + .set(has_fe_conn_settings ? fe_name : ""); + if (has_fe_conn_settings) { + this->get_rx_subtree()->access("antenna/value") + .add_coerced_subscriber([this](const std::string& ant){ + this->set_rx_ant(ant); + }) + ; + } this->get_rx_subtree()->create>("antenna/options") - .set({""}); + .set(antenna_options); this->get_rx_subtree()->create("sensors"); //phony property so this dir exists this->get_rx_subtree()->create("connection") .set(sd_name_to_conn[get_subdev_name()]); @@ -153,6 +171,18 @@ 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 **********************************************************************/ -- cgit v1.2.3