aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp102
-rw-r--r--host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp18
-rw-r--r--host/lib/rfnoc/rf_control/CMakeLists.txt1
-rw-r--r--host/lib/rfnoc/rf_control/antenna.cpp84
-rw-r--r--host/lib/usrp/dboard/zbx/zbx_dboard.cpp46
-rw-r--r--host/tests/CMakeLists.txt1
6 files changed, 203 insertions, 49 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp b/host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp
new file mode 100644
index 000000000..bd36fc869
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/rf_control/antenna_iface.hpp
@@ -0,0 +1,102 @@
+//
+// Copyright 2021 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#pragma once
+
+#include <uhd/property_tree.hpp>
+#include <uhd/rfnoc/rf_control/core_iface.hpp>
+#include <unordered_map>
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace uhd { namespace rfnoc { namespace rf_control {
+
+/*! Interface for setting and getting the current antenna.
+ */
+class antenna_iface
+{
+public:
+ using sptr = std::shared_ptr<antenna_iface>;
+
+ virtual ~antenna_iface() = default;
+
+ /*! Return a list of valid antenna for channel \p chan.
+ *
+ * \return The selected antenna.
+ */
+ virtual std::vector<std::string> get_antennas(const size_t chan) const = 0;
+
+ /*! Select antenna \p for channel \p chan.
+ *
+ * \throws uhd::value_error if \p ant is not a valid value.
+ */
+ virtual void set_antenna(const std::string& ant, const size_t chan) = 0;
+
+ /*! Return the selected antenna for channel \p chan.
+ *
+ * \return The selected antenna.
+ */
+ virtual std::string get_antenna(const size_t chan) const = 0;
+};
+
+/*! Class for getting and setting antennas out of an enumerated set, where
+ * the API calls for the antenna actually map to property nodes.
+ */
+class enumerated_antenna : public antenna_iface
+{
+public:
+ using prop_path = std::function<fs_path(const size_t chan)>;
+
+ /*! Constructs an enumerated_antenna class.
+ *
+ * \param tree The property tree the nodes are on
+ * \param prop_path_generator Closure to generate the property path given the channel.
+ * \param possible_antennas A vector of legal antennas.
+ * \param compat_map A map of alternative names for antennas.
+ */
+ enumerated_antenna(uhd::property_tree::sptr tree,
+ prop_path prop_path_generator,
+ const std::vector<std::string>& possible_antennas,
+ const std::unordered_map<std::string, std::string>& compat_map);
+
+ virtual ~enumerated_antenna() = default;
+
+ std::vector<std::string> get_antennas(const size_t chan) const override;
+ void set_antenna(const std::string& ant, const size_t chan) override;
+ std::string get_antenna(const size_t chan) const override;
+
+private:
+ // The property tree & node used to implement the API
+ uhd::property_tree::sptr _tree;
+ prop_path _prop_path_generator;
+
+ std::vector<std::string> _possible_antennas;
+ const std::unordered_map<std::string, std::string>& _compat_map;
+};
+
+/*! Partially implements core_iface for antenna, redirecting to one of two
+ * subobjects for RX or TX.
+ */
+class antenna_radio_control_mixin : virtual public core_iface
+{
+public:
+ virtual ~antenna_radio_control_mixin() = default;
+
+ std::string get_tx_antenna(const size_t chan) const override;
+ std::vector<std::string> get_tx_antennas(const size_t chan) const override;
+ void set_tx_antenna(const std::string& ant, const size_t chan) override;
+ std::string get_rx_antenna(const size_t chan) const override;
+ std::vector<std::string> get_rx_antennas(const size_t chan) const override;
+ void set_rx_antenna(const std::string& ant, const size_t chan) override;
+
+protected:
+ antenna_iface::sptr _rx_antenna;
+ antenna_iface::sptr _tx_antenna;
+};
+
+}}} // namespace uhd::rfnoc::rf_control
diff --git a/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp b/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp
index 0a52d7bdf..6e1d31381 100644
--- a/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp
+++ b/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp
@@ -21,6 +21,7 @@
#include <uhd/types/wb_iface.hpp>
#include <uhdlib/experts/expert_factory.hpp>
#include <uhdlib/rfnoc/rf_control/dboard_iface.hpp>
+#include <uhdlib/rfnoc/rf_control/antenna_iface.hpp>
#include <uhdlib/usrp/common/mpmd_mb_controller.hpp>
#include <uhdlib/usrp/common/pwr_cal_mgr.hpp>
#include <uhdlib/usrp/common/rpc.hpp>
@@ -40,7 +41,9 @@ const static uint16_t ZBX_PID = 0x4002;
/*! Provide access to a ZBX radio.
*/
-class zbx_dboard_impl : public uhd::usrp::x400::x400_dboard_iface
+class zbx_dboard_impl :
+ public uhd::usrp::x400::x400_dboard_iface,
+ public uhd::rfnoc::rf_control::antenna_radio_control_mixin
{
public:
using sptr = std::shared_ptr<zbx_dboard_impl>;
@@ -109,17 +112,6 @@ public:
return _rx_gain_profile_api;
}
- void set_tx_antenna(const std::string& ant, const size_t chan) override;
- void set_rx_antenna(const std::string& ant, const size_t chan) override;
- std::vector<std::string> get_tx_antennas(const size_t /*chan*/) const override
- {
- return TX_ANTENNAS;
- }
- std::vector<std::string> get_rx_antennas(const size_t /*chan*/) const override
- {
- return RX_ANTENNAS;
- }
-
double set_tx_frequency(const double freq, const size_t chan) override;
double set_rx_frequency(const double freq, const size_t chan) override;
uhd::freq_range_t get_tx_frequency_range(const size_t /*chan*/) const override
@@ -239,8 +231,6 @@ public:
* Radio Identification API Calls
*************************************************************************/
- std::string get_tx_antenna(size_t chan) const override;
- std::string get_rx_antenna(size_t chan) const override;
double get_tx_frequency(size_t chan) override;
double get_rx_frequency(size_t chan) override;
double get_rx_bandwidth(size_t chan) override;
diff --git a/host/lib/rfnoc/rf_control/CMakeLists.txt b/host/lib/rfnoc/rf_control/CMakeLists.txt
index 11c7e57ef..f55c9a8a1 100644
--- a/host/lib/rfnoc/rf_control/CMakeLists.txt
+++ b/host/lib/rfnoc/rf_control/CMakeLists.txt
@@ -9,5 +9,6 @@
########################################################################
LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/antenna.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gain_profile.cpp
)
diff --git a/host/lib/rfnoc/rf_control/antenna.cpp b/host/lib/rfnoc/rf_control/antenna.cpp
new file mode 100644
index 000000000..50153f3f0
--- /dev/null
+++ b/host/lib/rfnoc/rf_control/antenna.cpp
@@ -0,0 +1,84 @@
+//
+// Copyright 2021 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/antenna_iface.hpp>
+#include <stddef.h>
+#include <string>
+#include <vector>
+
+namespace uhd { namespace rfnoc { namespace rf_control {
+
+enumerated_antenna::enumerated_antenna(uhd::property_tree::sptr tree,
+ prop_path prop_path_generator,
+ const std::vector<std::string>& possible_antennas,
+ const std::unordered_map<std::string, std::string>& compat_map)
+ : _tree(tree)
+ , _prop_path_generator(prop_path_generator)
+ , _possible_antennas(possible_antennas)
+ , _compat_map(compat_map)
+{
+}
+
+std::vector<std::string> enumerated_antenna::get_antennas(const size_t) const
+{
+ return _possible_antennas;
+}
+
+void enumerated_antenna::set_antenna(const std::string& ant, const size_t chan)
+{
+ if (!_compat_map.count(ant)) {
+ assert_has(_possible_antennas, ant, "antenna");
+ }
+
+ auto path = _prop_path_generator(chan);
+
+ _tree->access<std::string>(path).set(ant);
+}
+
+std::string enumerated_antenna::get_antenna(const size_t chan) const
+{
+ auto path = _prop_path_generator(chan);
+ return _tree->access<std::string>(path).get();
+}
+
+std::string antenna_radio_control_mixin::get_tx_antenna(const size_t chan) const
+{
+ return _tx_antenna->get_antenna(chan);
+}
+
+std::vector<std::string> antenna_radio_control_mixin::get_tx_antennas(
+ const size_t chan) const
+{
+ return _tx_antenna->get_antennas(chan);
+}
+
+void antenna_radio_control_mixin::set_tx_antenna(
+ const std::string& ant, const size_t chan)
+{
+ _tx_antenna->set_antenna(ant, chan);
+}
+
+std::string antenna_radio_control_mixin::get_rx_antenna(const size_t chan) const
+{
+ return _rx_antenna->get_antenna(chan);
+}
+
+std::vector<std::string> antenna_radio_control_mixin::get_rx_antennas(
+ const size_t chan) const
+{
+ return _rx_antenna->get_antennas(chan);
+}
+
+void antenna_radio_control_mixin::set_rx_antenna(
+ const std::string& ant, const size_t chan)
+{
+ _rx_antenna->set_antenna(ant, chan);
+}
+
+}}} // namespace uhd::rfnoc::rf_control
diff --git a/host/lib/usrp/dboard/zbx/zbx_dboard.cpp b/host/lib/usrp/dboard/zbx/zbx_dboard.cpp
index d41302c8f..2a01425b6 100644
--- a/host/lib/usrp/dboard/zbx/zbx_dboard.cpp
+++ b/host/lib/usrp/dboard/zbx/zbx_dboard.cpp
@@ -48,6 +48,17 @@ zbx_dboard_impl::zbx_dboard_impl(register_iface& reg_iface,
RFNOC_LOG_TRACE("Entering zbx_dboard_impl ctor...");
RFNOC_LOG_TRACE("Radio slot: " << _radio_slot);
+ _rx_antenna = std::make_shared<uhd::rfnoc::rf_control::enumerated_antenna>(tree,
+ [this](size_t chan) {
+ return this->_get_frontend_path(RX_DIRECTION, chan) / "antenna" / "value";
+ },
+ RX_ANTENNAS, RX_ANTENNA_NAME_COMPAT_MAP);
+ _tx_antenna = std::make_shared<uhd::rfnoc::rf_control::enumerated_antenna>(tree,
+ [this](size_t chan) {
+ return this->_get_frontend_path(TX_DIRECTION, chan) / "antenna" / "value";
+ },
+ TX_ANTENNAS, TX_ANTENNA_NAME_COMPAT_MAP);
+
_tx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>(
ZBX_GAIN_PROFILES, ZBX_GAIN_PROFILE_DEFAULT, ZBX_NUM_CHANS);
_rx_gain_profile_api = std::make_shared<rf_control::enumerated_gain_profile>(
@@ -89,29 +100,6 @@ std::string zbx_dboard_impl::get_unique_id() const
/******************************************************************************
* API Calls
*****************************************************************************/
-void zbx_dboard_impl::set_tx_antenna(const std::string& ant, const size_t chan)
-{
- RFNOC_LOG_TRACE("Setting TX antenna to " << ant << " for chan " << chan);
- if (!TX_ANTENNA_NAME_COMPAT_MAP.count(ant)) {
- assert_has(TX_ANTENNAS, ant, "tx antenna");
- }
- const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan);
-
- _tree->access<std::string>(fe_path / "antenna" / "value").set(ant);
-}
-
-void zbx_dboard_impl::set_rx_antenna(const std::string& ant, const size_t chan)
-{
- RFNOC_LOG_TRACE("Setting RX antenna to " << ant << " for chan " << chan);
- if (!RX_ANTENNA_NAME_COMPAT_MAP.count(ant)) {
- assert_has(RX_ANTENNAS, ant, "rx antenna");
- }
-
- const fs_path fe_path = _get_frontend_path(RX_DIRECTION, chan);
-
- _tree->access<std::string>(fe_path / "antenna" / "value").set(ant);
-}
-
double zbx_dboard_impl::set_tx_frequency(const double req_freq, const size_t chan)
{
const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan);
@@ -592,18 +580,6 @@ double zbx_dboard_impl::get_rx_lo_freq(const std::string& name, size_t chan)
return _tree->access<double>(fe_path / "los" / name / "freq" / "value").get();
}
-std::string zbx_dboard_impl::get_tx_antenna(size_t chan) const
-{
- const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan);
- return _tree->access<std::string>(fe_path / "antenna" / "value").get();
-}
-
-std::string zbx_dboard_impl::get_rx_antenna(size_t chan) const
-{
- const fs_path fe_path = _get_frontend_path(RX_DIRECTION, chan);
- return _tree->access<std::string>(fe_path / "antenna" / "value").get();
-}
-
double zbx_dboard_impl::get_tx_frequency(size_t chan)
{
const fs_path fe_path = _get_frontend_path(TX_DIRECTION, chan);
diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt
index d8e26890a..758d2bbf0 100644
--- a/host/tests/CMakeLists.txt
+++ b/host/tests/CMakeLists.txt
@@ -376,6 +376,7 @@ IF(ENABLE_X400)
${UHD_SOURCE_DIR}/lib/usrp/x400/x400_rfdc_control.cpp
${UHD_SOURCE_DIR}/lib/usrp/x400/adc_self_calibration.cpp
${UHD_SOURCE_DIR}/lib/rfnoc/radio_control_impl.cpp
+ ${UHD_SOURCE_DIR}/lib/rfnoc/rf_control/antenna.cpp
${UHD_SOURCE_DIR}/lib/rfnoc/rf_control/gain_profile.cpp
${UHD_SOURCE_DIR}/lib/usrp/mpmd/mpmd_mb_controller.cpp
${UHD_SOURCE_DIR}/lib/usrp/dboard/zbx/zbx_dboard.cpp