diff options
-rw-r--r-- | include/usrp_uhd/usrp/dboard/base.hpp | 11 | ||||
-rw-r--r-- | include/usrp_uhd/usrp/dboard/manager.hpp | 39 | ||||
-rw-r--r-- | lib/usrp/dboard/base.cpp | 12 | ||||
-rw-r--r-- | lib/usrp/dboard/basic.cpp | 6 | ||||
-rw-r--r-- | lib/usrp/dboard/dboards.hpp | 10 | ||||
-rw-r--r-- | lib/usrp/dboard/manager.cpp | 109 |
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){ |