diff options
Diffstat (limited to 'host/lib')
| -rw-r--r-- | host/lib/usrp/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | host/lib/usrp/dboard_manager.cpp | 23 | ||||
| -rw-r--r-- | host/lib/usrp/mimo_usrp.cpp | 17 | ||||
| -rw-r--r-- | host/lib/usrp/misc_utils.cpp | 114 | ||||
| -rw-r--r-- | host/lib/usrp/misc_utils.hpp | 35 | ||||
| -rw-r--r-- | host/lib/usrp/simple_usrp.cpp | 17 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/codec_impl.cpp | 96 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_impl.cpp | 22 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/mboard_impl.cpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 9 | ||||
| -rw-r--r-- | host/lib/utils/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | host/lib/utils/gain_group.cpp | 152 | ||||
| -rw-r--r-- | host/lib/utils/gain_handler.cpp | 177 | 
14 files changed, 459 insertions, 211 deletions
diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt index 80ac537ee..da3e87a68 100644 --- a/host/lib/usrp/CMakeLists.txt +++ b/host/lib/usrp/CMakeLists.txt @@ -24,6 +24,8 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_manager.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/dsp_utils.hpp      ${CMAKE_SOURCE_DIR}/lib/usrp/mimo_usrp.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/misc_utils.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/misc_utils.hpp      ${CMAKE_SOURCE_DIR}/lib/usrp/simple_usrp.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/tune_helper.cpp  ) diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index bfaaf0969..ab80875f5 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -18,7 +18,6 @@  #include "dboard_ctor_args.hpp"  #include <uhd/usrp/dboard_manager.hpp>  #include <uhd/usrp/subdev_props.hpp> -#include <uhd/utils/gain_handler.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/assert.hpp>  #include <uhd/types/dict.hpp> @@ -98,33 +97,18 @@ public:      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::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){ +    subdev_proxy(dboard_base::sptr subdev, type_t type): +        _subdev(subdev), _type(type) +    {          /* 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); @@ -133,7 +117,6 @@ 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); diff --git a/host/lib/usrp/mimo_usrp.cpp b/host/lib/usrp/mimo_usrp.cpp index ec0f1dcc8..6b9318c39 100644 --- a/host/lib/usrp/mimo_usrp.cpp +++ b/host/lib/usrp/mimo_usrp.cpp @@ -18,6 +18,7 @@  #include <uhd/usrp/mimo_usrp.hpp>  #include <uhd/usrp/tune_helper.hpp>  #include <uhd/utils/assert.hpp> +#include <uhd/utils/gain_group.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/usrp/mboard_props.hpp> @@ -56,11 +57,13 @@ public:              _rx_dboards.push_back(_mboards.back()[MBOARD_PROP_RX_DBOARD]);              std::string rx_subdev_in_use = _rx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);              _rx_subdevs.push_back(_rx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, rx_subdev_in_use)]); +            _rx_gain_groups.push_back(_rx_dboards.back()[named_prop_t(DBOARD_PROP_GAIN_GROUP, rx_subdev_in_use)].as<gain_group::sptr>());              //extract tx subdevice              _tx_dboards.push_back(_mboards.back()[MBOARD_PROP_TX_DBOARD]);              std::string tx_subdev_in_use = _tx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);              _tx_subdevs.push_back(_tx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, tx_subdev_in_use)]); +            _tx_gain_groups.push_back(_tx_dboards.back()[named_prop_t(DBOARD_PROP_GAIN_GROUP, tx_subdev_in_use)].as<gain_group::sptr>());          }          //set the clock config across all mboards (TODO set through api) @@ -201,15 +204,15 @@ public:      }      void set_rx_gain(size_t chan, float gain){ -        _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN] = gain; +        _rx_gain_groups.at(chan)->set_value(gain);      }      float get_rx_gain(size_t chan){ -        return _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN].as<float>(); +        return _rx_gain_groups.at(chan)->get_value();      }      gain_range_t get_rx_gain_range(size_t chan){ -        return _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); +        return _rx_gain_groups.at(chan)->get_range();      }      void set_rx_antenna(size_t chan, const std::string &ant){ @@ -268,15 +271,15 @@ public:      }      void set_tx_gain(size_t chan, float gain){ -        _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN] = gain; +        _tx_gain_groups.at(chan)->set_value(gain);      }      float get_tx_gain(size_t chan){ -        return _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN].as<float>(); +        return _tx_gain_groups.at(chan)->get_value();      }      gain_range_t get_tx_gain_range(size_t chan){ -        return _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); +        return _tx_gain_groups.at(chan)->get_range();      }      void set_tx_antenna(size_t chan, const std::string &ant){ @@ -304,6 +307,8 @@ private:      std::vector<wax::obj> _tx_dboards;      std::vector<wax::obj> _rx_subdevs;      std::vector<wax::obj> _tx_subdevs; +    std::vector<gain_group::sptr> _rx_gain_groups; +    std::vector<gain_group::sptr> _tx_gain_groups;      //shadows      double _rx_rate, _tx_rate; diff --git a/host/lib/usrp/misc_utils.cpp b/host/lib/usrp/misc_utils.cpp new file mode 100644 index 000000000..0aa03a6cc --- /dev/null +++ b/host/lib/usrp/misc_utils.cpp @@ -0,0 +1,114 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include "misc_utils.hpp" +#include <uhd/utils/gain_group.hpp> +#include <uhd/usrp/subdev_props.hpp> +#include <uhd/usrp/codec_props.hpp> +#include <boost/bind.hpp> +#include <boost/foreach.hpp> + +using namespace uhd; +using namespace uhd::usrp; + +static const size_t subdev_gain_priority = 1; //higher, closer to the antenna +static const size_t codec_gain_priority = 0; + +/*********************************************************************** + * codec gain group helper functions: + *    do this so we dont have to bind a templated function + **********************************************************************/ +static gain_range_t get_codec_gain_range(wax::obj codec, const std::string &name){ +    return codec[named_prop_t(CODEC_PROP_GAIN_RANGE, name)].as<gain_range_t>(); +} + +static float get_codec_gain_i(wax::obj codec, const std::string &name){ +    return codec[named_prop_t(CODEC_PROP_GAIN_I, name)].as<float>(); +} + +static float get_codec_gain_q(wax::obj codec, const std::string &name){ +    return codec[named_prop_t(CODEC_PROP_GAIN_Q, name)].as<float>(); +} + +static void set_codec_gain_both(wax::obj codec, const std::string &name, float gain){ +    codec[named_prop_t(CODEC_PROP_GAIN_I, name)] = gain; +    codec[named_prop_t(CODEC_PROP_GAIN_Q, name)] = gain; +} + +static void set_codec_gain_i(wax::obj codec, const std::string &name, float gain){ +    codec[named_prop_t(CODEC_PROP_GAIN_I, name)] = gain; +} + +static void set_codec_gain_q(wax::obj codec, const std::string &name, float gain){ +    codec[named_prop_t(CODEC_PROP_GAIN_Q, name)] = gain; +} + +/*********************************************************************** + * subdev gain group helper functions: + *    do this so we dont have to bind a templated function + **********************************************************************/ +static float get_subdev_gain(wax::obj subdev, const std::string &name){ +    return subdev[named_prop_t(SUBDEV_PROP_GAIN, name)].as<float>(); +} + +static gain_range_t get_subdev_gain_range(wax::obj subdev, const std::string &name){ +    return subdev[named_prop_t(SUBDEV_PROP_GAIN_RANGE, name)].as<gain_range_t>(); +} + +static void set_subdev_gain(wax::obj subdev, const std::string &name, float gain){ +    subdev[named_prop_t(SUBDEV_PROP_GAIN, name)] = gain; +} + +/*********************************************************************** + * gain group factory function for usrp + **********************************************************************/ +gain_group::sptr usrp::make_gain_group(wax::obj subdev, wax::obj codec){ +    gain_group::sptr gg = gain_group::make(); +    gain_fcns_t fcns; +    //add all the subdev gains first (antenna to dsp order) +    BOOST_FOREACH(const std::string &name, subdev[SUBDEV_PROP_GAIN_NAMES].as<prop_names_t>()){ +        fcns.get_range = boost::bind(&get_subdev_gain_range, subdev, name); +        fcns.get_value = boost::bind(&get_subdev_gain, subdev, name); +        fcns.set_value = boost::bind(&set_subdev_gain, subdev, name, _1); +        gg->register_fcns(fcns, subdev_gain_priority); +    } +    //add all the codec gains last (antenna to dsp order) +    BOOST_FOREACH(const std::string &name, codec[CODEC_PROP_GAIN_NAMES].as<prop_names_t>()){ +        fcns.get_range = boost::bind(&get_codec_gain_range, codec, name); + +        //register the value functions depending upon the connection type +        switch(subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()){ +        case SUBDEV_CONN_COMPLEX_IQ: +        case SUBDEV_CONN_COMPLEX_QI: +            fcns.get_value = boost::bind(&get_codec_gain_i, codec, name); //same as Q +            fcns.set_value = boost::bind(&set_codec_gain_both, codec, name, _1); //sets both +            break; + +        case SUBDEV_CONN_REAL_I: +            fcns.get_value = boost::bind(&get_codec_gain_i, codec, name); +            fcns.set_value = boost::bind(&set_codec_gain_i, codec, name, _1); +            break; + +        case SUBDEV_CONN_REAL_Q: +            fcns.get_value = boost::bind(&get_codec_gain_q, codec, name); +            fcns.set_value = boost::bind(&set_codec_gain_q, codec, name, _1); +            break; +        } +        gg->register_fcns(fcns, codec_gain_priority); +    } +    return gg; +} diff --git a/host/lib/usrp/misc_utils.hpp b/host/lib/usrp/misc_utils.hpp new file mode 100644 index 000000000..7fe3c899d --- /dev/null +++ b/host/lib/usrp/misc_utils.hpp @@ -0,0 +1,35 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_LIBUHD_USRP_MISC_UTILS_HPP +#define INCLUDED_LIBUHD_USRP_MISC_UTILS_HPP + +#include <uhd/config.hpp> +#include <uhd/wax.hpp> +#include <uhd/utils/gain_group.hpp> + +namespace uhd{ namespace usrp{ + +    /*! +     * Create a gain group that represents the subdevice and its codec. +     */ +    gain_group::sptr make_gain_group(wax::obj subdev, wax::obj codec); + +}} //namespace + +#endif /* INCLUDED_LIBUHD_USRP_MISC_UTILS_HPP */ + diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp index 5cb9511f4..704232782 100644 --- a/host/lib/usrp/simple_usrp.cpp +++ b/host/lib/usrp/simple_usrp.cpp @@ -18,6 +18,7 @@  #include <uhd/usrp/simple_usrp.hpp>  #include <uhd/usrp/tune_helper.hpp>  #include <uhd/utils/assert.hpp> +#include <uhd/utils/gain_group.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/usrp/mboard_props.hpp>  #include <uhd/usrp/device_props.hpp> @@ -50,11 +51,13 @@ public:          _rx_dboard = _mboard[MBOARD_PROP_RX_DBOARD];          std::string rx_subdev_in_use = _rx_dboard[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);          _rx_subdev = _rx_dboard[named_prop_t(DBOARD_PROP_SUBDEV, rx_subdev_in_use)]; +        _rx_gain_group = _rx_dboard[named_prop_t(DBOARD_PROP_GAIN_GROUP, rx_subdev_in_use)].as<gain_group::sptr>();          //extract tx subdevice          _tx_dboard = _mboard[MBOARD_PROP_TX_DBOARD];          std::string tx_subdev_in_use = _tx_dboard[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0);          _tx_subdev = _tx_dboard[named_prop_t(DBOARD_PROP_SUBDEV, tx_subdev_in_use)]; +        _tx_gain_group = _tx_dboard[named_prop_t(DBOARD_PROP_GAIN_GROUP, tx_subdev_in_use)].as<gain_group::sptr>();      }      ~simple_usrp_impl(void){ @@ -139,15 +142,15 @@ public:      }      void set_rx_gain(float gain){ -        _rx_subdev[SUBDEV_PROP_GAIN] = gain; +        _rx_gain_group->set_value(gain);      }      float get_rx_gain(void){ -        return _rx_subdev[SUBDEV_PROP_GAIN].as<float>(); +        return _rx_gain_group->get_value();      }      gain_range_t get_rx_gain_range(void){ -        return _rx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); +        return _rx_gain_group->get_range();      }      void set_rx_antenna(const std::string &ant){ @@ -198,15 +201,15 @@ public:      }      void set_tx_gain(float gain){ -        _tx_subdev[SUBDEV_PROP_GAIN] = gain; +        _tx_gain_group->set_value(gain);      }      float get_tx_gain(void){ -        return _tx_subdev[SUBDEV_PROP_GAIN].as<float>(); +        return _tx_gain_group->get_value();      }      gain_range_t get_tx_gain_range(void){ -        return _tx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); +        return _tx_gain_group->get_range();      }      void set_tx_antenna(const std::string &ant){ @@ -234,6 +237,8 @@ private:      wax::obj _tx_dboard;      wax::obj _rx_subdev;      wax::obj _tx_subdev; +    gain_group::sptr _rx_gain_group; +    gain_group::sptr _tx_gain_group;  };  /*********************************************************************** diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index 99d0b8bdd..796126d07 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -22,6 +22,7 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_ctrl.hpp      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_ctrl.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_ctrl.hpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/codec_impl.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp new file mode 100644 index 000000000..b9d51abf5 --- /dev/null +++ b/host/lib/usrp/usrp2/codec_impl.cpp @@ -0,0 +1,96 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include "usrp2_impl.hpp" +#include <uhd/usrp/codec_props.hpp> +#include <boost/bind.hpp> + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Helper Methods + **********************************************************************/ +void usrp2_mboard_impl::codec_init(void){ +    //make proxies +    _rx_codec_proxy = wax_obj_proxy::make( +        boost::bind(&usrp2_mboard_impl::rx_codec_get, this, _1, _2), +        boost::bind(&usrp2_mboard_impl::rx_codec_set, this, _1, _2) +    ); +    _tx_codec_proxy = wax_obj_proxy::make( +        boost::bind(&usrp2_mboard_impl::tx_codec_get, this, _1, _2), +        boost::bind(&usrp2_mboard_impl::tx_codec_set, this, _1, _2) +    ); +} + +/*********************************************************************** + * RX Codec Properties + **********************************************************************/ +void usrp2_mboard_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the get request conditioned on the key +    switch(key.as<codec_prop_t>()){ +    case CODEC_PROP_NAME: +        val = std::string("usrp2 adc"); +        return; + +    case CODEC_PROP_OTHERS: +        val = prop_names_t(); +        return; + +    case CODEC_PROP_GAIN_NAMES: +        val = prop_names_t(); //no gain elements to be controlled +        return; + +    default: UHD_THROW_PROP_GET_ERROR(); +    } +} + +void usrp2_mboard_impl::rx_codec_set(const wax::obj &, const wax::obj &){ +    UHD_THROW_PROP_SET_ERROR(); +} + +/*********************************************************************** + * TX Codec Properties + **********************************************************************/ +void usrp2_mboard_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the get request conditioned on the key +    switch(key.as<codec_prop_t>()){ +    case CODEC_PROP_NAME: +        val = std::string("usrp2 dac - ad9777"); +        return; + +    case CODEC_PROP_OTHERS: +        val = prop_names_t(); +        return; + +    case CODEC_PROP_GAIN_NAMES: +        val = prop_names_t(); //no gain elements to be controlled +        return; + +    default: UHD_THROW_PROP_GET_ERROR(); +    } +} + +void usrp2_mboard_impl::tx_codec_set(const wax::obj &, const wax::obj &){ +    UHD_THROW_PROP_SET_ERROR(); +} diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 0aeb0ec1a..4309f43aa 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -15,10 +15,10 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // -  #include "usrp2_impl.hpp"  #include "usrp2_regs.hpp"  #include "../dsp_utils.hpp" +#include "../misc_utils.hpp"  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/usrp/dboard_props.hpp>  #include <uhd/utils/assert.hpp> @@ -92,6 +92,16 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){          val = _dboard_iface;          return; +    case DBOARD_PROP_CODEC: +        val = _rx_codec_proxy->get_link(); +        return; + +    case DBOARD_PROP_GAIN_GROUP: +        val = make_gain_group( +            _dboard_manager->get_rx_subdev(name), _rx_codec_proxy->get_link() +        ); +        return; +      default: UHD_THROW_PROP_GET_ERROR();      }  } @@ -151,6 +161,16 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){          val = _dboard_iface;          return; +    case DBOARD_PROP_CODEC: +        val = _tx_codec_proxy->get_link(); +        return; + +    case DBOARD_PROP_GAIN_GROUP: +        val = make_gain_group( +            _dboard_manager->get_tx_subdev(name), _tx_codec_proxy->get_link() +        ); +        return; +      default: UHD_THROW_PROP_GET_ERROR();      }  } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 7694a164d..4dab00ce2 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -96,6 +96,9 @@ usrp2_mboard_impl::usrp2_mboard_impl(      //initialize the clock configuration      init_clock_config(); +    //init the codec before the dboard +    codec_init(); +      //init the tx and rx dboards (do last)      dboard_init(); diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 2eaf12350..6d705f14e 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -161,6 +161,15 @@ private:      void update_clock_config(void);      void set_time_spec(const uhd::time_spec_t &time_spec, bool now); +    //properties interface for the codec +    void codec_init(void); +    void rx_codec_get(const wax::obj &, wax::obj &); +    void rx_codec_set(const wax::obj &, const wax::obj &); +    void tx_codec_get(const wax::obj &, wax::obj &); +    void tx_codec_set(const wax::obj &, const wax::obj &); +    wax_obj_proxy::sptr _rx_codec_proxy; +    wax_obj_proxy::sptr _tx_codec_proxy; +      //properties interface for rx dboard      void rx_dboard_get(const wax::obj &, wax::obj &);      void rx_dboard_set(const wax::obj &, const wax::obj &); diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt index 450112462..ee2cb0d76 100644 --- a/host/lib/utils/CMakeLists.txt +++ b/host/lib/utils/CMakeLists.txt @@ -19,7 +19,7 @@  LIBUHD_APPEND_SOURCES(      ${CMAKE_SOURCE_DIR}/lib/utils/assert.cpp -    ${CMAKE_SOURCE_DIR}/lib/utils/gain_handler.cpp +    ${CMAKE_SOURCE_DIR}/lib/utils/gain_group.cpp      ${CMAKE_SOURCE_DIR}/lib/utils/load_modules.cpp      ${CMAKE_SOURCE_DIR}/lib/utils/props.cpp      ${CMAKE_SOURCE_DIR}/lib/utils/thread_priority.cpp diff --git a/host/lib/utils/gain_group.cpp b/host/lib/utils/gain_group.cpp new file mode 100644 index 000000000..5a14fa96f --- /dev/null +++ b/host/lib/utils/gain_group.cpp @@ -0,0 +1,152 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils/gain_group.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/assert.hpp> +#include <boost/foreach.hpp> +#include <boost/bind.hpp> +#include <boost/math/special_functions/round.hpp> +#include <algorithm> +#include <vector> +#include <iostream> + +#define rint(x) boost::math::iround(x) + +using namespace uhd; + +static const bool verbose = false; + +static bool compare_by_step_size( +    const size_t &rhs, const size_t &lhs, std::vector<gain_fcns_t> &fcns +){ +    return fcns.at(rhs).get_range().step > fcns.at(lhs).get_range().step; +} + +/*********************************************************************** + * gain group implementation + **********************************************************************/ +class gain_group_impl : public gain_group{ +public: +    gain_group_impl(void){ +        /*NOP*/ +    } + +    gain_range_t get_range(void){ +        float overall_min = 0, overall_max = 0, overall_step = 0; +        BOOST_FOREACH(const gain_fcns_t &fcns, get_all_fcns()){ +            const gain_range_t range = fcns.get_range(); +            overall_min += range.min; +            overall_max += range.max; +            //the overall step is the min (zero is invalid, first run) +            if (overall_step == 0) overall_step = range.step; +            overall_step = std::min(overall_step, range.step); +        } +        return gain_range_t(overall_min, overall_max, overall_step); +    } + +    float get_value(void){ +        float overall_gain = 0; +        BOOST_FOREACH(const gain_fcns_t &fcns, get_all_fcns()){ +            overall_gain += fcns.get_value(); +        } +        return overall_gain; +    } + +    void set_value(float gain){ +        std::vector<gain_fcns_t> all_fcns = get_all_fcns(); +        if (all_fcns.size() == 0) return; //nothing to set! + +        //get the max step size among the gains +        float max_step = 0; +        BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){ +            max_step = std::max(max_step, fcns.get_range().step); +        } + +        //create gain bucket to distribute power +        std::vector<float> gain_bucket; + +        //distribute power according to priority (round to max step) +        float gain_left_to_distribute = gain; +        BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){ +            const gain_range_t range = fcns.get_range(); +            gain_bucket.push_back( +                max_step*rint(std::clip(gain_left_to_distribute, range.min, range.max)/max_step) +            ); +            gain_left_to_distribute -= gain_bucket.back(); +        } + +        //get a list of indexes sorted by step size large to small +        std::vector<size_t> indexes_step_size_dec; +        for (size_t i = 0; i < all_fcns.size(); i++){ +            indexes_step_size_dec.push_back(i); +        } +        std::sort( +            indexes_step_size_dec.begin(), indexes_step_size_dec.end(), +            boost::bind(&compare_by_step_size, _1, _2, all_fcns) +        ); +        UHD_ASSERT_THROW( +            all_fcns.at(indexes_step_size_dec.front()).get_range().step >= +            all_fcns.at(indexes_step_size_dec.back()).get_range().step +        ); + +        //distribute the remainder (less than max step) +        //fill in the largest step sizes first that are less than the remainder +        BOOST_FOREACH(size_t i, indexes_step_size_dec){ +            const gain_range_t range = all_fcns.at(i).get_range(); +            float additional_gain = range.step*rint( +                std::clip(gain_bucket.at(i) + gain_left_to_distribute, range.min, range.max +            )/range.step) - gain_bucket.at(i); +            gain_bucket.at(i) += additional_gain; +            gain_left_to_distribute -= additional_gain; +        } +        if (verbose) std::cout << "gain_left_to_distribute " << gain_left_to_distribute << std::endl; + +        //now write the bucket out to the individual gain values +        for (size_t i = 0; i < gain_bucket.size(); i++){ +            if (verbose) std::cout << gain_bucket.at(i) << std::endl; +            all_fcns.at(i).set_value(gain_bucket.at(i)); +        } +    } + +    void register_fcns( +        const gain_fcns_t &gain_fcns, size_t priority +    ){ +        _registry[priority].push_back(gain_fcns); +    } + +private: +    //! get the gain function sets in order (highest priority first) +    std::vector<gain_fcns_t> get_all_fcns(void){ +        std::vector<gain_fcns_t> all_fcns; +        BOOST_FOREACH(ssize_t key, std::sorted(_registry.keys())){ +            const std::vector<gain_fcns_t> &fcns = _registry[key]; +            all_fcns.insert(all_fcns.begin(), fcns.begin(), fcns.end()); +        } +        return all_fcns; +    } + +    uhd::dict<size_t, std::vector<gain_fcns_t> > _registry; +}; + +/*********************************************************************** + * gain group factory function + **********************************************************************/ +gain_group::sptr gain_group::make(void){ +    return sptr(new gain_group_impl()); +} diff --git a/host/lib/utils/gain_handler.cpp b/host/lib/utils/gain_handler.cpp deleted file mode 100644 index 36e2e8ed3..000000000 --- a/host/lib/utils/gain_handler.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program.  If not, see <http://www.gnu.org/licenses/>. -// - -#include <uhd/utils/gain_handler.hpp> -#include <uhd/utils/assert.hpp> -#include <uhd/types/ranges.hpp> -#include <uhd/utils/props.hpp> -#include <boost/assign/list_of.hpp> -#include <boost/foreach.hpp> -#include <boost/format.hpp> -#include <cmath> -#include <vector> - -using namespace uhd; - -/*********************************************************************** - * gain handler implementation interface - **********************************************************************/ -class gain_handler_impl : public gain_handler{ -public: -    gain_handler_impl( -        const wax::obj &link, -        const props_t &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; -    props_t _props; -    is_equal_t   _is_equal; - -    prop_names_t get_gain_names(void); -    float get_overall_gain_val(void); -    gain_range_t get_overall_gain_range(void); -    template <class T> T get_named_prop(const wax::obj &prop, const std::string &name){ -        return _link[named_prop_t(prop, name)].as<T>(); -    } -}; - -/*********************************************************************** - * the make function - **********************************************************************/ -gain_handler::sptr gain_handler::make( -    const wax::obj &link, -    const props_t &props, -    is_equal_t is_equal -){ -    return sptr(new gain_handler_impl(link, props, is_equal)); -} - -/*********************************************************************** - * gain handler implementation methods - **********************************************************************/ -gain_handler::props_t::props_t(void){ -    /* NOP */ -} - -gain_handler_impl::gain_handler_impl( -    const wax::obj &link, -    const props_t &props, -    is_equal_t is_equal -){ -    _link = link; -    _props = props; -    _is_equal = is_equal; -} - -gain_handler_impl::~gain_handler_impl(void){ -    /* NOP */ -} - -prop_names_t gain_handler_impl::get_gain_names(void){ -    return _link[_props.names].as<prop_names_t>(); -} - -float gain_handler_impl::get_overall_gain_val(void){ -    float gain_val = 0; -    BOOST_FOREACH(std::string name, get_gain_names()){ -        gain_val += get_named_prop<float>(_props.value, name); -    } -    return gain_val; -} - -gain_range_t gain_handler_impl::get_overall_gain_range(void){ -    float gain_min = 0, gain_max = 0, gain_step = 0; -    BOOST_FOREACH(std::string name, get_gain_names()){ -        gain_range_t floatmp = get_named_prop<gain_range_t>(_props.range, name); -        gain_min += floatmp.min; -        gain_max += floatmp.max; -        gain_step = std::max(gain_step, floatmp.step); -    } -    return gain_range_t(gain_min, gain_max, gain_step); -} - -/*********************************************************************** - * 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_); - -    //not a wildcard... dont handle (but check name) -    if (name != ""){ -        assert_has(get_gain_names(), name, "gain name"); -        return false; -    } - -    if (_is_equal(key, _props.value)){ -        val = get_overall_gain_val(); -        return true; -    } - -    if (_is_equal(key, _props.range)){ -        val = get_overall_gain_range(); -        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, _props.value)) return false; - -    float gain_val = val.as<float>(); - -    //not a wildcard... dont handle (but check name and range) -    if (name != ""){ -        assert_has(get_gain_names(), name, "gain name"); -        gain_range_t gain = get_named_prop<gain_range_t>(_props.range, 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_range_t gain = get_named_prop<gain_range_t>(_props.range, name); - -        //clip g to be within the allowed range -        float g = std::min(std::max(gain_val, gain.min), gain.max); -        //set g to be a multiple of the step size -        g -= std::fmod(g, gain.step); -        //set g to be the new gain -        _link[named_prop_t(_props.value, name)] = g; -        //subtract g out of the total gain left to apply -        gain_val -= g; -    } - -    return true; -}  | 
