mirror of
https://github.com/saymrwulf/uhd.git
synced 2026-05-16 21:10:10 +00:00
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.
This commit is contained in:
parent
9c0fb5e15d
commit
daed43a8a8
8 changed files with 288 additions and 215 deletions
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,53 +26,8 @@
|
|||
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)]);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Class methods of gain handler
|
||||
**********************************************************************/
|
||||
gain_handler::~gain_handler(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 &){}
|
||||
}
|
||||
|
||||
static gain_t gain_max(gain_t a, gain_t b){
|
||||
return std::max(a, b);
|
||||
}
|
||||
|
|
@ -79,89 +35,169 @@ static gain_t gain_sum(gain_t a, gain_t b){
|
|||
return std::sum(a, b);
|
||||
}
|
||||
|
||||
bool gain_handler::intercept_get(const wax::obj &key, wax::obj &val){
|
||||
_check_key(key); //verify the key
|
||||
/***********************************************************************
|
||||
* 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);
|
||||
|
||||
std::vector<wax::obj> gain_props = boost::assign::list_of
|
||||
(_gain_prop)(_gain_min_prop)(_gain_max_prop)(_gain_step_prop);
|
||||
private:
|
||||
wax::obj _link;
|
||||
gain_props_t _gain_props;
|
||||
is_equal_t _is_equal;
|
||||
|
||||
/*!
|
||||
* 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)
|
||||
);
|
||||
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);
|
||||
};
|
||||
|
||||
//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;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
/***********************************************************************
|
||||
* 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));
|
||||
}
|
||||
|
||||
bool gain_handler::intercept_set(const wax::obj &key_, const wax::obj &val){
|
||||
_check_key(key_); //verify the key
|
||||
/***********************************************************************
|
||||
* gain handler implementation methods
|
||||
**********************************************************************/
|
||||
gain_handler::gain_props_t::gain_props_t(void){
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
gain_handler_impl::~gain_handler_impl(void){
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
prop_names_t gain_handler_impl::get_gain_names(void){
|
||||
return wax::cast<prop_names_t>(_link[_gain_props.gain_names_prop]);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
gain_t gain_handler_impl::get_overall_gain_min(void){
|
||||
return std::reduce<gain_t>(get_gains(_gain_props.gain_min_prop), gain_sum);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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_val_prop)){
|
||||
val = get_overall_gain_val();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (_is_equal(key, _gain_props.gain_min_prop)){
|
||||
val = get_overall_gain_min();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_is_equal(key, _gain_props.gain_max_prop)){
|
||||
val = get_overall_gain_max();
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -51,6 +54,63 @@ std::string dboard_id::to_string(const dboard_id_t &id){
|
|||
return str(boost::format("%s (0x%.4x)") % name % id);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* internal helper classe
|
||||
**********************************************************************/
|
||||
/*!
|
||||
* A special wax proxy object that forwards calls to a subdev.
|
||||
* A sptr to an instance will be used in the properties structure.
|
||||
*/
|
||||
class subdev_proxy : boost::noncopyable, public wax::obj{
|
||||
public:
|
||||
typedef boost::shared_ptr<subdev_proxy> sptr;
|
||||
enum type_t{RX_TYPE, TX_TYPE};
|
||||
|
||||
//structors
|
||||
subdev_proxy(dboard_base::sptr subdev, type_t type)
|
||||
: _subdev(subdev), _type(type){
|
||||
//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){
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* dboard manager implementation class
|
||||
**********************************************************************/
|
||||
|
|
@ -74,55 +134,12 @@ 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;
|
||||
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);
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* internal helper classes
|
||||
**********************************************************************/
|
||||
/*!
|
||||
* A special wax proxy object that forwards calls to a subdev.
|
||||
* A sptr to an instance will be used in the properties structure.
|
||||
*/
|
||||
class subdev_proxy : boost::noncopyable, public wax::obj{
|
||||
public:
|
||||
typedef boost::shared_ptr<subdev_proxy> sptr;
|
||||
enum type_t{RX_TYPE, TX_TYPE};
|
||||
|
||||
//structors
|
||||
subdev_proxy(dboard_base::sptr subdev, type_t type)
|
||||
: _subdev(subdev), _type(type){
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
~subdev_proxy(void){
|
||||
/* NOP */
|
||||
}
|
||||
|
||||
private:
|
||||
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){
|
||||
switch(_type){
|
||||
case RX_TYPE: return _subdev->rx_get(key, val);
|
||||
case TX_TYPE: return _subdev->tx_get(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
//forward the set calls to the rx or tx
|
||||
void set(const wax::obj &key, const wax::obj &val){
|
||||
switch(_type){
|
||||
case RX_TYPE: return _subdev->rx_set(key, val);
|
||||
case TX_TYPE: return _subdev->tx_set(key, val);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* make routine for dboard manager
|
||||
**********************************************************************/
|
||||
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue