aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/usrp_uhd/usrp/dboard/base.hpp11
-rw-r--r--include/usrp_uhd/usrp/dboard/manager.hpp39
-rw-r--r--lib/usrp/dboard/base.cpp12
-rw-r--r--lib/usrp/dboard/basic.cpp6
-rw-r--r--lib/usrp/dboard/dboards.hpp10
-rw-r--r--lib/usrp/dboard/manager.cpp109
6 files changed, 153 insertions, 34 deletions
diff --git a/include/usrp_uhd/usrp/dboard/base.hpp b/include/usrp_uhd/usrp/dboard/base.hpp
index 86ab7dde6..09cc9b324 100644
--- a/include/usrp_uhd/usrp/dboard/base.hpp
+++ b/include/usrp_uhd/usrp/dboard/base.hpp
@@ -8,6 +8,7 @@
#include <usrp_uhd/wax.hpp>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/tuple/tuple.hpp>
#include <usrp_uhd/usrp/dboard/interface.hpp>
namespace usrp_uhd{ namespace usrp{ namespace dboard{
@@ -19,9 +20,13 @@ namespace usrp_uhd{ namespace usrp{ namespace dboard{
class xcvr_base : boost::noncopyable{
public:
typedef boost::shared_ptr<xcvr_base> sptr;
+ //the constructor args consist of a subdev index and an interface
+ //derived classes should pass the args into the base class ctor
+ //but should not have to deal with the internals of the args
+ typedef boost::tuple<size_t, interface::sptr> ctor_args_t;
//structors
- xcvr_base(size_t subdev_index, interface::sptr dboard_interface);
+ xcvr_base(ctor_args_t const&);
~xcvr_base(void);
//interface
@@ -48,7 +53,7 @@ public:
/*!
* Create a new rx dboard object, override in subclasses.
*/
- rx_base(size_t subdev_index, interface::sptr sptr_interface);
+ rx_base(ctor_args_t const&);
virtual ~rx_base(void);
@@ -66,7 +71,7 @@ public:
/*!
* Create a new rx dboard object, override in subclasses.
*/
- tx_base(size_t subdev_index, interface::sptr sptr_interface);
+ tx_base(ctor_args_t const&);
virtual ~tx_base(void);
diff --git a/include/usrp_uhd/usrp/dboard/manager.hpp b/include/usrp_uhd/usrp/dboard/manager.hpp
index 29aca83f0..788b8a6eb 100644
--- a/include/usrp_uhd/usrp/dboard/manager.hpp
+++ b/include/usrp_uhd/usrp/dboard/manager.hpp
@@ -8,6 +8,7 @@
#include <vector>
#include <usrp_uhd/wax.hpp>
#include <boost/utility.hpp>
+#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <usrp_uhd/usrp/dboard/base.hpp>
@@ -19,12 +20,46 @@ namespace usrp_uhd{ namespace usrp{ namespace dboard{
* Provide wax::obj access to the subdevs inside.
*/
class manager : boost::noncopyable{
+
+public:
+ //a dboard can be identified by a 16 bit integer
+ typedef uint16_t dboard_id_t;
+
+ //dboard constructor (each dboard should have a ::make with this signature)
+ typedef boost::function<xcvr_base::sptr(xcvr_base::ctor_args_t)> dboard_ctor_t;
+
+ /*!
+ * Register rx subdevices for a given dboard id.
+ *
+ * \param dboard_id the rx dboard id
+ * \param dboard_ctor the dboard constructor function pointer
+ * \param num_subdevs the number of rx subdevs in this dboard
+ */
+ static void register_rx_subdev(
+ dboard_id_t dboard_id,
+ dboard_ctor_t dboard_ctor,
+ size_t num_subdevs
+ );
+
+ /*!
+ * Register tx subdevices for a given dboard id.
+ *
+ * \param dboard_id the tx dboard id
+ * \param dboard_ctor the dboard constructor function pointer
+ * \param num_subdevs the number of tx subdevs in this dboard
+ */
+ static void register_tx_subdev(
+ dboard_id_t dboard_id,
+ dboard_ctor_t dboard_ctor,
+ size_t num_subdevs
+ );
+
public:
typedef boost::shared_ptr<manager> sptr;
//structors
manager(
- uint16_t rx_dboard_id,
- uint16_t tx_dboard_id,
+ dboard_id_t rx_dboard_id,
+ dboard_id_t tx_dboard_id,
interface::sptr dboard_interface
);
~manager(void);
diff --git a/lib/usrp/dboard/base.cpp b/lib/usrp/dboard/base.cpp
index c3fc332c9..4fbe4df8c 100644
--- a/lib/usrp/dboard/base.cpp
+++ b/lib/usrp/dboard/base.cpp
@@ -9,8 +9,8 @@ using namespace usrp_uhd::usrp::dboard;
/***********************************************************************
* xcvr dboard base class
**********************************************************************/
-xcvr_base::xcvr_base(size_t subdev_index, interface::sptr dboard_interface)
- : _subdev_index(subdev_index), _dboard_interface(dboard_interface){
+xcvr_base::xcvr_base(ctor_args_t const& args)
+ : _subdev_index(args.get<0>()), _dboard_interface(args.get<1>()){
/* NOP */
}
@@ -29,8 +29,8 @@ interface::sptr xcvr_base::get_interface(void){
/***********************************************************************
* rx dboard base class
**********************************************************************/
-rx_base::rx_base(size_t subdev_index, interface::sptr dboard_interface)
-: xcvr_base(subdev_index, dboard_interface){
+rx_base::rx_base(ctor_args_t const& args)
+: xcvr_base(args){
/* NOP */
}
@@ -49,8 +49,8 @@ void rx_base::tx_set(const wax::type &, const wax::type &){
/***********************************************************************
* tx dboard base class
**********************************************************************/
-tx_base::tx_base(size_t subdev_index, interface::sptr dboard_interface)
-: xcvr_base(subdev_index, dboard_interface){
+tx_base::tx_base(ctor_args_t const& args)
+: xcvr_base(args){
/* NOP */
}
diff --git a/lib/usrp/dboard/basic.cpp b/lib/usrp/dboard/basic.cpp
index 1c746815c..66358f0bb 100644
--- a/lib/usrp/dboard/basic.cpp
+++ b/lib/usrp/dboard/basic.cpp
@@ -7,8 +7,7 @@
/***********************************************************************
* Basic RX dboard
**********************************************************************/
-basic_rx::basic_rx(size_t subdev_index, interface::sptr dboard_interface)
-: rx_base(subdev_index, dboard_interface){
+basic_rx::basic_rx(ctor_args_t const& args) : rx_base(args){
/* NOP */
}
@@ -27,8 +26,7 @@ void basic_rx::rx_set(const wax::type &, const wax::type &){
/***********************************************************************
* Basic TX dboard
**********************************************************************/
-basic_tx::basic_tx(size_t subdev_index, interface::sptr dboard_interface)
-: tx_base(subdev_index, dboard_interface){
+basic_tx::basic_tx(ctor_args_t const& args) : tx_base(args){
/* NOP */
}
diff --git a/lib/usrp/dboard/dboards.hpp b/lib/usrp/dboard/dboards.hpp
index 0a54ec948..b46b5f590 100644
--- a/lib/usrp/dboard/dboards.hpp
+++ b/lib/usrp/dboard/dboards.hpp
@@ -14,7 +14,10 @@ using namespace usrp_uhd::usrp::dboard;
**********************************************************************/
class basic_rx : public rx_base{
public:
- basic_rx(size_t subdev_index, interface::sptr dboard_interface);
+ static xcvr_base::sptr make(ctor_args_t const& args){
+ return xcvr_base::sptr(new basic_rx(args));
+ }
+ basic_rx(ctor_args_t const& args);
~basic_rx(void);
void rx_get(const wax::type &key, wax::type &val);
@@ -23,7 +26,10 @@ public:
class basic_tx : public tx_base{
public:
- basic_tx(size_t subdev_index, interface::sptr dboard_interface);
+ static xcvr_base::sptr make(ctor_args_t const& args){
+ return xcvr_base::sptr(new basic_tx(args));
+ }
+ basic_tx(ctor_args_t const& args);
~basic_tx(void);
void tx_get(const wax::type &key, wax::type &val);
diff --git a/lib/usrp/dboard/manager.cpp b/lib/usrp/dboard/manager.cpp
index 4ceaf0b56..897b6e304 100644
--- a/lib/usrp/dboard/manager.cpp
+++ b/lib/usrp/dboard/manager.cpp
@@ -3,10 +3,75 @@
//
#include <usrp_uhd/usrp/dboard/manager.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/format.hpp>
+#include <map>
+#include "dboards.hpp"
using namespace usrp_uhd::usrp::dboard;
/***********************************************************************
+ * register internal dboards
+ *
+ * Register internal/known dboards located in this build tree.
+ * Each board should have entries below mapping an id to a constructor.
+ * The xcvr type boards should register both rx and tx sides.
+ *
+ * This function will be called before new boards are registered.
+ * This allows for internal boards to be externally overridden.
+ * This function will also be called when creating a new manager
+ * to ensure that the maps are filled with the entries below.
+ **********************************************************************/
+static void register_internal_dboards(void){
+ //ensure that this function can only be called once per instance
+ static bool called = false;
+ if (called) return; called = true;
+ //register the known dboards (dboard id, constructor, num subdevs)
+ manager::register_tx_subdev(0x0000, &basic_tx::make, 1);
+ manager::register_rx_subdev(0x0001, &basic_rx::make, 3);
+}
+
+/***********************************************************************
+ * storage and registering for dboards
+ **********************************************************************/
+//hold a dboard constructor and the number of subdevs
+typedef boost::tuple<manager::dboard_ctor_t, size_t> dboard_reg_val_t;
+
+//map a dboard id to a registered value tuple
+typedef std::map<manager::dboard_id_t, dboard_reg_val_t> dboard_reg_map_t;
+
+//static instances of registered dboard ids
+static dboard_reg_map_t dboard_rx_regs, dboard_tx_regs;
+
+/*!
+ * Helper function to register a dboard contructor to its id.
+ * This should be called by the api calls to register subdevs.
+ */
+static void register_xx_subdev(
+ manager::dboard_id_t dboard_id,
+ manager::dboard_ctor_t dboard_ctor,
+ size_t num_subdevs,
+ dboard_reg_map_t &dboard_reg_map
+){
+ register_internal_dboards(); //always call first
+ dboard_reg_map.insert(std::pair<manager::dboard_id_t, dboard_reg_val_t>(
+ dboard_id, dboard_reg_val_t(dboard_ctor, num_subdevs)
+ ));
+}
+
+void manager::register_rx_subdev(
+ dboard_id_t dboard_id, dboard_ctor_t dboard_ctor, size_t num_subdevs
+){
+ register_xx_subdev(dboard_id, dboard_ctor, num_subdevs, dboard_rx_regs);
+}
+
+void manager::register_tx_subdev(
+ dboard_id_t dboard_id, dboard_ctor_t dboard_ctor, size_t num_subdevs
+){
+ register_xx_subdev(dboard_id, dboard_ctor, num_subdevs, dboard_tx_regs);
+}
+
+/***********************************************************************
* internal helper classes
**********************************************************************/
/*!
@@ -52,27 +117,37 @@ private:
/***********************************************************************
* dboard manager methods
**********************************************************************/
-//include dboard derived classes (local include)
-#include "dboards.hpp"
-
-#define MAKE_DBOARD_ID_WORD(rx_id, tx_id) \
- ((uint32_t(rx_id) << 16) | (uint32_t(tx_id) << 0))
+static void create_subdevs(
+ dboard_reg_map_t &dboard_reg_map,
+ manager::dboard_id_t dboard_id,
+ interface::sptr dboard_interface,
+ std::vector<xcvr_base::sptr> &subdevs,
+ std::string const& xx_type
+){
+ //verify that there is a registered constructor for this id
+ if (dboard_reg_map.count(dboard_id) == 0){
+ throw std::runtime_error(str(
+ boost::format("Unknown %s dboard id: 0x%04x") % xx_type % dboard_id
+ ));
+ }
+ //create new subdevices for the dboard ids
+ for (size_t i = 0; i < dboard_reg_map[dboard_id].get<1>(); i++){
+ subdevs.push_back(
+ dboard_reg_map[dboard_id].get<0>()(
+ xcvr_base::ctor_args_t(i, dboard_interface)
+ )
+ );
+ }
+}
manager::manager(
- uint16_t rx_dboard_id,
- uint16_t tx_dboard_id,
+ dboard_id_t rx_dboard_id,
+ dboard_id_t tx_dboard_id,
interface::sptr dboard_interface
){
- //TODO build some boards based on ids
- //xcvrs will be added to both vectors
- switch(MAKE_DBOARD_ID_WORD(rx_dboard_id, tx_dboard_id)){
- default:
- _rx_dboards.push_back(xcvr_base::sptr(new basic_rx(0, dboard_interface)));
- _rx_dboards.push_back(xcvr_base::sptr(new basic_rx(1, dboard_interface)));
- _rx_dboards.push_back(xcvr_base::sptr(new basic_rx(2, dboard_interface)));
- _tx_dboards.push_back(xcvr_base::sptr(new basic_tx(0, dboard_interface)));
- break;
- }
+ register_internal_dboards(); //always call first
+ create_subdevs(dboard_rx_regs, rx_dboard_id, dboard_interface, _rx_dboards, "rx");
+ create_subdevs(dboard_tx_regs, tx_dboard_id, dboard_interface, _tx_dboards, "tx");
}
manager::~manager(void){