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.cpp439
1 files changed, 121 insertions, 318 deletions
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 5789c8a72..227ba4212 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -1,6 +1,7 @@
//
// Copyright 2010-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
+// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
@@ -20,15 +21,27 @@
#include <uhd/utils/soft_register.hpp>
#include <uhdlib/usrp/gpio_defs.hpp>
#include <uhdlib/rfnoc/legacy_compat.hpp>
+#include <uhdlib/rfnoc/rfnoc_device.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/make_shared.hpp>
#include <algorithm>
#include <cmath>
#include <bitset>
#include <chrono>
#include <thread>
+namespace uhd { namespace rfnoc {
+
+//! Factory function for RFNoC devices specifically
+uhd::usrp::multi_usrp::sptr make_rfnoc_device(
+ uhd::rfnoc::detail::rfnoc_device::sptr rfnoc_device,
+ const uhd::device_addr_t& dev_addr);
+
+}} /* namespace uhd::rfnoc */
+
+
using namespace uhd;
using namespace uhd::usrp;
@@ -384,31 +397,16 @@ static double derive_freq_from_xx_subdev_and_dsp(
**********************************************************************/
class multi_usrp_impl : public multi_usrp{
public:
- multi_usrp_impl(const device_addr_t &addr){
- _dev = device::make(addr, device::USRP);
+ multi_usrp_impl(device::sptr dev, const device_addr_t& addr)
+ : _dev(dev)
+ {
_tree = _dev->get_tree();
- _is_device3 = bool(boost::dynamic_pointer_cast<uhd::device3>(_dev));
-
- if (is_device3() and not addr.has_key("recover_mb_eeprom")) {
- _legacy_compat = rfnoc::legacy_compat::make(get_device3(), addr);
- }
}
device::sptr get_device(void){
return _dev;
}
- bool is_device3(void) {
- return _is_device3;
- }
-
- device3::sptr get_device3(void) {
- if (not is_device3()) {
- throw uhd::type_error("Cannot call get_device3() on a non-generation 3 device.");
- }
- return boost::dynamic_pointer_cast<uhd::device3>(_dev);
- }
-
dict<std::string, std::string> get_usrp_rx_info(size_t chan){
mboard_chan_pair mcp = rx_chan_to_mcp(chan);
dict<std::string, std::string> usrp_info;
@@ -684,12 +682,7 @@ public:
void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan){
if (chan != ALL_CHANS){
- if (is_device3()) {
- mboard_chan_pair mcp = rx_chan_to_mcp(chan);
- _legacy_compat->issue_stream_cmd(stream_cmd, mcp.mboard, mcp.chan);
- } else {
- _tree->access<stream_cmd_t>(rx_dsp_root(chan) / "stream_cmd").set(stream_cmd);
- }
+ _tree->access<stream_cmd_t>(rx_dsp_root(chan) / "stream_cmd").set(stream_cmd);
return;
}
for (size_t c = 0; c < get_rx_num_channels(); c++){
@@ -970,9 +963,6 @@ public:
******************************************************************/
rx_streamer::sptr get_rx_stream(const stream_args_t &args) {
_check_link_rate(args, false);
- if (is_device3()) {
- return _legacy_compat->get_rx_stream(args);
- }
return this->get_device()->get_rx_stream(args);
}
@@ -1020,18 +1010,6 @@ public:
}
void set_rx_rate(double rate, size_t chan){
- if (is_device3()) {
- _legacy_compat->set_rx_rate(rate, chan);
- if (chan == ALL_CHANS) {
- for (size_t c = 0; c < get_rx_num_channels(); c++){
- do_samp_rate_warning_message(rate, get_rx_rate(c), "RX");
- }
- } else {
- do_samp_rate_warning_message(rate, get_rx_rate(chan), "RX");
- }
- return;
- }
-
if (chan != ALL_CHANS){
_tree->access<double>(rx_dsp_root(chan) / "rate" / "value").set(rate);
do_samp_rate_warning_message(rate, get_rx_rate(chan), "RX");
@@ -1725,85 +1703,108 @@ public:
}
}
- std::vector<std::string> get_filter_names(const std::string &search_mask)
+ std::vector<std::string> get_rx_filter_names(const size_t chan)
{
+ if (chan >= get_rx_num_channels()) {
+ throw uhd::index_error("Attempting to get non-existent RX filter names");
+ }
std::vector<std::string> ret;
- for (size_t chan = 0; chan < get_rx_num_channels(); chan++){
-
- if (_tree->exists(rx_rf_fe_root(chan) / "filters")) {
- std::vector<std::string> names = _tree->list(rx_rf_fe_root(chan) / "filters");
- for(size_t i = 0; i < names.size(); i++)
- {
- std::string name = rx_rf_fe_root(chan) / "filters" / names[i];
- if((search_mask.empty()) or boost::contains(name, search_mask)) {
- ret.push_back(name);
- }
- }
+ if (_tree->exists(rx_rf_fe_root(chan) / "filters")) {
+ std::vector<std::string> names = _tree->list(rx_rf_fe_root(chan) / "filters");
+ for (size_t i = 0; i < names.size(); i++) {
+ std::string name = rx_rf_fe_root(chan) / "filters" / names[i];
+ ret.push_back(name);
}
- if (_tree->exists(rx_dsp_root(chan) / "filters")) {
- std::vector<std::string> names = _tree->list(rx_dsp_root(chan) / "filters");
- for(size_t i = 0; i < names.size(); i++)
- {
- std::string name = rx_dsp_root(chan) / "filters" / names[i];
- if((search_mask.empty()) or (boost::contains(name, search_mask))) {
- ret.push_back(name);
- }
- }
+ }
+ if (_tree->exists(rx_dsp_root(chan) / "filters")) {
+ std::vector<std::string> names = _tree->list(rx_dsp_root(chan) / "filters");
+ for (size_t i = 0; i < names.size(); i++) {
+ std::string name = rx_dsp_root(chan) / "filters" / names[i];
+ ret.push_back(name);
}
+ }
+
+ return ret;
+ }
+ uhd::filter_info_base::sptr get_rx_filter(const std::string& name, const size_t chan)
+ {
+ std::vector<std::string> possible_names = get_rx_filter_names(chan);
+ std::vector<std::string>::iterator it;
+ it = find(possible_names.begin(), possible_names.end(), name);
+ if (it == possible_names.end()) {
+ throw uhd::runtime_error("Attempting to get non-existing filter: " + name);
}
- for (size_t chan = 0; chan < get_tx_num_channels(); chan++){
+ return _tree->access<filter_info_base::sptr>(rx_rf_fe_root(chan) / name / "value")
+ .get();
+ }
- if (_tree->exists(tx_rf_fe_root(chan) / "filters")) {
- std::vector<std::string> names = _tree->list(tx_rf_fe_root(chan) / "filters");
- for(size_t i = 0; i < names.size(); i++)
- {
- std::string name = tx_rf_fe_root(chan) / "filters" / names[i];
- if((search_mask.empty()) or (boost::contains(name, search_mask))) {
- ret.push_back(name);
- }
- }
+ void set_rx_filter(
+ const std::string& name, uhd::filter_info_base::sptr filter, const size_t chan)
+ {
+ std::vector<std::string> possible_names = get_rx_filter_names(chan);
+ std::vector<std::string>::iterator it;
+ it = find(possible_names.begin(), possible_names.end(), name);
+ if (it == possible_names.end()) {
+ throw uhd::runtime_error("Attempting to set non-existing filter: " + name);
+ }
+
+ _tree->access<filter_info_base::sptr>(rx_rf_fe_root(chan) / name / "value")
+ .set(filter);
+ }
+
+ std::vector<std::string> get_tx_filter_names(const size_t chan)
+ {
+ if (chan >= get_tx_num_channels()) {
+ throw uhd::index_error("Attempting to get non-existent TX filter names");
+ }
+ std::vector<std::string> ret;
+
+ if (_tree->exists(tx_rf_fe_root(chan) / "filters")) {
+ std::vector<std::string> names = _tree->list(tx_rf_fe_root(chan) / "filters");
+ for (size_t i = 0; i < names.size(); i++) {
+ std::string name = tx_rf_fe_root(chan) / "filters" / names[i];
+ ret.push_back(name);
}
- if (_tree->exists(rx_dsp_root(chan) / "filters")) {
- std::vector<std::string> names = _tree->list(tx_dsp_root(chan) / "filters");
- for(size_t i = 0; i < names.size(); i++)
- {
- std::string name = tx_dsp_root(chan) / "filters" / names[i];
- if((search_mask.empty()) or (boost::contains(name, search_mask))) {
- ret.push_back(name);
- }
- }
+ }
+ if (_tree->exists(rx_dsp_root(chan) / "filters")) {
+ std::vector<std::string> names = _tree->list(tx_dsp_root(chan) / "filters");
+ for (size_t i = 0; i < names.size(); i++) {
+ std::string name = tx_dsp_root(chan) / "filters" / names[i];
+ ret.push_back(name);
}
-
}
return ret;
}
- filter_info_base::sptr get_filter(const std::string &path)
+ uhd::filter_info_base::sptr get_tx_filter(const std::string& name, const size_t chan)
{
- std::vector<std::string> possible_names = get_filter_names("");
+ std::vector<std::string> possible_names = get_tx_filter_names(chan);
std::vector<std::string>::iterator it;
- it = find(possible_names.begin(), possible_names.end(), path);
+ it = find(possible_names.begin(), possible_names.end(), name);
if (it == possible_names.end()) {
- throw uhd::runtime_error("Attempting to get non-existing filter: "+path);
+ throw uhd::runtime_error("Attempting to get non-existing filter: " + name);
}
- return _tree->access<filter_info_base::sptr>(path / "value").get();
+ return _tree->access<filter_info_base::sptr>(tx_rf_fe_root(chan) / name / "value")
+ .get();
}
- void set_filter(const std::string &path, filter_info_base::sptr filter)
+ void set_tx_filter(
+ const std::string& name, uhd::filter_info_base::sptr filter, const size_t chan)
{
- std::vector<std::string> possible_names = get_filter_names("");
+ std::vector<std::string> possible_names = get_tx_filter_names(chan);
std::vector<std::string>::iterator it;
- it = find(possible_names.begin(), possible_names.end(), path);
+ it = find(possible_names.begin(), possible_names.end(), name);
if (it == possible_names.end()) {
- throw uhd::runtime_error("Attempting to set non-existing filter: "+path);
+ throw uhd::runtime_error("Attempting to set non-existing filter: " + name);
}
- _tree->access<filter_info_base::sptr>(path / "value").set(filter);
+ _tree->access<filter_info_base::sptr>(tx_rf_fe_root(chan) / name / "value")
+ .set(filter);
}
/*******************************************************************
@@ -1811,9 +1812,6 @@ public:
******************************************************************/
tx_streamer::sptr get_tx_stream(const stream_args_t &args) {
_check_link_rate(args, true);
- if (is_device3()) {
- return _legacy_compat->get_tx_stream(args);
- }
return this->get_device()->get_tx_stream(args);
}
@@ -1861,18 +1859,6 @@ public:
}
void set_tx_rate(double rate, size_t chan){
- if (is_device3()) {
- _legacy_compat->set_tx_rate(rate, chan);
- if (chan == ALL_CHANS) {
- for (size_t c = 0; c < get_tx_num_channels(); c++){
- do_samp_rate_warning_message(rate, get_tx_rate(c), "TX");
- }
- } else {
- do_samp_rate_warning_message(rate, get_tx_rate(chan), "TX");
- }
- return;
- }
-
if (chan != ALL_CHANS){
_tree->access<double>(tx_dsp_root(chan) / "rate" / "value").set(rate);
do_samp_rate_warning_message(rate, get_tx_rate(chan), "TX");
@@ -2196,71 +2182,6 @@ public:
));
}
- void set_gpio_attr(
- const std::string &bank,
- const std::string &attr,
- const std::string &str_value,
- const uint32_t mask,
- const size_t mboard
- ) {
- const auto attr_type = gpio_atr::gpio_attr_rev_map.at(attr);
- if (_tree->exists(mb_root(mboard) / "gpio" / bank)) {
- if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)) {
- switch (attr_type){
- case gpio_atr::GPIO_SRC:
- case gpio_atr::GPIO_CTRL:
- case gpio_atr::GPIO_DDR:{
- auto attr_value =
- _tree->access<std::vector<std::string>>(
- mb_root(mboard) / "gpio" / bank / attr).get();
- UHD_ASSERT_THROW(attr_value.size() <= 32);
- std::bitset<32> bit_mask = std::bitset<32>(mask);
- for (size_t i = 0 ; i < bit_mask.size(); i++) {
- if (bit_mask[i] == 1) {
- attr_value[i] = str_value;
- }
- }
- _tree->access<std::vector<std::string>>(
- mb_root(mboard) / "gpio" / bank / attr
- ).set(attr_value);
- }
- break;
- default: {
- const uint32_t value =
- gpio_atr::gpio_attr_value_pair.at(attr).at(str_value) == 0 ? -1 : 0;
- const uint32_t current = _tree->access<uint32_t>(
- mb_root(mboard) / "gpio" / bank / attr).get();
- const uint32_t new_value =
- (current & ~mask) | (value & mask);
- _tree->access<uint32_t>(
- mb_root(mboard) / "gpio" / bank / attr
- ).set(new_value);
- }
- break;
- }
- return;
- } else {
- throw uhd::runtime_error(str(
- boost::format("The hardware has no gpio attribute `%s'")
- % attr
- ));
- }
- }
- // If the bank is not in the prop tree, convert string value to integer
- // value and have it handled by the other set_gpio_attr()
- const uint32_t value =
- gpio_atr::gpio_attr_value_pair.at(attr).at(str_value) == 0
- ? -1
- : 0;
- set_gpio_attr(
- bank,
- attr,
- value,
- mask,
- mboard
- );
- }
-
uint32_t get_gpio_attr(
const std::string &bank,
const std::string &attr,
@@ -2316,149 +2237,28 @@ public:
));
}
- std::vector<std::string> get_gpio_string_attr(
- const std::string &bank,
- const std::string &attr,
- const size_t mboard
- ) {
- const auto attr_type = gpio_atr::gpio_attr_rev_map.at(attr);
- auto str_val = std::vector<std::string>(32, gpio_atr::default_attr_value_map.at(attr_type));
- if (_tree->exists(mb_root(mboard) / "gpio" / bank)) {
- if (_tree->exists(mb_root(mboard) / "gpio" / bank / attr)) {
- const auto attr_type = gpio_atr::gpio_attr_rev_map.at(attr);
- switch (attr_type){
- case gpio_atr::GPIO_SRC:
- case gpio_atr::GPIO_CTRL:
- case gpio_atr::GPIO_DDR:
- return _tree->access<std::vector<std::string>>(mb_root(mboard) / "gpio" / bank / attr).get();
- default: {
- uint32_t value = uint32_t(_tree->access<uint32_t>(mb_root(mboard) / "gpio" / bank / attr).get());
- std::bitset<32> bit_value = std::bitset<32>(value);
- for (size_t i = 0; i < bit_value.size(); i++)
- {
- str_val[i] = bit_value[i] == 0 ? "LOW" : "HIGH";
- }
- return str_val;
- }
- }
- }
- else {
- throw uhd::runtime_error(str(
- boost::format("The hardware has no gpio attribute: `%s'")
- % attr
- ));
- }
- }
- throw uhd::runtime_error(str(
- boost::format("The hardware has no support for given gpio bank name `%s'")
- % bank
- ));
- }
-
- void write_register(const std::string &path, const uint32_t field, const uint64_t value, const size_t mboard)
- {
- if (_tree->exists(mb_root(mboard) / "registers"))
- {
- uhd::soft_regmap_accessor_t::sptr accessor =
- _tree->access<uhd::soft_regmap_accessor_t::sptr>(mb_root(mboard) / "registers").get();
- uhd::soft_register_base& reg = accessor->lookup(path);
-
- if (not reg.is_writable()) {
- throw uhd::runtime_error("multi_usrp::write_register - register not writable: " + path);
- }
-
- switch (reg.get_bitwidth()) {
- case 32:
- if (reg.is_readable())
- uhd::soft_register_base::cast<uhd::soft_reg32_rw_t>(reg).write(field, static_cast<uint32_t>(value));
- else
- uhd::soft_register_base::cast<uhd::soft_reg32_wo_t>(reg).write(field, static_cast<uint32_t>(value));
- break;
-
- case 64:
- if (reg.is_readable())
- uhd::soft_register_base::cast<uhd::soft_reg64_rw_t>(reg).write(field, value);
- else
- uhd::soft_register_base::cast<uhd::soft_reg64_wo_t>(reg).write(field, value);
- break;
-
- default:
- throw uhd::assertion_error("multi_usrp::write_register - register has invalid bitwidth");
- }
-
- } else {
- throw uhd::not_implemented_error("multi_usrp::write_register - register IO not supported for this device");
- }
- }
-
- uint64_t read_register(const std::string &path, const uint32_t field, const size_t mboard)
+ // The next three methods are only for RFNoC devices
+ std::vector<std::string> get_gpio_srcs(const std::string&, const size_t)
{
- if (_tree->exists(mb_root(mboard) / "registers"))
- {
- uhd::soft_regmap_accessor_t::sptr accessor =
- _tree->access<uhd::soft_regmap_accessor_t::sptr>(mb_root(mboard) / "registers").get();
- uhd::soft_register_base& reg = accessor->lookup(path);
-
- if (not reg.is_readable()) {
- throw uhd::runtime_error("multi_usrp::read_register - register not readable: " + path);
- }
-
- switch (reg.get_bitwidth()) {
- case 32:
- if (reg.is_writable())
- return static_cast<uint64_t>(uhd::soft_register_base::cast<uhd::soft_reg32_rw_t>(reg).read(field));
- else
- return static_cast<uint64_t>(uhd::soft_register_base::cast<uhd::soft_reg32_ro_t>(reg).read(field));
- break;
-
- case 64:
- if (reg.is_writable())
- return uhd::soft_register_base::cast<uhd::soft_reg64_rw_t>(reg).read(field);
- else
- return uhd::soft_register_base::cast<uhd::soft_reg64_ro_t>(reg).read(field);
- break;
-
- default:
- throw uhd::assertion_error("multi_usrp::read_register - register has invalid bitwidth: " + path);
- }
- }
- throw uhd::not_implemented_error("multi_usrp::read_register - register IO not supported for this device");
+ throw uhd::not_implemented_error(
+ "get_gpio_srcs() not implemented for this motherboard!");
}
- std::vector<std::string> enumerate_registers(const size_t mboard)
+ std::vector<std::string> get_gpio_src(const std::string&, const size_t)
{
- if (_tree->exists(mb_root(mboard) / "registers"))
- {
- uhd::soft_regmap_accessor_t::sptr accessor =
- _tree->access<uhd::soft_regmap_accessor_t::sptr>(mb_root(mboard) / "registers").get();
- return accessor->enumerate();
- } else {
- return std::vector<std::string>();
- }
+ throw uhd::not_implemented_error(
+ "get_gpio_src() not implemented for this motherboard!");
}
- register_info_t get_register_info(const std::string &path, const size_t mboard = 0)
+ void set_gpio_src(const std::string&, const std::vector<std::string>&, const size_t)
{
- if (_tree->exists(mb_root(mboard) / "registers"))
- {
- uhd::soft_regmap_accessor_t::sptr accessor =
- _tree->access<uhd::soft_regmap_accessor_t::sptr>(mb_root(mboard) / "registers").get();
- uhd::soft_register_base& reg = accessor->lookup(path);
-
- register_info_t info;
- info.bitwidth = reg.get_bitwidth();
- info.readable = reg.is_readable();
- info.writable = reg.is_writable();
- return info;
- } else {
- throw uhd::not_implemented_error("multi_usrp::read_register - register IO not supported for this device");
- }
+ throw uhd::not_implemented_error(
+ "set_gpio_src() not implemented for this motherboard!");
}
private:
device::sptr _dev;
property_tree::sptr _tree;
- bool _is_device3;
uhd::rfnoc::legacy_compat::sptr _legacy_compat;
struct mboard_chan_pair{
@@ -2516,10 +2316,6 @@ private:
fs_path rx_dsp_root(const size_t chan)
{
mboard_chan_pair mcp = rx_chan_to_mcp(chan);
- if (is_device3()) {
- return _legacy_compat->rx_dsp_root(mcp.mboard, mcp.chan);
- }
-
if (_tree->exists(mb_root(mcp.mboard) / "rx_chan_dsp_mapping")) {
std::vector<size_t> map = _tree->access<std::vector<size_t> >(mb_root(mcp.mboard) / "rx_chan_dsp_mapping").get();
UHD_ASSERT_THROW(map.size() > mcp.chan);
@@ -2544,10 +2340,6 @@ private:
fs_path tx_dsp_root(const size_t chan)
{
mboard_chan_pair mcp = tx_chan_to_mcp(chan);
- if (is_device3()) {
- return _legacy_compat->tx_dsp_root(mcp.mboard, mcp.chan);
- }
-
if (_tree->exists(mb_root(mcp.mboard) / "tx_chan_dsp_mapping")) {
std::vector<size_t> map = _tree->access<std::vector<size_t> >(mb_root(mcp.mboard) / "tx_chan_dsp_mapping").get();
UHD_ASSERT_THROW(map.size() > mcp.chan);
@@ -2571,9 +2363,6 @@ private:
fs_path rx_fe_root(const size_t chan)
{
mboard_chan_pair mcp = rx_chan_to_mcp(chan);
- if (is_device3()) {
- return _legacy_compat->rx_fe_root(mcp.mboard, mcp.chan);
- }
try
{
const subdev_spec_pair_t spec = get_rx_subdev_spec(mcp.mboard).at(mcp.chan);
@@ -2588,9 +2377,6 @@ private:
fs_path tx_fe_root(const size_t chan)
{
mboard_chan_pair mcp = tx_chan_to_mcp(chan);
- if (is_device3()) {
- return _legacy_compat->tx_fe_root(mcp.mboard, mcp.chan);
- }
try
{
const subdev_spec_pair_t spec = get_tx_subdev_spec(mcp.mboard).at(mcp.chan);
@@ -2709,10 +2495,27 @@ multi_usrp::~multi_usrp(void){
/* NOP */
}
+
/***********************************************************************
* The Make Function
**********************************************************************/
-multi_usrp::sptr multi_usrp::make(const device_addr_t &dev_addr){
- UHD_LOGGER_TRACE("MULTI_USRP") << "multi_usrp::make with args " << dev_addr.to_pp_string() ;
- return sptr(new multi_usrp_impl(dev_addr));
+namespace uhd { namespace rfnoc { namespace detail {
+// Forward declare
+multi_usrp::sptr make_rfnoc_device(
+ detail::rfnoc_device::sptr rfnoc_device, const uhd::device_addr_t& dev_addr);
+}}} // namespace uhd::rfnoc::detail
+
+
+multi_usrp::sptr multi_usrp::make(const device_addr_t& dev_addr)
+{
+ UHD_LOGGER_TRACE("MULTI_USRP")
+ << "multi_usrp::make with args " << dev_addr.to_pp_string();
+
+ device::sptr dev = device::make(dev_addr, device::USRP);
+
+ auto rfnoc_dev = boost::dynamic_pointer_cast<rfnoc::detail::rfnoc_device>(dev);
+ if (rfnoc_dev) {
+ return rfnoc::detail::make_rfnoc_device(rfnoc_dev, dev_addr);
+ }
+ return boost::make_shared<multi_usrp_impl>(dev, dev_addr);
}