aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/lib/include/uhdlib/rfnoc/rf_control/nameless_gain_mixin.hpp58
-rw-r--r--host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp26
-rw-r--r--host/lib/rfnoc/rf_control/CMakeLists.txt1
-rw-r--r--host/lib/rfnoc/rf_control/nameless_gain_mixin.cpp56
-rw-r--r--host/lib/usrp/dboard/zbx/zbx_dboard.cpp88
-rw-r--r--host/lib/usrp/dboard/zbx/zbx_dboard_init.cpp4
-rw-r--r--host/tests/CMakeLists.txt1
7 files changed, 151 insertions, 83 deletions
diff --git a/host/lib/include/uhdlib/rfnoc/rf_control/nameless_gain_mixin.hpp b/host/lib/include/uhdlib/rfnoc/rf_control/nameless_gain_mixin.hpp
new file mode 100644
index 000000000..149623352
--- /dev/null
+++ b/host/lib/include/uhdlib/rfnoc/rf_control/nameless_gain_mixin.hpp
@@ -0,0 +1,58 @@
+//
+// 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 <uhd/types/direction.hpp>
+#include <unordered_map>
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace uhd { namespace rfnoc { namespace rf_control {
+
+/*! Partially implements core_iface for the gain functions which take no name parameter
+ */
+class nameless_gain_mixin : virtual public core_iface
+{
+public:
+ using name_selector =
+ std::function<std::string(const uhd::direction_t trx, const size_t chan)>;
+
+ /*! Sets the name selector for the mixin. The closure receives the direction
+ * of the call and the channel, and returns the gain to use for the call. The
+ * name selector may simply return a string, or may do a more complex algorithm.
+ */
+ nameless_gain_mixin(name_selector name_selector);
+
+ virtual ~nameless_gain_mixin() = default;
+
+ double set_tx_gain(const double gain, const size_t chan) override;
+ double get_tx_gain(const size_t chan) override;
+
+ double set_rx_gain(const double gain, const size_t chan) override;
+ double get_rx_gain(const size_t chan) override;
+
+ // Getting the gain ranges is a bit different - these always use the empty name
+ gain_range_t get_tx_gain_range(const size_t chan) const override;
+ gain_range_t get_rx_gain_range(const size_t chan) const override;
+
+private:
+ name_selector _name_selector;
+
+ using core_iface::get_tx_gain;
+ using core_iface::get_tx_gain_range;
+ using core_iface::set_tx_gain;
+
+ using core_iface::get_rx_gain;
+ using core_iface::get_rx_gain_range;
+ using core_iface::set_rx_gain;
+};
+
+}}} // 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 6e1d31381..60666fd83 100644
--- a/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp
+++ b/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_dboard.hpp
@@ -22,6 +22,7 @@
#include <uhdlib/experts/expert_factory.hpp>
#include <uhdlib/rfnoc/rf_control/dboard_iface.hpp>
#include <uhdlib/rfnoc/rf_control/antenna_iface.hpp>
+#include <uhdlib/rfnoc/rf_control/nameless_gain_mixin.hpp>
#include <uhdlib/usrp/common/mpmd_mb_controller.hpp>
#include <uhdlib/usrp/common/pwr_cal_mgr.hpp>
#include <uhdlib/usrp/common/rpc.hpp>
@@ -43,7 +44,8 @@ const static uint16_t ZBX_PID = 0x4002;
*/
class zbx_dboard_impl :
public uhd::usrp::x400::x400_dboard_iface,
- public uhd::rfnoc::rf_control::antenna_radio_control_mixin
+ public uhd::rfnoc::rf_control::antenna_radio_control_mixin,
+ public uhd::rfnoc::rf_control::nameless_gain_mixin
{
public:
using sptr = std::shared_ptr<zbx_dboard_impl>;
@@ -140,28 +142,20 @@ public:
.get();
}
- double set_tx_gain(const double gain, const size_t chan) override;
+ using core_iface::set_tx_gain;
+ using core_iface::get_tx_gain;
+ using core_iface::set_rx_gain;
+ using core_iface::get_rx_gain;
+ using core_iface::get_tx_gain_range;
+ using core_iface::get_rx_gain_range;
+
double set_tx_gain(
const double gain, const std::string& name, const size_t chan) override;
- double set_rx_gain(const double gain, const size_t chan) override;
double set_rx_gain(
const double gain, const std::string& name, const size_t chan) override;
- double get_rx_gain(const size_t chan) override;
- double get_tx_gain(const size_t chan) override;
double get_rx_gain(const std::string& name, const size_t chan) override;
double get_tx_gain(const std::string& name, const size_t chan) override;
- uhd::gain_range_t get_tx_gain_range(const size_t /*chan*/) const override
- {
- return ZBX_TX_GAIN_RANGE;
- }
- uhd::gain_range_t get_rx_gain_range(const size_t /*chan*/) const override
- {
- // FIXME This should return a ZBX_RX_LOW_FREQ_GAIN_RANGE when freq is
- // low, but this function is const
- return ZBX_RX_GAIN_RANGE;
- }
-
// LO Property Getters
std::vector<std::string> get_tx_lo_names(const size_t /*chan*/) const override
{
diff --git a/host/lib/rfnoc/rf_control/CMakeLists.txt b/host/lib/rfnoc/rf_control/CMakeLists.txt
index f55c9a8a1..fd3ad6539 100644
--- a/host/lib/rfnoc/rf_control/CMakeLists.txt
+++ b/host/lib/rfnoc/rf_control/CMakeLists.txt
@@ -11,4 +11,5 @@
LIBUHD_APPEND_SOURCES(
${CMAKE_CURRENT_SOURCE_DIR}/antenna.cpp
${CMAKE_CURRENT_SOURCE_DIR}/gain_profile.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/nameless_gain_mixin.cpp
)
diff --git a/host/lib/rfnoc/rf_control/nameless_gain_mixin.cpp b/host/lib/rfnoc/rf_control/nameless_gain_mixin.cpp
new file mode 100644
index 000000000..d10d01efb
--- /dev/null
+++ b/host/lib/rfnoc/rf_control/nameless_gain_mixin.cpp
@@ -0,0 +1,56 @@
+//
+// Copyright 2021 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/property_tree.hpp>
+#include <uhdlib/rfnoc/rf_control/nameless_gain_mixin.hpp>
+#include <unordered_map>
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace uhd { namespace rfnoc { namespace rf_control {
+
+nameless_gain_mixin::nameless_gain_mixin(name_selector name_selector)
+ : _name_selector(name_selector)
+{
+}
+
+double nameless_gain_mixin::set_tx_gain(const double gain, const size_t chan)
+{
+ const auto name = _name_selector(TX_DIRECTION, chan);
+ return set_tx_gain(gain, name, chan);
+}
+
+double nameless_gain_mixin::get_tx_gain(const size_t chan)
+{
+ const auto name = _name_selector(TX_DIRECTION, chan);
+ return get_tx_gain(name, chan);
+}
+
+double nameless_gain_mixin::set_rx_gain(const double gain, const size_t chan)
+{
+ const auto name = _name_selector(RX_DIRECTION, chan);
+ return set_rx_gain(gain, name, chan);
+}
+
+double nameless_gain_mixin::get_rx_gain(const size_t chan)
+{
+ const auto name = _name_selector(RX_DIRECTION, chan);
+ return get_rx_gain(name, chan);
+}
+
+gain_range_t nameless_gain_mixin::get_tx_gain_range(const size_t chan) const
+{
+ return get_tx_gain_range("", chan);
+}
+
+gain_range_t nameless_gain_mixin::get_rx_gain_range(const size_t chan) const
+{
+ return get_rx_gain_range("", 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 2a01425b6..9efb7ec20 100644
--- a/host/lib/usrp/dboard/zbx/zbx_dboard.cpp
+++ b/host/lib/usrp/dboard/zbx/zbx_dboard.cpp
@@ -31,7 +31,22 @@ zbx_dboard_impl::zbx_dboard_impl(register_iface& reg_iface,
uhd::usrp::zbx_rpc_iface::sptr rpcc,
uhd::rfnoc::x400::rfdc_control::sptr rfdcc,
uhd::property_tree::sptr tree)
- : _unique_id(unique_id)
+ : nameless_gain_mixin([this](const uhd::direction_t trx, size_t chan) {
+ const auto gain_profile = trx == TX_DIRECTION ?
+ _tx_gain_profile_api->get_gain_profile(chan) :
+ _rx_gain_profile_api->get_gain_profile(chan);
+ if (gain_profile == ZBX_GAIN_PROFILE_MANUAL) {
+ const std::string err_msg = "When using 'manual' gain mode, a gain name is required!";
+ RFNOC_LOG_ERROR(err_msg);
+ throw uhd::runtime_error(err_msg);
+ }
+ if (gain_profile == ZBX_GAIN_PROFILE_CPLD
+ || gain_profile == ZBX_GAIN_PROFILE_CPLD_NOATR) {
+ return ZBX_GAIN_STAGE_TABLE;
+ }
+ return ZBX_GAIN_STAGE_ALL;
+ })
+ , _unique_id(unique_id)
, _regs(reg_iface)
, _reg_base_address(reg_base_address)
, _time_accessor(time_accessor)
@@ -263,66 +278,6 @@ double zbx_dboard_impl::set_rx_gain(
return _tree->access<double>(gains_path / name / "value").set(gain).get();
}
-double zbx_dboard_impl::set_tx_gain(const double gain, const size_t chan)
-{
- const auto gain_profile = _tx_gain_profile_api->get_gain_profile(chan);
- if (gain_profile == ZBX_GAIN_PROFILE_MANUAL) {
- const std::string err_msg = "When using 'manual' gain mode, calling "
- "set_tx_gain() without a gain name is not allowed!";
- RFNOC_LOG_ERROR(err_msg);
- throw uhd::runtime_error(err_msg);
- }
- if (gain_profile == ZBX_GAIN_PROFILE_CPLD
- || gain_profile == ZBX_GAIN_PROFILE_CPLD_NOATR) {
- return set_tx_gain(gain, ZBX_GAIN_STAGE_TABLE, chan);
- }
- return set_tx_gain(gain, ZBX_GAIN_STAGE_ALL, chan);
-}
-
-double zbx_dboard_impl::set_rx_gain(const double gain, const size_t chan)
-{
- const auto gain_profile = _rx_gain_profile_api->get_gain_profile(chan);
- if (gain_profile == ZBX_GAIN_PROFILE_MANUAL) {
- const std::string err_msg = "When using 'manual' gain mode, calling "
- "set_rx_gain() without a gain name is not allowed!";
- RFNOC_LOG_ERROR(err_msg);
- throw uhd::runtime_error(err_msg);
- }
- if (gain_profile == ZBX_GAIN_PROFILE_CPLD
- || gain_profile == ZBX_GAIN_PROFILE_CPLD_NOATR) {
- return set_rx_gain(gain, ZBX_GAIN_STAGE_TABLE, chan);
- }
- return set_rx_gain(gain, ZBX_GAIN_STAGE_ALL, chan);
-}
-
-double zbx_dboard_impl::get_tx_gain(const size_t chan)
-{
- const auto gain_profile = _tx_gain_profile_api->get_gain_profile(chan);
- if (gain_profile == ZBX_GAIN_PROFILE_CPLD
- || gain_profile == ZBX_GAIN_PROFILE_CPLD_NOATR) {
- return get_tx_gain(ZBX_GAIN_STAGE_TABLE, chan);
- }
- if (gain_profile == ZBX_GAIN_PROFILE_DEFAULT) {
- return get_tx_gain(ZBX_GAIN_STAGE_ALL, chan);
- }
- throw uhd::runtime_error(
- "get_tx_gain(): When in 'manual' gain profile, a gain name is required!");
-}
-
-double zbx_dboard_impl::get_rx_gain(const size_t chan)
-{
- const auto gain_profile = _rx_gain_profile_api->get_gain_profile(chan);
- if (gain_profile == ZBX_GAIN_PROFILE_CPLD
- || gain_profile == ZBX_GAIN_PROFILE_CPLD_NOATR) {
- return get_rx_gain(ZBX_GAIN_STAGE_TABLE, chan);
- }
- if (gain_profile == ZBX_GAIN_PROFILE_DEFAULT) {
- return get_rx_gain(ZBX_GAIN_STAGE_ALL, chan);
- }
- throw uhd::runtime_error(
- "get_rx_gain(): When in 'manual' gain profile, a gain name is required!");
-}
-
double zbx_dboard_impl::get_tx_gain(const std::string& name_, const size_t chan)
{
// We have to accept the empty string for "all", because that's widely used
@@ -608,7 +563,7 @@ void zbx_dboard_impl::set_rx_agc(const bool, const size_t)
}
uhd::gain_range_t zbx_dboard_impl::get_tx_gain_range(
- const std::string& name, const size_t chan) const
+ const std::string& name, const size_t) const
{
// We have to accept the empty string for "all", because that's widely used
// (e.g. by multi_usrp)
@@ -616,11 +571,11 @@ uhd::gain_range_t zbx_dboard_impl::get_tx_gain_range(
throw uhd::value_error(
std::string("get_tx_gain_range(): Unknown gain name '") + name + "'!");
}
- return get_tx_gain_range(chan);
+ return ZBX_TX_GAIN_RANGE;
}
uhd::gain_range_t zbx_dboard_impl::get_rx_gain_range(
- const std::string& name, const size_t chan) const
+ const std::string& name, const size_t) const
{
// We have to accept the empty string for "all", because that's widely used
// (e.g. by multi_usrp)
@@ -628,7 +583,10 @@ uhd::gain_range_t zbx_dboard_impl::get_rx_gain_range(
throw uhd::value_error(
std::string("get_rx_gain_range(): Unknown gain name '") + name + "'!");
}
- return get_rx_gain_range(chan);
+
+ // FIXME This should return a ZBX_RX_LOW_FREQ_GAIN_RANGE when freq is
+ // low, but this function is const
+ return ZBX_RX_GAIN_RANGE;
}
void zbx_dboard_impl::set_rx_lo_export_enabled(bool, const std::string&, const size_t)
diff --git a/host/lib/usrp/dboard/zbx/zbx_dboard_init.cpp b/host/lib/usrp/dboard/zbx/zbx_dboard_init.cpp
index f0558f8a4..6871080ff 100644
--- a/host/lib/usrp/dboard/zbx/zbx_dboard_init.cpp
+++ b/host/lib/usrp/dboard/zbx/zbx_dboard_init.cpp
@@ -245,8 +245,8 @@ uhd::usrp::pwr_cal_mgr::sptr zbx_dboard_impl::_init_power_cal(
: get_rx_gain(ZBX_GAIN_STAGE_ALL, chan_idx);
},
[this, trx, chan_idx](const double gain) {
- trx == TX_DIRECTION ? set_tx_gain(gain, chan_idx)
- : set_rx_gain(gain, chan_idx);
+ trx == TX_DIRECTION ? this->set_tx_gain(gain, chan_idx)
+ : this->set_rx_gain(gain, chan_idx);
}},
10 /* High priority */);
/* If we had a digital (baseband) gain, we would register it here,*/
diff --git a/host/tests/CMakeLists.txt b/host/tests/CMakeLists.txt
index b8c40ebeb..f170f26fe 100644
--- a/host/tests/CMakeLists.txt
+++ b/host/tests/CMakeLists.txt
@@ -382,6 +382,7 @@ IF(ENABLE_X400)
${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/rfnoc/rf_control/nameless_gain_mixin.cpp
${UHD_SOURCE_DIR}/lib/usrp/mpmd/mpmd_mb_controller.cpp
${UHD_SOURCE_DIR}/lib/usrp/dboard/zbx/zbx_dboard.cpp
${UHD_SOURCE_DIR}/lib/usrp/dboard/zbx/zbx_dboard_init.cpp