diff options
Diffstat (limited to 'host/lib/usrp/dboard_manager.cpp')
-rw-r--r-- | host/lib/usrp/dboard_manager.cpp | 186 |
1 files changed, 99 insertions, 87 deletions
diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index f0846db25..6ca15e98c 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -16,85 +16,49 @@ // #include <uhd/usrp/dboard_manager.hpp> +#include <uhd/gain_handler.hpp> #include <uhd/utils.hpp> #include <uhd/dict.hpp> -#include <boost/assign/list_of.hpp> #include <boost/tuple/tuple.hpp> #include <boost/format.hpp> +#include <boost/bind.hpp> #include <boost/foreach.hpp> -#include "dboard/dboards.hpp" using namespace uhd; using namespace uhd::usrp; -using namespace boost::assign; - -/*********************************************************************** - * 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 dboard_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, subdev names) - dboard_manager::register_subdevs(ID_BASIC_TX, &basic_tx::make, list_of("")); - dboard_manager::register_subdevs(ID_BASIC_RX, &basic_rx::make, list_of("a")("b")("ab")); -} /*********************************************************************** * storage and registering for dboards **********************************************************************/ -typedef boost::tuple<dboard_manager::dboard_ctor_t, prop_names_t> args_t; +//dboard registry tuple: dboard constructor, canonical name, subdev names +typedef boost::tuple<dboard_manager::dboard_ctor_t, std::string, prop_names_t> args_t; //map a dboard id to a dboard constructor -static uhd::dict<dboard_id_t, args_t> id_to_args_map; +typedef uhd::dict<dboard_id_t, args_t> id_to_args_map_t; +STATIC_INSTANCE(id_to_args_map_t, get_id_to_args_map) -void dboard_manager::register_subdevs( +void dboard_manager::register_dboard( dboard_id_t dboard_id, dboard_ctor_t dboard_ctor, + const std::string &name, const prop_names_t &subdev_names ){ - register_internal_dboards(); //always call first - id_to_args_map[dboard_id] = args_t(dboard_ctor, subdev_names); + //std::cout << "registering: " << name << std::endl; + if (get_id_to_args_map().has_key(dboard_id)){ + throw std::runtime_error(str(boost::format( + "The dboard id 0x%04x is already registered to %s." + ) % dboard_id % dboard_id::to_string(dboard_id))); + } + get_id_to_args_map()[dboard_id] = args_t(dboard_ctor, name, subdev_names); } -/*********************************************************************** - * dboard manager implementation class - **********************************************************************/ -class dboard_manager_impl : public dboard_manager{ - -public: - dboard_manager_impl( - dboard_id_t rx_dboard_id, - dboard_id_t tx_dboard_id, - dboard_interface::sptr interface - ); - ~dboard_manager_impl(void); - - //dboard_interface - prop_names_t get_rx_subdev_names(void); - prop_names_t get_tx_subdev_names(void); - wax::obj get_rx_subdev(const std::string &subdev_name); - wax::obj get_tx_subdev(const std::string &subdev_name); - -private: - //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 - uhd::dict<std::string, wax::obj> _rx_dboards; - uhd::dict<std::string, wax::obj> _tx_dboards; -}; +std::string dboard_id::to_string(const dboard_id_t &id){ + std::string name = (get_id_to_args_map().has_key(id))? get_id_to_args_map()[id].get<1>() : "unknown"; + return str(boost::format("%s (0x%04x)") % name % id); +} /*********************************************************************** - * internal helper classes + * internal helper classe **********************************************************************/ /*! * A special wax proxy object that forwards calls to a subdev. @@ -108,7 +72,17 @@ public: //structors subdev_proxy(dboard_base::sptr subdev, type_t type) : _subdev(subdev), _type(type){ - /* NOP */ + //initialize gain props struct + gain_handler::props_t gain_props; + gain_props.value = SUBDEV_PROP_GAIN; + gain_props.range = SUBDEV_PROP_GAIN_RANGE; + gain_props.names = SUBDEV_PROP_GAIN_NAMES; + + //make a new gain handler + _gain_handler = gain_handler::make( + this->get_link(), gain_props, + boost::bind(&gain_handler::is_equal<subdev_prop_t>, _1, _2) + ); } ~subdev_proxy(void){ @@ -116,11 +90,13 @@ public: } private: + gain_handler::sptr _gain_handler; dboard_base::sptr _subdev; type_t _type; //forward the get calls to the rx or tx void get(const wax::obj &key, wax::obj &val){ + if (_gain_handler->intercept_get(key, val)) return; switch(_type){ case RX_TYPE: return _subdev->rx_get(key, val); case TX_TYPE: return _subdev->tx_get(key, val); @@ -129,6 +105,7 @@ private: //forward the set calls to the rx or tx void set(const wax::obj &key, const wax::obj &val){ + if (_gain_handler->intercept_set(key, val)) return; switch(_type){ case RX_TYPE: return _subdev->rx_set(key, val); case TX_TYPE: return _subdev->tx_set(key, val); @@ -137,6 +114,35 @@ private: }; /*********************************************************************** + * dboard manager implementation class + **********************************************************************/ +class dboard_manager_impl : public dboard_manager{ + +public: + dboard_manager_impl( + dboard_id_t rx_dboard_id, + dboard_id_t tx_dboard_id, + dboard_interface::sptr interface + ); + ~dboard_manager_impl(void); + + //dboard_interface + prop_names_t get_rx_subdev_names(void); + prop_names_t get_tx_subdev_names(void); + wax::obj get_rx_subdev(const std::string &subdev_name); + wax::obj get_tx_subdev(const std::string &subdev_name); + +private: + //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 + uhd::dict<std::string, subdev_proxy::sptr> _rx_dboards; + uhd::dict<std::string, subdev_proxy::sptr> _tx_dboards; + dboard_interface::sptr _interface; + void set_nice_gpio_pins(void); +}; + +/*********************************************************************** * make routine for dboard manager **********************************************************************/ dboard_manager::sptr dboard_manager::make( @@ -158,16 +164,16 @@ static args_t get_dboard_args( ){ //special case, its rx and the none id (0xffff) if (xx_type == "rx" and dboard_id == ID_NONE){ - return args_t(&basic_rx::make, list_of("ab")); + return get_dboard_args(0x0001, xx_type); } //special case, its tx and the none id (0xffff) if (xx_type == "tx" and dboard_id == ID_NONE){ - return args_t(&basic_tx::make, list_of("")); + return get_dboard_args(0x0000, xx_type); } //verify that there is a registered constructor for this id - if (not id_to_args_map.has_key(dboard_id)){ + if (not get_id_to_args_map().has_key(dboard_id)){ throw std::runtime_error(str( boost::format("Unregistered %s dboard id: %s") % xx_type % dboard_id::to_string(dboard_id) @@ -175,7 +181,7 @@ static args_t get_dboard_args( } //return the dboard args for this id - return id_to_args_map[dboard_id]; + return get_id_to_args_map()[dboard_id]; } dboard_manager_impl::dboard_manager_impl( @@ -183,37 +189,30 @@ dboard_manager_impl::dboard_manager_impl( dboard_id_t tx_dboard_id, dboard_interface::sptr interface ){ - register_internal_dboards(); //always call first + _interface = interface; - dboard_ctor_t rx_dboard_ctor; prop_names_t rx_subdevs; - boost::tie(rx_dboard_ctor, rx_subdevs) = get_dboard_args(rx_dboard_id, "rx"); + dboard_ctor_t rx_dboard_ctor; std::string rx_name; prop_names_t rx_subdevs; + boost::tie(rx_dboard_ctor, rx_name, rx_subdevs) = get_dboard_args(rx_dboard_id, "rx"); - dboard_ctor_t tx_dboard_ctor; prop_names_t tx_subdevs; - boost::tie(tx_dboard_ctor, tx_subdevs) = get_dboard_args(tx_dboard_id, "tx"); + dboard_ctor_t tx_dboard_ctor; std::string tx_name; prop_names_t tx_subdevs; + boost::tie(tx_dboard_ctor, tx_name, tx_subdevs) = get_dboard_args(tx_dboard_id, "tx"); //initialize the gpio pins before creating subdevs - interface->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); //all inputs - interface->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); - - interface->write_gpio(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); //all zeros - interface->write_gpio(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); - - interface->set_atr_reg(dboard_interface::GPIO_RX_BANK, 0x0000, 0x0000, 0x0000); //software controlled - interface->set_atr_reg(dboard_interface::GPIO_TX_BANK, 0x0000, 0x0000, 0x0000); + set_nice_gpio_pins(); //make xcvr subdevs (make one subdev for both rx and tx dboards) if (rx_dboard_ctor == tx_dboard_ctor){ ASSERT_THROW(rx_subdevs == tx_subdevs); - BOOST_FOREACH(std::string name, rx_subdevs){ + BOOST_FOREACH(std::string subdev, rx_subdevs){ dboard_base::sptr xcvr_dboard = rx_dboard_ctor( - dboard_base::ctor_args_t(name, interface, rx_dboard_id, tx_dboard_id) + dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, tx_dboard_id) ); //create a rx proxy for this xcvr board - _rx_dboards[name] = subdev_proxy::sptr( + _rx_dboards[subdev] = subdev_proxy::sptr( new subdev_proxy(xcvr_dboard, subdev_proxy::RX_TYPE) ); //create a tx proxy for this xcvr board - _tx_dboards[name] = subdev_proxy::sptr( + _tx_dboards[subdev] = subdev_proxy::sptr( new subdev_proxy(xcvr_dboard, subdev_proxy::TX_TYPE) ); } @@ -222,22 +221,22 @@ dboard_manager_impl::dboard_manager_impl( //make tx and rx subdevs (separate subdevs for rx and tx dboards) else{ //make the rx subdevs - BOOST_FOREACH(std::string name, rx_subdevs){ + BOOST_FOREACH(std::string subdev, rx_subdevs){ dboard_base::sptr rx_dboard = rx_dboard_ctor( - dboard_base::ctor_args_t(name, interface, rx_dboard_id, ID_NONE) + dboard_base::ctor_args_t(subdev, interface, rx_dboard_id, ID_NONE) ); //create a rx proxy for this rx board - _rx_dboards[name] = subdev_proxy::sptr( + _rx_dboards[subdev] = subdev_proxy::sptr( new subdev_proxy(rx_dboard, subdev_proxy::RX_TYPE) ); } //make the tx subdevs - BOOST_FOREACH(std::string name, tx_subdevs){ + BOOST_FOREACH(std::string subdev, tx_subdevs){ dboard_base::sptr tx_dboard = tx_dboard_ctor( - dboard_base::ctor_args_t(name, interface, ID_NONE, tx_dboard_id) + dboard_base::ctor_args_t(subdev, interface, ID_NONE, tx_dboard_id) ); //create a tx proxy for this tx board - _tx_dboards[name] = subdev_proxy::sptr( + _tx_dboards[subdev] = subdev_proxy::sptr( new subdev_proxy(tx_dboard, subdev_proxy::TX_TYPE) ); } @@ -245,7 +244,7 @@ dboard_manager_impl::dboard_manager_impl( } dboard_manager_impl::~dboard_manager_impl(void){ - /* NOP */ + set_nice_gpio_pins(); } prop_names_t dboard_manager_impl::get_rx_subdev_names(void){ @@ -261,7 +260,7 @@ wax::obj dboard_manager_impl::get_rx_subdev(const std::string &subdev_name){ str(boost::format("Unknown rx subdev name %s") % subdev_name) ); //get a link to the rx subdev proxy - return wax::cast<subdev_proxy::sptr>(_rx_dboards[subdev_name])->get_link(); + return _rx_dboards[subdev_name]->get_link(); } wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){ @@ -269,5 +268,18 @@ wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){ str(boost::format("Unknown tx subdev name %s") % subdev_name) ); //get a link to the tx subdev proxy - return wax::cast<subdev_proxy::sptr>(_tx_dboards[subdev_name])->get_link(); + return _tx_dboards[subdev_name]->get_link(); +} + +void dboard_manager_impl::set_nice_gpio_pins(void){ + //std::cout << "Set nice GPIO pins" << std::endl; + + _interface->set_gpio_ddr(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); //all inputs + _interface->set_gpio_ddr(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); + + _interface->write_gpio(dboard_interface::GPIO_RX_BANK, 0x0000, 0xffff); //all zeros + _interface->write_gpio(dboard_interface::GPIO_TX_BANK, 0x0000, 0xffff); + + _interface->set_atr_reg(dboard_interface::GPIO_RX_BANK, 0x0000, 0x0000, 0x0000); //software controlled + _interface->set_atr_reg(dboard_interface::GPIO_TX_BANK, 0x0000, 0x0000, 0x0000); } |