aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/multi_usrp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/multi_usrp.cpp')
-rw-r--r--host/lib/usrp/multi_usrp.cpp71
1 files changed, 66 insertions, 5 deletions
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index f08709669..71b1f8995 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -24,6 +24,7 @@
#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/usrp/dboard_eeprom.hpp>
+#include <uhd/convert.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
@@ -103,6 +104,8 @@ static meta_range_t make_overall_tune_range(
return range;
}
+
+
/***********************************************************************
* Gain helper functions
**********************************************************************/
@@ -589,6 +592,11 @@ public:
/*******************************************************************
* RX methods
******************************************************************/
+ rx_streamer::sptr get_rx_stream(const stream_args_t &args) {
+ _check_link_rate(args, false);
+ return this->get_device()->get_rx_stream(args);
+ }
+
void set_rx_subdev_spec(const subdev_spec_t &spec, size_t mboard){
if (mboard != ALL_MBOARDS){
_tree->access<subdev_spec_t>(mb_root(mboard) / "rx_subdev_spec").set(spec);
@@ -739,7 +747,11 @@ public:
void set_rx_dc_offset(const bool enb, size_t chan){
if (chan != ALL_CHANS){
- _tree->access<bool>(rx_fe_root(chan) / "dc_offset" / "enable").set(enb);
+ if (_tree->exists(rx_fe_root(chan) / "dc_offset" / "enable")) {
+ _tree->access<bool>(rx_fe_root(chan) / "dc_offset" / "enable").set(enb);
+ } else {
+ UHD_MSG(warning) << "Setting DC offset compensation is not possible on this device." << std::endl;
+ }
return;
}
for (size_t c = 0; c < get_rx_num_channels(); c++){
@@ -749,7 +761,11 @@ public:
void set_rx_dc_offset(const std::complex<double> &offset, size_t chan){
if (chan != ALL_CHANS){
- _tree->access<std::complex<double> >(rx_fe_root(chan) / "dc_offset" / "value").set(offset);
+ if (_tree->exists(rx_fe_root(chan) / "dc_offset" / "value")) {
+ _tree->access<std::complex<double> >(rx_fe_root(chan) / "dc_offset" / "value").set(offset);
+ } else {
+ UHD_MSG(warning) << "Setting DC offset is not possible on this device." << std::endl;
+ }
return;
}
for (size_t c = 0; c < get_rx_num_channels(); c++){
@@ -759,7 +775,11 @@ public:
void set_rx_iq_balance(const std::complex<double> &offset, size_t chan){
if (chan != ALL_CHANS){
- _tree->access<std::complex<double> >(rx_fe_root(chan) / "iq_balance" / "value").set(offset);
+ if (_tree->exists(rx_fe_root(chan) / "iq_balance" / "value")) {
+ _tree->access<std::complex<double> >(rx_fe_root(chan) / "iq_balance" / "value").set(offset);
+ } else {
+ UHD_MSG(warning) << "Setting IQ balance is not possible on this device." << std::endl;
+ }
return;
}
for (size_t c = 0; c < get_rx_num_channels(); c++){
@@ -770,6 +790,11 @@ public:
/*******************************************************************
* TX methods
******************************************************************/
+ tx_streamer::sptr get_tx_stream(const stream_args_t &args) {
+ _check_link_rate(args, true);
+ return this->get_device()->get_tx_stream(args);
+ }
+
void set_tx_subdev_spec(const subdev_spec_t &spec, size_t mboard){
if (mboard != ALL_MBOARDS){
_tree->access<subdev_spec_t>(mb_root(mboard) / "tx_subdev_spec").set(spec);
@@ -920,7 +945,11 @@ public:
void set_tx_dc_offset(const std::complex<double> &offset, size_t chan){
if (chan != ALL_CHANS){
- _tree->access<std::complex<double> >(tx_fe_root(chan) / "dc_offset" / "value").set(offset);
+ if (_tree->exists(tx_fe_root(chan) / "dc_offset" / "value")) {
+ _tree->access<std::complex<double> >(tx_fe_root(chan) / "dc_offset" / "value").set(offset);
+ } else {
+ UHD_MSG(warning) << "Setting DC offset is not possible on this device." << std::endl;
+ }
return;
}
for (size_t c = 0; c < get_tx_num_channels(); c++){
@@ -930,7 +959,11 @@ public:
void set_tx_iq_balance(const std::complex<double> &offset, size_t chan){
if (chan != ALL_CHANS){
- _tree->access<std::complex<double> >(tx_fe_root(chan) / "iq_balance" / "value").set(offset);
+ if (_tree->exists(tx_fe_root(chan) / "iq_balance" / "value")) {
+ _tree->access<std::complex<double> >(tx_fe_root(chan) / "iq_balance" / "value").set(offset);
+ } else {
+ UHD_MSG(warning) << "Setting IQ balance is not possible on this device." << std::endl;
+ }
return;
}
for (size_t c = 0; c < get_tx_num_channels(); c++){
@@ -1178,6 +1211,34 @@ private:
}
return gg;
}
+
+ //! \param is_tx True for tx
+ // Assumption is that all mboards use the same link
+ bool _check_link_rate(const stream_args_t &args, bool is_tx) {
+ bool link_rate_is_ok = true;
+ size_t bytes_per_sample = convert::get_bytes_per_item(args.otw_format.empty() ? "sc16" : args.otw_format);
+ double max_link_rate = 0;
+ double sum_rate = 0;
+ BOOST_FOREACH(const size_t chan, args.channels) {
+ mboard_chan_pair mcp = is_tx ? tx_chan_to_mcp(chan) : rx_chan_to_mcp(chan);
+ if (_tree->exists(mb_root(mcp.mboard) / "link_max_rate")) {
+ max_link_rate = std::max(
+ max_link_rate,
+ _tree->access<double>(mb_root(mcp.mboard) / "link_max_rate").get()
+ );
+ }
+ sum_rate += is_tx ? get_tx_rate(chan) : get_rx_rate(chan);
+ }
+ if (max_link_rate > 0 and (max_link_rate / bytes_per_sample) < sum_rate) {
+ UHD_MSG(warning) << boost::format(
+ "The total sum of rates (%f MSps on %u channels) exceeds the maximum capacity of the connection.\n"
+ "This can cause %s."
+ ) % (sum_rate/1e6) % args.channels.size() % (is_tx ? "underruns (U)" : "overflows (O)") << std::endl;
+ link_rate_is_ok = false;
+ }
+
+ return link_rate_is_ok;
+ }
};
/***********************************************************************