summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-01-05 12:17:06 -0800
committerJosh Blum <josh@joshknows.com>2011-01-05 12:17:06 -0800
commit283067dea28c2082b71793706f582ce96e667370 (patch)
tree2e728f479a2c64e4afc91ec264bd5d8822efb057 /host/lib
parent03f4ce0fb260b8ebf7982a896fbd2ce8ab4c9c5a (diff)
downloaduhd-283067dea28c2082b71793706f582ce96e667370.tar.gz
uhd-283067dea28c2082b71793706f582ce96e667370.tar.bz2
uhd-283067dea28c2082b71793706f582ce96e667370.zip
uhd: replaced templated ranges with one range thing using doubles only to avoid trouble with compiler portability
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/CMakeLists.txt1
-rw-r--r--host/lib/ranges.cpp163
-rw-r--r--host/lib/types.cpp9
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp10
-rw-r--r--host/lib/utils/gain_group.cpp18
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;