aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/docs/devices.dox1
-rw-r--r--host/docs/power.dox154
-rw-r--r--host/include/uhd/rfnoc/radio_control.hpp99
-rw-r--r--host/include/uhd/usrp/multi_usrp.hpp106
-rw-r--r--host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp6
-rw-r--r--host/lib/rfnoc/radio_control_impl.cpp36
-rw-r--r--host/lib/usrp/multi_usrp.cpp56
-rw-r--r--host/lib/usrp/multi_usrp_python.hpp6
-rw-r--r--host/lib/usrp/multi_usrp_rfnoc.cpp36
9 files changed, 500 insertions, 0 deletions
diff --git a/host/docs/devices.dox b/host/docs/devices.dox
index 5deb39f3c..dbe860382 100644
--- a/host/docs/devices.dox
+++ b/host/docs/devices.dox
@@ -14,6 +14,7 @@
\li \subpage page_dpdk
\li \subpage page_configfiles
\li \subpage page_compat
+\li \subpage page_power
## USRP N-Series Devices
diff --git a/host/docs/power.dox b/host/docs/power.dox
new file mode 100644
index 000000000..816c74824
--- /dev/null
+++ b/host/docs/power.dox
@@ -0,0 +1,154 @@
+/*! \page page_power Power Level Controls
+
+\tableofcontents
+
+\section power_overview
+
+Starting with UHD 4, UHD comes with reference power level APIs. These allow to
+not just set a relative gain level, but configure a USRP to transmit a certain
+power, or to estimate received power levels.
+
+The actual transmitted or received power also depends on the transmitted signal
+itself. The absolute power setting is thus a *reference power level*.
+The reference power level maps a digital signal level (in dBFS) to an absolute,
+analog power level (in dBm). The power level setting is the analog power level
+that corresponds to a 0 dBFS digital signal.
+
+Note that most USRPs do not support setting reference power levels. Refer to the
+individual device manual pages for more information.
+
+\section power_ref_levels RX and TX reference power levels
+
+<b>RX reference power level:</b>
+
+The RX reference power level is defined as such: When a signal with this power
+level is applied to the RF input, the digital signal will be at a 0 dBFS power
+level.
+
+If a tone with this power level is applied to the RF input, it will be
+full-scale in the digital representation.
+
+Example: The reference power level is set to -4 dBm by calling
+~~~{.cpp}
+U->set_rx_power_reference(-4.0, 0);
+~~~
+
+Then, a signal is captured. It turns out the signal is a sine wave with
+an amplitude of 0.5, which means its power is 6 dB lower than a signal
+with an amplitude of 1.0 (or -6 dBFS). Based on the reference power level, we
+can thus infer that the tone injected into the RF port is:
+
+ (-4 dBm - 6 dB) = -10 dBm
+
+<b>TX reference power level:</b>
+
+The TX reference power level is defined as such: When a 0 dBFS signal is
+transmitted, it will leave the RF output at the selected reference power level.
+In other contexts, this value is sometimes referred to as "peak power level",
+because it's the maximum power that can be transmitted.
+
+If a fullscale tone is transmitted, the transmitted analog tone will have the
+reference power level.
+
+Example: The reference power level is set to -4 dBm by calling
+~~~{.cpp}
+U->set_tx_power_reference(-4.0, 0);
+~~~
+
+Then, we generate a tone that is a sine wave with amplitude 0.5 and
+transmit it using this device and channel. With this amplitude, the
+signal is 6 dB lower in power than a sine wave with amplitude 1.0.
+Based on the reference power level, we can thus infer that the tone
+leaving the RF port has the following absolute power:
+
+ (-4 dBm - 6 dB) = -10 dBm
+
+\section power_amp_rate Amplitude Ranges and Clipping
+
+In practice, it is never possible to cleanly transmit or receive a signal at
+0 dBFS, so the reference levels need to be appropriately normalized. Because
+all USRPs have a different amplitude range they can transmit/receive before
+clipping or distortion occurs, the APIs are designed to be agnostic of the
+hardware. The derivation of the actual analog power is thus the responsibility
+of the application (i.e., the code that also calls `recv()` and `send()`), which has
+access to the sample values. UHD itself doesn't inspect the sample values for
+performance reasons, and thus can only manage reference levels.
+
+\section power_tune_owner Retaining gain or power levels across frequency
+
+When tuning a USRP (i.e., changing its frequency) it may be necessary to also
+adjust gain stages. Due to physical limitations, the same output power is not
+always available (or possible) at different frequencies. This means that the
+output power may vary when retuning. The relative gain range is usually the same
+across frequencies, though.
+
+UHD will try to maintain the relative gain setting, or the power level setting.
+The choice is determined by which API was called last. If the gain level was set
+last (i.e., by either calling `set_tx_gain()` or `set_rx_gain()`), then the gain
+level will be kept constant after retuning, but the power level will likely have
+changed. If the power reference level was set last (by either calling
+`set_rx_power_reference()` or `set_tx_power_reference()`), then UHD will attempt
+to maintain a constant power reference level, which means UHD will likely have
+to modify the relative gain values. To get the exact power level after a retune,
+read back the current power reference level (`get_rx_power_reference()` or
+`get_tx_power_reference()`).
+
+The following example shows how the APIs behave for reception. For transmission,
+the behaviour is the same (just replace 'rx' with 'tx' in the API calls). Note
+that the determination of relative gain or power is retained over retunes is
+independent for TX and RX.
+
+~~~{.cpp}
+// usrp is a multi_usrp object, f0 and f1 are valid frequencies
+usrp->set_rx_frequency(f0);
+usrp->set_rx_gain(10);
+// This should print '10', or the closest coerced value:
+std::cout << usrp->get_rx_gain() << std::endl;
+// This can print anything, depending on device and calibration data:
+std::cout << usrp->get_rx_power_reference() << std::endl;
+usrp->set_rx_frequency(f1);
+// This should still print '10', or the closest coerced value:
+std::cout << usrp->get_rx_gain() << std::endl;
+// This can print anything, and possibly not the same value as before
+std::cout << usrp->get_rx_power_reference() << std::endl;
+usrp->set_rx_power_reference(-20);
+// This should print -20, assuming the device can transmit at that power:
+std::cout << usrp->get_rx_power_reference() << std::endl;
+// This will print the current gain value, whatever that is
+std::cout << usrp->get_rx_gain() << std::endl;
+usrp->set_rx_frequency(f0);
+// This should still print -20, or the closest coerced value
+std::cout << usrp->get_rx_power_reference() << std::endl;
+// This will print the current gain value, possibly not the same as before
+std::cout << usrp->get_rx_gain() << std::endl;
+~~~
+
+\section power_implementation Device Implementations of Power Level APIs
+
+Under the hood, this API call will affect any gain stage that it needs to
+affect. It is possible to read back the current gain settings by calling
+`get_tx_gain()` or `get_rx_gain()`. However, changing the gain settings by calling
+`set_tx_gain()` or `set_rx_gain()` will cause the power level to change.
+
+The specific implementation of this API is very device-specific. Refer to the
+individual USRP manual pages for more details.
+
+\section power_storage Calibration Table Storage
+
+UHD needs to store calibration tables to be able to map reference power levels
+to settings for the individual gain stages of each USRP and/or daughterboard.
+These tables can be stored in three different ways:
+
+- Hard-coded as part of UHD. If a gain table is hard-coded as part of UHD, it
+ means that the gain table is considered an average table for a given device.
+ Its accuracy may vary a lot, as it is not calibrated to a specific device
+ and/or environment.
+- In the device EEPROM. By storing calibration data in an EEPROM on the device,
+ it is possible to use the same calibration data even when using different host
+ computers. Calibration data in EEPROMs can also be updated to account for
+ different environments, aging of components, or anything else.
+- On a file. Calibration data in a file is the most flexible, it can be replaced
+ easily. It is however local to the computer that stores the calibration data.
+
+*/
+// vim:ft=doxygen:
diff --git a/host/include/uhd/rfnoc/radio_control.hpp b/host/include/uhd/rfnoc/radio_control.hpp
index 9d343cdac..96c3e1bbe 100644
--- a/host/include/uhd/rfnoc/radio_control.hpp
+++ b/host/include/uhd/rfnoc/radio_control.hpp
@@ -189,6 +189,56 @@ public:
virtual double set_tx_gain(
const double gain, const std::string& name, const size_t chan) = 0;
+ /*! Return true if this channel has a reference power API enabled
+ *
+ * Many devices either don't have a built-in reference power API, or they
+ * require calibration data for it to work. This means that it is not clear,
+ * even when the device type is known, if a device supports setting a power
+ * reference level. Use this method to query the availability of
+ * set_tx_power_reference() and get_tx_power_reference(), which will throw
+ * a uhd::not_implemented_error or uhd::runtime_error if they cannot be used.
+ *
+ * See \ref page_power for more information, or query the specific device's
+ * manual page to see if a power API is available, and how to enable it.
+ *
+ * \param chan The channel for which this feature is queried
+ *
+ * \returns true if this channel has a TX power API available
+ */
+ virtual bool has_tx_power_reference(const size_t chan = 0) = 0;
+
+ /*! Set the reference TX power level for a given channel
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param power_dbm The reference power level in dBm
+ * \param chan The channel for which this setting applies
+ *
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual void set_tx_power_reference(
+ const double power_dbm, const size_t chan = 0) = 0;
+
+ /*! Return the actual reference TX power level.
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param chan The channel for which this setting is queried
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual double get_tx_power_reference(const size_t chan = 0) = 0;
+
+
/*! Return a list of valid RX gain names
*/
virtual std::vector<std::string> get_rx_gain_names(const size_t chan) const = 0;
@@ -239,6 +289,55 @@ public:
*/
virtual void set_rx_agc(const bool enable, const size_t chan) = 0;
+ /*! Return true if this channel has a reference power API enabled
+ *
+ * Many devices either don't have a built-in reference power API, or they
+ * require calibration data for it to work. This means that it is not clear,
+ * even when the device type is known, if a device supports setting a power
+ * reference level. Use this method to query the availability of
+ * set_rx_power_reference() and get_rx_power_reference(), which will throw
+ * a uhd::not_implemented_error or uhd::runtime_error if they cannot be used.
+ *
+ * See \ref page_power for more information, or query the specific device's
+ * manual page to see if a power API is available, and how to enable it.
+ *
+ * \param chan The channel for which this feature is queried
+ *
+ * \returns true if this channel has an RX power API available
+ */
+ virtual bool has_rx_power_reference(const size_t chan = 0) = 0;
+
+ /*! Set the reference RX power level for a given channel
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param power_dbm The reference power level in dBm
+ * \param chan The channel for which this setting applies
+ *
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual void set_rx_power_reference(
+ const double power_dbm, const size_t chan = 0) = 0;
+
+ /*! Return the actual reference RX power level.
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param chan The channel for which this setting is queried
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual double get_rx_power_reference(const size_t chan = 0) = 0;
+
/*! Return a list of TX gain profiles for this radio
*/
virtual std::vector<std::string> get_tx_gain_profile_names(
diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp
index 53e63361f..e177e7cf7 100644
--- a/host/include/uhd/usrp/multi_usrp.hpp
+++ b/host/include/uhd/usrp/multi_usrp.hpp
@@ -22,6 +22,7 @@
#define UHD_USRP_MULTI_USRP_FILTER_API
#define UHD_USRP_MULTI_USRP_LO_CONFIG_API
#define UHD_USRP_MULTI_USRP_TX_LO_CONFIG_API
+#define UHD_USRP_MULTI_USRP_POWER_LEVEL
#include <uhd/config.hpp>
#include <uhd/device.hpp>
@@ -1176,6 +1177,59 @@ public:
virtual void set_rx_iq_balance(
const std::complex<double>& correction, size_t chan = ALL_CHANS) = 0;
+
+ /**************************************************************************
+ * Power level controls
+ *************************************************************************/
+ /*! Return true if this channel has a reference power API enabled
+ *
+ * Many devices either don't have a built-in reference power API, or they
+ * require calibration data for it to work. This means that it is not clear,
+ * even when the device type is known, if a device supports setting a power
+ * reference level. Use this method to query the availability of
+ * set_rx_power_reference() and get_rx_power_reference(), which will throw
+ * a uhd::not_implemented_error or uhd::runtime_error if they cannot be used.
+ *
+ * See \ref page_power for more information, or query the specific device's
+ * manual page to see if a power API is available, and how to enable it.
+ *
+ * \param chan The channel for which this feature is queried
+ *
+ * \returns true if this channel has an RX power API available
+ */
+ virtual bool has_rx_power_reference(const size_t chan = 0) = 0;
+
+ /*! Set the reference RX power level for a given channel
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param power_dbm The reference power level in dBm
+ * \param chan The channel for which this setting applies
+ *
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual void set_rx_power_reference(
+ const double power_dbm, const size_t chan = 0) = 0;
+
+ /*! Return the actual reference RX power level.
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param chan The channel for which this setting is queried
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual double get_rx_power_reference(const size_t chan = 0) = 0;
+
/*******************************************************************
* TX methods
******************************************************************/
@@ -1372,6 +1426,58 @@ public:
*/
virtual std::vector<std::string> get_tx_gain_names(size_t chan = 0) = 0;
+ /**************************************************************************
+ * Power level controls
+ *************************************************************************/
+ /*! Return true if this channel has a reference power API enabled
+ *
+ * Many devices either don't have a built-in reference power API, or they
+ * require calibration data for it to work. This means that it is not clear,
+ * even when the device type is known, if a device supports setting a power
+ * reference level. Use this method to query the availability of
+ * set_tx_power_reference() and get_tx_power_reference(), which will throw
+ * a uhd::not_implemented_error or uhd::runtime_error if they cannot be used.
+ *
+ * See \ref page_power for more information, or query the specific device's
+ * manual page to see if a power API is available, and how to enable it.
+ *
+ * \param chan The channel for which this feature is queried
+ *
+ * \returns true if this channel has a TX power API available
+ */
+ virtual bool has_tx_power_reference(const size_t chan = 0) = 0;
+
+ /*! Set the reference TX power level for a given channel
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param power_dbm The reference power level in dBm
+ * \param chan The channel for which this setting applies
+ *
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual void set_tx_power_reference(
+ const double power_dbm, const size_t chan = 0) = 0;
+
+ /*! Return the actual reference TX power level.
+ *
+ * Note: This functionality is not supported for most devices, and will
+ * cause a uhd::not_implemented_error exception to be thrown on devices that
+ * do not have this functionality.
+ *
+ * For more information on how to use this API, see \ref page_power.
+ *
+ * \param chan The channel for which this setting is queried
+ * \throws uhd::not_implemented_error if this functionality does not exist
+ * for this device
+ */
+ virtual double get_tx_power_reference(const size_t chan = 0) = 0;
+
/*!
* Select the TX antenna on the frontend.
* \param ant the antenna name
diff --git a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp
index c3a6bd507..4916ecf6f 100644
--- a/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp
+++ b/host/lib/include/uhdlib/rfnoc/radio_control_impl.hpp
@@ -72,6 +72,8 @@ public:
virtual double set_rx_bandwidth(const double bandwidth, const size_t chan);
virtual void set_tx_gain_profile(const std::string& profile, const size_t chan);
virtual void set_rx_gain_profile(const std::string& profile, const size_t chan);
+ virtual void set_rx_power_reference(const double power_dbm, const size_t chan);
+ virtual void set_tx_power_reference(const double power_dbm, const size_t chan);
// Getters
virtual std::string get_tx_antenna(const size_t chan) const;
@@ -100,6 +102,10 @@ public:
virtual double get_rx_bandwidth(const size_t);
virtual meta_range_t get_tx_bandwidth_range(size_t chan) const;
virtual meta_range_t get_rx_bandwidth_range(size_t chan) const;
+ virtual bool has_rx_power_reference(const size_t chan);
+ virtual bool has_tx_power_reference(const size_t chan);
+ virtual double get_rx_power_reference(const size_t chan);
+ virtual double get_tx_power_reference(const size_t chan);
/**************************************************************************
* LO Controls
diff --git a/host/lib/rfnoc/radio_control_impl.cpp b/host/lib/rfnoc/radio_control_impl.cpp
index 4f1246e5c..e34a9b430 100644
--- a/host/lib/rfnoc/radio_control_impl.cpp
+++ b/host/lib/rfnoc/radio_control_impl.cpp
@@ -404,6 +404,28 @@ double radio_control_impl::set_rx_gain(
return set_rx_gain(gain, chan);
}
+bool radio_control_impl::has_rx_power_reference(const size_t)
+{
+ return false;
+}
+
+bool radio_control_impl::has_tx_power_reference(const size_t)
+{
+ return false;
+}
+
+void radio_control_impl::set_rx_power_reference(const double, const size_t)
+{
+ throw uhd::not_implemented_error(
+ "set_rx_power_reference() is not supported on this radio!");
+}
+
+void radio_control_impl::set_tx_power_reference(const double, const size_t)
+{
+ throw uhd::not_implemented_error(
+ "set_tx_power_reference() is not supported on this radio!");
+}
+
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!");
@@ -575,6 +597,20 @@ uhd::meta_range_t radio_control_impl::get_rx_bandwidth_range(size_t chan) const
return result;
}
+double radio_control_impl::get_rx_power_reference(const size_t)
+{
+ throw uhd::not_implemented_error(
+ "get_rx_power_reference() is not supported on this radio!");
+ return 0.0;
+}
+
+double radio_control_impl::get_tx_power_reference(const size_t)
+{
+ throw uhd::not_implemented_error(
+ "get_tx_power_reference() is not supported on this radio!");
+ return 0.0;
+}
+
/******************************************************************************
* LO Default API
*****************************************************************************/
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index c91f596cd..0392d4df9 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -1718,6 +1718,34 @@ public:
return rx_gain_group(chan)->get_names();
}
+ /**************************************************************************
+ * RX Power control
+ *************************************************************************/
+ bool has_rx_power_reference(const size_t chan)
+ {
+ return _tree->exists(rx_rf_fe_root(chan) / "ref_power/value");
+ }
+
+ void set_rx_power_reference(const double power_dbm, const size_t chan = 0)
+ {
+ const auto power_ref_path = rx_rf_fe_root(chan) / "ref_power/value";
+ if (!_tree->exists(power_ref_path)) {
+ throw uhd::not_implemented_error(
+ "set_rx_power_reference() not available for this device and channel");
+ }
+ _tree->access<double>(power_ref_path).set(power_dbm);
+ }
+
+ double get_rx_power_reference(const size_t chan = 0)
+ {
+ const auto power_ref_path = rx_rf_fe_root(chan) / "ref_power/value";
+ if (!_tree->exists(power_ref_path)) {
+ throw uhd::not_implemented_error(
+ "get_rx_power_reference() not available for this device and channel");
+ }
+ return _tree->access<double>(power_ref_path).get();
+ }
+
void set_rx_antenna(const std::string& ant, size_t chan)
{
_tree->access<std::string>(rx_rf_fe_root(chan) / "antenna" / "value").set(ant);
@@ -2194,6 +2222,34 @@ public:
return tx_gain_group(chan)->get_names();
}
+ /**************************************************************************
+ * TX Power Controls
+ *************************************************************************/
+ bool has_tx_power_reference(const size_t chan)
+ {
+ return _tree->exists(tx_rf_fe_root(chan) / "ref_power/value");
+ }
+
+ void set_tx_power_reference(const double power_dbm, const size_t chan = 0)
+ {
+ const auto power_ref_path = tx_rf_fe_root(chan) / "ref_power/value";
+ if (!_tree->exists(power_ref_path)) {
+ throw uhd::not_implemented_error(
+ "set_tx_power_reference() not available for this device and channel");
+ }
+ _tree->access<double>(power_ref_path).set(power_dbm);
+ }
+
+ double get_tx_power_reference(const size_t chan = 0)
+ {
+ const auto power_ref_path = tx_rf_fe_root(chan) / "ref_power/value";
+ if (!_tree->exists(power_ref_path)) {
+ throw uhd::not_implemented_error(
+ "get_tx_power_reference() not available for this device and channel");
+ }
+ return _tree->access<double>(power_ref_path).get();
+ }
+
void set_tx_antenna(const std::string& ant, size_t chan)
{
_tree->access<std::string>(tx_rf_fe_root(chan) / "antenna" / "value").set(ant);
diff --git a/host/lib/usrp/multi_usrp_python.hpp b/host/lib/usrp/multi_usrp_python.hpp
index f4e0a73e1..62f34ffa2 100644
--- a/host/lib/usrp/multi_usrp_python.hpp
+++ b/host/lib/usrp/multi_usrp_python.hpp
@@ -19,6 +19,7 @@ void export_multi_usrp(py::module& m)
const auto ALL_CHANS = multi_usrp::ALL_CHANS;
const auto ALL_LOS = multi_usrp::ALL_LOS;
+ // clang-format off
py::class_<multi_usrp, multi_usrp::sptr>(m, "multi_usrp")
// Factory
@@ -125,6 +126,8 @@ void export_multi_usrp(py::module& m)
.def("get_rx_gain_profile" , &multi_usrp::get_rx_gain_profile, py::arg("chan") = 0)
.def("set_rx_gain_profile" , &multi_usrp::set_rx_gain_profile, py::arg("profile"), py::arg("chan") = 0)
.def("get_rx_gain_profile_names", &multi_usrp::get_rx_gain_profile_names, py::arg("chan") = 0)
+ .def("set_rx_power_reference" , &multi_usrp::set_rx_power_reference, py::arg("power_dbm"), py::arg("chan") = 0)
+ .def("get_rx_power_reference" , &multi_usrp::get_rx_power_reference, py::arg("chan") = 0)
// TX methods
.def("set_tx_subdev_spec" , &multi_usrp::set_tx_subdev_spec, py::arg("spec"), py::arg("mboard") = ALL_MBOARDS)
@@ -163,6 +166,8 @@ void export_multi_usrp(py::module& m)
.def("get_tx_gain_profile" , &multi_usrp::get_tx_gain_profile, py::arg("chan") = 0)
.def("set_tx_gain_profile" , &multi_usrp::set_tx_gain_profile, py::arg("profile"), py::arg("chan") = 0)
.def("get_tx_gain_profile_names", &multi_usrp::get_tx_gain_profile_names, py::arg("chan") = 0)
+ .def("set_tx_power_reference" , &multi_usrp::set_tx_power_reference, py::arg("power_dbm"), py::arg("chan") = 0)
+ .def("get_tx_power_reference" , &multi_usrp::get_tx_power_reference, py::arg("chan") = 0)
// GPIO methods
.def("get_gpio_banks" , &multi_usrp::get_gpio_banks)
@@ -182,6 +187,7 @@ void export_multi_usrp(py::module& m)
.def("set_tx_filter" , &multi_usrp::set_tx_filter)
// clang-format off
;
+ // clang-format on
}
#endif /* INCLUDED_UHD_USRP_MULTI_USRP_PYTHON_HPP */
diff --git a/host/lib/usrp/multi_usrp_rfnoc.cpp b/host/lib/usrp/multi_usrp_rfnoc.cpp
index 14b5fd50b..a62fe3f8e 100644
--- a/host/lib/usrp/multi_usrp_rfnoc.cpp
+++ b/host/lib/usrp/multi_usrp_rfnoc.cpp
@@ -1396,6 +1396,24 @@ public:
return rx_chain.radio->get_rx_gain_names(rx_chain.block_chan);
}
+ bool has_rx_power_reference(const size_t chan)
+ {
+ auto& rx_chain = _get_rx_chan(chan);
+ return rx_chain.radio->has_rx_power_reference(rx_chain.block_chan);
+ }
+
+ void set_rx_power_reference(const double power_dbm, const size_t chan)
+ {
+ auto& rx_chain = _get_rx_chan(chan);
+ rx_chain.radio->set_rx_power_reference(power_dbm, rx_chain.block_chan);
+ }
+
+ double get_rx_power_reference(const size_t chan)
+ {
+ auto& rx_chain = _get_rx_chan(chan);
+ return rx_chain.radio->get_rx_power_reference(rx_chain.block_chan);
+ }
+
void set_rx_antenna(const std::string& ant, size_t chan)
{
auto& rx_chain = _get_rx_chan(chan);
@@ -1836,6 +1854,24 @@ public:
return tx_chain.radio->get_tx_gain_names(tx_chain.block_chan);
}
+ bool has_tx_power_reference(const size_t chan)
+ {
+ auto& tx_chain = _get_tx_chan(chan);
+ return tx_chain.radio->has_rx_power_reference(tx_chain.block_chan);
+ }
+
+ void set_tx_power_reference(const double power_dbm, const size_t chan)
+ {
+ auto& tx_chain = _get_tx_chan(chan);
+ tx_chain.radio->set_tx_power_reference(power_dbm, tx_chain.block_chan);
+ }
+
+ double get_tx_power_reference(const size_t chan)
+ {
+ auto& tx_chain = _get_tx_chan(chan);
+ return tx_chain.radio->get_tx_power_reference(tx_chain.block_chan);
+ }
+
void set_tx_antenna(const std::string& ant, size_t chan)
{
auto tx_chain = _get_tx_chan(chan);