diff options
author | Josh Blum <josh@joshknows.com> | 2010-03-11 18:37:34 -0800 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-03-11 18:37:34 -0800 |
commit | daed43a8a873ad5cc16ac8a3eb6db5a8fe126fa5 (patch) | |
tree | 72286b6649af0bf99e84edca08b584cb2e6af6ae | |
parent | 9c0fb5e15da3c8ccbc1c8537671703411b210fcf (diff) | |
download | uhd-daed43a8a873ad5cc16ac8a3eb6db5a8fe126fa5.tar.gz uhd-daed43a8a873ad5cc16ac8a3eb6db5a8fe126fa5.tar.bz2 uhd-daed43a8a873ad5cc16ac8a3eb6db5a8fe126fa5.zip |
Cleaned up the gain handler (thing that gets and sets wildcard gains)
and made use of it in the dboard manager so it intercepts the sets and gets.
While doing this, fixed something with nested links in wax obj.
Added some useful macros and templates to the utils.
-rw-r--r-- | host/include/uhd/gain_handler.hpp | 68 | ||||
-rw-r--r-- | host/include/uhd/utils.hpp | 7 | ||||
-rw-r--r-- | host/lib/device.cpp | 15 | ||||
-rw-r--r-- | host/lib/gain_handler.cpp | 264 | ||||
-rw-r--r-- | host/lib/usrp/dboard/basic.cpp | 4 | ||||
-rw-r--r-- | host/lib/usrp/dboard_manager.cpp | 83 | ||||
-rw-r--r-- | host/lib/wax.cpp | 10 | ||||
-rw-r--r-- | host/test/gain_handler_test.cpp | 18 |
8 files changed, 271 insertions, 198 deletions
diff --git a/host/include/uhd/gain_handler.hpp b/host/include/uhd/gain_handler.hpp index 06800315a..fade86f53 100644 --- a/host/include/uhd/gain_handler.hpp +++ b/host/include/uhd/gain_handler.hpp @@ -15,11 +15,9 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <boost/shared_ptr.hpp> #include <uhd/wax.hpp> -#include <uhd/props.hpp> +#include <boost/shared_ptr.hpp> #include <boost/function.hpp> -#include <boost/bind.hpp> #ifndef INCLUDED_UHD_GAIN_HANDLER_HPP #define INCLUDED_UHD_GAIN_HANDLER_HPP @@ -29,29 +27,41 @@ namespace uhd{ class gain_handler{ public: typedef boost::shared_ptr<gain_handler> sptr; + typedef boost::function<bool(const wax::obj &, const wax::obj &)> is_equal_t; - template <class T> gain_handler( - wax::obj *wax_obj_ptr, const T &gain_prop, - const T &gain_min_prop, const T &gain_max_prop, - const T &gain_step_prop, const T &gain_names_prop - ){ - _wax_obj_ptr = wax_obj_ptr; - _gain_prop = gain_prop; - _gain_min_prop = gain_min_prop; - _gain_max_prop = gain_max_prop; - _gain_step_prop = gain_step_prop; - _gain_names_prop = gain_names_prop; - _is_equal = boost::bind(&gain_handler::is_equal<T>, _1, _2); - } + /*! + * A set of properties for dealing with gains. + */ + struct gain_props_t{ + wax::obj gain_val_prop; + wax::obj gain_min_prop; + wax::obj gain_max_prop; + wax::obj gain_step_prop; + wax::obj gain_names_prop; + gain_props_t(void); //default constructor + }; - ~gain_handler(void); + /*! + * Make a new gain handler. + * The construction arguments are agnostic to the property type. + * It is up to the caller to provide an "is_equal" function that + * can tell weather two properties (in a wax obj) are equal. + * \param link a link to the wax obj with properties + * \param gain_props a struct of properties keys + * \param is_equal the function that tests for equal properties + */ + static sptr make( + const wax::obj &link, + const gain_props_t &gain_props, + is_equal_t is_equal + ); /*! * Intercept gets for overall gain, min, max, step. * Ensures that the gain name is valid. * \return true for handled, false to pass on */ - bool intercept_get(const wax::obj &key, wax::obj &val); + virtual bool intercept_get(const wax::obj &key, wax::obj &val) = 0; /*! * Intercept sets for overall gain. @@ -59,27 +69,10 @@ public: * Ensures that the new gain is within range. * \return true for handled, false to pass on */ - bool intercept_set(const wax::obj &key, const wax::obj &val); - -private: - - wax::obj *_wax_obj_ptr; - wax::obj _gain_prop; - wax::obj _gain_min_prop; - wax::obj _gain_max_prop; - wax::obj _gain_step_prop; - wax::obj _gain_names_prop; + virtual bool intercept_set(const wax::obj &key, const wax::obj &val) = 0; /*! - * Verify that the key is valid: - * If its a named prop for gain, ensure that name is valid. - * If the name if not valid, throw a std::invalid_argument. - * The name can only be valid if its in the list of gain names. - */ - void _check_key(const wax::obj &key); - - /* - * Private interface to test if two wax types are equal: + * Function template to test if two wax types are equal: * The constructor will bind an instance of this for a specific type. * This bound equals functions allows the intercept methods to be non-templated. */ @@ -91,7 +84,6 @@ private: return false; } } - boost::function<bool(const wax::obj &, const wax::obj &)> _is_equal; }; diff --git a/host/include/uhd/utils.hpp b/host/include/uhd/utils.hpp index e4cfd098b..5d6a18b3a 100644 --- a/host/include/uhd/utils.hpp +++ b/host/include/uhd/utils.hpp @@ -26,7 +26,7 @@ /*! * Defines a static code block that will be called before main() */ -#define STATIC_BLOCK(_name, _code) struct _name{_name(void){_code}} _name +#define STATIC_BLOCK(_x) struct _x{_x();}_x;_x::_x() /*! * Useful templated functions and classes that I like to pretend are part of stl @@ -55,6 +55,11 @@ namespace std{ return tmp; } + template<class T, class Iterable, class Function> + T reduce(Iterable iterable, Function fcn, T init = 0){ + return reduce(iterable.begin(), iterable.end(), fcn, init); + } + template<class T, class InputIterator> bool has(InputIterator first, InputIterator last, const T &elem){ return last != std::find(first, last, elem); diff --git a/host/lib/device.cpp b/host/lib/device.cpp index 82052708a..4b64e4a15 100644 --- a/host/lib/device.cpp +++ b/host/lib/device.cpp @@ -32,9 +32,16 @@ using namespace uhd; * Create a new device from a device address. * Based on the address, call the appropriate make functions. * \param dev_addr the device address + * \param hint the device address that was used to find the device * \return a smart pointer to a device */ -static device::sptr make_device(const device_addr_t &dev_addr){ +static device::sptr make_device(const device_addr_t &dev_addr_, const device_addr_t &hint){ + //copy keys that were in hint but not in dev_addr + //this way, we can pass additional transport arguments + device_addr_t dev_addr = dev_addr_; + BOOST_FOREACH(std::string key, hint.get_keys()){ + if (not dev_addr.has_key(key)) dev_addr[key] = hint[key]; + } //create a usrp1e if (dev_addr["type"] == "usrp1e"){ @@ -46,7 +53,9 @@ static device::sptr make_device(const device_addr_t &dev_addr){ return usrp::usrp2::make(dev_addr); } - throw std::runtime_error("cant make a device"); + throw std::runtime_error(str( + boost::format("Cant make a device for %s") % device_addr::to_string(dev_addr) + )); } /*! @@ -126,7 +135,7 @@ device::sptr device::make(const device_addr_t &hint, size_t which){ } //create and register a new device catch(const std::assert_error &e){ - device::sptr dev = make_device(dev_addr); + device::sptr dev = make_device(dev_addr, hint); hash_to_device[dev_hash] = dev; return dev; } diff --git a/host/lib/gain_handler.cpp b/host/lib/gain_handler.cpp index b03d5bda2..8f840ae7f 100644 --- a/host/lib/gain_handler.cpp +++ b/host/lib/gain_handler.cpp @@ -17,6 +17,7 @@ #include <uhd/gain_handler.hpp> #include <uhd/utils.hpp> +#include <uhd/props.hpp> #include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> #include <boost/format.hpp> @@ -25,143 +26,178 @@ using namespace uhd; /*********************************************************************** - * Helper functions and macros + * helper functions **********************************************************************/ -#define GET_PROP_NAMES() \ - wax::cast<prop_names_t>((*_wax_obj_ptr)[_gain_names_prop]) - -/*! - * Helper function to simplify getting a named gain (also min, max, step). - */ -static gain_t get_named_gain(wax::obj *wax_obj_ptr, wax::obj prop, std::string name){ - return wax::cast<gain_t>((*wax_obj_ptr)[named_prop_t(prop, name)]); +static gain_t gain_max(gain_t a, gain_t b){ + return std::max(a, b); +} +static gain_t gain_sum(gain_t a, gain_t b){ + return std::sum(a, b); +} + +/*********************************************************************** + * gain handler implementation interface + **********************************************************************/ +class gain_handler_impl : public gain_handler{ +public: + gain_handler_impl( + const wax::obj &link, + const gain_props_t &gain_props, + is_equal_t is_equal + ); + ~gain_handler_impl(void); + bool intercept_get(const wax::obj &key, wax::obj &val); + bool intercept_set(const wax::obj &key, const wax::obj &val); + +private: + wax::obj _link; + gain_props_t _gain_props; + is_equal_t _is_equal; + + prop_names_t get_gain_names(void); + std::vector<gain_t> get_gains(const wax::obj &prop_key); + gain_t get_overall_gain_val(void); + gain_t get_overall_gain_min(void); + gain_t get_overall_gain_max(void); + gain_t get_overall_gain_step(void); +}; + +/*********************************************************************** + * the make function + **********************************************************************/ +gain_handler::sptr gain_handler::make( + const wax::obj &link, + const gain_props_t &gain_props, + is_equal_t is_equal +){ + return sptr(new gain_handler_impl(link, gain_props, is_equal)); } /*********************************************************************** - * Class methods of gain handler + * gain handler implementation methods **********************************************************************/ -gain_handler::~gain_handler(void){ +gain_handler::gain_props_t::gain_props_t(void){ /* NOP */ } -void gain_handler::_check_key(const wax::obj &key_){ - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); - - try{ - //only handle non wildcard names - ASSERT_THROW(name != ""); - - //only handle these gain props - ASSERT_THROW( - _is_equal(key, _gain_prop) or - _is_equal(key, _gain_min_prop) or - _is_equal(key, _gain_max_prop) or - _is_equal(key, _gain_step_prop) - ); - - //check that the name is allowed - prop_names_t prop_names = GET_PROP_NAMES(); - ASSERT_THROW(not std::has(prop_names.begin(), prop_names.end(), name)); - - //if we get here, throw an exception - throw std::invalid_argument(str( - boost::format("Unknown gain name %s") % name - )); - } - catch(const std::assert_error &){} +gain_handler_impl::gain_handler_impl( + const wax::obj &link, + const gain_props_t &gain_props, + is_equal_t is_equal +){ + _link = link; + _gain_props = gain_props; + _is_equal = is_equal; } -static gain_t gain_max(gain_t a, gain_t b){ - return std::max(a, b); +gain_handler_impl::~gain_handler_impl(void){ + /* NOP */ } -static gain_t gain_sum(gain_t a, gain_t b){ - return std::sum(a, b); + +prop_names_t gain_handler_impl::get_gain_names(void){ + return wax::cast<prop_names_t>(_link[_gain_props.gain_names_prop]); } -bool gain_handler::intercept_get(const wax::obj &key, wax::obj &val){ - _check_key(key); //verify the key - - std::vector<wax::obj> gain_props = boost::assign::list_of - (_gain_prop)(_gain_min_prop)(_gain_max_prop)(_gain_step_prop); - - /*! - * Handle getting overall gains when a name is not specified. - * For the gain props below, set the overall value and return true. - */ - BOOST_FOREACH(wax::obj prop_key, gain_props){ - if (_is_equal(key, prop_key)){ - //form the gains vector from the props vector - prop_names_t prop_names = GET_PROP_NAMES(); - std::vector<gain_t> gains(prop_names.size()); - std::transform( - prop_names.begin(), prop_names.end(), gains.begin(), - boost::bind(get_named_gain, _wax_obj_ptr, key, _1) - ); - - //reduce across the gain vector - if (_is_equal(key, _gain_step_prop)){ - val = std::reduce<gain_t>(gains.begin(), gains.end(), gain_max); - } - else{ - val = std::reduce<gain_t>(gains.begin(), gains.end(), gain_sum); - } - return true; - } +std::vector<gain_t> gain_handler_impl::get_gains(const wax::obj &prop_key){ + std::vector<gain_t> gains; + BOOST_FOREACH(std::string name, get_gain_names()){ + gains.push_back(wax::cast<gain_t>(_link[named_prop_t(prop_key, name)])); } + return gains; +} + +gain_t gain_handler_impl::get_overall_gain_val(void){ + return std::reduce<gain_t>(get_gains(_gain_props.gain_val_prop), gain_sum); +} - return false; +gain_t gain_handler_impl::get_overall_gain_min(void){ + return std::reduce<gain_t>(get_gains(_gain_props.gain_min_prop), gain_sum); } -bool gain_handler::intercept_set(const wax::obj &key_, const wax::obj &val){ - _check_key(key_); //verify the key +gain_t gain_handler_impl::get_overall_gain_max(void){ + return std::reduce<gain_t>(get_gains(_gain_props.gain_max_prop), gain_sum); +} + +gain_t gain_handler_impl::get_overall_gain_step(void){ + return std::reduce<gain_t>(get_gains(_gain_props.gain_step_prop), gain_max); +} +/*********************************************************************** + * gain handler implementation get method + **********************************************************************/ +bool gain_handler_impl::intercept_get(const wax::obj &key_, wax::obj &val){ wax::obj key; std::string name; boost::tie(key, name) = extract_named_prop(key_); - /*! - * Verify that a named gain component is in range. - */ - try{ - //only handle the gain props - ASSERT_THROW(_is_equal(key, _gain_prop)); - - //check that the gain is in range - gain_t gain = wax::cast<gain_t>(val); - gain_t gain_min = get_named_gain(_wax_obj_ptr, _gain_min_prop, name); - gain_t gain_max = get_named_gain(_wax_obj_ptr, _gain_max_prop, name); - ASSERT_THROW(gain > gain_max or gain < gain_min); - - //if we get here, throw an exception - throw std::range_error(str( - boost::format("gain %s is out of range of (%f, %f)") % name % gain_min % gain_max - )); + //not a wildcard... dont handle (but check name) + if (name != ""){ + assert_has(get_gain_names(), name, "gain name"); + return false; + } + + if (_is_equal(key, _gain_props.gain_val_prop)){ + val = get_overall_gain_val(); + return true; + } + + if (_is_equal(key, _gain_props.gain_min_prop)){ + val = get_overall_gain_min(); + return true; } - catch(const std::assert_error &){} - - /*! - * Handle setting the overall gain. - */ - if (_is_equal(key, _gain_prop) and name == ""){ - gain_t gain = wax::cast<gain_t>(val); - prop_names_t prop_names = GET_PROP_NAMES(); - BOOST_FOREACH(std::string name, prop_names){ - //get the min, max, step for this gain name - gain_t gain_min = get_named_gain(_wax_obj_ptr, _gain_min_prop, name); - gain_t gain_max = get_named_gain(_wax_obj_ptr, _gain_max_prop, name); - gain_t gain_step = get_named_gain(_wax_obj_ptr, _gain_step_prop, name); - - //clip g to be within the allowed range - gain_t g = std::min(std::max(gain, gain_min), gain_max); - //set g to be a multiple of the step size - g -= fmod(g, gain_step); - //set g to be the new gain - (*_wax_obj_ptr)[named_prop_t(_gain_prop, name)] = g; - //subtract g out of the total gain left to apply - gain -= g; - } + + if (_is_equal(key, _gain_props.gain_max_prop)){ + val = get_overall_gain_max(); return true; } - return false; + if (_is_equal(key, _gain_props.gain_step_prop)){ + val = get_overall_gain_step(); + return true; + } + + return false; //not handled +} + +/*********************************************************************** + * gain handler implementation set method + **********************************************************************/ +bool gain_handler_impl::intercept_set(const wax::obj &key_, const wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //not a gain value key... dont handle + if (not _is_equal(key, _gain_props.gain_val_prop)) return false; + + gain_t gain_val = wax::cast<gain_t>(val); + + //not a wildcard... dont handle (but check name and range) + if (name != ""){ + assert_has(get_gain_names(), name, "gain name"); + gain_t gain_min = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_min_prop, name)]); + gain_t gain_max = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_max_prop, name)]); + if (gain_val > gain_max or gain_val < gain_min) throw std::range_error(str( + boost::format("A value of %f for gain %s is out of range of (%f, %f)") + % gain_val % name % gain_min % gain_max + )); + return false; + } + + //set the overall gain + BOOST_FOREACH(std::string name, get_gain_names()){ + //get the min, max, step for this gain name + gain_t gain_min = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_min_prop, name)]); + gain_t gain_max = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_max_prop, name)]); + gain_t gain_step = wax::cast<gain_t>(_link[named_prop_t(_gain_props.gain_step_prop, name)]); + + //clip g to be within the allowed range + gain_t g = std::min(std::max(gain_val, gain_min), gain_max); + //set g to be a multiple of the step size + g -= fmod(g, gain_step); + //set g to be the new gain + _link[named_prop_t(_gain_props.gain_val_prop, name)] = g; + //subtract g out of the total gain left to apply + gain_val -= g; + } + + return true; } diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/basic.cpp index 5e245a8cf..4b74e4a47 100644 --- a/host/lib/usrp/dboard/basic.cpp +++ b/host/lib/usrp/dboard/basic.cpp @@ -73,12 +73,12 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){ return dboard_base::sptr(new basic_tx(args, 32e6)); } -STATIC_BLOCK(reg_dboards, { +STATIC_BLOCK(reg_dboards){ dboard_manager::register_subdevs(0x0000, &make_basic_tx, "Basic TX", list_of("")); dboard_manager::register_subdevs(0x0001, &make_basic_rx, "Basic RX", list_of("a")("b")("ab")); dboard_manager::register_subdevs(0x000e, &make_lf_tx, "LF TX", list_of("")); dboard_manager::register_subdevs(0x000f, &make_lf_rx, "LF RX", list_of("a")("b")("ab")); -}); +} /*********************************************************************** * Basic and LF RX dboard diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 57b449175..08b92e62a 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -16,10 +16,12 @@ // #include <uhd/usrp/dboard_manager.hpp> +#include <uhd/gain_handler.hpp> #include <uhd/utils.hpp> #include <uhd/dict.hpp> #include <boost/tuple/tuple.hpp> #include <boost/format.hpp> +#include <boost/bind.hpp> #include <boost/foreach.hpp> using namespace uhd; @@ -42,6 +44,7 @@ void dboard_manager::register_subdevs( const std::string &name, const prop_names_t &subdev_names ){ + //std::cout << "registering: " << name << std::endl; id_to_str[dboard_id] = name; id_to_args_map[dboard_id] = args_t(dboard_ctor, subdev_names); } @@ -52,36 +55,7 @@ std::string dboard_id::to_string(const dboard_id_t &id){ } /*********************************************************************** - * 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; - dboard_interface::sptr _interface; - void set_nice_gpio_pins(void); -}; - -/*********************************************************************** - * internal helper classes + * internal helper classe **********************************************************************/ /*! * A special wax proxy object that forwards calls to a subdev. @@ -95,7 +69,18 @@ public: //structors subdev_proxy(dboard_base::sptr subdev, type_t type) : _subdev(subdev), _type(type){ - /* NOP */ + //initialize gain props struct + gain_handler::gain_props_t gain_props; + gain_props.gain_val_prop = SUBDEV_PROP_GAIN; + gain_props.gain_min_prop = SUBDEV_PROP_GAIN_MIN; + gain_props.gain_max_prop = SUBDEV_PROP_GAIN_MAX; + gain_props.gain_step_prop = SUBDEV_PROP_GAIN_STEP; + gain_props.gain_names_prop = 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){ @@ -103,11 +88,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); @@ -116,6 +103,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); @@ -124,6 +112,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( @@ -241,7 +258,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){ @@ -249,7 +266,7 @@ 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){ diff --git a/host/lib/wax.cpp b/host/lib/wax.cpp index c08398c50..0348d9a66 100644 --- a/host/lib/wax.cpp +++ b/host/lib/wax.cpp @@ -36,7 +36,11 @@ public: link_args_t(const wax::obj *obj_ptr) : _obj_ptr(obj_ptr){ /* NOP */ } - wax::obj & operator()(void){ + wax::obj & operator()(void) const{ + //recursively resolve link args to get at original pointer + if (_obj_ptr->type() == typeid(link_args_t)){ + return wax::cast<link_args_t>(*_obj_ptr)(); + } return *const_cast<wax::obj *>(_obj_ptr); } private: @@ -56,10 +60,10 @@ public: proxy_args_t(const wax::obj *obj_ptr, const wax::obj &key) : _key(key){ _obj_link = obj_ptr->get_link(); } - wax::obj & operator()(void){ + wax::obj & operator()(void) const{ return wax::cast<link_args_t>(_obj_link)(); } - const wax::obj & key(void){ + const wax::obj & key(void) const{ return _key; } private: diff --git a/host/test/gain_handler_test.cpp b/host/test/gain_handler_test.cpp index c81221aac..9a6a50dab 100644 --- a/host/test/gain_handler_test.cpp +++ b/host/test/gain_handler_test.cpp @@ -17,7 +17,9 @@ #include <boost/test/unit_test.hpp> #include <uhd/gain_handler.hpp> +#include <uhd/props.hpp> #include <uhd/dict.hpp> +#include <boost/bind.hpp> #include <iostream> using namespace uhd; @@ -33,9 +35,17 @@ enum prop_t{ class gainful_obj : public wax::obj{ public: gainful_obj(void){ - _gain_handler = gain_handler::sptr(new gain_handler( - this, PROP_GAIN, PROP_GAIN_MIN, PROP_GAIN_MAX, PROP_GAIN_STEP, PROP_GAIN_NAMES - )); + //initialize gain props struct + gain_handler::gain_props_t gain_props; + gain_props.gain_val_prop = PROP_GAIN; + gain_props.gain_min_prop = PROP_GAIN_MIN; + gain_props.gain_max_prop = PROP_GAIN_MAX; + gain_props.gain_step_prop = PROP_GAIN_STEP; + gain_props.gain_names_prop = PROP_GAIN_NAMES; + //make a new gain handler + _gain_handler = gain_handler::make( + this->get_link(), gain_props, boost::bind(&gain_handler::is_equal<prop_t>, _1, _2) + ); _gains["g0"] = 0; _gains["g1"] = 0; _gains_min["g0"] = -10; @@ -113,7 +123,7 @@ BOOST_AUTO_TEST_CASE(test_gain_handler){ BOOST_CHECK_THROW( wax::cast<gain_t>(go0[named_prop_t(PROP_GAIN, "fail")]), - std::invalid_argument + std::exception ); std::cout << "verifying the overall min, max, step" << std::endl; |