From 4a6543bd481370ae924ca90c325d5cd5b2dfe692 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 23 Jul 2010 22:55:30 -0700 Subject: usrp2: added codec impl for codec properties to usrp2 --- host/lib/usrp/usrp2/CMakeLists.txt | 1 + host/lib/usrp/usrp2/codec_impl.cpp | 96 +++++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp2/dboard_impl.cpp | 8 ++++ host/lib/usrp/usrp2/mboard_impl.cpp | 3 ++ host/lib/usrp/usrp2/usrp2_impl.hpp | 9 ++++ 5 files changed, 117 insertions(+) create mode 100644 host/lib/usrp/usrp2/codec_impl.cpp (limited to 'host/lib/usrp') 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 . +// + +#include "usrp2_impl.hpp" +#include +#include + +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()){ + 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()){ + 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 8942f9d31..de091fcdc 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -92,6 +92,10 @@ 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; + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -151,6 +155,10 @@ 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; + 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 7518d3114..2f5a51c51 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -90,6 +90,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 cae1b21d6..eb61609c2 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 &); -- cgit v1.2.3 From 707b103ce5f3b9cc299e741c968c35bd4038b610 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 24 Jul 2010 00:02:10 -0700 Subject: usrp: added gain group support usrp2 dboard and to wrapper implementations --- host/include/uhd/usrp/dboard_props.hpp | 3 +- host/lib/usrp/CMakeLists.txt | 2 + host/lib/usrp/mimo_usrp.cpp | 17 +++++--- host/lib/usrp/misc_utils.cpp | 71 ++++++++++++++++++++++++++++++++++ host/lib/usrp/misc_utils.hpp | 35 +++++++++++++++++ host/lib/usrp/simple_usrp.cpp | 17 +++++--- host/lib/usrp/usrp2/dboard_impl.cpp | 18 +++++++-- 7 files changed, 147 insertions(+), 16 deletions(-) create mode 100644 host/lib/usrp/misc_utils.cpp create mode 100644 host/lib/usrp/misc_utils.hpp (limited to 'host/lib/usrp') diff --git a/host/include/uhd/usrp/dboard_props.hpp b/host/include/uhd/usrp/dboard_props.hpp index fcccb5492..e2c0f9c7b 100644 --- a/host/include/uhd/usrp/dboard_props.hpp +++ b/host/include/uhd/usrp/dboard_props.hpp @@ -34,7 +34,8 @@ namespace uhd{ namespace usrp{ DBOARD_PROP_USED_SUBDEVS = 'u', //ro, prop_names_t DBOARD_PROP_DBOARD_ID = 'i', //rw, dboard_id_t DBOARD_PROP_DBOARD_IFACE = 'f', //ro, dboard_iface::sptr - DBOARD_PROP_CODEC = 'c' //ro, wax::obj + DBOARD_PROP_CODEC = 'c', //ro, wax::obj + DBOARD_PROP_GAIN_GROUP = 'g' //ro, gain_group }; }} //namespace diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt index 814affdd0..4f0710b20 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/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 #include #include +#include #include #include #include @@ -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().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()); //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().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()); } //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(); + 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(); + 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(); + 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(); + 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 _tx_dboards; std::vector _rx_subdevs; std::vector _tx_subdevs; + std::vector _rx_gain_groups; + std::vector _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..2e94e9d47 --- /dev/null +++ b/host/lib/usrp/misc_utils.cpp @@ -0,0 +1,71 @@ +// +// 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 . +// + +#include "misc_utils.hpp" +#include +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * gain group functions + **********************************************************************/ +static void gg_set_iq_value(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; +} + +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()){ + fcns.get_range = boost::bind(&wax::obj::as, subdev[named_prop_t(SUBDEV_PROP_GAIN_RANGE, name)]); + fcns.get_value = boost::bind(&wax::obj::as, subdev[named_prop_t(SUBDEV_PROP_GAIN, name)]); + fcns.set_value = boost::bind(&wax::obj::operator[], subdev[named_prop_t(SUBDEV_PROP_GAIN, name)], _1); + gg->register_fcns(fcns); + } + //add all the codec gains last (antenna to dsp order) + BOOST_FOREACH(const std::string &name, codec[CODEC_PROP_GAIN_NAMES].as()){ + fcns.get_range = boost::bind(&wax::obj::as, codec[named_prop_t(CODEC_PROP_GAIN_RANGE, name)]); + + //register the value functions depending upon the connection type + switch(subdev[SUBDEV_PROP_CONNECTION].as()){ + case SUBDEV_CONN_COMPLEX_IQ: + case SUBDEV_CONN_COMPLEX_QI: + fcns.get_value = boost::bind(&wax::obj::as, codec[named_prop_t(CODEC_PROP_GAIN_I, name)]); //same as Q + fcns.set_value = boost::bind(&gg_set_iq_value, codec, name, _1); //sets both + break; + + case SUBDEV_CONN_REAL_I: + fcns.get_value = boost::bind(&wax::obj::as, codec[named_prop_t(CODEC_PROP_GAIN_I, name)]); + fcns.set_value = boost::bind(&wax::obj::operator[], codec[named_prop_t(CODEC_PROP_GAIN_I, name)], _1); + break; + + case SUBDEV_CONN_REAL_Q: + fcns.get_value = boost::bind(&wax::obj::as, codec[named_prop_t(CODEC_PROP_GAIN_Q, name)]); + fcns.set_value = boost::bind(&wax::obj::operator[], codec[named_prop_t(CODEC_PROP_GAIN_Q, name)], _1); + break; + } + gg->register_fcns(fcns); + } + 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 . +// + +#ifndef INCLUDED_LIBUHD_USRP_MISC_UTILS_HPP +#define INCLUDED_LIBUHD_USRP_MISC_UTILS_HPP + +#include +#include +#include + +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 #include #include +#include #include #include #include @@ -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().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(); //extract tx subdevice _tx_dboard = _mboard[MBOARD_PROP_TX_DBOARD]; std::string tx_subdev_in_use = _tx_dboard[DBOARD_PROP_USED_SUBDEVS].as().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(); } ~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(); + return _rx_gain_group->get_value(); } gain_range_t get_rx_gain_range(void){ - return _rx_subdev[SUBDEV_PROP_GAIN_RANGE].as(); + 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(); + return _tx_gain_group->get_value(); } gain_range_t get_tx_gain_range(void){ - return _tx_subdev[SUBDEV_PROP_GAIN_RANGE].as(); + 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/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index de091fcdc..e0d6beafc 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 . // - #include "usrp2_impl.hpp" #include "usrp2_regs.hpp" #include "../dsp_utils.hpp" +#include "../misc_utils.hpp" #include #include #include @@ -93,7 +93,13 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ return; case DBOARD_PROP_CODEC: - val = _rx_codec_proxy; + 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(); @@ -156,7 +162,13 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ return; case DBOARD_PROP_CODEC: - val = _tx_codec_proxy; + 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(); -- cgit v1.2.3 From 5ba60fa140d2f6e96aea1394554232809b3eeae9 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 24 Jul 2010 00:11:44 -0700 Subject: usrp: removed gain handler code (replaced by gain group) --- host/include/uhd/utils/CMakeLists.txt | 1 - host/include/uhd/utils/gain_handler.hpp | 90 ---------------- host/lib/CMakeLists.txt | 1 - host/lib/gain_handler.cpp | 177 -------------------------------- host/lib/usrp/dboard_manager.cpp | 23 +---- host/test/CMakeLists.txt | 1 - host/test/gain_handler_test.cpp | 121 ---------------------- host/utils/uhd_usrp_probe.cpp | 2 +- 8 files changed, 4 insertions(+), 412 deletions(-) delete mode 100644 host/include/uhd/utils/gain_handler.hpp delete mode 100644 host/lib/gain_handler.cpp delete mode 100644 host/test/gain_handler_test.cpp (limited to 'host/lib/usrp') diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index 4a5f20e3c..f7feab5a8 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -23,7 +23,6 @@ INSTALL(FILES byteswap.ipp exception.hpp gain_group.hpp - gain_handler.hpp pimpl.hpp props.hpp safe_main.hpp diff --git a/host/include/uhd/utils/gain_handler.hpp b/host/include/uhd/utils/gain_handler.hpp deleted file mode 100644 index f4629e6a7..000000000 --- a/host/include/uhd/utils/gain_handler.hpp +++ /dev/null @@ -1,90 +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 . -// - -#ifndef INCLUDED_UHD_UTILS_GAIN_HANDLER_HPP -#define INCLUDED_UHD_UTILS_GAIN_HANDLER_HPP - -#include -#include -#include -#include - -namespace uhd{ - -class UHD_API gain_handler{ -public: - typedef boost::shared_ptr sptr; - typedef boost::function is_equal_t; - - /*! - * A set of properties for dealing with gains. - */ - struct UHD_API props_t{ - wax::obj value, range, names; - props_t(void); //default constructor - }; - - /*! - * 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 props a struct of properties keys - * \param is_equal the function that tests for equal properties - */ - static sptr make( - const wax::obj &link, - const props_t &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 - */ - virtual bool intercept_get(const wax::obj &key, wax::obj &val) = 0; - - /*! - * Intercept sets for overall gain. - * Ensures that the gain name is valid. - * Ensures that the new gain is within range. - * \return true for handled, false to pass on - */ - virtual bool intercept_set(const wax::obj &key, const wax::obj &val) = 0; - - /*! - * 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. - */ - template static bool is_equal(const wax::obj &a, const wax::obj &b){ - try{ - return a.as() == b.as(); - } - catch(const wax::bad_cast &){ - return false; - } - } - -}; - -} //namespace uhd - -#endif /* INCLUDED_UHD_UTILS_GAIN_HANDLER_HPP */ - diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 010478821..4899d3dbc 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -113,7 +113,6 @@ CONFIGURE_FILE( LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/device.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gain_group.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/gain_handler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp ${CMAKE_CURRENT_SOURCE_DIR}/thread_priority.cpp ${CMAKE_CURRENT_SOURCE_DIR}/types.cpp diff --git a/host/lib/gain_handler.cpp b/host/lib/gain_handler.cpp deleted file mode 100644 index 36e2e8ed3..000000000 --- a/host/lib/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 . -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 T get_named_prop(const wax::obj &prop, const std::string &name){ - return _link[named_prop_t(prop, name)].as(); - } -}; - -/*********************************************************************** - * 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(); -} - -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(_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(_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(); - - //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(_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(_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; -} 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 #include -#include #include #include #include @@ -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, _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/test/CMakeLists.txt b/host/test/CMakeLists.txt index 25cae6e7f..37832edde 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -27,7 +27,6 @@ ADD_EXECUTABLE(main_test dict_test.cpp error_test.cpp gain_group_test.cpp - gain_handler_test.cpp tune_helper_test.cpp vrt_test.cpp wax_test.cpp diff --git a/host/test/gain_handler_test.cpp b/host/test/gain_handler_test.cpp deleted file mode 100644 index 5a9f2b714..000000000 --- a/host/test/gain_handler_test.cpp +++ /dev/null @@ -1,121 +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 . -// - -#include -#include -#include -#include -#include -#include -#include - -using namespace uhd; - -enum prop_t{ - PROP_GAIN_VALUE, - PROP_GAIN_RANGE, - PROP_GAIN_NAMES -}; - -class gainful_obj : public wax::obj{ -public: - gainful_obj(void){ - //initialize gain props struct - gain_handler::props_t gain_props; - gain_props.value = PROP_GAIN_VALUE; - gain_props.range = PROP_GAIN_RANGE; - gain_props.names = PROP_GAIN_NAMES; - //make a new gain handler - _gain_handler = gain_handler::make( - this->get_link(), gain_props, - boost::bind(&gain_handler::is_equal, _1, _2) - ); - _gain_values["g0"] = 0; - _gain_values["g1"] = 0; - _gain_ranges["g0"] = gain_range_t(-10, 0, float(.1)); - _gain_ranges["g1"] = gain_range_t(0, 100, float(1.5)); - } - - ~gainful_obj(void){} - -private: - void get(const wax::obj &key_, wax::obj &val){ - if (_gain_handler->intercept_get(key_, val)) return; - - 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()){ - case PROP_GAIN_VALUE: - val = _gain_values[name]; - return; - - case PROP_GAIN_RANGE: - val = _gain_ranges[name]; - return; - - case PROP_GAIN_NAMES: - val = _gain_values.keys(); - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } - } - - void set(const wax::obj &key_, const wax::obj &val){ - if (_gain_handler->intercept_set(key_, val)) return; - - 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()){ - case PROP_GAIN_VALUE: - _gain_values[name] = val.as(); - return; - - default: UHD_THROW_PROP_SET_ERROR(); - } - } - - gain_handler::sptr _gain_handler; - uhd::dict _gain_values; - uhd::dict _gain_ranges; - -}; - -BOOST_AUTO_TEST_CASE(test_gain_handler){ - std::cout << "Testing the gain handler..." << std::endl; - gainful_obj go0; - - BOOST_CHECK_THROW( - go0[named_prop_t(PROP_GAIN_VALUE, "fail")].as(), - std::exception - ); - - std::cout << "verifying the overall min, max, step" << std::endl; - gain_range_t gain = go0[PROP_GAIN_RANGE].as(); - BOOST_CHECK_EQUAL(gain.min, float(-10)); - BOOST_CHECK_EQUAL(gain.max, float(100)); - BOOST_CHECK_EQUAL(gain.step, float(1.5)); - - std::cout << "verifying the overall gain" << std::endl; - go0[named_prop_t(PROP_GAIN_VALUE, "g0")] = float(-5); - go0[named_prop_t(PROP_GAIN_VALUE, "g1")] = float(30); - BOOST_CHECK_EQUAL(go0[PROP_GAIN_VALUE].as(), float(25)); -} diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 9587ea9a3..097317516 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -89,7 +89,7 @@ static std::string get_subdev_pp_string(const std::string &type, wax::obj subdev ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.min % gain_range.max % gain_range.step << std::endl; } - ss << boost::format("Connection Type: %c") % (subdev[usrp::SUBDEV_PROP_CONNECTION].as()) << std::endl; + ss << boost::format("Connection Type: %c") % char(subdev[usrp::SUBDEV_PROP_CONNECTION].as()) << std::endl; ss << boost::format("Uses LO offset: %s") % (subdev[usrp::SUBDEV_PROP_USE_LO_OFFSET].as()? "Yes" : "No") << std::endl; return ss.str(); -- cgit v1.2.3 From 02f5347c71f53f11162796b70f15fe74adcc3aa0 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Tue, 27 Jul 2010 13:56:59 -0700 Subject: Added gain support for USRP2+ ADC. --- host/lib/usrp/usrp2/codec_ctrl.cpp | 27 ++++++++++++---- host/lib/usrp/usrp2/codec_ctrl.hpp | 13 ++++++++ host/lib/usrp/usrp2/codec_impl.cpp | 63 ++++++++++++++++++++++++++++++++++++-- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 ++ 4 files changed, 96 insertions(+), 9 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 107894d2a..b8f1df799 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -22,6 +22,7 @@ #include #include #include +#include static const bool codec_ctrl_debug = false; @@ -79,15 +80,29 @@ public: if(_iface->get_hw_rev() < USRP2P_FIRST_HW_REV) { //if we're on a USRP2 _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_OFF); } else { //we're on a USRP2+ -// _ads62p44_regs.reset = 1; -// this->send_ads62p44_reg(0x00); //issue a reset to the ADC - //everything else should be pretty much default, i think -// _ads62p44_regs.decimation = DECIMATION_DECIMATE_1; - - + //send a global power-down to the ADC here... it will get lifted on reset + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_GLOBAL_PD; + this->send_ads62p44_reg(0x14); } } + void set_rx_digital_gain(float gain) { //combine fine/correction digital gains + if(_iface->get_hw_rev() >= USRP2P_FIRST_HW_REV) { + int fine_gain = int(gain/0.5); + _ads62p44_regs.fine_gain = fine_gain; //hey what about when it calls for 6.5dB? + _ads62p44_regs.gain_correction = (gain - (double(fine_gain) * 0.5)) / 0.05; + this->send_ads62p44_reg(0x17); + this->send_ads62p44_reg(0x1A); + } else UHD_THROW_INVALID_CODE_PATH(); //should never have been called for USRP2 + } + + void set_rx_analog_gain(bool gain) { //turns on/off analog 3.5dB preamp + if(_iface->get_hw_rev() >= USRP2P_FIRST_HW_REV) { + _ads62p44_regs.coarse_gain = gain ? ads62p44_regs_t::COARSE_GAIN_3_5DB : ads62p44_regs_t::COARSE_GAIN_0DB; + this->send_ads62p44_reg(0x14); + } else UHD_THROW_INVALID_CODE_PATH(); + } + private: ad9777_regs_t _ad9777_regs; ads62p44_regs_t _ads62p44_regs; diff --git a/host/lib/usrp/usrp2/codec_ctrl.hpp b/host/lib/usrp/usrp2/codec_ctrl.hpp index ad014e0e1..d485690f6 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.hpp +++ b/host/lib/usrp/usrp2/codec_ctrl.hpp @@ -33,6 +33,19 @@ public: */ static sptr make(usrp2_iface::sptr iface); + /*! + * Set the analog preamplifier on the USRP2+ ADC (ADS62P44). + * \param gain enable or disable the 3.5dB preamp + */ + + virtual void set_rx_analog_gain(bool gain) = 0; + + /*! + * Set the digital gain on the USRP2+ ADC (ADS62P44). + * \param gain from 0-6.5dB + */ + + virtual void set_rx_digital_gain(float gain) = 0; }; #endif /* INCLUDED_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp index b9d51abf5..b246a35f8 100644 --- a/host/lib/usrp/usrp2/codec_impl.cpp +++ b/host/lib/usrp/usrp2/codec_impl.cpp @@ -17,10 +17,22 @@ #include "usrp2_impl.hpp" #include +#include +#include #include +#include +#include +#include using namespace uhd; using namespace uhd::usrp; +using namespace boost::assign; + +//this only applies to USRP2P +static const uhd::dict codec_rx_gain_ranges = map_list_of + ("analog", gain_range_t(0, 3.5, float(3.5))) + ("digital", gain_range_t(0, 6.45, float(0.05))); + /*********************************************************************** * Helper Methods @@ -55,17 +67,62 @@ void usrp2_mboard_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ return; case CODEC_PROP_GAIN_NAMES: - val = prop_names_t(); //no gain elements to be controlled + if(_iface->get_hw_rev() >= USRP2P_FIRST_HW_REV) { + val = prop_names_t(codec_rx_gain_ranges.keys()); + } else val = prop_names_t(); + return; + + case CODEC_PROP_GAIN_I: + case CODEC_PROP_GAIN_Q: + assert_has(_codec_rx_gains.keys(), name, "codec rx gain name"); + val = _codec_rx_gains[name]; 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(); +void usrp2_mboard_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + float gain; + + switch(key.as()) { + case CODEC_PROP_GAIN_I: + case CODEC_PROP_GAIN_Q: + if(_iface->get_hw_rev() < USRP2P_FIRST_HW_REV) UHD_THROW_PROP_SET_ERROR();//this capability is only found in USRP2P + + gain = val.as(); + this->rx_codec_set_gain(gain, name); //okay. we can either have ONE gain and let codec_ctrl do the sorting between analog/digital gains, or we can have TWO gains and do the priority somewhere else. + return; + + default: + UHD_THROW_PROP_SET_ERROR(); + } } +/*********************************************************************** + * Helper function to set RX codec gain + ***********************************************************************/ + +void usrp2_mboard_impl::rx_codec_set_gain(float gain, const std::string &name){ + assert_has(codec_rx_gain_ranges.keys(), name, "codec rx gain name"); + + _codec_rx_gains[name] = gain; + + if(name == "analog") { + _codec_ctrl->set_rx_analog_gain(gain > 0); //just turn it on or off + return; + } + if(name == "digital") { + _codec_ctrl->set_rx_digital_gain(gain); + return; + } + UHD_THROW_PROP_SET_ERROR(); +} + + /*********************************************************************** * TX Codec Properties **********************************************************************/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index eb61609c2..70c3705c9 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -169,6 +169,8 @@ private: void tx_codec_set(const wax::obj &, const wax::obj &); wax_obj_proxy::sptr _rx_codec_proxy; wax_obj_proxy::sptr _tx_codec_proxy; + void rx_codec_set_gain(float, const std::string &); + uhd::dict _codec_rx_gains; //properties interface for rx dboard void rx_dboard_get(const wax::obj &, wax::obj &); -- cgit v1.2.3