aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorLane Kolbly <lane.kolbly@ni.com>2020-06-18 17:46:06 -0500
committerAaron Rossetto <aaron.rossetto@ni.com>2021-01-11 12:26:00 -0600
commit12673d9290319d2453fedd806ddf248d3d5586e3 (patch)
tree811016297552c5358129aecb5953a0c143229e86 /host/lib
parentc9b35e3b7107ab82c0e3978b7cbfd76ba98e2407 (diff)
downloaduhd-12673d9290319d2453fedd806ddf248d3d5586e3.tar.gz
uhd-12673d9290319d2453fedd806ddf248d3d5586e3.tar.bz2
uhd-12673d9290319d2453fedd806ddf248d3d5586e3.zip
uhd: Split radio_control into rf_control interfaces
These rf_control interfaces allow easier implementation of radio controls as well as allowing easier sharing of code for implementing e.g. gain_profile.
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp5
-rw-r--r--host/lib/include/uhdlib/rfnoc/rf_control/dboard_iface.hpp41
-rw-r--r--host/lib/include/uhdlib/rfnoc/rf_control/gain_profile_iface.hpp86
-rw-r--r--host/lib/rfnoc/CMakeLists.txt1
-rw-r--r--host/lib/rfnoc/radio_control_impl.cpp36
-rw-r--r--host/lib/rfnoc/rf_control/CMakeLists.txt13
-rw-r--r--host/lib/rfnoc/rf_control/gain_profile.cpp68
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp48
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp9
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp2
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp4
11 files changed, 237 insertions, 76 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp
index f60319d32..2a93fbfa5 100644
--- a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp
+++ b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp
@@ -11,6 +11,8 @@
#include <uhd/rfnoc/radio_control.hpp>
#include <uhdlib/features/discoverable_feature_registry.hpp>
#include <uhdlib/usrp/common/pwr_cal_mgr.hpp>
+#include <uhd/rfnoc/rf_control/core_iface.hpp>
+#include <uhdlib/rfnoc/rf_control/gain_profile_iface.hpp>
#include <unordered_map>
#include <mutex>
@@ -322,6 +324,9 @@ protected:
// simply leave these empty.
std::vector<uhd::usrp::pwr_cal_mgr::sptr> _tx_pwr_mgr;
+ rf_control::gain_profile_iface::sptr _tx_gain_profile_api;
+ rf_control::gain_profile_iface::sptr _rx_gain_profile_api;
+
private:
//! Validator for the async messages
//
diff --git a/host/lib/include/uhdlib/rfnoc/rf_control/dboard_iface.hpp b/host/lib/include/uhdlib/rfnoc/rf_control/dboard_iface.hpp
new file mode 100644
index 000000000..1651a1580
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/rf_control/dboard_iface.hpp
@@ -0,0 +1,41 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#pragma once
+
+#include <uhd/rfnoc/rf_control/core_iface.hpp>
+#include <uhdlib/rfnoc/rf_control/gain_profile_iface.hpp>
+#include <uhdlib/usrp/common/pwr_cal_mgr.hpp>
+#include <memory>
+
+namespace uhd { namespace rfnoc { namespace rf_control {
+
+/*! Interface that daughterboards expose to the motherboard radio_control
+ *
+ * This interface contains everything required for a daughterboard to implement
+ * all the methods required for radio_control. For the most part, this class
+ * just includes accessors to objects which implement the required functionality.
+ * This class also directly implements core_iface for the remainder.
+ */
+class dboard_iface : public core_iface
+{
+public:
+ using sptr = std::shared_ptr<dboard_iface>;
+
+ virtual ~dboard_iface() = default;
+
+ virtual gain_profile_iface::sptr get_tx_gain_profile_api() = 0;
+ virtual gain_profile_iface::sptr get_rx_gain_profile_api() = 0;
+
+ virtual size_t get_chan_from_dboard_fe(
+ const std::string&, uhd::direction_t) const = 0;
+ virtual std::string get_dboard_fe_from_chan(size_t chan, uhd::direction_t) const = 0;
+
+ virtual std::vector<uhd::usrp::pwr_cal_mgr::sptr>& get_pwr_mgr(
+ uhd::direction_t trx) = 0;
+};
+
+}}} // namespace uhd::rfnoc::rf_control
diff --git a/host/lib/include/uhdlib/rfnoc/rf_control/gain_profile_iface.hpp b/host/lib/include/uhdlib/rfnoc/rf_control/gain_profile_iface.hpp
new file mode 100644
index 000000000..f93a42936
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/rf_control/gain_profile_iface.hpp
@@ -0,0 +1,86 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace uhd { namespace rfnoc { namespace rf_control {
+
+/*! Interface for gain profile API commands
+ *
+ * This interface contains methods to configure the current gain profile of the
+ * device. Note that this interface is RX/TX agnostic, it does not provide
+ * specialized methods for RX and TX.
+ */
+class gain_profile_iface
+{
+public:
+ using sptr = std::shared_ptr<gain_profile_iface>;
+
+ virtual ~gain_profile_iface() = default;
+
+ /*! Return a list of TX gain profiles for this radio
+ */
+ virtual std::vector<std::string> get_gain_profile_names(const size_t chan) const = 0;
+
+ /*! Set the gain profile
+ */
+ virtual void set_gain_profile(const std::string& profile, const size_t chan) = 0;
+
+ /*! Return the gain profile
+ */
+ virtual std::string get_gain_profile(const size_t chan) const = 0;
+};
+
+/*! "Default" implementation for gain_profile_iface
+ *
+ * This class implements gain_profile_iface such that the device is always
+ * and can only be configured using a single "default" gain profile. Setting
+ * a gain profile which is not the default profile is an error, and getting the
+ * gain profile will always return the default profile.
+ */
+class default_gain_profile : public gain_profile_iface
+{
+public:
+ std::vector<std::string> get_gain_profile_names(const size_t chan) const override;
+
+ void set_gain_profile(const std::string& profile, const size_t chan) override;
+ std::string get_gain_profile(const size_t chan) const override;
+
+private:
+ static const std::string DEFAULT_GAIN_PROFILE;
+};
+
+/*! "Enumerated" implementation for gain_profile_iface
+ *
+ * This class implements gain_profile_iface so that the gain profile can only be
+ * one of several different enumerated values. Setting an invalid gain profile
+ * is an error. Retrieving a gain profile will always return one of the
+ * enumerated gain profiles.
+ */
+class enumerated_gain_profile : public gain_profile_iface
+{
+public:
+ enumerated_gain_profile(const std::vector<std::string>& possible_profiles,
+ const std::string& default_profile,
+ size_t num_channels);
+
+ void set_gain_profile(const std::string& profile, const size_t chan) override;
+
+ std::string get_gain_profile(const size_t chan) const override;
+
+ std::vector<std::string> get_gain_profile_names(const size_t) const override;
+
+private:
+ std::vector<std::string> _possible_profiles;
+
+ std::vector<std::string> _gain_profile;
+};
+
+}}} // namespace uhd::rfnoc::rf_control
diff --git a/host/lib/rfnoc/CMakeLists.txt b/host/lib/rfnoc/CMakeLists.txt
index 33da287fe..53bca9b45 100644
--- a/host/lib/rfnoc/CMakeLists.txt
+++ b/host/lib/rfnoc/CMakeLists.txt
@@ -61,3 +61,4 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/window_block_control.cpp
)
+INCLUDE_SUBDIRECTORY(rf_control)
diff --git a/host/lib/rfnoc/radio_control_impl.cpp b/host/lib/rfnoc/radio_control_impl.cpp
index f9347b9e7..e20f5d4f6 100644
--- a/host/lib/rfnoc/radio_control_impl.cpp
+++ b/host/lib/rfnoc/radio_control_impl.cpp
@@ -253,6 +253,10 @@ radio_control_impl::radio_control_impl(make_args_ptr make_args)
boost::optional<uint64_t> timestamp) {
this->async_message_handler(addr, data, timestamp);
});
+
+ // Set the default gain profiles
+ _rx_gain_profile_api = std::make_shared<rf_control::default_gain_profile>();
+ _tx_gain_profile_api = std::make_shared<rf_control::default_gain_profile>();
} /* ctor */
/******************************************************************************
@@ -436,42 +440,34 @@ void radio_control_impl::set_rx_agc(const bool, const size_t)
throw uhd::not_implemented_error("set_rx_agc() is not supported on this radio!");
}
-void radio_control_impl::set_tx_gain_profile(const std::string& profile, const size_t)
+void radio_control_impl::set_tx_gain_profile(const std::string& profile, const size_t chan)
{
- if (profile != DEFAULT_GAIN_PROFILE) {
- throw uhd::value_error(
- std::string("set_tx_gain_profile(): Unknown gain profile: `") + profile
- + "'");
- }
+ _tx_gain_profile_api->set_gain_profile(profile, chan);
}
-void radio_control_impl::set_rx_gain_profile(const std::string& profile, const size_t)
+void radio_control_impl::set_rx_gain_profile(const std::string& profile, const size_t chan)
{
- if (profile != DEFAULT_GAIN_PROFILE) {
- throw uhd::value_error(
- std::string("set_rx_gain_profile(): Unknown gain profile: `") + profile
- + "'");
- }
+ _rx_gain_profile_api->set_gain_profile(profile, chan);
}
-std::vector<std::string> radio_control_impl::get_tx_gain_profile_names(const size_t) const
+std::vector<std::string> radio_control_impl::get_tx_gain_profile_names(const size_t chan) const
{
- return {DEFAULT_GAIN_PROFILE};
+ return _tx_gain_profile_api->get_gain_profile_names(chan);
}
-std::vector<std::string> radio_control_impl::get_rx_gain_profile_names(const size_t) const
+std::vector<std::string> radio_control_impl::get_rx_gain_profile_names(const size_t chan) const
{
- return {DEFAULT_GAIN_PROFILE};
+ return _rx_gain_profile_api->get_gain_profile_names(chan);
}
-std::string radio_control_impl::get_tx_gain_profile(const size_t) const
+std::string radio_control_impl::get_tx_gain_profile(const size_t chan) const
{
- return DEFAULT_GAIN_PROFILE;
+ return _tx_gain_profile_api->get_gain_profile(chan);
}
-std::string radio_control_impl::get_rx_gain_profile(const size_t) const
+std::string radio_control_impl::get_rx_gain_profile(const size_t chan) const
{
- return DEFAULT_GAIN_PROFILE;
+ return _rx_gain_profile_api->get_gain_profile(chan);
}
double radio_control_impl::set_tx_bandwidth(const double bandwidth, const size_t chan)
diff --git a/host/lib/rfnoc/rf_control/CMakeLists.txt b/host/lib/rfnoc/rf_control/CMakeLists.txt
new file mode 100644
index 000000000..11c7e57ef
--- /dev/null
+++ b/host/lib/rfnoc/rf_control/CMakeLists.txt
@@ -0,0 +1,13 @@
+#
+# Copyright 2020 Ettus Research, a National Instruments Brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gain_profile.cpp
+)
diff --git a/host/lib/rfnoc/rf_control/gain_profile.cpp b/host/lib/rfnoc/rf_control/gain_profile.cpp
new file mode 100644
index 000000000..54ccb9006
--- /dev/null
+++ b/host/lib/rfnoc/rf_control/gain_profile.cpp
@@ -0,0 +1,68 @@
+//
+// Copyright 2020 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/exception.hpp>
+#include <uhd/utils/assert_has.hpp>
+#include <uhd/utils/log.hpp>
+#include <uhdlib/rfnoc/rf_control/gain_profile_iface.hpp>
+#include <stddef.h>
+#include <string>
+#include <vector>
+
+namespace uhd { namespace rfnoc { namespace rf_control {
+
+const std::string default_gain_profile::DEFAULT_GAIN_PROFILE = "default";
+
+std::vector<std::string> default_gain_profile::get_gain_profile_names(const size_t) const
+{
+ return {DEFAULT_GAIN_PROFILE};
+}
+
+void default_gain_profile::set_gain_profile(const std::string& profile, const size_t)
+{
+ if (profile != DEFAULT_GAIN_PROFILE) {
+ throw uhd::value_error(
+ std::string("set_tx_gain_profile(): Unknown gain profile: `") + profile
+ + "'");
+ }
+}
+
+std::string default_gain_profile::get_gain_profile(const size_t) const
+{
+ return DEFAULT_GAIN_PROFILE;
+}
+
+enumerated_gain_profile::enumerated_gain_profile(
+ const std::vector<std::string>& possible_profiles,
+ const std::string& default_profile,
+ size_t num_channels)
+ : _possible_profiles(possible_profiles), _gain_profile(num_channels, default_profile)
+{
+}
+
+void enumerated_gain_profile::set_gain_profile(
+ const std::string& profile, const size_t chan)
+{
+ if (!uhd::has(_possible_profiles, profile)) {
+ const std::string err_msg = ("Invalid gain profile provided: " + profile);
+ UHD_LOG_ERROR("gain_profile", err_msg);
+ throw uhd::key_error(err_msg);
+ }
+ _gain_profile.at(chan) = profile;
+}
+
+std::string enumerated_gain_profile::get_gain_profile(const size_t chan) const
+{
+ return _gain_profile.at(chan);
+}
+
+std::vector<std::string> enumerated_gain_profile::get_gain_profile_names(
+ const size_t) const
+{
+ return _possible_profiles;
+}
+
+}}} // namespace uhd::rfnoc::rf_control
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
index 5eb0f63a5..879885640 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
@@ -103,6 +103,10 @@ magnesium_radio_control_impl::magnesium_radio_control_impl(make_args_ptr make_ar
{
RFNOC_LOG_TRACE("Entering magnesium_radio_control_impl ctor...");
UHD_ASSERT_THROW(get_block_id().get_block_count() < 2);
+
+ _tx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>(MAGNESIUM_GP_OPTIONS, "default", MAGNESIUM_NUM_CHANS);
+ _rx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>(MAGNESIUM_GP_OPTIONS, "default", MAGNESIUM_NUM_CHANS);
+
const char radio_slot_name[2] = {'A', 'B'};
_radio_slot = radio_slot_name[get_block_id().get_block_count()];
RFNOC_LOG_TRACE("Radio slot: " << _radio_slot);
@@ -363,28 +367,6 @@ double magnesium_radio_control_impl::set_tx_bandwidth(
return AD9371_TX_MAX_BANDWIDTH;
}
-void magnesium_radio_control_impl::set_tx_gain_profile(
- const std::string& profile, const size_t)
-{
- if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile)
- == MAGNESIUM_GP_OPTIONS.end()) {
- RFNOC_LOG_ERROR("Invalid TX gain profile: " << profile);
- throw uhd::key_error("Invalid TX gain profile!");
- }
- _gain_profile[TX_DIRECTION] = profile;
-}
-
-void magnesium_radio_control_impl::set_rx_gain_profile(
- const std::string& profile, const size_t)
-{
- if (std::find(MAGNESIUM_GP_OPTIONS.begin(), MAGNESIUM_GP_OPTIONS.end(), profile)
- == MAGNESIUM_GP_OPTIONS.end()) {
- RFNOC_LOG_ERROR("Invalid RX gain profile: " << profile);
- throw uhd::key_error("Invalid RX gain profile!");
- }
- _gain_profile[RX_DIRECTION] = profile;
-}
-
double magnesium_radio_control_impl::set_tx_gain(const double gain, const size_t chan)
{
std::lock_guard<std::recursive_mutex> l(_set_lock);
@@ -716,28 +698,6 @@ uhd::gain_range_t magnesium_radio_control_impl::get_rx_gain_range(
throw uhd::key_error("Invalid RX gain name!");
}
-std::vector<std::string> magnesium_radio_control_impl::get_tx_gain_profile_names(
- const size_t) const
-{
- return MAGNESIUM_GP_OPTIONS;
-}
-
-std::vector<std::string> magnesium_radio_control_impl::get_rx_gain_profile_names(
- const size_t) const
-{
- return MAGNESIUM_GP_OPTIONS;
-}
-
-std::string magnesium_radio_control_impl::get_tx_gain_profile(const size_t) const
-{
- return _gain_profile.at(TX_DIRECTION);
-}
-
-std::string magnesium_radio_control_impl::get_rx_gain_profile(const size_t) const
-{
- return _gain_profile.at(RX_DIRECTION);
-}
-
meta_range_t magnesium_radio_control_impl::get_tx_bandwidth_range(size_t) const
{
return meta_range_t(AD9371_TX_MIN_BANDWIDTH, AD9371_TX_MAX_BANDWIDTH);
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp
index fc8c79b5a..e8c252605 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.hpp
@@ -87,8 +87,6 @@ public:
double set_rx_gain(const double gain, const std::string& name, const size_t chan);
double set_tx_bandwidth(const double bandwidth, const size_t chan);
double set_rx_bandwidth(const double bandwidth, const size_t chan);
- void set_tx_gain_profile(const std::string& profile, const size_t chan);
- void set_rx_gain_profile(const std::string& profile, const size_t chan);
// Getters
std::vector<std::string> get_tx_antennas(const size_t chan) const;
@@ -103,10 +101,6 @@ public:
uhd::gain_range_t get_tx_gain_range(const std::string&, const size_t) const;
uhd::gain_range_t get_rx_gain_range(const size_t) const;
uhd::gain_range_t get_rx_gain_range(const std::string&, const size_t) const;
- std::vector<std::string> get_tx_gain_profile_names(const size_t chan) const;
- std::vector<std::string> get_rx_gain_profile_names(const size_t chan) const;
- std::string get_tx_gain_profile(const size_t chan) const;
- std::string get_rx_gain_profile(const size_t chan) const;
uhd::meta_range_t get_tx_bandwidth_range(size_t chan) const;
uhd::meta_range_t get_rx_bandwidth_range(size_t chan) const;
@@ -351,9 +345,6 @@ private:
//! All gain
double _all_rx_gain = 0.0;
double _all_tx_gain = 0.0;
- //! Gain profile
- std::map<direction_t, std::string> _gain_profile = {
- {RX_DIRECTION, "default"}, {TX_DIRECTION, "default"}};
bool _rx_bypass_lnas = true;
bool _tx_bypass_amp = true;
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp
index b06222205..72d8d564c 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_gain.cpp
@@ -31,7 +31,7 @@ double magnesium_radio_control_impl::_set_all_gain(
const size_t ad9371_chan = chan;
auto chan_sel = static_cast<magnesium_cpld_ctrl::chan_sel_t>(chan);
gain_tuple_t gain_tuple;
- std::string gp = _gain_profile[dir];
+ std::string gp = dir == RX_DIRECTION ? get_rx_gain_profile(0) : get_tx_gain_profile(0);
RFNOC_LOG_TRACE("Gain profile: " << gp);
if (gp == "manual") {
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp
index d9bf5c3d2..82da7ec75 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control_init.cpp
@@ -51,13 +51,13 @@ void magnesium_radio_control_impl::_init_defaults()
if (block_args.has_key("tx_gain_profile")) {
RFNOC_LOG_INFO("Using user specified TX gain profile: " << block_args.get(
"tx_gain_profile"));
- _gain_profile[TX_DIRECTION] = block_args.get("tx_gain_profile");
+ set_tx_gain_profile(block_args.get("tx_gain_profile"), 0);
}
if (block_args.has_key("rx_gain_profile")) {
RFNOC_LOG_INFO("Using user specified RX gain profile: " << block_args.get(
"rx_gain_profile"));
- _gain_profile[RX_DIRECTION] = block_args.get("rx_gain_profile");
+ set_rx_gain_profile(block_args.get("rx_gain_profile"), 0);
}
if (block_args.has_key("rx_band_map")) {