aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-08-05 16:27:16 -0700
committerJosh Blum <josh@joshknows.com>2010-08-06 12:15:05 -0700
commita333a01ac0d1d0cb011d52f04bed2534a708f944 (patch)
tree602ca754d0a549d32e7900c03f5e38e8bbb4f46a
parent53341c286eb71ead76ff11796ab67bd98f73c3ab (diff)
downloaduhd-a333a01ac0d1d0cb011d52f04bed2534a708f944.tar.gz
uhd-a333a01ac0d1d0cb011d52f04bed2534a708f944.tar.bz2
uhd-a333a01ac0d1d0cb011d52f04bed2534a708f944.zip
uhd: implemented subdev spec in mimo and simple usrp wrappers.
implemented subdev spec in usrp2 mboard impl removed subdevs used in dboard impl
-rw-r--r--host/include/uhd/usrp/dboard_props.hpp1
-rw-r--r--host/include/uhd/usrp/mboard_props.hpp2
-rw-r--r--host/include/uhd/usrp/mimo_usrp.hpp5
-rw-r--r--host/include/uhd/usrp/simple_usrp.hpp5
-rw-r--r--host/lib/usrp/mimo_usrp.cpp169
-rw-r--r--host/lib/usrp/simple_usrp.cpp131
-rw-r--r--host/lib/usrp/usrp2/dboard_impl.cpp32
-rw-r--r--host/lib/usrp/usrp2/mboard_impl.cpp46
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp4
9 files changed, 223 insertions, 172 deletions
diff --git a/host/include/uhd/usrp/dboard_props.hpp b/host/include/uhd/usrp/dboard_props.hpp
index 4d5c5efbd..8a6ef9129 100644
--- a/host/include/uhd/usrp/dboard_props.hpp
+++ b/host/include/uhd/usrp/dboard_props.hpp
@@ -29,7 +29,6 @@ namespace uhd{ namespace usrp{
DBOARD_PROP_NAME = 'n', //ro, std::string
DBOARD_PROP_SUBDEV = 's', //ro, wax::obj
DBOARD_PROP_SUBDEV_NAMES = 'S', //ro, prop_names_t
- DBOARD_PROP_USED_SUBDEVS = 'u', //ro, prop_names_t
DBOARD_PROP_DBOARD_ID = 'i', //rw, dboard_id_t
DBOARD_PROP_DBOARD_IFACE = 'f' //ro, dboard_iface::sptr
//DBOARD_PROP_CODEC //ro, wax::obj //----> not sure, dont have to deal with yet
diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp
index a432ce50c..0f250f439 100644
--- a/host/include/uhd/usrp/mboard_props.hpp
+++ b/host/include/uhd/usrp/mboard_props.hpp
@@ -39,6 +39,8 @@ namespace uhd{ namespace usrp{
MBOARD_PROP_RX_DBOARD_NAMES = 'E', //ro, prop_names_t
MBOARD_PROP_TX_DBOARD = 'v', //ro, wax::obj
MBOARD_PROP_TX_DBOARD_NAMES = 'V', //ro, prop_names_t
+ MBOARD_PROP_RX_SUBDEV_SPEC = 'r', //rw, subdev_spec_t
+ MBOARD_PROP_TX_SUBDEV_SPEC = 'R', //rw, subdev_spec_t
MBOARD_PROP_CLOCK_CONFIG = 'C', //rw, clock_config_t
MBOARD_PROP_TIME_NOW = 't', //rw, time_spec_t
MBOARD_PROP_TIME_NEXT_PPS = 'T', //wo, time_spec_t
diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp
index fd0f4596f..9856f9d32 100644
--- a/host/include/uhd/usrp/mimo_usrp.hpp
+++ b/host/include/uhd/usrp/mimo_usrp.hpp
@@ -24,6 +24,7 @@
#include <uhd/types/stream_cmd.hpp>
#include <uhd/types/clock_config.hpp>
#include <uhd/types/tune_result.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <vector>
@@ -119,6 +120,8 @@ public:
/*******************************************************************
* RX methods
******************************************************************/
+ virtual void set_rx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0;
+
virtual void set_rx_rate_all(double rate) = 0;
virtual double get_rx_rate_all(void) = 0;
@@ -148,6 +151,8 @@ public:
/*******************************************************************
* TX methods
******************************************************************/
+ virtual void set_tx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0;
+
virtual void set_tx_rate_all(double rate) = 0;
virtual double get_tx_rate_all(void) = 0;
diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp
index a100579ce..a6275cfcc 100644
--- a/host/include/uhd/usrp/simple_usrp.hpp
+++ b/host/include/uhd/usrp/simple_usrp.hpp
@@ -24,6 +24,7 @@
#include <uhd/types/stream_cmd.hpp>
#include <uhd/types/clock_config.hpp>
#include <uhd/types/tune_result.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
#include <vector>
@@ -107,6 +108,8 @@ public:
/*******************************************************************
* RX methods
******************************************************************/
+ virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0;
+
virtual void set_rx_rate(double rate) = 0;
virtual double get_rx_rate(void) = 0;
@@ -135,6 +138,8 @@ public:
/*******************************************************************
* TX methods
******************************************************************/
+ virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0;
+
virtual void set_tx_rate(double rate) = 0;
virtual double get_tx_rate(void) = 0;
diff --git a/host/lib/usrp/mimo_usrp.cpp b/host/lib/usrp/mimo_usrp.cpp
index ec0f1dcc8..5fb3571ec 100644
--- a/host/lib/usrp/mimo_usrp.cpp
+++ b/host/lib/usrp/mimo_usrp.cpp
@@ -19,6 +19,7 @@
#include <uhd/usrp/tune_helper.hpp>
#include <uhd/utils/assert.hpp>
#include <uhd/utils/algorithm.hpp>
+#include <uhd/utils/warning.hpp>
#include <uhd/usrp/subdev_props.hpp>
#include <uhd/usrp/mboard_props.hpp>
#include <uhd/usrp/device_props.hpp>
@@ -46,29 +47,12 @@ public:
mimo_usrp_impl(const device_addr_t &addr){
_dev = device::make(addr);
- //extract each mboard and its sub-devices
- BOOST_FOREACH(const std::string &name, (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>()){
- _mboards.push_back((*_dev)[named_prop_t(DEVICE_PROP_MBOARD, name)]);
- _rx_dsps.push_back(_mboards.back()[MBOARD_PROP_RX_DSP]);
- _tx_dsps.push_back(_mboards.back()[MBOARD_PROP_TX_DSP]);
-
- //extract rx subdevice
- _rx_dboards.push_back(_mboards.back()[MBOARD_PROP_RX_DBOARD]);
- std::string rx_subdev_in_use = _rx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _rx_subdevs.push_back(_rx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, rx_subdev_in_use)]);
-
- //extract tx subdevice
- _tx_dboards.push_back(_mboards.back()[MBOARD_PROP_TX_DBOARD]);
- std::string tx_subdev_in_use = _tx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _tx_subdevs.push_back(_tx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, tx_subdev_in_use)]);
- }
-
//set the clock config across all mboards (TODO set through api)
clock_config_t clock_config;
clock_config.ref_source = clock_config_t::REF_SMA;
clock_config.pps_source = clock_config_t::PPS_SMA;
- BOOST_FOREACH(wax::obj mboard, _mboards){
- mboard[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _mboard(chan)[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
}
}
@@ -87,7 +71,7 @@ public:
)
% (*_dev)[DEVICE_PROP_NAME].as<std::string>()
);
- for (size_t i = 0; i < get_num_channels(); i++){
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
buff += str(boost::format(
" Channel: %u\n"
" Mboard: %s\n"
@@ -97,21 +81,21 @@ public:
" TX DSP: %s\n"
" TX Dboard: %s\n"
" TX Subdev: %s\n"
- ) % i
- % _mboards.at(i)[MBOARD_PROP_NAME].as<std::string>()
- % _rx_dsps.at(i)[DSP_PROP_NAME].as<std::string>()
- % _rx_dboards.at(i)[DBOARD_PROP_NAME].as<std::string>()
- % _rx_subdevs.at(i)[SUBDEV_PROP_NAME].as<std::string>()
- % _tx_dsps.at(i)[DSP_PROP_NAME].as<std::string>()
- % _tx_dboards.at(i)[DBOARD_PROP_NAME].as<std::string>()
- % _tx_subdevs.at(i)[SUBDEV_PROP_NAME].as<std::string>()
+ ) % chan
+ % _mboard(chan)[MBOARD_PROP_NAME].as<std::string>()
+ % _rx_dsp(chan)[DSP_PROP_NAME].as<std::string>()
+ % _rx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>()
+ % _rx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>()
+ % _tx_dsp(chan)[DSP_PROP_NAME].as<std::string>()
+ % _tx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>()
+ % _tx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>()
);
}
return buff;
}
size_t get_num_channels(void){
- return _mboards.size();
+ return (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>().size();
}
/*******************************************************************
@@ -119,12 +103,12 @@ public:
******************************************************************/
time_spec_t get_time_now(void){
//the time on the first mboard better be the same on all
- return _mboards.front()[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ return _mboard(0)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
}
void set_time_next_pps(const time_spec_t &time_spec){
- BOOST_FOREACH(wax::obj mboard, _mboards){
- mboard[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _mboard(chan)[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
}
}
@@ -146,33 +130,38 @@ public:
boost::this_thread::sleep(boost::posix_time::seconds(1));
//verify that the time registers are read to be within a few RTT
- for (size_t i = 1; i < get_num_channels(); i++){
- time_spec_t time_0 = _mboards.front()[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
- time_spec_t time_i = _mboards.at(i)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ for (size_t chan = 1; chan < get_num_channels(); chan++){
+ time_spec_t time_0 = _mboard(0)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ time_spec_t time_i = _mboard(chan)[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)){ //10 ms: greater than RTT but not too big
- std::cerr << boost::format(
- "Error: time deviation between board %d and board 0.\n"
- " Board 0 time is %f seconds.\n"
- " Board %d time is %f seconds.\n"
- ) % i % time_0.get_real_secs() % i % time_i.get_real_secs() << std::endl;
+ uhd::print_warning(str(boost::format(
+ "Detected time deviation between board %d and board 0.\n"
+ "Board 0 time is %f seconds.\n"
+ "Board %d time is %f seconds.\n"
+ ) % chan % time_0.get_real_secs() % chan % time_i.get_real_secs()));
}
}
}
void issue_stream_cmd(const stream_cmd_t &stream_cmd){
- BOOST_FOREACH(wax::obj mboard, _mboards){
- mboard[MBOARD_PROP_STREAM_CMD] = stream_cmd;
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _mboard(chan)[MBOARD_PROP_STREAM_CMD] = stream_cmd;
}
}
/*******************************************************************
* RX methods
******************************************************************/
+ void set_rx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec){
+ UHD_ASSERT_THROW(spec.size() <= 1);
+ _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC] = spec;
+ }
+
void set_rx_rate_all(double rate){
std::vector<double> _actual_rates;
- BOOST_FOREACH(wax::obj rx_dsp, _rx_dsps){
- rx_dsp[DSP_PROP_HOST_RATE] = rate;
- _actual_rates.push_back(rx_dsp[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _rx_dsp(chan)[DSP_PROP_HOST_RATE] = rate;
+ _actual_rates.push_back(_rx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>());
}
_rx_rate = _actual_rates.front();
if (std::count(_actual_rates, _rx_rate) != _actual_rates.size()) throw std::runtime_error(
@@ -185,61 +174,66 @@ public:
}
tune_result_t set_rx_freq(size_t chan, double target_freq){
- return tune_rx_subdev_and_dsp(_rx_subdevs.at(chan), _rx_dsps.at(chan), target_freq);
+ return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), target_freq);
}
tune_result_t set_rx_freq(size_t chan, double target_freq, double lo_off){
- return tune_rx_subdev_and_dsp(_rx_subdevs.at(chan), _rx_dsps.at(chan), target_freq, lo_off);
+ return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), target_freq, lo_off);
}
double get_rx_freq(size_t chan){
- return derive_freq_from_rx_subdev_and_dsp(_rx_subdevs.at(chan), _rx_dsps.at(chan));
+ return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan));
}
freq_range_t get_rx_freq_range(size_t chan){
- return add_dsp_shift(_rx_subdevs.at(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsps.at(chan));
+ return add_dsp_shift(_rx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp(chan));
}
void set_rx_gain(size_t chan, float gain){
- _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN] = gain;
+ _rx_subdev(chan)[SUBDEV_PROP_GAIN] = gain;
}
float get_rx_gain(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN].as<float>();
+ return _rx_subdev(chan)[SUBDEV_PROP_GAIN].as<float>();
}
gain_range_t get_rx_gain_range(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
+ return _rx_subdev(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
}
void set_rx_antenna(size_t chan, const std::string &ant){
- _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA] = ant;
+ _rx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_rx_antenna(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_rx_antennas(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_rx_lo_locked(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _rx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
float read_rssi(size_t chan){
- return _rx_subdevs.at(chan)[SUBDEV_PROP_RSSI].as<float>();
+ return _rx_subdev(chan)[SUBDEV_PROP_RSSI].as<float>();
}
/*******************************************************************
* TX methods
******************************************************************/
+ void set_tx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec){
+ UHD_ASSERT_THROW(spec.size() <= 1);
+ _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC] = spec;
+ }
+
void set_tx_rate_all(double rate){
std::vector<double> _actual_rates;
- BOOST_FOREACH(wax::obj tx_dsp, _tx_dsps){
- tx_dsp[DSP_PROP_HOST_RATE] = rate;
- _actual_rates.push_back(tx_dsp[DSP_PROP_HOST_RATE].as<double>());
+ for (size_t chan = 0; chan < get_num_channels(); chan++){
+ _tx_dsp(chan)[DSP_PROP_HOST_RATE] = rate;
+ _actual_rates.push_back(_tx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>());
}
_tx_rate = _actual_rates.front();
if (std::count(_actual_rates, _tx_rate) != _actual_rates.size()) throw std::runtime_error(
@@ -252,58 +246,77 @@ public:
}
tune_result_t set_tx_freq(size_t chan, double target_freq){
- return tune_tx_subdev_and_dsp(_tx_subdevs.at(chan), _tx_dsps.at(chan), target_freq);
+ return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), target_freq);
}
tune_result_t set_tx_freq(size_t chan, double target_freq, double lo_off){
- return tune_tx_subdev_and_dsp(_tx_subdevs.at(chan), _tx_dsps.at(chan), target_freq, lo_off);
+ return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), target_freq, lo_off);
}
double get_tx_freq(size_t chan){
- return derive_freq_from_tx_subdev_and_dsp(_tx_subdevs.at(chan), _tx_dsps.at(chan));
+ return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan));
}
freq_range_t get_tx_freq_range(size_t chan){
- return add_dsp_shift(_tx_subdevs.at(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsps.at(chan));
+ return add_dsp_shift(_tx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp(chan));
}
void set_tx_gain(size_t chan, float gain){
- _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN] = gain;
+ _tx_subdev(chan)[SUBDEV_PROP_GAIN] = gain;
}
float get_tx_gain(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN].as<float>();
+ return _tx_subdev(chan)[SUBDEV_PROP_GAIN].as<float>();
}
gain_range_t get_tx_gain_range(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
+ return _tx_subdev(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
}
void set_tx_antenna(size_t chan, const std::string &ant){
- _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA] = ant;
+ _tx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_tx_antenna(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_tx_antennas(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_tx_lo_locked(size_t chan){
- return _tx_subdevs.at(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _tx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
private:
device::sptr _dev;
- std::vector<wax::obj> _mboards;
- std::vector<wax::obj> _rx_dsps;
- std::vector<wax::obj> _tx_dsps;
- std::vector<wax::obj> _rx_dboards;
- std::vector<wax::obj> _tx_dboards;
- std::vector<wax::obj> _rx_subdevs;
- std::vector<wax::obj> _tx_subdevs;
+ wax::obj _mboard(size_t chan){
+ prop_names_t names = (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>();
+ return (*_dev)[named_prop_t(DEVICE_PROP_MBOARD, names.at(chan))];
+ }
+ wax::obj _rx_dsp(size_t chan){
+ return _mboard(chan)[MBOARD_PROP_RX_DSP];
+ }
+ wax::obj _tx_dsp(size_t chan){
+ return _mboard(chan)[MBOARD_PROP_TX_DSP];
+ }
+ wax::obj _rx_dboard(size_t chan){
+ std::string db_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _mboard(chan)[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)];
+ }
+ wax::obj _tx_dboard(size_t chan){
+ std::string db_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _mboard(chan)[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)];
+ }
+ wax::obj _rx_subdev(size_t chan){
+ std::string sd_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _rx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
+ wax::obj _tx_subdev(size_t chan){
+ std::string sd_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
//shadows
double _rx_rate, _tx_rate;
diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp
index 5cb9511f4..1606ad2e8 100644
--- a/host/lib/usrp/simple_usrp.cpp
+++ b/host/lib/usrp/simple_usrp.cpp
@@ -42,19 +42,6 @@ class simple_usrp_impl : public simple_usrp{
public:
simple_usrp_impl(const device_addr_t &addr){
_dev = device::make(addr);
- _mboard = (*_dev)[DEVICE_PROP_MBOARD];
- _rx_dsp = _mboard[MBOARD_PROP_RX_DSP];
- _tx_dsp = _mboard[MBOARD_PROP_TX_DSP];
-
- //extract rx subdevice
- _rx_dboard = _mboard[MBOARD_PROP_RX_DBOARD];
- std::string rx_subdev_in_use = _rx_dboard[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _rx_subdev = _rx_dboard[named_prop_t(DBOARD_PROP_SUBDEV, rx_subdev_in_use)];
-
- //extract tx subdevice
- _tx_dboard = _mboard[MBOARD_PROP_TX_DBOARD];
- std::string tx_subdev_in_use = _tx_dboard[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);
- _tx_subdev = _tx_dboard[named_prop_t(DBOARD_PROP_SUBDEV, tx_subdev_in_use)];
}
~simple_usrp_impl(void){
@@ -78,13 +65,13 @@ public:
" TX Subdev: %s\n"
)
% (*_dev)[DEVICE_PROP_NAME].as<std::string>()
- % _mboard[MBOARD_PROP_NAME].as<std::string>()
- % _rx_dsp[DSP_PROP_NAME].as<std::string>()
- % _rx_dboard[DBOARD_PROP_NAME].as<std::string>()
- % _rx_subdev[SUBDEV_PROP_NAME].as<std::string>()
- % _tx_dsp[DSP_PROP_NAME].as<std::string>()
- % _tx_dboard[DBOARD_PROP_NAME].as<std::string>()
- % _tx_subdev[SUBDEV_PROP_NAME].as<std::string>()
+ % _mboard()[MBOARD_PROP_NAME].as<std::string>()
+ % _rx_dsp()[DSP_PROP_NAME].as<std::string>()
+ % _rx_dboard()[DBOARD_PROP_NAME].as<std::string>()
+ % _rx_subdev()[SUBDEV_PROP_NAME].as<std::string>()
+ % _tx_dsp()[DSP_PROP_NAME].as<std::string>()
+ % _tx_dboard()[DBOARD_PROP_NAME].as<std::string>()
+ % _tx_subdev()[SUBDEV_PROP_NAME].as<std::string>()
);
}
@@ -92,148 +79,174 @@ public:
* Misc
******************************************************************/
time_spec_t get_time_now(void){
- return _mboard[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
+ return _mboard()[MBOARD_PROP_TIME_NOW].as<time_spec_t>();
}
void set_time_now(const time_spec_t &time_spec){
- _mboard[MBOARD_PROP_TIME_NOW] = time_spec;
+ _mboard()[MBOARD_PROP_TIME_NOW] = time_spec;
}
void set_time_next_pps(const time_spec_t &time_spec){
- _mboard[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
+ _mboard()[MBOARD_PROP_TIME_NEXT_PPS] = time_spec;
}
void issue_stream_cmd(const stream_cmd_t &stream_cmd){
- _mboard[MBOARD_PROP_STREAM_CMD] = stream_cmd;
+ _mboard()[MBOARD_PROP_STREAM_CMD] = stream_cmd;
}
void set_clock_config(const clock_config_t &clock_config){
- _mboard[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
+ _mboard()[MBOARD_PROP_CLOCK_CONFIG] = clock_config;
}
/*******************************************************************
* RX methods
******************************************************************/
+ void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){
+ _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC] = spec;
+ }
+
void set_rx_rate(double rate){
- _rx_dsp[DSP_PROP_HOST_RATE] = rate;
+ _rx_dsp()[DSP_PROP_HOST_RATE] = rate;
}
double get_rx_rate(void){
- return _rx_dsp[DSP_PROP_HOST_RATE].as<double>();
+ return _rx_dsp()[DSP_PROP_HOST_RATE].as<double>();
}
tune_result_t set_rx_freq(double target_freq){
- return tune_rx_subdev_and_dsp(_rx_subdev, _rx_dsp, target_freq);
+ return tune_rx_subdev_and_dsp(_rx_subdev(), _rx_dsp(), target_freq);
}
tune_result_t set_rx_freq(double target_freq, double lo_off){
- return tune_rx_subdev_and_dsp(_rx_subdev, _rx_dsp, target_freq, lo_off);
+ return tune_rx_subdev_and_dsp(_rx_subdev(), _rx_dsp(), target_freq, lo_off);
}
double get_rx_freq(void){
- return derive_freq_from_rx_subdev_and_dsp(_rx_subdev, _rx_dsp);
+ return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(), _rx_dsp());
}
freq_range_t get_rx_freq_range(void){
- return add_dsp_shift(_rx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp);
+ return add_dsp_shift(_rx_subdev()[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp());
}
void set_rx_gain(float gain){
- _rx_subdev[SUBDEV_PROP_GAIN] = gain;
+ _rx_subdev()[SUBDEV_PROP_GAIN] = gain;
}
float get_rx_gain(void){
- return _rx_subdev[SUBDEV_PROP_GAIN].as<float>();
+ return _rx_subdev()[SUBDEV_PROP_GAIN].as<float>();
}
gain_range_t get_rx_gain_range(void){
- return _rx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
+ return _rx_subdev()[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
}
void set_rx_antenna(const std::string &ant){
- _rx_subdev[SUBDEV_PROP_ANTENNA] = ant;
+ _rx_subdev()[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_rx_antenna(void){
- return _rx_subdev[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _rx_subdev()[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_rx_antennas(void){
- return _rx_subdev[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _rx_subdev()[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_rx_lo_locked(void){
- return _rx_subdev[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _rx_subdev()[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
float read_rssi(void){
- return _rx_subdev[SUBDEV_PROP_RSSI].as<float>();
+ return _rx_subdev()[SUBDEV_PROP_RSSI].as<float>();
}
/*******************************************************************
* TX methods
******************************************************************/
+ void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec){
+ _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC] = spec;
+ }
+
void set_tx_rate(double rate){
- _tx_dsp[DSP_PROP_HOST_RATE] = rate;
+ _tx_dsp()[DSP_PROP_HOST_RATE] = rate;
}
double get_tx_rate(void){
- return _tx_dsp[DSP_PROP_HOST_RATE].as<double>();
+ return _tx_dsp()[DSP_PROP_HOST_RATE].as<double>();
}
tune_result_t set_tx_freq(double target_freq){
- return tune_tx_subdev_and_dsp(_tx_subdev, _tx_dsp, target_freq);
+ return tune_tx_subdev_and_dsp(_tx_subdev(), _tx_dsp(), target_freq);
}
tune_result_t set_tx_freq(double target_freq, double lo_off){
- return tune_tx_subdev_and_dsp(_tx_subdev, _tx_dsp, target_freq, lo_off);
+ return tune_tx_subdev_and_dsp(_tx_subdev(), _tx_dsp(), target_freq, lo_off);
}
double get_tx_freq(void){
- return derive_freq_from_tx_subdev_and_dsp(_tx_subdev, _tx_dsp);
+ return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(), _tx_dsp());
}
freq_range_t get_tx_freq_range(void){
- return add_dsp_shift(_tx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp);
+ return add_dsp_shift(_tx_subdev()[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp());
}
void set_tx_gain(float gain){
- _tx_subdev[SUBDEV_PROP_GAIN] = gain;
+ _tx_subdev()[SUBDEV_PROP_GAIN] = gain;
}
float get_tx_gain(void){
- return _tx_subdev[SUBDEV_PROP_GAIN].as<float>();
+ return _tx_subdev()[SUBDEV_PROP_GAIN].as<float>();
}
gain_range_t get_tx_gain_range(void){
- return _tx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
+ return _tx_subdev()[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>();
}
void set_tx_antenna(const std::string &ant){
- _tx_subdev[SUBDEV_PROP_ANTENNA] = ant;
+ _tx_subdev()[SUBDEV_PROP_ANTENNA] = ant;
}
std::string get_tx_antenna(void){
- return _tx_subdev[SUBDEV_PROP_ANTENNA].as<std::string>();
+ return _tx_subdev()[SUBDEV_PROP_ANTENNA].as<std::string>();
}
std::vector<std::string> get_tx_antennas(void){
- return _tx_subdev[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
+ return _tx_subdev()[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>();
}
bool get_tx_lo_locked(void){
- return _tx_subdev[SUBDEV_PROP_LO_LOCKED].as<bool>();
+ return _tx_subdev()[SUBDEV_PROP_LO_LOCKED].as<bool>();
}
private:
device::sptr _dev;
- wax::obj _mboard;
- wax::obj _rx_dsp;
- wax::obj _tx_dsp;
- wax::obj _rx_dboard;
- wax::obj _tx_dboard;
- wax::obj _rx_subdev;
- wax::obj _tx_subdev;
+ wax::obj _mboard(void){
+ return (*_dev)[DEVICE_PROP_MBOARD];
+ }
+ wax::obj _rx_dsp(void){
+ return _mboard()[MBOARD_PROP_RX_DSP];
+ }
+ wax::obj _tx_dsp(void){
+ return _mboard()[MBOARD_PROP_TX_DSP];
+ }
+ wax::obj _rx_dboard(void){
+ std::string db_name = _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _mboard()[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)];
+ }
+ wax::obj _tx_dboard(void){
+ std::string db_name = _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _mboard()[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)];
+ }
+ wax::obj _rx_subdev(void){
+ std::string sd_name = _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _rx_dboard()[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
+ wax::obj _tx_subdev(void){
+ std::string sd_name = _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().first;
+ return _tx_dboard()[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)];
+ }
};
/***********************************************************************
diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp
index 0aeb0ec1a..8f6182fb5 100644
--- a/host/lib/usrp/usrp2/dboard_impl.cpp
+++ b/host/lib/usrp/usrp2/dboard_impl.cpp
@@ -53,10 +53,6 @@ void usrp2_mboard_impl::dboard_init(void){
boost::bind(&usrp2_mboard_impl::tx_dboard_get, this, _1, _2),
boost::bind(&usrp2_mboard_impl::tx_dboard_set, this, _1, _2)
);
-
- //init the subdevs in use (use the first subdevice)
- rx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_rx_subdev_names().at(0)));
- tx_dboard_set(DBOARD_PROP_USED_SUBDEVS, prop_names_t(1, _dboard_manager->get_tx_subdev_names().at(0)));
}
/***********************************************************************
@@ -80,10 +76,6 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_rx_subdev_names();
return;
- case DBOARD_PROP_USED_SUBDEVS:
- val = _rx_subdevs_in_use;
- return;
-
case DBOARD_PROP_DBOARD_ID:
val = _rx_db_eeprom.id;
return;
@@ -98,16 +90,6 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){
void usrp2_mboard_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){
switch(key.as<dboard_prop_t>()){
- case DBOARD_PROP_USED_SUBDEVS:{
- _rx_subdevs_in_use = val.as<prop_names_t>();
- UHD_ASSERT_THROW(_rx_subdevs_in_use.size() == 1);
- wax::obj rx_subdev = _dboard_manager->get_rx_subdev(_rx_subdevs_in_use.at(0));
- std::cout << "Using: " << rx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl;
- _iface->poke32(U2_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word(
- rx_subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
- ));
- }
- return;
case DBOARD_PROP_DBOARD_ID:
_rx_db_eeprom.id = val.as<dboard_id_t>();
@@ -139,10 +121,6 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){
val = _dboard_manager->get_tx_subdev_names();
return;
- case DBOARD_PROP_USED_SUBDEVS:
- val = _tx_subdevs_in_use;
- return;
-
case DBOARD_PROP_DBOARD_ID:
val = _tx_db_eeprom.id;
return;
@@ -157,16 +135,6 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){
void usrp2_mboard_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){
switch(key.as<dboard_prop_t>()){
- case DBOARD_PROP_USED_SUBDEVS:{
- _tx_subdevs_in_use = val.as<prop_names_t>();
- UHD_ASSERT_THROW(_tx_subdevs_in_use.size() == 1);
- wax::obj tx_subdev = _dboard_manager->get_tx_subdev(_tx_subdevs_in_use.at(0));
- std::cout << "Using: " << tx_subdev[SUBDEV_PROP_NAME].as<std::string>() << std::endl;
- _iface->poke32(U2_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word(
- tx_subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
- ));
- }
- return;
case DBOARD_PROP_DBOARD_ID:
_tx_db_eeprom.id = val.as<dboard_id_t>();
diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp
index 7694a164d..c35171fec 100644
--- a/host/lib/usrp/usrp2/mboard_impl.cpp
+++ b/host/lib/usrp/usrp2/mboard_impl.cpp
@@ -99,6 +99,10 @@ usrp2_mboard_impl::usrp2_mboard_impl(
//init the tx and rx dboards (do last)
dboard_init();
+ //set default subdev specs
+ (*this)[MBOARD_PROP_RX_SUBDEV_SPEC] = subdev_spec_t();
+ (*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t();
+
//Issue a stop streaming command (in case it was left running).
//Since this command is issued before the networking is setup,
//most if not all junk packets will never make it to the socket.
@@ -263,6 +267,14 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){
}
return;
+ case MBOARD_PROP_RX_SUBDEV_SPEC:
+ val = _rx_subdev_spec;
+ return;
+
+ case MBOARD_PROP_TX_SUBDEV_SPEC:
+ val = _tx_subdev_spec;
+ return;
+
default: UHD_THROW_PROP_GET_ERROR();
}
}
@@ -307,6 +319,40 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){
issue_ddc_stream_cmd(val.as<stream_cmd_t>());
return;
+ case MBOARD_PROP_RX_SUBDEV_SPEC:
+ _rx_subdev_spec = val.as<subdev_spec_t>();
+ //handle automatic
+ if (_rx_subdev_spec.empty()) _rx_subdev_spec.push_back(
+ subdev_spec_t::pair_t("", _dboard_manager->get_rx_subdev_names().front())
+ );
+ std::cout << "RX " << _rx_subdev_spec.to_pp_string() << std::endl;
+ //sanity check
+ UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1);
+ uhd::assert_has((*this)[MBOARD_PROP_RX_DBOARD_NAMES].as<prop_names_t>(), _rx_subdev_spec.front().first, "rx dboard names");
+ uhd::assert_has(_dboard_manager->get_rx_subdev_names(), _rx_subdev_spec.front().second, "rx subdev names");
+ //set the mux
+ _iface->poke32(U2_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word(
+ _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().second)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ return;
+
+ case MBOARD_PROP_TX_SUBDEV_SPEC:
+ _tx_subdev_spec = val.as<subdev_spec_t>();
+ //handle automatic
+ if (_tx_subdev_spec.empty()) _tx_subdev_spec.push_back(
+ subdev_spec_t::pair_t("", _dboard_manager->get_tx_subdev_names().front())
+ );
+ std::cout << "TX " << _tx_subdev_spec.to_pp_string() << std::endl;
+ //sanity check
+ UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1);
+ uhd::assert_has((*this)[MBOARD_PROP_TX_DBOARD_NAMES].as<prop_names_t>(), _tx_subdev_spec.front().first, "tx dboard names");
+ uhd::assert_has(_dboard_manager->get_tx_subdev_names(), _tx_subdev_spec.front().second, "tx subdev names");
+ //set the mux
+ _iface->poke32(U2_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word(
+ _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().second)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()
+ ));
+ return;
+
default: UHD_THROW_PROP_SET_ERROR();
}
}
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 2eaf12350..e7e560469 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -35,6 +35,7 @@
#include <uhd/transport/udp_simple.hpp> //mtu
#include <uhd/transport/udp_zero_copy.hpp>
#include <uhd/usrp/dboard_manager.hpp>
+#include <uhd/usrp/subdev_spec.hpp>
/*!
* Make a usrp2 dboard interface.
@@ -143,6 +144,7 @@ private:
//properties for this mboard
void get(const wax::obj &, wax::obj &);
void set(const wax::obj &, const wax::obj &);
+ uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec;
//interfaces
usrp2_iface::sptr _iface;
@@ -165,14 +167,12 @@ private:
void rx_dboard_get(const wax::obj &, wax::obj &);
void rx_dboard_set(const wax::obj &, const wax::obj &);
wax_obj_proxy::sptr _rx_dboard_proxy;
- uhd::prop_names_t _rx_subdevs_in_use;
uhd::usrp::dboard_eeprom_t _rx_db_eeprom;
//properties interface for tx dboard
void tx_dboard_get(const wax::obj &, wax::obj &);
void tx_dboard_set(const wax::obj &, const wax::obj &);
wax_obj_proxy::sptr _tx_dboard_proxy;
- uhd::prop_names_t _tx_subdevs_in_use;
uhd::usrp::dboard_eeprom_t _tx_db_eeprom;
//methods and shadows for the ddc dsp