2010-01-13 00:59:03 +00:00
|
|
|
//
|
2017-12-05 23:49:28 +00:00
|
|
|
// Copyright 2010-2011,2017 Ettus Research, A National Instruments Company
|
2010-01-13 00:59:03 +00:00
|
|
|
//
|
2018-02-19 23:30:32 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
2010-01-30 00:40:23 +00:00
|
|
|
//
|
2010-01-13 00:59:03 +00:00
|
|
|
|
2010-05-02 23:03:46 +00:00
|
|
|
#include "dboard_ctor_args.hpp"
|
2020-03-02 23:25:13 +00:00
|
|
|
#include <uhd/exception.hpp>
|
|
|
|
|
#include <uhd/types/dict.hpp>
|
2010-02-21 20:59:41 +00:00
|
|
|
#include <uhd/usrp/dboard_manager.hpp>
|
2017-02-08 00:37:25 +00:00
|
|
|
#include <uhd/utils/log.hpp>
|
2011-06-10 20:11:22 +00:00
|
|
|
#include <uhd/utils/safe_call.hpp>
|
2010-03-27 08:02:58 +00:00
|
|
|
#include <uhd/utils/static.hpp>
|
2010-01-15 03:02:55 +00:00
|
|
|
#include <boost/format.hpp>
|
uhd: Replace all occurrences of boost::bind with std::bind
Note: Replacing everything with a lambda would be even better, but that
can't be easily scripted so we'll do this as a first step to reduce the
Boost footprint.
This also removes occurences of #include <boost/bind.hpp>, and makes
sure all usages of std::bind have an #include <functional>. clang-format
wasn't always applied to minimize the changeset in this commit, however,
it was applied to the blocks of #includes.
Due to conflicts with other Boost libraries, the placeholders _1, _2,
etc. could not be directly used, but had to be explicitly called out
(as std::placeholders::_1, etc.). This makes the use of std::bind even
uglier, which serves as another reminder that using std::bind (and even
more so, boost::bind) should be avoided.
nirio/rpc/rpc_client.cpp still contains a reference to boost::bind. It
was not possible to remove it by simply doing a search and replace, so
it will be removed in a separate commit.
2019-10-16 23:21:19 +00:00
|
|
|
#include <functional>
|
2019-10-17 23:01:22 +00:00
|
|
|
#include <tuple>
|
2010-01-13 00:59:03 +00:00
|
|
|
|
2010-02-10 00:28:16 +00:00
|
|
|
using namespace uhd;
|
2010-02-21 20:59:41 +00:00
|
|
|
using namespace uhd::usrp;
|
2010-01-15 03:02:55 +00:00
|
|
|
|
2011-04-24 03:03:57 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* dboard key class to use for look-up
|
|
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
class dboard_key_t
|
|
|
|
|
{
|
2011-04-24 03:03:57 +00:00
|
|
|
public:
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_key_t(const dboard_id_t& id = dboard_id_t::none(), bool restricted = false)
|
|
|
|
|
: _rx_id(id), _tx_id(id), _xcvr(false), _restricted(restricted)
|
|
|
|
|
{
|
|
|
|
|
}
|
2011-04-24 03:03:57 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_key_t(
|
|
|
|
|
const dboard_id_t& rx_id, const dboard_id_t& tx_id, bool restricted = false)
|
|
|
|
|
: _rx_id(rx_id), _tx_id(tx_id), _xcvr(true), _restricted(restricted)
|
|
|
|
|
{
|
|
|
|
|
}
|
2011-04-24 03:03:57 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_id_t xx_id(void) const
|
|
|
|
|
{
|
2011-04-24 03:03:57 +00:00
|
|
|
UHD_ASSERT_THROW(not this->is_xcvr());
|
|
|
|
|
return this->_rx_id;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_id_t rx_id(void) const
|
|
|
|
|
{
|
2011-04-24 03:03:57 +00:00
|
|
|
UHD_ASSERT_THROW(this->is_xcvr());
|
|
|
|
|
return this->_rx_id;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_id_t tx_id(void) const
|
|
|
|
|
{
|
2011-04-24 03:03:57 +00:00
|
|
|
UHD_ASSERT_THROW(this->is_xcvr());
|
|
|
|
|
return this->_tx_id;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
bool is_xcvr(void) const
|
|
|
|
|
{
|
2011-04-24 03:03:57 +00:00
|
|
|
return this->_xcvr;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
bool is_restricted(void) const
|
|
|
|
|
{
|
2015-09-30 21:53:35 +00:00
|
|
|
return this->_restricted;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-24 03:03:57 +00:00
|
|
|
private:
|
|
|
|
|
dboard_id_t _rx_id, _tx_id;
|
|
|
|
|
bool _xcvr;
|
2015-09-30 21:53:35 +00:00
|
|
|
bool _restricted;
|
2011-04-24 03:03:57 +00:00
|
|
|
};
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
bool operator==(const dboard_key_t& lhs, const dboard_key_t& rhs)
|
|
|
|
|
{
|
2011-04-24 03:03:57 +00:00
|
|
|
if (lhs.is_xcvr() and rhs.is_xcvr())
|
|
|
|
|
return lhs.rx_id() == rhs.rx_id() and lhs.tx_id() == rhs.tx_id();
|
|
|
|
|
if (not lhs.is_xcvr() and not rhs.is_xcvr())
|
|
|
|
|
return lhs.xx_id() == rhs.xx_id();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-15 03:02:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* storage and registering for dboards
|
|
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
// dboard registry tuple: dboard constructor, canonical name, subdev names, container
|
|
|
|
|
// constructor
|
|
|
|
|
typedef std::tuple<dboard_manager::dboard_ctor_t,
|
|
|
|
|
std::string,
|
|
|
|
|
std::vector<std::string>,
|
|
|
|
|
dboard_manager::dboard_ctor_t>
|
|
|
|
|
args_t;
|
|
|
|
|
|
|
|
|
|
// map a dboard id to a dboard constructor
|
2011-04-24 03:03:57 +00:00
|
|
|
typedef uhd::dict<dboard_key_t, args_t> id_to_args_map_t;
|
2010-03-27 08:02:58 +00:00
|
|
|
UHD_SINGLETON_FCN(id_to_args_map_t, get_id_to_args_map)
|
2010-01-15 03:02:55 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
static void register_dboard_key(const dboard_key_t& dboard_key,
|
2016-02-20 01:42:44 +00:00
|
|
|
dboard_manager::dboard_ctor_t db_subdev_ctor,
|
2020-03-02 23:25:13 +00:00
|
|
|
const std::string& name,
|
|
|
|
|
const std::vector<std::string>& subdev_names,
|
|
|
|
|
dboard_manager::dboard_ctor_t db_container_ctor)
|
|
|
|
|
{
|
2017-05-20 00:43:26 +00:00
|
|
|
// UHD_LOGGER_TRACE("DBMGR") << "registering: " << name;
|
2020-03-02 23:25:13 +00:00
|
|
|
if (get_id_to_args_map().has_key(dboard_key)) {
|
|
|
|
|
if (dboard_key.is_xcvr())
|
|
|
|
|
throw uhd::key_error(str(
|
|
|
|
|
boost::format("The dboard id pair [%s, %s] is already registered to %s.")
|
|
|
|
|
% dboard_key.rx_id().to_string() % dboard_key.tx_id().to_string()
|
|
|
|
|
% std::get<1>(get_id_to_args_map()[dboard_key])));
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
throw uhd::key_error(
|
|
|
|
|
str(boost::format("The dboard id %s is already registered to %s.")
|
|
|
|
|
% dboard_key.xx_id().to_string()
|
|
|
|
|
% std::get<1>(get_id_to_args_map()[dboard_key])));
|
2010-03-15 19:15:33 +00:00
|
|
|
}
|
2020-03-02 23:25:13 +00:00
|
|
|
get_id_to_args_map()[dboard_key] =
|
|
|
|
|
args_t(db_subdev_ctor, name, subdev_names, db_container_ctor);
|
2010-01-15 03:02:55 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void dboard_manager::register_dboard(const dboard_id_t& dboard_id,
|
2016-02-20 01:42:44 +00:00
|
|
|
dboard_ctor_t db_subdev_ctor,
|
2020-03-02 23:25:13 +00:00
|
|
|
const std::string& name,
|
|
|
|
|
const std::vector<std::string>& subdev_names,
|
|
|
|
|
dboard_ctor_t db_container_ctor)
|
|
|
|
|
{
|
|
|
|
|
register_dboard_key(
|
|
|
|
|
dboard_key_t(dboard_id), db_subdev_ctor, name, subdev_names, db_container_ctor);
|
2011-04-24 03:03:57 +00:00
|
|
|
}
|
2010-06-19 00:20:46 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void dboard_manager::register_dboard(const dboard_id_t& rx_dboard_id,
|
|
|
|
|
const dboard_id_t& tx_dboard_id,
|
2016-02-20 01:42:44 +00:00
|
|
|
dboard_ctor_t db_subdev_ctor,
|
2020-03-02 23:25:13 +00:00
|
|
|
const std::string& name,
|
|
|
|
|
const std::vector<std::string>& subdev_names,
|
|
|
|
|
dboard_ctor_t db_container_ctor)
|
|
|
|
|
{
|
|
|
|
|
register_dboard_key(dboard_key_t(rx_dboard_id, tx_dboard_id),
|
|
|
|
|
db_subdev_ctor,
|
|
|
|
|
name,
|
|
|
|
|
subdev_names,
|
|
|
|
|
db_container_ctor);
|
2010-06-18 23:39:45 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void dboard_manager::register_dboard_restricted(const dboard_id_t& dboard_id,
|
2016-02-20 01:42:44 +00:00
|
|
|
dboard_ctor_t db_subdev_ctor,
|
2020-03-02 23:25:13 +00:00
|
|
|
const std::string& name,
|
|
|
|
|
const std::vector<std::string>& subdev_names,
|
|
|
|
|
dboard_ctor_t db_container_ctor)
|
|
|
|
|
{
|
|
|
|
|
register_dboard_key(dboard_key_t(dboard_id, true),
|
|
|
|
|
db_subdev_ctor,
|
|
|
|
|
name,
|
|
|
|
|
subdev_names,
|
|
|
|
|
db_container_ctor);
|
2015-09-30 21:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void dboard_manager::register_dboard_restricted(const dboard_id_t& rx_dboard_id,
|
|
|
|
|
const dboard_id_t& tx_dboard_id,
|
2016-02-20 01:42:44 +00:00
|
|
|
dboard_ctor_t db_subdev_ctor,
|
2020-03-02 23:25:13 +00:00
|
|
|
const std::string& name,
|
|
|
|
|
const std::vector<std::string>& subdev_names,
|
|
|
|
|
dboard_ctor_t db_container_ctor)
|
|
|
|
|
{
|
|
|
|
|
register_dboard_key(dboard_key_t(rx_dboard_id, tx_dboard_id, true),
|
|
|
|
|
db_subdev_ctor,
|
|
|
|
|
name,
|
|
|
|
|
subdev_names,
|
|
|
|
|
db_container_ctor);
|
2015-09-30 21:53:35 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
std::string dboard_id_t::to_cname(void) const
|
|
|
|
|
{
|
2011-04-24 03:03:57 +00:00
|
|
|
std::string cname;
|
2020-03-02 23:25:13 +00:00
|
|
|
for (const dboard_key_t& key : get_id_to_args_map().keys()) {
|
|
|
|
|
if ((not key.is_xcvr() and *this == key.xx_id())
|
|
|
|
|
or (key.is_xcvr() and (*this == key.rx_id() or *this == key.tx_id()))) {
|
|
|
|
|
if (not cname.empty())
|
|
|
|
|
cname += ", ";
|
2019-10-17 23:01:22 +00:00
|
|
|
cname += std::get<1>(get_id_to_args_map()[key]);
|
2011-04-24 03:03:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-03-02 23:25:13 +00:00
|
|
|
return (cname.empty()) ? "Unknown" : cname;
|
2010-10-21 00:41:59 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
std::string dboard_id_t::to_pp_string(void) const
|
|
|
|
|
{
|
2010-10-21 00:41:59 +00:00
|
|
|
return str(boost::format("%s (%s)") % this->to_cname() % this->to_string());
|
2010-03-11 03:33:38 +00:00
|
|
|
}
|
|
|
|
|
|
2010-03-12 02:37:34 +00:00
|
|
|
/***********************************************************************
|
|
|
|
|
* dboard manager implementation class
|
|
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
class dboard_manager_impl : public dboard_manager
|
|
|
|
|
{
|
2010-03-12 02:37:34 +00:00
|
|
|
public:
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_manager_impl(dboard_eeprom_t rx_eeprom,
|
2017-12-05 23:49:28 +00:00
|
|
|
dboard_eeprom_t tx_eeprom,
|
2011-07-30 17:11:49 +00:00
|
|
|
dboard_iface::sptr iface,
|
2016-07-29 01:14:20 +00:00
|
|
|
property_tree::sptr subtree,
|
2020-03-02 23:25:13 +00:00
|
|
|
bool defer_db_init);
|
2016-02-26 22:36:26 +00:00
|
|
|
virtual ~dboard_manager_impl(void);
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
inline const std::vector<std::string>& get_rx_frontends() const
|
|
|
|
|
{
|
2016-02-26 22:36:26 +00:00
|
|
|
return _rx_frontends;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
inline const std::vector<std::string>& get_tx_frontends() const
|
|
|
|
|
{
|
2016-02-26 22:36:26 +00:00
|
|
|
return _tx_frontends;
|
|
|
|
|
}
|
2010-03-12 02:37:34 +00:00
|
|
|
|
2016-07-29 01:14:20 +00:00
|
|
|
void initialize_dboards();
|
|
|
|
|
|
2010-03-12 02:37:34 +00:00
|
|
|
private:
|
2017-12-05 23:49:28 +00:00
|
|
|
void init(dboard_eeprom_t, dboard_eeprom_t, property_tree::sptr, bool);
|
2020-03-02 23:25:13 +00:00
|
|
|
// list of rx and tx dboards in this dboard_manager
|
|
|
|
|
// each dboard here is actually a subdevice proxy
|
|
|
|
|
// the subdevice proxy is internal to the cpp file
|
2011-07-30 17:11:49 +00:00
|
|
|
uhd::dict<std::string, dboard_base::sptr> _rx_dboards;
|
|
|
|
|
uhd::dict<std::string, dboard_base::sptr> _tx_dboards;
|
2020-03-02 23:25:13 +00:00
|
|
|
std::vector<dboard_base::sptr> _rx_containers;
|
|
|
|
|
std::vector<dboard_base::sptr> _tx_containers;
|
|
|
|
|
std::vector<std::string> _rx_frontends;
|
|
|
|
|
std::vector<std::string> _tx_frontends;
|
2010-04-14 15:41:13 +00:00
|
|
|
dboard_iface::sptr _iface;
|
2010-04-13 02:37:38 +00:00
|
|
|
void set_nice_dboard_if(void);
|
2010-03-12 02:37:34 +00:00
|
|
|
};
|
|
|
|
|
|
2010-01-13 00:59:03 +00:00
|
|
|
/***********************************************************************
|
2010-02-22 08:37:53 +00:00
|
|
|
* make routine for dboard manager
|
|
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_manager::sptr dboard_manager::make(dboard_id_t rx_dboard_id,
|
2017-12-06 00:00:44 +00:00
|
|
|
dboard_id_t tx_dboard_id,
|
|
|
|
|
dboard_id_t gdboard_id,
|
|
|
|
|
dboard_iface::sptr iface,
|
|
|
|
|
property_tree::sptr subtree,
|
2020-03-02 23:25:13 +00:00
|
|
|
bool defer_db_init)
|
|
|
|
|
{
|
2017-12-06 00:00:44 +00:00
|
|
|
dboard_eeprom_t rx_eeprom;
|
|
|
|
|
dboard_eeprom_t tx_eeprom;
|
|
|
|
|
rx_eeprom.id = rx_dboard_id;
|
|
|
|
|
tx_eeprom.id = (gdboard_id == dboard_id_t::none()) ? tx_dboard_id : gdboard_id;
|
|
|
|
|
return dboard_manager::sptr(
|
2020-03-02 23:25:13 +00:00
|
|
|
new dboard_manager_impl(rx_eeprom, tx_eeprom, iface, subtree, defer_db_init));
|
2017-12-06 00:00:44 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_manager::sptr dboard_manager::make(dboard_eeprom_t rx_eeprom,
|
2017-12-05 23:49:28 +00:00
|
|
|
dboard_eeprom_t tx_eeprom,
|
|
|
|
|
dboard_eeprom_t gdb_eeprom,
|
2011-07-30 17:11:49 +00:00
|
|
|
dboard_iface::sptr iface,
|
2016-07-29 01:14:20 +00:00
|
|
|
property_tree::sptr subtree,
|
2020-03-02 23:25:13 +00:00
|
|
|
bool defer_db_init)
|
|
|
|
|
{
|
|
|
|
|
return dboard_manager::sptr(new dboard_manager_impl(rx_eeprom,
|
|
|
|
|
(gdb_eeprom.id == dboard_id_t::none()) ? tx_eeprom : gdb_eeprom,
|
|
|
|
|
iface,
|
|
|
|
|
subtree,
|
|
|
|
|
defer_db_init));
|
2010-02-22 08:37:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
|
* implementation class methods
|
2010-01-13 00:59:03 +00:00
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_manager_impl::dboard_manager_impl(dboard_eeprom_t rx_eeprom,
|
2017-12-05 23:49:28 +00:00
|
|
|
dboard_eeprom_t tx_eeprom,
|
2011-07-30 17:11:49 +00:00
|
|
|
dboard_iface::sptr iface,
|
2016-07-29 01:14:20 +00:00
|
|
|
property_tree::sptr subtree,
|
2020-03-02 23:25:13 +00:00
|
|
|
bool defer_db_init)
|
|
|
|
|
: _iface(iface)
|
2011-02-22 19:55:54 +00:00
|
|
|
{
|
2020-03-02 23:25:13 +00:00
|
|
|
try {
|
2017-12-05 23:49:28 +00:00
|
|
|
this->init(rx_eeprom, tx_eeprom, subtree, defer_db_init);
|
2020-03-02 23:25:13 +00:00
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
UHD_LOGGER_ERROR("DBMGR")
|
|
|
|
|
<< boost::format(
|
|
|
|
|
"The daughterboard manager encountered a recoverable error in init.\n"
|
|
|
|
|
"Loading the \"unknown\" daughterboard implementations to continue.\n"
|
|
|
|
|
"The daughterboard cannot operate until this error is resolved.\n")
|
|
|
|
|
<< e.what();
|
|
|
|
|
// clean up the stuff added by the call above
|
|
|
|
|
if (subtree->exists("rx_frontends"))
|
|
|
|
|
subtree->remove("rx_frontends");
|
|
|
|
|
if (subtree->exists("tx_frontends"))
|
|
|
|
|
subtree->remove("tx_frontends");
|
|
|
|
|
if (subtree->exists("iface"))
|
|
|
|
|
subtree->remove("iface");
|
2017-12-05 23:49:28 +00:00
|
|
|
dboard_eeprom_t dummy_eeprom;
|
|
|
|
|
dummy_eeprom.id = dboard_id_t::none();
|
|
|
|
|
this->init(dummy_eeprom, dummy_eeprom, subtree, false);
|
2011-02-22 19:55:54 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-02-19 01:48:14 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void dboard_manager_impl::init(dboard_eeprom_t rx_eeprom,
|
2017-12-05 23:49:28 +00:00
|
|
|
dboard_eeprom_t tx_eeprom,
|
|
|
|
|
property_tree::sptr subtree,
|
2020-03-02 23:25:13 +00:00
|
|
|
bool defer_db_init)
|
|
|
|
|
{
|
|
|
|
|
// find the dboard key matches for the dboard ids
|
2011-04-24 03:03:57 +00:00
|
|
|
dboard_key_t rx_dboard_key, tx_dboard_key, xcvr_dboard_key;
|
2020-03-02 23:25:13 +00:00
|
|
|
for (const dboard_key_t& key : get_id_to_args_map().keys()) {
|
|
|
|
|
if (key.is_xcvr()) {
|
|
|
|
|
if (rx_eeprom.id == key.rx_id() and tx_eeprom.id == key.tx_id())
|
|
|
|
|
xcvr_dboard_key = key;
|
|
|
|
|
if (rx_eeprom.id == key.rx_id())
|
|
|
|
|
rx_dboard_key = key; // kept to handle warning
|
|
|
|
|
if (rx_eeprom.id == key.tx_id())
|
|
|
|
|
tx_dboard_key = key; // kept to handle warning
|
|
|
|
|
} else {
|
|
|
|
|
if (rx_eeprom.id == key.xx_id())
|
|
|
|
|
rx_dboard_key = key;
|
|
|
|
|
if (tx_eeprom.id == key.xx_id())
|
|
|
|
|
tx_dboard_key = key;
|
2011-04-24 03:03:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
2010-06-19 00:20:46 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// warn for invalid dboard id xcvr combinations
|
|
|
|
|
if (not xcvr_dboard_key.is_xcvr()
|
|
|
|
|
and (rx_dboard_key.is_xcvr() or tx_dboard_key.is_xcvr())) {
|
|
|
|
|
UHD_LOGGER_WARNING("DBMGR")
|
|
|
|
|
<< boost::format("Unknown transceiver board ID combination.\n"
|
|
|
|
|
"Is your daughter-board mounted properly?\n"
|
|
|
|
|
"RX dboard ID: %s\n"
|
|
|
|
|
"TX dboard ID: %s\n")
|
|
|
|
|
% rx_eeprom.id.to_pp_string() % tx_eeprom.id.to_pp_string();
|
2010-09-28 17:21:11 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// initialize the gpio pins before creating subdevs
|
2010-04-13 02:37:38 +00:00
|
|
|
set_nice_dboard_if();
|
2010-02-18 00:23:12 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// conditionally register the dboard iface in the tree
|
|
|
|
|
if (not(rx_dboard_key.is_restricted() or tx_dboard_key.is_restricted()
|
|
|
|
|
or xcvr_dboard_key.is_restricted())) {
|
2015-09-30 21:53:35 +00:00
|
|
|
subtree->create<dboard_iface::sptr>("iface").set(_iface);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// dboard constructor args
|
2010-07-22 17:26:48 +00:00
|
|
|
dboard_ctor_args_t db_ctor_args;
|
2011-02-22 19:55:54 +00:00
|
|
|
db_ctor_args.db_iface = _iface;
|
2010-05-02 23:03:46 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// make xcvr subdevs
|
|
|
|
|
if (xcvr_dboard_key.is_xcvr()) {
|
|
|
|
|
// extract data for the xcvr dboard key
|
|
|
|
|
dboard_ctor_t subdev_ctor;
|
|
|
|
|
std::string name;
|
|
|
|
|
std::vector<std::string> subdevs;
|
|
|
|
|
dboard_ctor_t container_ctor;
|
|
|
|
|
std::tie(subdev_ctor, name, subdevs, container_ctor) =
|
|
|
|
|
get_id_to_args_map()[xcvr_dboard_key];
|
|
|
|
|
|
|
|
|
|
// create the container class.
|
|
|
|
|
// a container class exists per N subdevs registered in a register_dboard* call
|
|
|
|
|
db_ctor_args.sd_name = "common";
|
|
|
|
|
db_ctor_args.rx_eeprom = rx_eeprom;
|
|
|
|
|
db_ctor_args.tx_eeprom = tx_eeprom;
|
|
|
|
|
db_ctor_args.rx_subtree =
|
|
|
|
|
subtree->subtree("rx_frontends/" + db_ctor_args.sd_name);
|
|
|
|
|
db_ctor_args.tx_subtree =
|
|
|
|
|
subtree->subtree("tx_frontends/" + db_ctor_args.sd_name);
|
2016-02-20 01:42:44 +00:00
|
|
|
if (container_ctor) {
|
|
|
|
|
db_ctor_args.rx_container = container_ctor(&db_ctor_args);
|
|
|
|
|
} else {
|
|
|
|
|
db_ctor_args.rx_container = dboard_base::sptr();
|
|
|
|
|
}
|
2020-03-02 23:25:13 +00:00
|
|
|
db_ctor_args.tx_container = db_ctor_args.rx_container; // Same TX and RX container
|
2011-04-24 03:03:57 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// create the xcvr object for each subdevice
|
|
|
|
|
for (const std::string& subdev : subdevs) {
|
2010-05-02 23:03:46 +00:00
|
|
|
db_ctor_args.sd_name = subdev;
|
2020-03-02 23:25:13 +00:00
|
|
|
db_ctor_args.rx_subtree =
|
|
|
|
|
subtree->subtree("rx_frontends/" + db_ctor_args.sd_name);
|
|
|
|
|
db_ctor_args.tx_subtree =
|
|
|
|
|
subtree->subtree("tx_frontends/" + db_ctor_args.sd_name);
|
2016-02-20 01:42:44 +00:00
|
|
|
dboard_base::sptr xcvr_dboard = subdev_ctor(&db_ctor_args);
|
2020-03-02 23:25:13 +00:00
|
|
|
_rx_dboards[subdev] = xcvr_dboard;
|
|
|
|
|
_tx_dboards[subdev] = xcvr_dboard;
|
2016-02-20 01:42:44 +00:00
|
|
|
xcvr_dboard->initialize();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// initialize the container after all subdevs have been created
|
2016-02-20 01:42:44 +00:00
|
|
|
if (container_ctor) {
|
2016-07-29 01:14:20 +00:00
|
|
|
if (defer_db_init) {
|
|
|
|
|
_rx_containers.push_back(db_ctor_args.rx_container);
|
|
|
|
|
} else {
|
|
|
|
|
db_ctor_args.rx_container->initialize();
|
|
|
|
|
}
|
2010-01-15 23:45:33 +00:00
|
|
|
}
|
2016-02-26 22:36:26 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// Populate frontend names in-order.
|
|
|
|
|
// We cannot use _xx_dboards.keys() here because of the ordering requirement
|
2016-02-26 22:36:26 +00:00
|
|
|
_rx_frontends = subdevs;
|
|
|
|
|
_tx_frontends = subdevs;
|
2010-01-15 23:45:33 +00:00
|
|
|
}
|
2010-02-18 00:23:12 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// make tx and rx subdevs (separate subdevs for rx and tx dboards)
|
|
|
|
|
else {
|
|
|
|
|
// force the rx key to the unknown board for bad combinations
|
|
|
|
|
if (rx_dboard_key.is_xcvr() or rx_dboard_key.xx_id() == dboard_id_t::none()) {
|
2011-04-24 03:03:57 +00:00
|
|
|
rx_dboard_key = dboard_key_t(0xfff1);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// extract data for the rx dboard key
|
|
|
|
|
dboard_ctor_t rx_dboard_ctor;
|
|
|
|
|
std::string rx_name;
|
|
|
|
|
std::vector<std::string> rx_subdevs;
|
|
|
|
|
dboard_ctor_t rx_cont_ctor;
|
|
|
|
|
std::tie(rx_dboard_ctor, rx_name, rx_subdevs, rx_cont_ctor) =
|
|
|
|
|
get_id_to_args_map()[rx_dboard_key];
|
|
|
|
|
|
|
|
|
|
// create the container class.
|
|
|
|
|
// a container class exists per N subdevs registered in a register_dboard* call
|
|
|
|
|
db_ctor_args.sd_name = "common";
|
|
|
|
|
db_ctor_args.rx_eeprom = rx_eeprom;
|
2017-12-05 23:49:28 +00:00
|
|
|
db_ctor_args.tx_eeprom.id = dboard_id_t::none();
|
2020-03-02 23:25:13 +00:00
|
|
|
db_ctor_args.rx_subtree =
|
|
|
|
|
subtree->subtree("rx_frontends/" + db_ctor_args.sd_name);
|
2016-02-20 01:42:44 +00:00
|
|
|
db_ctor_args.tx_subtree = property_tree::sptr();
|
|
|
|
|
if (rx_cont_ctor) {
|
|
|
|
|
db_ctor_args.rx_container = rx_cont_ctor(&db_ctor_args);
|
|
|
|
|
} else {
|
|
|
|
|
db_ctor_args.rx_container = dboard_base::sptr();
|
|
|
|
|
}
|
2011-04-24 03:03:57 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// make the rx subdevs
|
|
|
|
|
for (const std::string& subdev : rx_subdevs) {
|
2010-05-02 23:03:46 +00:00
|
|
|
db_ctor_args.sd_name = subdev;
|
2020-03-02 23:25:13 +00:00
|
|
|
db_ctor_args.rx_subtree =
|
|
|
|
|
subtree->subtree("rx_frontends/" + db_ctor_args.sd_name);
|
2011-07-30 17:11:49 +00:00
|
|
|
_rx_dboards[subdev] = rx_dboard_ctor(&db_ctor_args);
|
2016-02-20 01:42:44 +00:00
|
|
|
_rx_dboards[subdev]->initialize();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// initialize the container after all subdevs have been created
|
2016-02-20 01:42:44 +00:00
|
|
|
if (rx_cont_ctor) {
|
2016-07-29 01:14:20 +00:00
|
|
|
if (defer_db_init) {
|
|
|
|
|
_rx_containers.push_back(db_ctor_args.rx_container);
|
|
|
|
|
} else {
|
|
|
|
|
db_ctor_args.rx_container->initialize();
|
|
|
|
|
}
|
2010-01-15 23:45:33 +00:00
|
|
|
}
|
2011-04-24 03:03:57 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// force the tx key to the unknown board for bad combinations
|
|
|
|
|
if (tx_dboard_key.is_xcvr() or tx_dboard_key.xx_id() == dboard_id_t::none()) {
|
2011-04-24 03:03:57 +00:00
|
|
|
tx_dboard_key = dboard_key_t(0xfff0);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// extract data for the tx dboard key
|
|
|
|
|
dboard_ctor_t tx_dboard_ctor;
|
|
|
|
|
std::string tx_name;
|
|
|
|
|
std::vector<std::string> tx_subdevs;
|
|
|
|
|
dboard_ctor_t tx_cont_ctor;
|
|
|
|
|
std::tie(tx_dboard_ctor, tx_name, tx_subdevs, tx_cont_ctor) =
|
|
|
|
|
get_id_to_args_map()[tx_dboard_key];
|
|
|
|
|
|
|
|
|
|
// create the container class.
|
|
|
|
|
// a container class exists per N subdevs registered in a register_dboard* call
|
|
|
|
|
db_ctor_args.sd_name = "common";
|
2017-12-05 23:49:28 +00:00
|
|
|
db_ctor_args.rx_eeprom.id = dboard_id_t::none();
|
2020-03-02 23:25:13 +00:00
|
|
|
db_ctor_args.tx_eeprom = tx_eeprom;
|
|
|
|
|
db_ctor_args.rx_subtree = property_tree::sptr();
|
|
|
|
|
db_ctor_args.tx_subtree =
|
|
|
|
|
subtree->subtree("tx_frontends/" + db_ctor_args.sd_name);
|
2016-02-20 01:42:44 +00:00
|
|
|
if (tx_cont_ctor) {
|
|
|
|
|
db_ctor_args.tx_container = tx_cont_ctor(&db_ctor_args);
|
|
|
|
|
} else {
|
|
|
|
|
db_ctor_args.tx_container = dboard_base::sptr();
|
|
|
|
|
}
|
2011-04-24 03:03:57 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// make the tx subdevs
|
|
|
|
|
for (const std::string& subdev : tx_subdevs) {
|
2010-05-02 23:03:46 +00:00
|
|
|
db_ctor_args.sd_name = subdev;
|
2020-03-02 23:25:13 +00:00
|
|
|
db_ctor_args.tx_subtree =
|
|
|
|
|
subtree->subtree("tx_frontends/" + db_ctor_args.sd_name);
|
2011-07-30 17:11:49 +00:00
|
|
|
_tx_dboards[subdev] = tx_dboard_ctor(&db_ctor_args);
|
2016-02-20 01:42:44 +00:00
|
|
|
_tx_dboards[subdev]->initialize();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// initialize the container after all subdevs have been created
|
2016-02-20 01:42:44 +00:00
|
|
|
if (tx_cont_ctor) {
|
2016-07-29 01:14:20 +00:00
|
|
|
if (defer_db_init) {
|
|
|
|
|
_tx_containers.push_back(db_ctor_args.tx_container);
|
|
|
|
|
} else {
|
|
|
|
|
db_ctor_args.tx_container->initialize();
|
|
|
|
|
}
|
2010-01-15 23:45:33 +00:00
|
|
|
}
|
2016-02-26 22:36:26 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// Populate frontend names in-order.
|
|
|
|
|
// We cannot use _xx_dboards.keys() here because of the ordering requirement
|
2016-02-26 22:36:26 +00:00
|
|
|
_rx_frontends = rx_subdevs;
|
|
|
|
|
_tx_frontends = tx_subdevs;
|
2010-01-15 23:45:33 +00:00
|
|
|
}
|
2010-01-13 00:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void dboard_manager_impl::initialize_dboards(void)
|
|
|
|
|
{
|
|
|
|
|
for (dboard_base::sptr& _rx_container : _rx_containers) {
|
2016-07-29 01:14:20 +00:00
|
|
|
_rx_container->initialize();
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
for (dboard_base::sptr& _tx_container : _tx_containers) {
|
2016-07-29 01:14:20 +00:00
|
|
|
_tx_container->initialize();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_manager_impl::~dboard_manager_impl(void)
|
|
|
|
|
{
|
|
|
|
|
UHD_SAFE_CALL(set_nice_dboard_if();)
|
|
|
|
|
}
|
2010-01-13 00:59:03 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void dboard_manager_impl::set_nice_dboard_if(void)
|
|
|
|
|
{
|
|
|
|
|
// make a list of possible unit types
|
2018-04-26 20:13:32 +00:00
|
|
|
const std::vector<dboard_iface::unit_t> units{
|
2020-03-02 23:25:13 +00:00
|
|
|
dboard_iface::UNIT_RX, dboard_iface::UNIT_TX};
|
|
|
|
|
|
|
|
|
|
// set nice settings on each unit
|
|
|
|
|
for (dboard_iface::unit_t unit : units) {
|
|
|
|
|
_iface->set_gpio_ddr(unit, 0x0000); // all inputs
|
|
|
|
|
_iface->set_gpio_out(unit, 0x0000); // all low
|
|
|
|
|
_iface->set_pin_ctrl(unit, 0x0000); // all gpio
|
|
|
|
|
_iface->set_clock_enabled(unit, false); // clock off
|
2010-04-13 02:37:38 +00:00
|
|
|
}
|
2011-06-28 03:26:52 +00:00
|
|
|
}
|