diff options
Diffstat (limited to 'host/lib')
-rw-r--r-- | host/lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/lib/ranges.cpp | 163 | ||||
-rw-r--r-- | host/lib/types.cpp | 9 | ||||
-rw-r--r-- | host/lib/usrp/dboard/db_xcvr2450.cpp | 10 | ||||
-rw-r--r-- | host/lib/utils/gain_group.cpp | 18 |
5 files changed, 178 insertions, 23 deletions
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 9ab121df5..43a29df59 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -117,6 +117,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_BINARY_DIR}/constants.hpp ${CMAKE_CURRENT_SOURCE_DIR}/device.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ranges.cpp ${CMAKE_CURRENT_SOURCE_DIR}/types.cpp ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wax.cpp diff --git a/host/lib/ranges.cpp b/host/lib/ranges.cpp new file mode 100644 index 000000000..0503cc71c --- /dev/null +++ b/host/lib/ranges.cpp @@ -0,0 +1,163 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/types/ranges.hpp> +#include <boost/math/special_functions/round.hpp> +#include <boost/foreach.hpp> +#include <algorithm> +#include <stdexcept> +#include <sstream> + +using namespace uhd; + +/*********************************************************************** + * range_t implementation code + **********************************************************************/ +struct range_t::impl{ + impl(double start, double stop, double step): + start(start), stop(stop), step(step) + { + /* NOP */ + } + double start, stop, step; +}; + +range_t::range_t(double value): + _impl(UHD_PIMPL_MAKE(impl, (value, value, 0))) +{ + /* NOP */ +} + +range_t::range_t( + double start, double stop, double step +): + _impl(UHD_PIMPL_MAKE(impl, (start, stop, step))) +{ + if (stop < start){ + throw std::invalid_argument("cannot make range where stop < start"); + } +} + +double range_t::start(void) const{ + return _impl->start; +} + +double range_t::stop(void) const{ + return _impl->stop; +} + +double range_t::step(void) const{ + return _impl->step; +} + +const std::string range_t::to_pp_string(void) const{ + std::stringstream ss; + ss << "(" << this->start(); + if (this->start() != this->stop()) ss << ", " << this->stop(); + if (this->step() != 0) ss << ", " << this->step(); + ss << ")"; + return ss.str(); +} + +/*********************************************************************** + * meta_range_t implementation code + **********************************************************************/ +void check_meta_range_monotonic(const meta_range_t &mr){ + if (mr.empty()){ + throw std::runtime_error("meta-range cannot be empty"); + } + for (size_t i = 1; i < mr.size(); i++){ + if (mr.at(i).start() < mr.at(i-1).stop()){ + throw std::runtime_error("meta-range is not monotonic"); + } + } +} + +meta_range_t::meta_range_t(void){ + /* NOP */ +} + +meta_range_t::meta_range_t( + double start, double stop, double step +): + std::vector<range_t > (1, range_t(start, stop, step)) +{ + /* NOP */ +} + +double meta_range_t::start(void) const{ + check_meta_range_monotonic(*this); + double min_start = this->front().start(); + BOOST_FOREACH(const range_t &r, (*this)){ + min_start = std::min(min_start, r.start()); + } + return min_start; +} + +double meta_range_t::stop(void) const{ + check_meta_range_monotonic(*this); + double max_stop = this->front().stop(); + BOOST_FOREACH(const range_t &r, (*this)){ + max_stop = std::max(max_stop, r.stop()); + } + return max_stop; +} + +double meta_range_t::step(void) const{ + check_meta_range_monotonic(*this); + std::vector<double> non_zero_steps; + range_t last = this->front(); + BOOST_FOREACH(const range_t &r, (*this)){ + //steps at each range + if (r.step() > 0) non_zero_steps.push_back(r.step()); + //and steps in-between ranges + double ibtw_step = r.start() - last.stop(); + if (ibtw_step > 0) non_zero_steps.push_back(ibtw_step); + //store ref to last + last = r; + } + if (non_zero_steps.empty()) return 0; //all zero steps, its zero... + return *std::min_element(non_zero_steps.begin(), non_zero_steps.end()); +} + +double meta_range_t::clip(double value, bool clip_step) const{ + check_meta_range_monotonic(*this); + double last_stop = this->front().stop(); + BOOST_FOREACH(const range_t &r, (*this)){ + //in-between ranges, clip to nearest + if (value < r.start()){ + return (std::abs(value - r.start()) < std::abs(value - last_stop))? + r.start() : last_stop; + } + //in this range, clip here + if (value <= r.stop()){ + if (not clip_step or r.step() == 0) return value; + return boost::math::round((value - r.start())/r.step())*r.step() + r.start(); + } + //continue on to the next range + last_stop = r.stop(); + } + return last_stop; +} + +const std::string meta_range_t::to_pp_string(void) const{ + std::stringstream ss; + BOOST_FOREACH(const range_t &r, (*this)){ + ss << r.to_pp_string() << std::endl; + } + return ss.str(); +} diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 9e4a26c23..8ccb664d5 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -21,7 +21,6 @@ #include <uhd/types/clock_config.hpp> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/metadata.hpp> -#include <uhd/types/ranges.hpp> #include <uhd/types/time_spec.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/types/mac_addr.hpp> @@ -41,14 +40,6 @@ using namespace uhd; /*********************************************************************** - * ranges template instantiation - **********************************************************************/ -#ifdef UHD_USE_EXIM_TMPL -template struct uhd::meta_range_t<float>; -template struct uhd::meta_range_t<double>; -#endif - -/*********************************************************************** * tune request **********************************************************************/ tune_request_t::tune_request_t(double target_freq): diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index e76727bec..6fdac7c6f 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -73,8 +73,8 @@ using namespace boost::assign; static const bool xcvr2450_debug = false; static const freq_range_t xcvr_freq_range = list_of - (range_t<double>(2.4e9, 2.5e9)) - (range_t<double>(4.9e9, 6.0e9)) + (range_t(2.4e9, 2.5e9)) + (range_t(4.9e9, 6.0e9)) ; static const prop_names_t xcvr_antennas = list_of("J1")("J2"); @@ -85,9 +85,9 @@ static const uhd::dict<std::string, gain_range_t> xcvr_tx_gain_ranges = map_list ; static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = map_list_of ("LNA", gain_range_t(list_of - (range_t<float>(0)) - (range_t<float>(15)) - (range_t<float>(30.5)) + (range_t(0)) + (range_t(15)) + (range_t(30.5)) )) ("VGA", gain_range_t(0, 62, 2.0)) ; diff --git a/host/lib/utils/gain_group.cpp b/host/lib/utils/gain_group.cpp index 11bbb8c0a..cba5056ea 100644 --- a/host/lib/utils/gain_group.cpp +++ b/host/lib/utils/gain_group.cpp @@ -39,7 +39,7 @@ static bool compare_by_step_size( * Get a multiple of step with the following relation: * result = step*floor(num/step) * - * Due to small floating-point inaccuracies: + * Due to small gain_ting-point inaccuracies: * num = n*step + e, where e is a small inaccuracy. * When e is negative, floor would yeild (n-1)*step, * despite that n*step is really the desired result. @@ -66,7 +66,7 @@ public: gain_range_t get_range(const std::string &name){ if (not name.empty()) return _name_to_fcns[name].get_range(); - float overall_min = 0, overall_max = 0, overall_step = 0; + gain_t 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.start(); @@ -78,33 +78,33 @@ public: return gain_range_t(overall_min, overall_max, overall_step); } - float get_value(const std::string &name){ + gain_t get_value(const std::string &name){ if (not name.empty()) return _name_to_fcns[name].get_value(); - float overall_gain = 0; + gain_t 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, const std::string &name){ + void set_value(gain_t gain, const std::string &name){ if (not name.empty()) return _name_to_fcns[name].set_value(gain); std::vector<gain_fcns_t> all_fcns = get_all_fcns(); if (all_fcns.size() == 0) return; //nothing to set! //get the max step size among the gains - float max_step = 0; + gain_t max_step = 0; BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){ max_step = std::max(max_step, fcns.get_range().step()); } //create gain bucket to distribute power - std::vector<float> gain_bucket; + std::vector<gain_t> gain_bucket; //distribute power according to priority (round to max step) - float gain_left_to_distribute = gain; + gain_t 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(floor_step(std::clip( @@ -131,7 +131,7 @@ public: //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 = floor_step(std::clip( + gain_t additional_gain = floor_step(std::clip( gain_bucket.at(i) + gain_left_to_distribute, range.start(), range.stop() ), range.step()) - gain_bucket.at(i); gain_bucket.at(i) += additional_gain; |