From d8f3980e45458cf68c8efaa029e492a1b8d08354 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Mon, 26 Jul 2010 16:33:17 -0700 Subject: Host-side changes to work with the USRP2+. Change summary: Added clock register selection between USRP2/USRP2+ Added memory map selection between USRP2/USRP2+ Added ADS62P44 support for USRP2+ --- host/lib/usrp/usrp2/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'host/lib/usrp/usrp2/CMakeLists.txt') diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index 99d0b8bdd..1da8f4419 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -34,4 +34,5 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.cpp ) -- cgit v1.2.3 From 92e7a28de3f022f52da3fb9232a8287f6fa07d46 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Tue, 27 Jul 2010 16:53:05 -0700 Subject: This is a manual merge of codec_gains2 into usrp2py. --- host/include/uhd/usrp/codec_props.hpp | 42 ++++++++ host/include/uhd/usrp/dboard_props.hpp | 5 +- host/include/uhd/utils/CMakeLists.txt | 2 +- host/include/uhd/utils/gain_handler.hpp | 90 ---------------- host/lib/CMakeLists.txt | 2 +- host/lib/gain_group.cpp | 151 +++++++++++++++++++++++++++ host/lib/gain_handler.cpp | 177 -------------------------------- host/lib/usrp/CMakeLists.txt | 2 + host/lib/usrp/dboard_manager.cpp | 23 +---- 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/CMakeLists.txt | 1 + host/lib/usrp/usrp2/codec_impl.cpp | 96 +++++++++++++++++ host/lib/usrp/usrp2/dboard_impl.cpp | 22 +++- host/lib/usrp/usrp2/mboard_impl.cpp | 3 + host/lib/usrp/usrp2/usrp2_impl.hpp | 9 ++ host/test/CMakeLists.txt | 2 +- host/test/gain_group_test.cpp | 122 ++++++++++++++++++++++ host/test/gain_handler_test.cpp | 121 ---------------------- host/utils/uhd_usrp_probe.cpp | 17 ++- 22 files changed, 600 insertions(+), 427 deletions(-) create mode 100644 host/include/uhd/usrp/codec_props.hpp delete mode 100644 host/include/uhd/utils/gain_handler.hpp create mode 100644 host/lib/gain_group.cpp delete mode 100644 host/lib/gain_handler.cpp create mode 100644 host/lib/usrp/misc_utils.cpp create mode 100644 host/lib/usrp/misc_utils.hpp create mode 100644 host/lib/usrp/usrp2/codec_impl.cpp create mode 100644 host/test/gain_group_test.cpp delete mode 100644 host/test/gain_handler_test.cpp (limited to 'host/lib/usrp/usrp2/CMakeLists.txt') diff --git a/host/include/uhd/usrp/codec_props.hpp b/host/include/uhd/usrp/codec_props.hpp new file mode 100644 index 000000000..ab09b1703 --- /dev/null +++ b/host/include/uhd/usrp/codec_props.hpp @@ -0,0 +1,42 @@ +// +// 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_USRP_CODEC_PROPS_HPP +#define INCLUDED_UHD_USRP_CODEC_PROPS_HPP + +#include + +namespace uhd{ namespace usrp{ + + /*! + * Possible device codec properties: + * A codec is expected to have a rate and gain elements. + * Other properties can be discovered through the others prop. + */ + enum codec_prop_t{ + CODEC_PROP_NAME = 'n', //ro, std::string + CODEC_PROP_OTHERS = 'o', //ro, prop_names_t + CODEC_PROP_GAIN_I = 'i', //rw, float + CODEC_PROP_GAIN_Q = 'q', //rw, float + CODEC_PROP_GAIN_RANGE = 'r', //ro, gain_range_t + CODEC_PROP_GAIN_NAMES = 'G' //ro, prop_names_t + }; + + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_CODEC_PROPS_HPP */ diff --git a/host/include/uhd/usrp/dboard_props.hpp b/host/include/uhd/usrp/dboard_props.hpp index 4d5c5efbd..071918273 100644 --- a/host/include/uhd/usrp/dboard_props.hpp +++ b/host/include/uhd/usrp/dboard_props.hpp @@ -31,8 +31,9 @@ namespace uhd{ namespace usrp{ DBOARD_PROP_SUBDEV_NAMES = 'S', //ro, prop_names_t 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 //ro, wax::obj //----> not sure, dont have to deal with yet + DBOARD_PROP_DBOARD_IFACE = 'f', //ro, dboard_iface::sptr + DBOARD_PROP_CODEC = 'c', //ro, wax::obj + DBOARD_PROP_GAIN_GROUP = 'g' //ro, gain_group }; }} //namespace diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index d484788b2..f7feab5a8 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -22,7 +22,7 @@ INSTALL(FILES byteswap.hpp byteswap.ipp exception.hpp - gain_handler.hpp + gain_group.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 767029dc4..4899d3dbc 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -112,7 +112,7 @@ CONFIGURE_FILE( LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/device.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/gain_handler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/gain_group.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_group.cpp b/host/lib/gain_group.cpp new file mode 100644 index 000000000..3ae9a285e --- /dev/null +++ b/host/lib/gain_group.cpp @@ -0,0 +1,151 @@ +// +// 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 +#include + +#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 &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 all_fcns = get_all_fcns(); + + //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 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 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 get_all_fcns(void){ + std::vector all_fcns; + BOOST_FOREACH(ssize_t key, std::sorted(_registry.keys())){ + const std::vector &fcns = _registry[key]; + all_fcns.insert(all_fcns.begin(), fcns.begin(), fcns.end()); + } + return all_fcns; + } + + uhd::dict > _registry; +}; + +/*********************************************************************** + * gain group factory function + **********************************************************************/ +gain_group::sptr gain_group::make(void){ + return sptr(new gain_group_impl()); +} 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/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/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/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/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index 1da8f4419..b4a90a6ba 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 07e36a21b..3a2a53674 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 @@ -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 133e6f989..7243880f3 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -99,6 +99,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/test/CMakeLists.txt b/host/test/CMakeLists.txt index b7dcb741a..37832edde 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -26,7 +26,7 @@ ADD_EXECUTABLE(main_test convert_types_test.cpp dict_test.cpp error_test.cpp - gain_handler_test.cpp + gain_group_test.cpp tune_helper_test.cpp vrt_test.cpp wax_test.cpp diff --git a/host/test/gain_group_test.cpp b/host/test/gain_group_test.cpp new file mode 100644 index 000000000..6a6af8eb2 --- /dev/null +++ b/host/test/gain_group_test.cpp @@ -0,0 +1,122 @@ +// +// 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 + +#define rint(x) boost::math::iround(x) + +using namespace uhd; + +/*********************************************************************** + * Define gain element classes with needed functions + **********************************************************************/ +class gain_element1{ +public: + + gain_range_t get_range(void){ + return gain_range_t(0, 90, 1); + } + + float get_value(void){ + return _gain; + } + + void set_value(float gain){ + float step = get_range().step; + _gain = step*rint(gain/step); + } + +private: + float _gain; +}; + +class gain_element2{ +public: + + gain_range_t get_range(void){ + return gain_range_t(-20, 10, 0.1); + } + + float get_value(void){ + return _gain; + } + + void set_value(float gain){ + float step = get_range().step; + _gain = step*rint(gain/step); + } + +private: + float _gain; +}; + +//create static instances of gain elements to be shared by the tests +static gain_element1 g1; +static gain_element2 g2; + +static gain_group::sptr get_gain_group(size_t pri1 = 0, size_t pri2 = 0){ + //create instance of gain group + gain_fcns_t gain_fcns; + gain_group::sptr gg(gain_group::make()); + + //load gain group with function sets + gain_fcns.get_range = boost::bind(&gain_element1::get_range, &g1); + gain_fcns.get_value = boost::bind(&gain_element1::get_value, &g1); + gain_fcns.set_value = boost::bind(&gain_element1::set_value, &g1, _1); + gg->register_fcns(gain_fcns, pri1); + + gain_fcns.get_range = boost::bind(&gain_element2::get_range, &g2); + gain_fcns.get_value = boost::bind(&gain_element2::get_value, &g2); + gain_fcns.set_value = boost::bind(&gain_element2::set_value, &g2, _1); + gg->register_fcns(gain_fcns, pri2); + + return gg; +} + +/*********************************************************************** + * Test cases + **********************************************************************/ +static const double tolerance = 0.001; + +BOOST_AUTO_TEST_CASE(test_gain_group_overall){ + gain_group::sptr gg = get_gain_group(); + + //test the overall stuff + gg->set_value(80); + BOOST_CHECK_CLOSE(gg->get_value(), float(80), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().min, float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().max, float(100), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().step, float(0.1), tolerance); +} + +BOOST_AUTO_TEST_CASE(test_gain_group_priority){ + gain_group::sptr gg = get_gain_group(0, 1); + + //test the overall stuff + gg->set_value(80); + BOOST_CHECK_CLOSE(gg->get_value(), float(80), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().min, float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().max, float(100), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().step, float(0.1), tolerance); + + //test the the higher priority gain got filled first (gain 2) + BOOST_CHECK_CLOSE(g2.get_value(), g2.get_range().max, tolerance); +} 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 1b73b5788..097317516 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -88,12 +89,25 @@ 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(); } +static std::string get_codec_pp_string(const std::string &type, wax::obj codec){ + std::stringstream ss; + ss << boost::format("%s Codec: %s") % type % codec[usrp::CODEC_PROP_NAME].as() << std::endl; + //ss << std::endl; + prop_names_t gain_names(codec[usrp::CODEC_PROP_GAIN_NAMES].as()); + if (gain_names.size() == 0) ss << "Gain Elements: None" << std::endl; + BOOST_FOREACH(const std::string &gain_name, gain_names){ + gain_range_t gain_range(codec[named_prop_t(usrp::CODEC_PROP_GAIN_RANGE, gain_name)].as()); + 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; + } + return ss.str(); +} + static std::string get_dboard_pp_string(const std::string &type, wax::obj dboard){ std::stringstream ss; ss << boost::format("%s Dboard: %s") % type % dboard[usrp::DBOARD_PROP_NAME].as() << std::endl; @@ -101,6 +115,7 @@ static std::string get_dboard_pp_string(const std::string &type, wax::obj dboard BOOST_FOREACH(const std::string &subdev_name, dboard[usrp::DBOARD_PROP_SUBDEV_NAMES].as()){ ss << make_border(get_subdev_pp_string(type, dboard[named_prop_t(usrp::DBOARD_PROP_SUBDEV, subdev_name)])); } + ss << make_border(get_codec_pp_string(type, dboard[usrp::DBOARD_PROP_CODEC])); return ss.str(); } -- cgit v1.2.3 From f09d9820ed40371f552d3a910bc2d8170d290653 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Fri, 13 Aug 2010 11:34:07 -0700 Subject: first stab at a GPS driver in gps_ctrl.cpp. not the most expandable thing in the world but there's only so many GPS interfaces out there. --- firmware/microblaze/apps/txrx_uhd.c | 3 + firmware/microblaze/lib/hal_uart.c | 7 ++ firmware/microblaze/lib/hal_uart.h | 1 + host/lib/usrp/usrp2/CMakeLists.txt | 2 + host/lib/usrp/usrp2/gps_ctrl.cpp | 140 ++++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp2/gps_ctrl.hpp | 53 ++++++++++++++ host/lib/usrp/usrp2/mboard_impl.cpp | 7 +- host/lib/usrp/usrp2/usrp2_impl.hpp | 2 + 8 files changed, 209 insertions(+), 6 deletions(-) create mode 100644 host/lib/usrp/usrp2/gps_ctrl.cpp create mode 100644 host/lib/usrp/usrp2/gps_ctrl.hpp (limited to 'host/lib/usrp/usrp2/CMakeLists.txt') diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index 2065830ff..9fe17e262 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -324,6 +324,9 @@ void handle_udp_ctrl_packet( case USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO:{ int num_bytes = ctrl_data_in->data.uart_args.bytes; if(num_bytes > 20) num_bytes = 20; + //before we write to the UART, we flush the receive buffer + //this assumes that we're interested in the reply + hal_uart_rx_flush(ctrl_data_in->data.uart_args.dev); fnputstr(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); ctrl_data_out.id = USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE; ctrl_data_out.data.uart_args.bytes = num_bytes; diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index a8344daf5..8f7f83a68 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -101,3 +101,10 @@ hal_uart_getc(hal_uart_name_t u) return uart_regs[u].rxchar; } +int hal_uart_rx_flush(hal_uart_name_t u) +{ + char x; + while(uart_regs[u].rxlevel) x = uart_regs[u].rxchar; + return x; +} + diff --git a/firmware/microblaze/lib/hal_uart.h b/firmware/microblaze/lib/hal_uart.h index 81f4a6777..051dffe92 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -82,5 +82,6 @@ void hal_uart_putc_nowait(hal_uart_name_t u, int ch); */ int hal_uart_getc(hal_uart_name_t u); +int hal_uart_rx_flush(hal_uart_name_t u); #endif /* INCLUDED_HAL_UART_H */ diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index b4a90a6ba..47d74cec8 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -26,6 +26,8 @@ LIBUHD_APPEND_SOURCES( ${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 + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp diff --git a/host/lib/usrp/usrp2/gps_ctrl.cpp b/host/lib/usrp/usrp2/gps_ctrl.cpp new file mode 100644 index 000000000..5c015be14 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.cpp @@ -0,0 +1,140 @@ +// +// 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 "gps_ctrl.hpp" +#include +#include +#include +#include + +using namespace uhd; +using namespace boost::gregorian; +using namespace boost::posix_time; + +/*! + * A usrp2 GPS control for Jackson Labs devices + */ + +//TODO: multiple baud rate support (requires mboard_impl changes for poking UART registers), NMEA support, better autodetection +class usrp2_gps_ctrl_impl : public usrp2_gps_ctrl{ +public: + usrp2_gps_ctrl_impl(usrp2_iface::sptr iface){ + _iface = iface; + //do init here + //so the Jackson Labs Firefly (and Fury) don't acknowledge successful commands -- only invalid ones. + //first we test to see if there's a Firefly/Fury connected by sending an invalid packet and listening for the response + + std::string reply; + + //TODO: try multiple baud rates (many GPS's are set up for 4800bps, you're fixed at 115200bps 8N1 right now) + //you have to poke registers in order to set baud rate, there's no dude/bro interface for it + _iface->write_uart(GPS_UART, "HAAAY GUYYYYS\n"); + try { + reply = _iface->read_uart(GPS_UART, 20); + } catch (std::runtime_error err) { + if(err.what() != std::string("usrp2 no control response")) throw; //sorry can't cope with that + else { //we don't actually have a GPS installed + gps_type = GPS_TYPE_NONE; + } + } + + if(reply == "Command Error") gps_type = GPS_TYPE_JACKSON_LABS; + else gps_type = GPS_TYPE_NONE; //we'll add NMEA support later + + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + //issue some setup stuff so it quits spewing data out when not asked to + //none of these should issue replies so we don't bother looking for it + _iface->write_uart(GPS_UART, "SYST:COMM:SER:"); + _iface->write_uart(GPS_UART, "ECHO OFF\n"); //we split lines before 20 chars right now -- TODO: fix driver to split writes/reads for you + _iface->write_uart(GPS_UART, "SYST:COMM:SER:"); + _iface->write_uart(GPS_UART, "PRO OFF\n"); + _iface->write_uart(GPS_UART, "GPS:GPGGA 0\n"); + _iface->write_uart(GPS_UART, "GPS:GGAST 0\n"); + break; + + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + + break; + } + } + + ~usrp2_gps_ctrl_impl(void){ + + } + + ptime get_time(void) { + std::string reply; + ptime now; + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + _iface->write_uart(GPS_UART, "PTIME:TIME\n"); + reply = _iface->read_uart(GPS_UART, 20); + now = ptime(get_date(), duration_from_string(reply)); + break; + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + throw std::runtime_error("get_time(): Unsupported GPS or no GPS detected\n"); + break; + } + return now; + } + + date get_date(void) { + std::string reply; + date today; + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + _iface->write_uart(GPS_UART, "PTIME:DATE\n"); + reply = _iface->read_uart(GPS_UART, 20); + today = from_string(reply); + break; + case GPS_TYPE_GENERIC_NMEA: + case GPS_TYPE_NONE: + default: + throw std::runtime_error("get_date(): Unsupported GPS or no GPS detected\n"); + break; + } + return today; + } + + bool gps_detected(void) { + return (gps_type != GPS_TYPE_NONE); + } + +private: + usrp2_iface::sptr _iface; + + enum { + GPS_TYPE_JACKSON_LABS, + GPS_TYPE_GENERIC_NMEA, + GPS_TYPE_NONE + } gps_type; + + static const int GPS_UART = 2; //TODO: this should be plucked from fw_common.h or memory_map.h or somewhere in common with the firmware + +}; + +/*********************************************************************** + * Public make function for the GPS control + **********************************************************************/ +usrp2_gps_ctrl::sptr usrp2_gps_ctrl::make(usrp2_iface::sptr iface){ + return sptr(new usrp2_gps_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp2/gps_ctrl.hpp b/host/lib/usrp/usrp2/gps_ctrl.hpp new file mode 100644 index 000000000..5936a6fb6 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.hpp @@ -0,0 +1,53 @@ +// +// 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_GPS_CTRL_HPP +#define INCLUDED_GPS_CTRL_HPP + +#include "usrp2_iface.hpp" +#include +#include +#include + +using namespace boost::posix_time; + +class usrp2_gps_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a GPS config for Jackson Labs or generic NMEA GPS devices + */ + static sptr make(usrp2_iface::sptr iface); + + /*! + * Get the current GPS time and date + * \return current GPS time and date as boost::posix_time::ptime object + */ + virtual ptime get_time(void) = 0; + + /*! + * Tell you if there's a supported GPS connected or not + * \return true if a supported GPS is connected + */ + virtual bool gps_detected(void) = 0; + + //TODO: other fun things you can do with a GPS. + +}; + +#endif /* INCLUDED_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 96c98f6c5..ed6398405 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -51,16 +51,11 @@ usrp2_mboard_impl::usrp2_mboard_impl( //set the device revision (USRP2 or USRP2+) based on the above _iface->set_hw_rev((_rev_hi << 8) | _rev_lo); - //TODO DEBUG! this is just here to test writing to and reading from the UART. - std::string mystr = "PTIME:TIME?\n"; - _iface->write_uart(2, mystr); - mystr = _iface->read_uart(2, 20); - std::cout << "what time is it? " << mystr.c_str(); - //contruct the interfaces to mboard perifs _clock_ctrl = usrp2_clock_ctrl::make(_iface); _codec_ctrl = usrp2_codec_ctrl::make(_iface); _serdes_ctrl = usrp2_serdes_ctrl::make(_iface); + _gps_ctrl = usrp2_gps_ctrl::make(_iface); //TODO move to dsp impl... //load the allowed decim/interp rates diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 21a56cb67..b37c61488 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -21,6 +21,7 @@ #include "usrp2_iface.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include "gps_ctrl.hpp" #include "serdes_ctrl.hpp" #include #include @@ -151,6 +152,7 @@ private: usrp2_clock_ctrl::sptr _clock_ctrl; usrp2_codec_ctrl::sptr _codec_ctrl; usrp2_serdes_ctrl::sptr _serdes_ctrl; + usrp2_gps_ctrl::sptr _gps_ctrl; //rx and tx dboard methods and objects uhd::usrp::dboard_manager::sptr _dboard_manager; -- cgit v1.2.3 From 8fe1e7b29aacce7f75ae36e81706bbde02749b97 Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 10 Nov 2010 12:02:28 -0800 Subject: 2+: moved mboard_rev to usrp2/ in preparation for merging upstream --- host/include/uhd/usrp/mboard_rev.hpp | 118 --------------------------------- host/lib/usrp/CMakeLists.txt | 1 - host/lib/usrp/mboard_rev.cpp | 91 ------------------------- host/lib/usrp/usrp2/CMakeLists.txt | 2 + host/lib/usrp/usrp2/clock_ctrl.cpp | 2 +- host/lib/usrp/usrp2/mboard_impl.cpp | 2 +- host/lib/usrp/usrp2/mboard_rev.cpp | 89 +++++++++++++++++++++++++ host/lib/usrp/usrp2/mboard_rev.hpp | 114 +++++++++++++++++++++++++++++++ host/lib/usrp/usrp2/usrp2_clk_regs.hpp | 4 +- host/lib/usrp/usrp2/usrp2_iface.cpp | 8 +-- host/lib/usrp/usrp2/usrp2_iface.hpp | 8 +-- host/lib/usrp/usrp2/usrp2_regs.cpp | 4 +- host/lib/usrp/usrp2/usrp2_regs.hpp | 6 +- host/utils/CMakeLists.txt | 3 - host/utils/usrp2_burn_mb_rev.cpp | 82 ----------------------- 15 files changed, 222 insertions(+), 312 deletions(-) delete mode 100644 host/include/uhd/usrp/mboard_rev.hpp delete mode 100644 host/lib/usrp/mboard_rev.cpp create mode 100644 host/lib/usrp/usrp2/mboard_rev.cpp create mode 100644 host/lib/usrp/usrp2/mboard_rev.hpp delete mode 100644 host/utils/usrp2_burn_mb_rev.cpp (limited to 'host/lib/usrp/usrp2/CMakeLists.txt') diff --git a/host/include/uhd/usrp/mboard_rev.hpp b/host/include/uhd/usrp/mboard_rev.hpp deleted file mode 100644 index be968d01d..000000000 --- a/host/include/uhd/usrp/mboard_rev.hpp +++ /dev/null @@ -1,118 +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_USRP_MBOARD_REV_HPP -#define INCLUDED_UHD_USRP_MBOARD_REV_HPP - -#include -#include -#include -#include - -namespace uhd{ namespace usrp{ - - class UHD_API mboard_rev_t : boost::equality_comparable, boost::less_than_comparable{ - public: - /*! - * Create a mboard rev from an integer. - * \param rev the integer representation - */ - mboard_rev_t(boost::uint16_t rev = 0xffff); - - /*! - * Obtain a mboard rev that represents an invalid/uninit mboard ID - * \return the mboard rev with the 0xffff rev. - */ - static mboard_rev_t none(void); - - /*! - * Create a new mboard rev from an integer representation. - * \param uint16 an unsigned 16 bit integer - * \return a new mboard rev containing the integer - */ - static mboard_rev_t from_uint16(boost::uint16_t uint16); - - /*! - * Get the mboard rev represented as an integer. - * \return an unsigned 16 bit integer representation - */ - boost::uint16_t to_uint16(void) const; - - /*! - * Create a new mboard rev from a string representation. - * If the string has a 0x prefix, it will be parsed as hex. - * \param string a numeric string, possibly hex - * \return a new dboard id containing the integer - */ - static mboard_rev_t from_string(const std::string &string); - - /*! - * Get the mboard rev represented as an integer. - * \return a hex string representation with 0x prefix - */ - std::string to_string(void) const; - - /*! - * Get the pretty print representation of this mboard rev. - * \return a string with the mboard name and rev number - */ - std::string to_pp_string(void) const; - - /*! - * Tell you if you're USRP2 or USRP2+ - * \return true if USRP2+, false if USRP2 - */ - bool is_usrp2p(void) const; - - /*! - * Get the major revision number - * \return major revision number - */ - boost::uint8_t major(void) const; - - /*! - * Get the minor revision number - * \return minor revision number - */ - boost::uint8_t minor(void) const; - - private: - boost::uint16_t _rev; //internal representation - }; - - /*! - * Comparator operator overloaded for mboard rev. - * The boost::equality_comparable provides the !=. - * \param lhs the mboard rev to the left of the operator - * \param rhs the mboard rev to the right of the operator - * \return true when the mboard revs are equal - */ - UHD_API bool operator==(const mboard_rev_t &lhs, const mboard_rev_t &rhs); - - /*! - * Comparator operator overloaded for mboard rev. - * The boost::less_than_comparable provides the >, <=, >=. - * \param lhs the mboard rev to the left of the operator - * \param rhs the mboard rev to the right of the operator - * \return true when lhs < rhs - */ - - UHD_API bool operator<(const mboard_rev_t &lhs, const mboard_rev_t &rhs); - -}} //namespace - -#endif /* INCLUDED_UHD_USRP_MBOARD_REV_HPP */ diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt index 6c7f6adf4..eeb181e0b 100644 --- a/host/lib/usrp/CMakeLists.txt +++ b/host/lib/usrp/CMakeLists.txt @@ -23,7 +23,6 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_id.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_manager.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/dsp_utils.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/mboard_rev.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/misc_utils.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/multi_usrp.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/single_usrp.cpp diff --git a/host/lib/usrp/mboard_rev.cpp b/host/lib/usrp/mboard_rev.cpp deleted file mode 100644 index 41600951f..000000000 --- a/host/lib/usrp/mboard_rev.cpp +++ /dev/null @@ -1,91 +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 - -using namespace uhd::usrp; - -static const mboard_rev_t usrp2p_first_hw_rev = mboard_rev_t(0x0A00); - -mboard_rev_t::mboard_rev_t(boost::uint16_t rev){ - _rev = rev; -} - -mboard_rev_t mboard_rev_t::none(void){ - return mboard_rev_t(); -} - -mboard_rev_t mboard_rev_t::from_uint16(boost::uint16_t uint16){ - return mboard_rev_t(uint16); -} - -boost::uint16_t mboard_rev_t::to_uint16(void) const{ - return _rev; -} - -//used with lexical cast to parse a hex string -template struct to_hex{ - T value; - operator T() const {return value;} - friend std::istream& operator>>(std::istream& in, to_hex& out){ - in >> std::hex >> out.value; - return in; - } -}; - -mboard_rev_t mboard_rev_t::from_string(const std::string &string){ - if (string.substr(0, 2) == "0x"){ - return mboard_rev_t::from_uint16(boost::lexical_cast >(string)); - } - return mboard_rev_t::from_uint16(boost::lexical_cast(string)); -} - -std::string mboard_rev_t::to_string(void) const{ - return str(boost::format("0x%04x") % this->to_uint16()); -} - -std::string mboard_rev_t::to_pp_string(void) const{ - if(this->is_usrp2p()) { - return str(boost::format("USRP2+, major rev %i, minor rev %i") % int(this->major()) % int(this->minor())); - } else { - return str(boost::format("USRP2, major rev %i, minor rev %i") % int(this->major()) % int(this->minor())); - } -} - -bool mboard_rev_t::is_usrp2p(void) const{ - return _rev >= usrp2p_first_hw_rev; -} - -boost::uint8_t mboard_rev_t::major(void) const{ - return _rev >> 8; -} - -boost::uint8_t mboard_rev_t::minor(void) const{ - return _rev & 0xff; -} - -bool uhd::usrp::operator==(const mboard_rev_t &lhs, const mboard_rev_t &rhs){ - return lhs.to_uint16() == rhs.to_uint16(); -} - -bool uhd::usrp::operator<(const mboard_rev_t &lhs, const mboard_rev_t &rhs){ - return lhs.to_uint16() < rhs.to_uint16(); -} diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index f7984fce5..a09c833bd 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -48,6 +48,8 @@ IF(ENABLE_USRP2) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_rev.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_rev.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.cpp diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index c652b592b..04bbd6ba3 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -17,7 +17,7 @@ #include "clock_ctrl.hpp" #include "ad9510_regs.hpp" -#include +#include "mboard_rev.hpp" #include "usrp2_regs.hpp" //spi slave constants #include "usrp2_clk_regs.hpp" #include diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 805fd23db..9ccf90bbb 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include "mboard_rev.hpp" #include #include #include diff --git a/host/lib/usrp/usrp2/mboard_rev.cpp b/host/lib/usrp/usrp2/mboard_rev.cpp new file mode 100644 index 000000000..9d0ff89f5 --- /dev/null +++ b/host/lib/usrp/usrp2/mboard_rev.cpp @@ -0,0 +1,89 @@ +// +// 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 "mboard_rev.hpp" +#include +#include +#include +#include + +static const mboard_rev_t usrp2p_first_hw_rev = mboard_rev_t(0x0A00); + +mboard_rev_t::mboard_rev_t(boost::uint16_t rev){ + _rev = rev; +} + +mboard_rev_t mboard_rev_t::none(void){ + return mboard_rev_t(); +} + +mboard_rev_t mboard_rev_t::from_uint16(boost::uint16_t uint16){ + return mboard_rev_t(uint16); +} + +boost::uint16_t mboard_rev_t::to_uint16(void) const{ + return _rev; +} + +//used with lexical cast to parse a hex string +template struct to_hex{ + T value; + operator T() const {return value;} + friend std::istream& operator>>(std::istream& in, to_hex& out){ + in >> std::hex >> out.value; + return in; + } +}; + +mboard_rev_t mboard_rev_t::from_string(const std::string &string){ + if (string.substr(0, 2) == "0x"){ + return mboard_rev_t::from_uint16(boost::lexical_cast >(string)); + } + return mboard_rev_t::from_uint16(boost::lexical_cast(string)); +} + +std::string mboard_rev_t::to_string(void) const{ + return str(boost::format("0x%04x") % this->to_uint16()); +} + +std::string mboard_rev_t::to_pp_string(void) const{ + if(this->is_usrp2p()) { + return str(boost::format("USRP2+, major rev %i, minor rev %i") % int(this->major()) % int(this->minor())); + } else { + return str(boost::format("USRP2, major rev %i, minor rev %i") % int(this->major()) % int(this->minor())); + } +} + +bool mboard_rev_t::is_usrp2p(void) const{ + return _rev >= usrp2p_first_hw_rev; +} + +boost::uint8_t mboard_rev_t::major(void) const{ + return _rev >> 8; +} + +boost::uint8_t mboard_rev_t::minor(void) const{ + return _rev & 0xff; +} + +bool operator==(const mboard_rev_t &lhs, const mboard_rev_t &rhs){ + return lhs.to_uint16() == rhs.to_uint16(); +} + +bool operator<(const mboard_rev_t &lhs, const mboard_rev_t &rhs){ + return lhs.to_uint16() < rhs.to_uint16(); +} diff --git a/host/lib/usrp/usrp2/mboard_rev.hpp b/host/lib/usrp/usrp2/mboard_rev.hpp new file mode 100644 index 000000000..a1b1d9605 --- /dev/null +++ b/host/lib/usrp/usrp2/mboard_rev.hpp @@ -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 . +// + +#ifndef INCLUDED_MBOARD_REV_HPP +#define INCLUDED_MBOARD_REV_HPP + +#include +#include +#include +#include + +class UHD_API mboard_rev_t : boost::equality_comparable, boost::less_than_comparable{ + public: + /*! + * Create a mboard rev from an integer. + * \param rev the integer representation + */ + mboard_rev_t(boost::uint16_t rev = 0xffff); + + /*! + * Obtain a mboard rev that represents an invalid/uninit mboard ID + * \return the mboard rev with the 0xffff rev. + */ + static mboard_rev_t none(void); + + /*! + * Create a new mboard rev from an integer representation. + * \param uint16 an unsigned 16 bit integer + * \return a new mboard rev containing the integer + */ + static mboard_rev_t from_uint16(boost::uint16_t uint16); + + /*! + * Get the mboard rev represented as an integer. + * \return an unsigned 16 bit integer representation + */ + boost::uint16_t to_uint16(void) const; + + /*! + * Create a new mboard rev from a string representation. + * If the string has a 0x prefix, it will be parsed as hex. + * \param string a numeric string, possibly hex + * \return a new dboard id containing the integer + */ + static mboard_rev_t from_string(const std::string &string); + + /*! + * Get the mboard rev represented as an integer. + * \return a hex string representation with 0x prefix + */ + std::string to_string(void) const; + + /*! + * Get the pretty print representation of this mboard rev. + * \return a string with the mboard name and rev number + */ + std::string to_pp_string(void) const; + + /*! + * Tell you if you're USRP2 or USRP2+ + * \return true if USRP2+, false if USRP2 + */ + bool is_usrp2p(void) const; + + /*! + * Get the major revision number + * \return major revision number + */ + boost::uint8_t major(void) const; + + /*! + * Get the minor revision number + * \return minor revision number + */ + boost::uint8_t minor(void) const; + + private: + boost::uint16_t _rev; //internal representation + }; + + /*! + * Comparator operator overloaded for mboard rev. + * The boost::equality_comparable provides the !=. + * \param lhs the mboard rev to the left of the operator + * \param rhs the mboard rev to the right of the operator + * \return true when the mboard revs are equal + */ + UHD_API bool operator==(const mboard_rev_t &lhs, const mboard_rev_t &rhs); + + /*! + * Comparator operator overloaded for mboard rev. + * The boost::less_than_comparable provides the >, <=, >=. + * \param lhs the mboard rev to the left of the operator + * \param rhs the mboard rev to the right of the operator + * \return true when lhs < rhs + */ + + UHD_API bool operator<(const mboard_rev_t &lhs, const mboard_rev_t &rhs); + +#endif /* INCLUDED_MBOARD_REV_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp index edbdfa15d..fcfd1e227 100644 --- a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp @@ -18,13 +18,13 @@ #ifndef INCLUDED_USRP2_CLK_REGS_HPP #define INCLUDED_USRP2_CLK_REGS_HPP -#include +#include "mboard_rev.hpp" #include "usrp2_regs.hpp" class usrp2_clk_regs_t { public: usrp2_clk_regs_t(void) { ; } - usrp2_clk_regs_t(uhd::usrp::mboard_rev_t hw_rev) { + usrp2_clk_regs_t(mboard_rev_t hw_rev) { test = 0; fpga = 1; adc = (hw_rev.is_usrp2p()) ? 2 : 4; diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index a5b39ceed..d5ac14155 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -19,7 +19,7 @@ #include "usrp2_iface.hpp" #include #include -#include +#include "mboard_rev.hpp" #include #include #include //used for htonl and ntohl @@ -54,7 +54,7 @@ public: //extract the mboard rev numbers byte_vector_t rev_bytes = read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV, 2); - set_hw_rev(uhd::usrp::mboard_rev_t::from_uint16(rev_bytes.at(0) | (rev_bytes.at(1) << 8))); + set_hw_rev(mboard_rev_t::from_uint16(rev_bytes.at(0) | (rev_bytes.at(1) << 8))); //check the fpga compatibility number const boost::uint32_t fpga_compat_num = this->peek32(this->regs.compat_num_rb); @@ -265,12 +265,12 @@ public: /*********************************************************************** * Get/set hardware revision **********************************************************************/ - void set_hw_rev(uhd::usrp::mboard_rev_t rev) { + void set_hw_rev(mboard_rev_t rev) { hw_rev = rev; regs = usrp2_get_regs(rev); //might be a better place to do this } - uhd::usrp::mboard_rev_t get_hw_rev(void) { + mboard_rev_t get_hw_rev(void) { return hw_rev; } diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index 53a8e4bc8..fee3b23af 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include "mboard_rev.hpp" #include #include "fw_common.h" #include "usrp2_regs.hpp" @@ -113,12 +113,12 @@ public: * Set the hardware revision number. Also selects the proper register set for the device. * \param rev the 16-bit revision */ - virtual void set_hw_rev(uhd::usrp::mboard_rev_t rev) = 0; + virtual void set_hw_rev(mboard_rev_t rev) = 0; /*! Return the hardware revision number * \return hardware revision */ - virtual uhd::usrp::mboard_rev_t get_hw_rev(void) = 0; + virtual mboard_rev_t get_hw_rev(void) = 0; /*! * Register map selected from USRP2/USRP2+. @@ -127,7 +127,7 @@ public: /*! * Hardware revision as returned by the device. */ - uhd::usrp::mboard_rev_t hw_rev; + mboard_rev_t hw_rev; }; #endif /* INCLUDED_USRP2_IFACE_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp index f9b54b76e..0f0360c95 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.cpp +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -15,14 +15,14 @@ // along with this program. If not, see . // -#include +#include "mboard_rev.hpp" #include "usrp2_regs.hpp" int sr_addr(int misc_output_base, int sr) { return misc_output_base + 4 * sr; } -usrp2_regs_t usrp2_get_regs(uhd::usrp::mboard_rev_t hw_rev) { +usrp2_regs_t usrp2_get_regs(mboard_rev_t hw_rev) { //how about you just make this dependent on hw_rev instead of doing the init before main, and give up the const globals, since the application won't ever need both. const int misc_output_base = (hw_rev.is_usrp2p()) ? USRP2P_MISC_OUTPUT_BASE : USRP2_MISC_OUTPUT_BASE, diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index bb15ed496..0d68c65c2 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -18,7 +18,7 @@ #ifndef INCLUDED_USRP2_REGS_HPP #define INCLUDED_USRP2_REGS_HPP -#include +#include "mboard_rev.hpp" #define USRP2_MISC_OUTPUT_BASE 0xD400 #define USRP2_GPIO_BASE 0xC800 @@ -30,7 +30,7 @@ #define USRP2P_ATR_BASE 0x3800 #define USRP2P_BP_STATUS_BASE 0x3300 -const uhd::usrp::mboard_rev_t USRP2P_FIRST_HW_REV(0x0A00); +const mboard_rev_t USRP2P_FIRST_HW_REV(0x0A00); typedef struct { int sr_misc; @@ -103,7 +103,7 @@ typedef struct { extern const usrp2_regs_t usrp2_regs; //the register definitions, set in usrp2_regs.cpp and usrp2p_regs.cpp -usrp2_regs_t usrp2_get_regs(uhd::usrp::mboard_rev_t hw_rev); +usrp2_regs_t usrp2_get_regs(mboard_rev_t hw_rev); //////////////////////////////////////////////////// // Settings Bus, Slave #7, Not Byte Addressable! diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index 083c7629c..a95864ca7 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -45,9 +45,6 @@ TARGET_LINK_LIBRARIES(usrp1_init_eeprom uhd) ADD_EXECUTABLE(usrp1_serial_burner usrp1_serial_burner.cpp) TARGET_LINK_LIBRARIES(usrp1_serial_burner uhd) -ADD_EXECUTABLE(usrp2_burn_mb_rev usrp2_burn_mb_rev.cpp) -TARGET_LINK_LIBRARIES(usrp2_burn_mb_rev uhd) - INSTALL(TARGETS usrp2_addr_burner usrp_burn_db_eeprom diff --git a/host/utils/usrp2_burn_mb_rev.cpp b/host/utils/usrp2_burn_mb_rev.cpp deleted file mode 100644 index 59b072d17..000000000 --- a/host/utils/usrp2_burn_mb_rev.cpp +++ /dev/null @@ -1,82 +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 -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; -namespace po = boost::program_options; - -int UHD_SAFE_MAIN(int argc, char *argv[]){ - //command line variables - std::string args; - - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("args", po::value(&args)->default_value(""), "device address args [default = \"\"]") - ("rev", po::value(), "mboard rev to burn, omit for readback") - ; - - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //print the help message - if (vm.count("help")){ - std::cout << boost::format("USRP Burn MB HW revision %s") % desc << std::endl; - std::cout << boost::format( - "Omit the rev argument to perform readback,\n" - "Or specify a new rev to burn into the eeprom.\n" - ) << std::endl; - return ~0; - } - - //make the device and extract the mboard - device::sptr dev = device::make(args); - wax::obj u2_mb = (*dev)[DEVICE_PROP_MBOARD]; - - //read the current mboard rev from eeprom - if (vm.count("rev") == 0){ - std::cout << "Getting rev..." << std::endl; - uhd::usrp::mboard_rev_t rev = mboard_rev_t::from_string(u2_mb[std::string("hw-rev")].as()); - std::cout << boost::format(" Current rev: %s") % rev.to_pp_string() << std::endl; - } - - //write a new mboard rev to eeprom - else{ - mboard_rev_t rev = mboard_rev_t::from_string(vm["rev"].as()); - std::cout << "Setting mboard rev..." << std::endl; - std::cout << boost::format(" New rev: %s") % rev.to_pp_string() << std::endl; - u2_mb[std::string("hw-rev")] = rev.to_string(); - } - - std::cout << " Done" << std::endl << std::endl; - return 0; -} -- cgit v1.2.3 From e0b3b4e3dd9f22d27e9465bba0c978a488733aae Mon Sep 17 00:00:00 2001 From: Nick Foster Date: Wed, 10 Nov 2010 16:23:11 -0800 Subject: U2P: Ripped out the mboard_rev_t structure in favor of an enum in usrp2_regs.hpp and some logic. Also change ethernet.c to move generic code to eth_lib. --- firmware/microblaze/usrp2p/ethernet.c | 4 +- host/lib/usrp/usrp2/CMakeLists.txt | 2 - host/lib/usrp/usrp2/clock_ctrl.cpp | 1 - host/lib/usrp/usrp2/codec_ctrl.cpp | 10 +-- host/lib/usrp/usrp2/codec_impl.cpp | 4 +- host/lib/usrp/usrp2/mboard_impl.cpp | 5 +- host/lib/usrp/usrp2/mboard_rev.cpp | 89 -------------------- host/lib/usrp/usrp2/mboard_rev.hpp | 114 -------------------------- host/lib/usrp/usrp2/usrp2_clk_regs.hpp | 26 ++++-- host/lib/usrp/usrp2/usrp2_iface.cpp | 26 +++--- host/lib/usrp/usrp2/usrp2_iface.hpp | 21 ++--- host/lib/usrp/usrp2/usrp2_regs.cpp | 14 ++-- host/lib/usrp/usrp2/usrp2_regs.hpp | 144 +++++++++++++++++---------------- 13 files changed, 123 insertions(+), 337 deletions(-) delete mode 100644 host/lib/usrp/usrp2/mboard_rev.cpp delete mode 100644 host/lib/usrp/usrp2/mboard_rev.hpp (limited to 'host/lib/usrp/usrp2/CMakeLists.txt') diff --git a/firmware/microblaze/usrp2p/ethernet.c b/firmware/microblaze/usrp2p/ethernet.c index 660f28934..36d6a17ca 100644 --- a/firmware/microblaze/usrp2p/ethernet.c +++ b/firmware/microblaze/usrp2p/ethernet.c @@ -294,7 +294,7 @@ unprogrammed(const void *t, size_t len) } //////////////////// MAC Addr Stuff /////////////////////// - +/* static int8_t src_mac_addr_initialized = false; static eth_mac_addr_t src_mac_addr = {{ 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff @@ -373,7 +373,7 @@ bool set_ip_addr(const struct ip_addr *t){ return ok; } - +*/ int ethernet_check_errors(void) { diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index a09c833bd..f7984fce5 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -48,8 +48,6 @@ IF(ENABLE_USRP2) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_rev.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_rev.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.cpp diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index 8eaafe680..1f8e65ce6 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -17,7 +17,6 @@ #include "clock_ctrl.hpp" #include "ad9510_regs.hpp" -#include "mboard_rev.hpp" #include "usrp2_regs.hpp" //spi slave constants #include "usrp2_clk_regs.hpp" #include diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 533534bd0..8680c285a 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -59,7 +59,7 @@ public: } //power-up adc - if(!_iface->get_hw_rev().is_usrp2p()) { //if we're on a USRP2 + if(!_iface->is_usrp2p()) { //if we're on a USRP2 _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_ON); } else { //we're on a USRP2+ _ads62p44_regs.reset = 1; @@ -77,7 +77,7 @@ public: this->send_ad9777_reg(0); //power-down adc - if(!_iface->get_hw_rev().is_usrp2p()) { //if we're on a USRP2 + if(!_iface->is_usrp2p()) { //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+ //send a global power-down to the ADC here... it will get lifted on reset @@ -87,21 +87,21 @@ public: } void set_rx_digital_gain(float gain) { //fine digital gain - if(_iface->get_hw_rev().is_usrp2p()) { + if(_iface->is_usrp2p()) { _ads62p44_regs.fine_gain = int(gain/0.5); this->send_ads62p44_reg(0x17); } else UHD_THROW_INVALID_CODE_PATH(); //should never have been called for USRP2 } void set_rx_digital_fine_gain(float gain) { //gain correction - if(_iface->get_hw_rev().is_usrp2p()) { + if(_iface->is_usrp2p()) { _ads62p44_regs.gain_correction = int(gain / 0.05); 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().is_usrp2p()) { + if(_iface->is_usrp2p()) { _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(); diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp index 6065b6c28..1c1f60765 100644 --- a/host/lib/usrp/usrp2/codec_impl.cpp +++ b/host/lib/usrp/usrp2/codec_impl.cpp @@ -67,7 +67,7 @@ void usrp2_mboard_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ return; case CODEC_PROP_GAIN_NAMES: - if(_iface->get_hw_rev().is_usrp2p()) { + if(_iface->is_usrp2p()) { val = prop_names_t(codec_rx_gain_ranges.keys()); } else val = prop_names_t(); return; @@ -94,7 +94,7 @@ void usrp2_mboard_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ switch(key.as()) { case CODEC_PROP_GAIN_I: case CODEC_PROP_GAIN_Q: - if(!_iface->get_hw_rev().is_usrp2p()) UHD_THROW_PROP_SET_ERROR();//this capability is only found in USRP2P + if(!_iface->is_usrp2p()) UHD_THROW_PROP_SET_ERROR();//this capability is only found in USRP2P gain = val.as(); this->rx_codec_set_gain(gain, key.name); diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index eb5b79b20..5b9dd1fa3 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -20,7 +20,6 @@ #include #include #include -#include "mboard_rev.hpp" #include #include #include @@ -148,7 +147,7 @@ void usrp2_mboard_impl::update_clock_config(void){ _iface->poke32(_iface->regs.time64_flags, pps_flags); //clock source ref 10mhz - if(_iface->get_hw_rev().is_usrp2p()) { + if(_iface->is_usrp2p()) { switch(_clock_config.ref_source){ case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break; case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; @@ -166,7 +165,7 @@ void usrp2_mboard_impl::update_clock_config(void){ //clock source ref 10mhz bool use_external = (_clock_config.ref_source != clock_config_t::REF_INT) - || (_iface->get_hw_rev().is_usrp2p()); //USRP2P has an internal 10MHz TCXO + || (_iface->is_usrp2p()); //USRP2P has an internal 10MHz TCXO _clock_ctrl->enable_external_ref(use_external); } diff --git a/host/lib/usrp/usrp2/mboard_rev.cpp b/host/lib/usrp/usrp2/mboard_rev.cpp deleted file mode 100644 index 9d0ff89f5..000000000 --- a/host/lib/usrp/usrp2/mboard_rev.cpp +++ /dev/null @@ -1,89 +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 "mboard_rev.hpp" -#include -#include -#include -#include - -static const mboard_rev_t usrp2p_first_hw_rev = mboard_rev_t(0x0A00); - -mboard_rev_t::mboard_rev_t(boost::uint16_t rev){ - _rev = rev; -} - -mboard_rev_t mboard_rev_t::none(void){ - return mboard_rev_t(); -} - -mboard_rev_t mboard_rev_t::from_uint16(boost::uint16_t uint16){ - return mboard_rev_t(uint16); -} - -boost::uint16_t mboard_rev_t::to_uint16(void) const{ - return _rev; -} - -//used with lexical cast to parse a hex string -template struct to_hex{ - T value; - operator T() const {return value;} - friend std::istream& operator>>(std::istream& in, to_hex& out){ - in >> std::hex >> out.value; - return in; - } -}; - -mboard_rev_t mboard_rev_t::from_string(const std::string &string){ - if (string.substr(0, 2) == "0x"){ - return mboard_rev_t::from_uint16(boost::lexical_cast >(string)); - } - return mboard_rev_t::from_uint16(boost::lexical_cast(string)); -} - -std::string mboard_rev_t::to_string(void) const{ - return str(boost::format("0x%04x") % this->to_uint16()); -} - -std::string mboard_rev_t::to_pp_string(void) const{ - if(this->is_usrp2p()) { - return str(boost::format("USRP2+, major rev %i, minor rev %i") % int(this->major()) % int(this->minor())); - } else { - return str(boost::format("USRP2, major rev %i, minor rev %i") % int(this->major()) % int(this->minor())); - } -} - -bool mboard_rev_t::is_usrp2p(void) const{ - return _rev >= usrp2p_first_hw_rev; -} - -boost::uint8_t mboard_rev_t::major(void) const{ - return _rev >> 8; -} - -boost::uint8_t mboard_rev_t::minor(void) const{ - return _rev & 0xff; -} - -bool operator==(const mboard_rev_t &lhs, const mboard_rev_t &rhs){ - return lhs.to_uint16() == rhs.to_uint16(); -} - -bool operator<(const mboard_rev_t &lhs, const mboard_rev_t &rhs){ - return lhs.to_uint16() < rhs.to_uint16(); -} diff --git a/host/lib/usrp/usrp2/mboard_rev.hpp b/host/lib/usrp/usrp2/mboard_rev.hpp deleted file mode 100644 index a1b1d9605..000000000 --- a/host/lib/usrp/usrp2/mboard_rev.hpp +++ /dev/null @@ -1,114 +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_MBOARD_REV_HPP -#define INCLUDED_MBOARD_REV_HPP - -#include -#include -#include -#include - -class UHD_API mboard_rev_t : boost::equality_comparable, boost::less_than_comparable{ - public: - /*! - * Create a mboard rev from an integer. - * \param rev the integer representation - */ - mboard_rev_t(boost::uint16_t rev = 0xffff); - - /*! - * Obtain a mboard rev that represents an invalid/uninit mboard ID - * \return the mboard rev with the 0xffff rev. - */ - static mboard_rev_t none(void); - - /*! - * Create a new mboard rev from an integer representation. - * \param uint16 an unsigned 16 bit integer - * \return a new mboard rev containing the integer - */ - static mboard_rev_t from_uint16(boost::uint16_t uint16); - - /*! - * Get the mboard rev represented as an integer. - * \return an unsigned 16 bit integer representation - */ - boost::uint16_t to_uint16(void) const; - - /*! - * Create a new mboard rev from a string representation. - * If the string has a 0x prefix, it will be parsed as hex. - * \param string a numeric string, possibly hex - * \return a new dboard id containing the integer - */ - static mboard_rev_t from_string(const std::string &string); - - /*! - * Get the mboard rev represented as an integer. - * \return a hex string representation with 0x prefix - */ - std::string to_string(void) const; - - /*! - * Get the pretty print representation of this mboard rev. - * \return a string with the mboard name and rev number - */ - std::string to_pp_string(void) const; - - /*! - * Tell you if you're USRP2 or USRP2+ - * \return true if USRP2+, false if USRP2 - */ - bool is_usrp2p(void) const; - - /*! - * Get the major revision number - * \return major revision number - */ - boost::uint8_t major(void) const; - - /*! - * Get the minor revision number - * \return minor revision number - */ - boost::uint8_t minor(void) const; - - private: - boost::uint16_t _rev; //internal representation - }; - - /*! - * Comparator operator overloaded for mboard rev. - * The boost::equality_comparable provides the !=. - * \param lhs the mboard rev to the left of the operator - * \param rhs the mboard rev to the right of the operator - * \return true when the mboard revs are equal - */ - UHD_API bool operator==(const mboard_rev_t &lhs, const mboard_rev_t &rhs); - - /*! - * Comparator operator overloaded for mboard rev. - * The boost::less_than_comparable provides the >, <=, >=. - * \param lhs the mboard rev to the left of the operator - * \param rhs the mboard rev to the right of the operator - * \return true when lhs < rhs - */ - - UHD_API bool operator<(const mboard_rev_t &lhs, const mboard_rev_t &rhs); - -#endif /* INCLUDED_MBOARD_REV_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp index fcfd1e227..d5f80a919 100644 --- a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp @@ -18,23 +18,33 @@ #ifndef INCLUDED_USRP2_CLK_REGS_HPP #define INCLUDED_USRP2_CLK_REGS_HPP -#include "mboard_rev.hpp" #include "usrp2_regs.hpp" class usrp2_clk_regs_t { public: usrp2_clk_regs_t(void) { ; } - usrp2_clk_regs_t(mboard_rev_t hw_rev) { + usrp2_clk_regs_t(boost::uint16_t hw_rev) { test = 0; fpga = 1; - adc = (hw_rev.is_usrp2p()) ? 2 : 4; + adc = (hw_rev >= usrp2_rev_nums(N2XX)) ? 2 : 4; dac = 3; - serdes = (hw_rev.is_usrp2p()) ? 4 : 2; //only used by usrp2+ - tx_db = (hw_rev.is_usrp2p()) ? 5 : 6; + serdes = (hw_rev >= usrp2_rev_nums(N2XX)) ? 4 : 2; //only used by usrp2+ + tx_db = (hw_rev >= usrp2_rev_nums(N2XX)) ? 5 : 6; - if(hw_rev.major() == 3) exp = 2; - else if(hw_rev.major() >= 4) exp = 5; - else if(hw_rev.major() > 10) exp = 6; + switch(hw_rev) { + case usrp2_rev_nums(USRP2_REV3): + exp = 2; + break; + case usrp2_rev_nums(USRP2_REV4): + exp = 5; + break; + case usrp2_rev_nums(N2XX): + exp = 6; + break; + default: + throw std::runtime_error("Unknown hardware revision"); + break; + } rx_db = 7; } diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 52adb5373..147b968b4 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -19,7 +19,6 @@ #include "usrp2_iface.hpp" #include #include -#include "mboard_rev.hpp" #include #include #include //used for htonl and ntohl @@ -53,9 +52,8 @@ public: usrp2_iface_impl(udp_simple::sptr ctrl_transport){ _ctrl_transport = ctrl_transport; - //extract the mboard rev numbers - byte_vector_t rev_bytes = read_eeprom(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV, 2); - set_hw_rev(mboard_rev_t::from_uint16(rev_bytes.at(0) | (rev_bytes.at(1) << 8))); + mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_N100); + regs = usrp2_get_regs(get_hw_rev()); //check the fpga compatibility number const boost::uint32_t fpga_compat_num = this->peek32(this->regs.compat_num_rb); @@ -65,8 +63,6 @@ public: "The fpga build is not compatible with the host code build." ) % int(USRP2_FPGA_COMPAT_NUM) % fpga_compat_num)); } - - mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_N100); } ~usrp2_iface_impl(void){ @@ -263,17 +259,13 @@ public: } throw std::runtime_error("usrp2 no control response"); } - - /*********************************************************************** - * Get/set hardware revision - **********************************************************************/ - void set_hw_rev(mboard_rev_t rev) { - hw_rev = rev; - regs = usrp2_get_regs(rev); //might be a better place to do this + + bool is_usrp2p(void) { + return (get_hw_rev() >= usrp2_rev_nums(N2XX)); } - - mboard_rev_t get_hw_rev(void) { - return hw_rev; + + boost::uint16_t get_hw_rev(void) { + return boost::lexical_cast(mb_eeprom["rev"]); } @@ -313,7 +305,6 @@ private: UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE); return T(ntohl(in_data.data.poke_args.data)); } - }; /*********************************************************************** @@ -322,3 +313,4 @@ private: usrp2_iface::sptr usrp2_iface::make(udp_simple::sptr ctrl_transport){ return usrp2_iface::sptr(new usrp2_iface_impl(ctrl_transport)); } + diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index 88bff5913..d7e5df9f5 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -24,7 +24,6 @@ #include #include #include -#include "mboard_rev.hpp" #include #include "fw_common.h" #include "usrp2_regs.hpp" @@ -109,26 +108,16 @@ public: virtual void write_uart(boost::uint8_t dev, const std::string &buf) = 0; virtual std::string read_uart(boost::uint8_t dev) = 0; - - /*! - * Set the hardware revision number. Also selects the proper register set for the device. - * \param rev the 16-bit revision - */ - virtual void set_hw_rev(mboard_rev_t rev) = 0; - - /*! Return the hardware revision number - * \return hardware revision - */ - virtual mboard_rev_t get_hw_rev(void) = 0; + + virtual boost::uint16_t get_hw_rev(void) = 0; + + virtual bool is_usrp2p(void) = 0; /*! * Register map selected from USRP2/USRP2+. */ usrp2_regs_t regs; - /*! - * Hardware revision as returned by the device. - */ - mboard_rev_t hw_rev; + //motherboard eeprom map structure uhd::usrp::mboard_eeprom_t mb_eeprom; }; diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp index 0f0360c95..5853e91e5 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.cpp +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -15,25 +15,23 @@ // along with this program. If not, see . // -#include "mboard_rev.hpp" #include "usrp2_regs.hpp" int sr_addr(int misc_output_base, int sr) { return misc_output_base + 4 * sr; } -usrp2_regs_t usrp2_get_regs(mboard_rev_t hw_rev) { - +usrp2_regs_t usrp2_get_regs(boost::uint16_t hw_rev) { //how about you just make this dependent on hw_rev instead of doing the init before main, and give up the const globals, since the application won't ever need both. - const int misc_output_base = (hw_rev.is_usrp2p()) ? USRP2P_MISC_OUTPUT_BASE : USRP2_MISC_OUTPUT_BASE, - gpio_base = (hw_rev.is_usrp2p()) ? USRP2P_GPIO_BASE : USRP2_GPIO_BASE, - atr_base = (hw_rev.is_usrp2p()) ? USRP2P_ATR_BASE : USRP2_ATR_BASE, - bp_base = (hw_rev.is_usrp2p()) ? USRP2P_BP_STATUS_BASE : USRP2_BP_STATUS_BASE; + const int misc_output_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_MISC_OUTPUT_BASE : USRP2_MISC_OUTPUT_BASE, + gpio_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_GPIO_BASE : USRP2_GPIO_BASE, + atr_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_ATR_BASE : USRP2_ATR_BASE, + bp_base = (hw_rev >= usrp2_rev_nums(N2XX)) ? USRP2P_BP_STATUS_BASE : USRP2_BP_STATUS_BASE; usrp2_regs_t x; x.sr_misc = 0; x.sr_tx_prot_eng = 32; - x.sr_rx_prot_eng = 48; + x.sr_rx_prot_eng = 48; x.sr_buffer_pool_ctrl = 64; x.sr_udp_sm = 96; x.sr_tx_dsp = 208; diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 0d68c65c2..d84106f36 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -18,7 +18,13 @@ #ifndef INCLUDED_USRP2_REGS_HPP #define INCLUDED_USRP2_REGS_HPP -#include "mboard_rev.hpp" +#include + +enum usrp2_rev_nums { + USRP2_REV3 = 0x0003, + USRP2_REV4 = 0x0004, + N2XX = 0x0A00 +}; #define USRP2_MISC_OUTPUT_BASE 0xD400 #define USRP2_GPIO_BASE 0xC800 @@ -30,80 +36,78 @@ #define USRP2P_ATR_BASE 0x3800 #define USRP2P_BP_STATUS_BASE 0x3300 -const mboard_rev_t USRP2P_FIRST_HW_REV(0x0A00); - typedef struct { - int sr_misc; - int sr_tx_prot_eng; - int sr_rx_prot_eng; - int sr_buffer_pool_ctrl; - int sr_udp_sm; - int sr_tx_dsp; - int sr_tx_ctrl; - int sr_rx_dsp; - int sr_rx_ctrl; - int sr_time64; - int sr_simtimer; - int sr_last; - int misc_ctrl_clock; - int misc_ctrl_serdes; - int misc_ctrl_adc; - int misc_ctrl_leds; - int misc_ctrl_phy; - int misc_ctrl_dbg_mux; - int misc_ctrl_ram_page; - int misc_ctrl_flush_icache; - int misc_ctrl_led_src; - int time64_secs; // value to set absolute secs to on next PPS - int time64_ticks; // value to set absolute ticks to on next PPS - int time64_flags; // flags -- see chart below - int time64_imm; // set immediate (0=latch on next pps, 1=latch immediate, default=0) - int time64_tps; // ticks per second rollover count - int time64_secs_rb; - int time64_ticks_rb; - int compat_num_rb; - int dsp_tx_freq; - int dsp_tx_scale_iq; - int dsp_tx_interp_rate; - int dsp_tx_mux; - int dsp_rx_freq; - int dsp_rx_scale_iq; - int dsp_rx_decim_rate; - int dsp_rx_dcoffset_i; - int dsp_rx_dcoffset_q; - int dsp_rx_mux; - int gpio_base; - int gpio_io; - int gpio_ddr; - int gpio_tx_sel; - int gpio_rx_sel; - int atr_base; - int atr_idle_txside; - int atr_idle_rxside; - int atr_intx_txside; - int atr_intx_rxside; - int atr_inrx_txside; - int atr_inrx_rxside; - int atr_full_txside; - int atr_full_rxside; - int rx_ctrl_stream_cmd; - int rx_ctrl_time_secs; - int rx_ctrl_time_ticks; - int rx_ctrl_clear_overrun; - int rx_ctrl_vrt_header; - int rx_ctrl_vrt_stream_id; - int rx_ctrl_vrt_trailer; - int rx_ctrl_nsamps_per_pkt; - int rx_ctrl_nchannels; - int tx_ctrl_num_chan; - int tx_ctrl_clear_state; - int tx_ctrl_report_sid; - int tx_ctrl_policy; + int sr_misc; + int sr_tx_prot_eng; + int sr_rx_prot_eng; + int sr_buffer_pool_ctrl; + int sr_udp_sm; + int sr_tx_dsp; + int sr_tx_ctrl; + int sr_rx_dsp; + int sr_rx_ctrl; + int sr_time64; + int sr_simtimer; + int sr_last; + int misc_ctrl_clock; + int misc_ctrl_serdes; + int misc_ctrl_adc; + int misc_ctrl_leds; + int misc_ctrl_phy; + int misc_ctrl_dbg_mux; + int misc_ctrl_ram_page; + int misc_ctrl_flush_icache; + int misc_ctrl_led_src; + int time64_secs; // value to set absolute secs to on next PPS + int time64_ticks; // value to set absolute ticks to on next PPS + int time64_flags; // flags -- see chart below + int time64_imm; // set immediate (0=latch on next pps, 1=latch immediate, default=0) + int time64_tps; // ticks per second rollover count + int time64_secs_rb; + int time64_ticks_rb; + int compat_num_rb; + int dsp_tx_freq; + int dsp_tx_scale_iq; + int dsp_tx_interp_rate; + int dsp_tx_mux; + int dsp_rx_freq; + int dsp_rx_scale_iq; + int dsp_rx_decim_rate; + int dsp_rx_dcoffset_i; + int dsp_rx_dcoffset_q; + int dsp_rx_mux; + int gpio_base; + int gpio_io; + int gpio_ddr; + int gpio_tx_sel; + int gpio_rx_sel; + int atr_base; + int atr_idle_txside; + int atr_idle_rxside; + int atr_intx_txside; + int atr_intx_rxside; + int atr_inrx_txside; + int atr_inrx_rxside; + int atr_full_txside; + int atr_full_rxside; + int rx_ctrl_stream_cmd; + int rx_ctrl_time_secs; + int rx_ctrl_time_ticks; + int rx_ctrl_clear_overrun; + int rx_ctrl_vrt_header; + int rx_ctrl_vrt_stream_id; + int rx_ctrl_vrt_trailer; + int rx_ctrl_nsamps_per_pkt; + int rx_ctrl_nchannels; + int tx_ctrl_num_chan; + int tx_ctrl_clear_state; + int tx_ctrl_report_sid; + int tx_ctrl_policy; } usrp2_regs_t; extern const usrp2_regs_t usrp2_regs; //the register definitions, set in usrp2_regs.cpp and usrp2p_regs.cpp -usrp2_regs_t usrp2_get_regs(mboard_rev_t hw_rev); +usrp2_regs_t usrp2_get_regs(boost::uint16_t hw_rev); //////////////////////////////////////////////////// // Settings Bus, Slave #7, Not Byte Addressable! -- cgit v1.2.3