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){ | 
