From b7b3e8288dcd64e47c242edbc5b009b9300615a2 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 10 Nov 2010 19:19:25 -0800 Subject: usrpbbbbbbbbbbbeeeeeeeeeeee fix typo --- host/lib/usrp/mboard_eeprom.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 661030aa7..1c2519291 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -139,7 +139,7 @@ static void store_n100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ * Implementation of B000 load/store **********************************************************************/ static const boost::uint8_t B000_EEPROM_ADDR = 0x50; -static const size_t B000X_SERIAL_LEN = 8; +static const size_t B000_SERIAL_LEN = 8; static const uhd::dict USRP_B000_OFFSETS = boost::assign::map_list_of ("serial", 0xf8) @@ -149,7 +149,7 @@ static const uhd::dict USRP_B000_OFFSETS = boost::a static void load_b000(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ //extract the serial mb_eeprom["serial"] = bytes_to_string(iface.read_eeprom( - B000_EEPROM_ADDR, USRP_B000_OFFSETS["serial"], B000X_SERIAL_LEN + B000_EEPROM_ADDR, USRP_B000_OFFSETS["serial"], B000_SERIAL_LEN )); //extract the name @@ -162,7 +162,7 @@ static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ //store the serial if (mb_eeprom.has_key("serial")) iface.write_eeprom( B000_EEPROM_ADDR, USRP_B000_OFFSETS["serial"], - string_to_bytes(mb_eeprom["serial"], B000X_SERIAL_LEN) + string_to_bytes(mb_eeprom["serial"], B000_SERIAL_LEN) ); //store the name -- cgit v1.2.3 From 08dfff379865656e94b31fd565a4b13b4609ea63 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 1 Nov 2010 18:56:38 -0700 Subject: uhd: created a meta range that is a range of ranges for gains and freqs created a templated range that that holds a start, stop, and step created a meta-range template that is a vector of ranges meta-range can calculate the overall start, stop, step or be indexed to get at components replaced instances of range.min, max, step with the functions start() stop() and step() the xcvr frequency range is now expressed in as two ranges (have to fix its clip function though) --- host/include/uhd/types/CMakeLists.txt | 1 + host/include/uhd/types/dict.ipp | 11 ++- host/include/uhd/types/ranges.hpp | 81 +++++++++++++++++--- host/include/uhd/types/ranges.ipp | 134 ++++++++++++++++++++++++++++++++++ host/include/uhd/usrp/mimo_usrp.hpp | 2 +- host/lib/types.cpp | 19 ----- host/lib/usrp/dboard/db_dbsrx.cpp | 16 ++-- host/lib/usrp/dboard/db_rfx.cpp | 40 +++++----- host/lib/usrp/dboard/db_tvrx.cpp | 14 ++-- host/lib/usrp/dboard/db_wbx.cpp | 20 ++--- host/lib/usrp/dboard/db_xcvr2450.cpp | 22 ++---- host/lib/usrp/usrp1/codec_ctrl.cpp | 8 +- host/lib/usrp/wrapper_utils.hpp | 2 +- host/lib/utils/gain_group.cpp | 22 +++--- host/test/gain_group_test.cpp | 18 ++--- host/utils/uhd_usrp_probe.cpp | 6 +- 16 files changed, 291 insertions(+), 125 deletions(-) create mode 100644 host/include/uhd/types/ranges.ipp (limited to 'host/lib/usrp') diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index a96976b5e..1d2c0c41c 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -25,6 +25,7 @@ INSTALL(FILES mac_addr.hpp metadata.hpp otw_type.hpp + ranges.ipp ranges.hpp serial.hpp stream_cmd.hpp diff --git a/host/include/uhd/types/dict.ipp b/host/include/uhd/types/dict.ipp index ba05d5272..f037d7988 100644 --- a/host/include/uhd/types/dict.ipp +++ b/host/include/uhd/types/dict.ipp @@ -46,12 +46,11 @@ namespace uhd{ /* NOP */ } - template - template - dict::dict(InputIterator first, InputIterator last){ - for(InputIterator it = first; it != last; it++){ - _map.push_back(*it); - } + template template + dict::dict(InputIterator first, InputIterator last): + _map(first, last) + { + /* NOP */ } template diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp index a2057d1c8..0811fc4c8 100644 --- a/host/include/uhd/types/ranges.hpp +++ b/host/include/uhd/types/ranges.hpp @@ -19,28 +19,87 @@ #define INCLUDED_UHD_TYPES_RANGES_HPP #include +#include +#include namespace uhd{ /*! - * The gain range struct describes possible gain settings. - * The mimumum gain, maximum gain, and step size are in dB. + * A range object describes a set of discrete values of the form: + * y = start + step*n, where n is an integer between 0 and (stop - start)/step */ - struct UHD_API gain_range_t{ - float min, max, step; - gain_range_t(float min = 0.0, float max = 0.0, float step = 0.0); + template class range_t{ + public: + /*! + * Create a range from a single value. + * The step size will be taken as zero. + * \param value the only possible value in this range + */ + range_t(const T &value = T(0)); + + /*! + * Create a range from a full set of values. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range + */ + range_t(const T &start, const T &stop, const T &step = T(0)); + + //! Get the start value for this range. + const T start(void) const; + + //! Get the stop value for this range. + const T stop(void) const; + + //! Get the step value for this range. + const T step(void) const; + + private: UHD_PIMPL_DECL(impl) _impl; }; /*! - * The frequency range struct describes possible frequency settings. - * Because tuning is very granular (sub-Hz), step size is not listed. - * The mimumum frequency and maximum frequency are in Hz. + * A meta-range object holds a list of individual ranges. */ - struct UHD_API freq_range_t{ - double min, max; - freq_range_t(double min = 0.0, double max = 0.0); + template struct meta_range_t : std::vector >{ + + //! A default constructor for an empty meta-range + meta_range_t(void); + + /*! + * Input iterator constructor: + * Makes boost::assign::list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template + meta_range_t(InputIterator first, InputIterator last); + + /*! + * A convenience constructor for a single range. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range + */ + meta_range_t(const T &start, const T &stop, const T &step = T(0)); + + //! Get the overall start value for this meta-range. + const T start(void) const; + + //! Get the overall stop value for this meta-range. + const T stop(void) const; + + //! Get the overall step value for this meta-range. + const T step(void) const; + }; + typedef meta_range_t gain_range_t; + typedef meta_range_t freq_range_t; + } //namespace uhd +#include + #endif /* INCLUDED_UHD_TYPES_RANGES_HPP */ diff --git a/host/include/uhd/types/ranges.ipp b/host/include/uhd/types/ranges.ipp new file mode 100644 index 000000000..cb1628c53 --- /dev/null +++ b/host/include/uhd/types/ranges.ipp @@ -0,0 +1,134 @@ +// +// 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_TYPES_RANGES_IPP +#define INCLUDED_UHD_TYPES_RANGES_IPP + +#include +#include +#include +#include + +namespace uhd{ + + /******************************************************************* + * range_t implementation code + ******************************************************************/ + template struct range_t::impl{ + impl(const T &start, const T &stop, const T &step): + start(start), stop(stop), step(step) + { + /* NOP */ + } + const T start, stop, step; + }; + + template range_t::range_t(const T &value): + _impl(UHD_PIMPL_MAKE(impl, (value, value, T(0)))) + { + /* NOP */ + } + + template range_t::range_t( + const T &start, const T &stop, const T &step + ): + _impl(UHD_PIMPL_MAKE(impl, (start, stop, step))) + { + if (stop < start){ + throw std::invalid_argument("cannot make range where stop < start"); + } + } + + template const T range_t::start(void) const{ + return _impl->start; + } + + template const T range_t::stop(void) const{ + return _impl->stop; + } + + template const T range_t::step(void) const{ + return _impl->step; + } + + /******************************************************************* + * meta_range_t implementation code + ******************************************************************/ + + template meta_range_t::meta_range_t(void){ + /* NOP */ + } + + template template + meta_range_t::meta_range_t( + InputIterator first, InputIterator last + ): + std::vector >(first, last) + { + /* NOP */ + } + + template meta_range_t::meta_range_t( + const T &start, const T &stop, const T &step + ): + std::vector > (1, range_t(start, stop, step)) + { + /* NOP */ + } + + template const T meta_range_t::start(void) const{ + if (this->empty()){ + throw std::runtime_error("cannot calculate overall start on empty meta-range"); + } + T min_start = this->at(0).start(); + for (size_t i = 1; i < this->size(); i++){ + min_start = std::min(min_start, this->at(i).start()); + } + return min_start; + } + + template const T meta_range_t::stop(void) const{ + if (this->empty()){ + throw std::runtime_error("cannot calculate overall stop on empty meta-range"); + } + T max_stop = this->at(0).stop(); + for (size_t i = 1; i < this->size(); i++){ + max_stop = std::max(max_stop, this->at(i).stop()); + } + return max_stop; + } + + template const T meta_range_t::step(void) const{ + if (this->empty()){ + throw std::runtime_error("cannot calculate overall step on empty meta-range"); + } + T min_step = this->at(0).step(); + for (size_t i = 1; i < this->size(); i++){ + if (this->at(i).start() < this->at(i-1).stop()){ + throw std::runtime_error("cannot calculate overall range when start(n) < stop(n-1) "); + } + if (this->at(i).start() != this->at(i).stop()){ + min_step = std::min(min_step, this->at(i).step()); + } + min_step = std::min(min_step, this->at(i).start() - this->at(i-1).stop()); + } + return min_step; + } + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_RANGES_IPP */ diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp index a2092f04f..977559b0b 100644 --- a/host/include/uhd/usrp/mimo_usrp.hpp +++ b/host/include/uhd/usrp/mimo_usrp.hpp @@ -200,7 +200,7 @@ namespace uhd{ namespace usrp{ namespace /*anon*/{ static inline freq_range_t add_dsp_shift(const freq_range_t &range, wax::obj dsp){ double codec_rate = dsp[DSP_PROP_CODEC_RATE].as(); - return freq_range_t(range.min - codec_rate/2.0, range.max + codec_rate/2.0); + return freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0); } /*********************************************************************** diff --git a/host/lib/types.cpp b/host/lib/types.cpp index e5e6a2512..8ccb664d5 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -16,7 +16,6 @@ // #include -#include #include #include #include @@ -40,24 +39,6 @@ using namespace uhd; -/*********************************************************************** - * ranges - **********************************************************************/ -gain_range_t::gain_range_t(float min, float max, float step): - min(min), - max(max), - step(step) -{ - /* NOP */ -} - -freq_range_t::freq_range_t(double min, double max): - min(min), - max(max) -{ - /* NOP */ -} - /*********************************************************************** * tune request **********************************************************************/ diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 85251bdf9..70bf03158 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -212,10 +212,10 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ //set defaults for LO, gains, and filter bandwidth _bandwidth = 33e6; - set_lo_freq(dbsrx_freq_range.min); + set_lo_freq(dbsrx_freq_range.start()); BOOST_FOREACH(const std::string &name, dbsrx_gain_ranges.keys()){ - set_gain(dbsrx_gain_ranges[name].min, name); + set_gain(dbsrx_gain_ranges[name].start(), name); } set_bandwidth(33e6); // default bandwidth from datasheet @@ -229,7 +229,7 @@ dbsrx::~dbsrx(void){ * Tuning **********************************************************************/ void dbsrx::set_lo_freq(double target_freq){ - target_freq = std::clip(target_freq, dbsrx_freq_range.min, dbsrx_freq_range.max); + target_freq = std::clip(target_freq, dbsrx_freq_range.start(), dbsrx_freq_range.stop()); double actual_freq=0.0, pfd_freq=0.0, ref_clock=0.0; int R=0, N=0, r=0, m=0; @@ -261,7 +261,7 @@ void dbsrx::set_lo_freq(double target_freq){ pfd_freq = ref_clock / R; //constrain the PFD frequency to specified range - if ((pfd_freq < dbsrx_pfd_freq_range.min) or (pfd_freq > dbsrx_pfd_freq_range.max)) continue; + if ((pfd_freq < dbsrx_pfd_freq_range.start()) or (pfd_freq > dbsrx_pfd_freq_range.stop())) continue; //compute N N = int(std::floor(target_freq/pfd_freq)); @@ -278,7 +278,7 @@ void dbsrx::set_lo_freq(double target_freq){ //Assert because we failed to find a suitable combination of ref_clock, R and N UHD_ASSERT_THROW(ref_clock <= 27.0e6 and ref_clock >= 0.0); UHD_ASSERT_THROW(ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6); - UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.min) and (pfd_freq <= dbsrx_pfd_freq_range.max)); + UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) and (pfd_freq <= dbsrx_pfd_freq_range.stop())); UHD_ASSERT_THROW((N >= 256) and (N <= 32768)); if(dbsrx_debug) std::cerr << boost::format( @@ -417,7 +417,7 @@ void dbsrx::set_lo_freq(double target_freq){ */ static int gain_to_gc2_vga_reg(float &gain){ int reg = 0; - gain = std::clip(float(boost::math::iround(gain)), dbsrx_gain_ranges["GC2"].min, dbsrx_gain_ranges["GC2"].max); + gain = std::clip(gain, dbsrx_gain_ranges["GC2"].start(), dbsrx_gain_ranges["GC2"].stop()); // Half dB steps from 0-5dB, 1dB steps from 5-24dB if (gain < 5) { @@ -443,11 +443,11 @@ static int gain_to_gc2_vga_reg(float &gain){ */ static float gain_to_gc1_rfvga_dac(float &gain){ //clip the input - gain = std::clip(gain, dbsrx_gain_ranges["GC1"].min, dbsrx_gain_ranges["GC1"].max); + gain = std::clip(gain, dbsrx_gain_ranges["GC1"].start(), dbsrx_gain_ranges["GC1"].stop()); //voltage level constants static const float max_volts = float(1.2), min_volts = float(2.7); - static const float slope = (max_volts-min_volts)/dbsrx_gain_ranges["GC1"].max; + static const float slope = (max_volts-min_volts)/dbsrx_gain_ranges["GC1"].stop(); //calculate the voltage for the aux dac float dac_volts = gain*slope + min_volts; diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 152198c3a..bb9e19708 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -93,9 +93,9 @@ public: void tx_set(const wax::obj &key, const wax::obj &val); private: - freq_range_t _freq_range; - uhd::dict _rx_gain_ranges; - uhd::dict _div2; + const freq_range_t _freq_range; + const uhd::dict _rx_gain_ranges; + const uhd::dict _div2; double _rx_lo_freq, _tx_lo_freq; std::string _rx_ant; uhd::dict _rx_gains; @@ -168,19 +168,17 @@ rfx_xcvr::rfx_xcvr( ctor_args_t args, const freq_range_t &freq_range, bool rx_div2, bool tx_div2 -) : xcvr_dboard_base(args){ - _freq_range = freq_range; - _div2[dboard_iface::UNIT_RX] = rx_div2; - _div2[dboard_iface::UNIT_TX] = tx_div2; - - if(this->get_rx_id() == 0x0024) { //RFX400 - _rx_gain_ranges = rfx400_rx_gain_ranges; - } - else { - _rx_gain_ranges = rfx_rx_gain_ranges; - } - - +): + xcvr_dboard_base(args), + _freq_range(freq_range), + _rx_gain_ranges((this->get_rx_id() == 0x0024)? + rfx400_rx_gain_ranges : rfx_rx_gain_ranges + ), + _div2(map_list_of + (dboard_iface::UNIT_RX, rx_div2) + (dboard_iface::UNIT_TX, tx_div2) + ) +{ //enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); @@ -204,12 +202,12 @@ rfx_xcvr::rfx_xcvr( this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, POWER_UP | ANT_RX2| MIXER_ENB); //set some default values - set_rx_lo_freq((_freq_range.min + _freq_range.max)/2.0); - set_tx_lo_freq((_freq_range.min + _freq_range.max)/2.0); + set_rx_lo_freq((_freq_range.start() + _freq_range.stop())/2.0); + set_tx_lo_freq((_freq_range.start() + _freq_range.stop())/2.0); set_rx_ant("RX2"); BOOST_FOREACH(const std::string &name, _rx_gain_ranges.keys()){ - set_rx_gain(_rx_gain_ranges[name].min, name); + set_rx_gain(_rx_gain_ranges[name].start(), name); } } @@ -265,7 +263,7 @@ void rfx_xcvr::set_rx_gain(float gain, const std::string &name){ assert_has(_rx_gain_ranges.keys(), name, "rfx rx gain name"); if(name == "PGA0"){ float dac_volts = rx_pga0_gain_to_dac_volts(gain, - (_rx_gain_ranges["PGA0"].max - _rx_gain_ranges["PGA0"].min)); + (_rx_gain_ranges["PGA0"].stop() - _rx_gain_ranges["PGA0"].start())); _rx_gains[name] = gain; //write the new voltage to the aux dac @@ -294,7 +292,7 @@ double rfx_xcvr::set_lo_freq( ) % (target_freq/1e6) << std::endl; //clip the input - target_freq = std::clip(target_freq, _freq_range.min, _freq_range.max); + target_freq = std::clip(target_freq, _freq_range.start(), _freq_range.stop()); if (_div2[unit]) target_freq *= 2; //map prescalers to the register enums diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index 2873e3d54..94ab86898 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -200,12 +200,12 @@ tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){ //send initial register settings if necessary //set default freq - _lo_freq = tvrx_freq_range.min + tvrx_if_freq; //init _lo_freq to a sane default - set_freq(tvrx_freq_range.min); + _lo_freq = tvrx_freq_range.start() + tvrx_if_freq; //init _lo_freq to a sane default + set_freq(tvrx_freq_range.start()); //set default gains BOOST_FOREACH(const std::string &name, get_tvrx_gain_ranges().keys()){ - set_gain(get_tvrx_gain_ranges()[name].min, name); + set_gain(get_tvrx_gain_ranges()[name].start(), name); } } @@ -219,7 +219,7 @@ tvrx::~tvrx(void){ static std::string get_band(double freq) { BOOST_FOREACH(const std::string &band, tvrx_freq_ranges.keys()) { - if(freq >= tvrx_freq_ranges[band].min && freq <= tvrx_freq_ranges[band].max){ + if(freq >= tvrx_freq_ranges[band].start() && freq <= tvrx_freq_ranges[band].stop()){ if(tvrx_debug) std::cout << "Band: " << band << std::endl; return band; } @@ -277,7 +277,7 @@ static double gain_interp(double gain, boost::array db_vector, boost static float rf_gain_to_voltage(float gain, double lo_freq){ //clip the input - gain = std::clip(gain, get_tvrx_gain_ranges()["RF"].min, get_tvrx_gain_ranges()["RF"].max); + gain = std::clip(gain, get_tvrx_gain_ranges()["RF"].start(), get_tvrx_gain_ranges()["RF"].stop()); //first we need to find out what band we're in, because gains are different across different bands std::string band = get_band(lo_freq + tvrx_if_freq); @@ -305,7 +305,7 @@ static float rf_gain_to_voltage(float gain, double lo_freq){ static float if_gain_to_voltage(float gain){ //clip the input - gain = std::clip(gain, get_tvrx_gain_ranges()["IF"].min, get_tvrx_gain_ranges()["IF"].max); + gain = std::clip(gain, get_tvrx_gain_ranges()["IF"].start(), get_tvrx_gain_ranges()["IF"].stop()); double gain_volts = gain_interp(gain, tvrx_if_gains_db, tvrx_gains_volts); double dac_volts = gain_volts / opamp_gain; @@ -337,7 +337,7 @@ void tvrx::set_gain(float gain, const std::string &name){ */ void tvrx::set_freq(double freq) { - freq = std::clip(freq, tvrx_freq_range.min, tvrx_freq_range.max); + freq = std::clip(freq, tvrx_freq_range.start(), tvrx_freq_range.stop()); std::string prev_band = get_band(_lo_freq - tvrx_if_freq); std::string new_band = get_band(freq); diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index 572f5de97..d68cd4eaa 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -177,15 +177,15 @@ wbx_xcvr::wbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ ) % RXIO_MASK % TXIO_MASK << std::endl; //set some default values - set_rx_lo_freq((wbx_freq_range.min + wbx_freq_range.max)/2.0); - set_tx_lo_freq((wbx_freq_range.min + wbx_freq_range.max)/2.0); + set_rx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); + set_tx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); set_rx_ant("RX2"); BOOST_FOREACH(const std::string &name, wbx_tx_gain_ranges.keys()){ - set_tx_gain(wbx_tx_gain_ranges[name].min, name); + set_tx_gain(wbx_tx_gain_ranges[name].start(), name); } BOOST_FOREACH(const std::string &name, wbx_rx_gain_ranges.keys()){ - set_rx_gain(wbx_rx_gain_ranges[name].min, name); + set_rx_gain(wbx_rx_gain_ranges[name].start(), name); } } @@ -198,10 +198,10 @@ wbx_xcvr::~wbx_xcvr(void){ **********************************************************************/ static int rx_pga0_gain_to_iobits(float &gain){ //clip the input - gain = std::clip(gain, wbx_rx_gain_ranges["PGA0"].min, wbx_rx_gain_ranges["PGA0"].max); + gain = std::clip(gain, wbx_rx_gain_ranges["PGA0"].start(), wbx_rx_gain_ranges["PGA0"].stop()); //convert to attenuation and update iobits for atr - float attn = wbx_rx_gain_ranges["PGA0"].max - gain; + float attn = wbx_rx_gain_ranges["PGA0"].stop() - gain; //calculate the attenuation int attn_code = int(floor(attn*2)); @@ -213,18 +213,18 @@ static int rx_pga0_gain_to_iobits(float &gain){ ) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK << std::endl; //the actual gain setting - gain = wbx_rx_gain_ranges["PGA0"].max - float(attn_code)/2; + gain = wbx_rx_gain_ranges["PGA0"].stop() - float(attn_code)/2; return iobits; } static float tx_pga0_gain_to_dac_volts(float &gain){ //clip the input - gain = std::clip(gain, wbx_tx_gain_ranges["PGA0"].min, wbx_tx_gain_ranges["PGA0"].max); + gain = std::clip(gain, wbx_tx_gain_ranges["PGA0"].start(), wbx_tx_gain_ranges["PGA0"].stop()); //voltage level constants static const float max_volts = float(0.5), min_volts = float(1.4); - static const float slope = (max_volts-min_volts)/wbx_tx_gain_ranges["PGA0"].max; + static const float slope = (max_volts-min_volts)/wbx_tx_gain_ranges["PGA0"].stop(); //calculate the voltage for the aux dac float dac_volts = gain*slope + min_volts; @@ -328,7 +328,7 @@ double wbx_xcvr::set_lo_freq( ) % (target_freq/1e6) << std::endl; //clip the input - target_freq = std::clip(target_freq, wbx_freq_range.min, wbx_freq_range.max); + target_freq = std::clip(target_freq, wbx_freq_range.start(), wbx_freq_range.stop()); //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler) static const uhd::dict prescaler_to_min_int_div = map_list_of diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index be0e42b92..d3084b0a0 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -72,8 +72,10 @@ using namespace boost::assign; **********************************************************************/ static const bool xcvr2450_debug = false; -static const freq_range_t xcvr_freq_range(2.4e9, 6.0e9); -static const freq_range_t xcvr_freq_band_seperation(2.5e9, 4.9e9); +static const freq_range_t xcvr_freq_range = list_of + (range_t(2.4e9, 2.5e9)) + (range_t(4.9e9, 6.0e9)) +; static const prop_names_t xcvr_antennas = list_of("J1")("J2"); @@ -212,10 +214,10 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){ set_rx_ant(xcvr_antennas.at(0)); set_tx_ant(xcvr_antennas.at(1)); BOOST_FOREACH(const std::string &name, xcvr_tx_gain_ranges.keys()){ - set_tx_gain(xcvr_tx_gain_ranges[name].min, name); + set_tx_gain(xcvr_tx_gain_ranges[name].start(), name); } BOOST_FOREACH(const std::string &name, xcvr_rx_gain_ranges.keys()){ - set_rx_gain(xcvr_rx_gain_ranges[name].min, name); + set_rx_gain(xcvr_rx_gain_ranges[name].start(), name); } } @@ -259,17 +261,9 @@ void xcvr2450::update_atr(void){ * Tuning **********************************************************************/ void xcvr2450::set_lo_freq(double target_freq){ - //clip for highband and lowband - if((target_freq > xcvr_freq_band_seperation.min) and (target_freq < xcvr_freq_band_seperation.max)){ - if(target_freq - xcvr_freq_band_seperation.min < xcvr_freq_band_seperation.max - target_freq){ - target_freq = xcvr_freq_band_seperation.min; - }else{ - target_freq = xcvr_freq_band_seperation.max; - } - } - //clip for max and min - target_freq = std::clip(target_freq, xcvr_freq_range.min, xcvr_freq_range.max); + //clip the input to the range (TODO FIXME not right) + target_freq = std::clip(target_freq, xcvr_freq_range.start(), xcvr_freq_range.stop()); //variables used in the calculation below double scaler = xcvr2450::is_highband(target_freq)? (4.0/5.0) : (4.0/3.0); diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp index 4aa730573..18f794632 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.cpp +++ b/host/lib/usrp/usrp1/codec_ctrl.cpp @@ -160,19 +160,19 @@ usrp1_codec_ctrl_impl::~usrp1_codec_ctrl_impl(void) static const int mtpgw = 255; //maximum tx pga gain word void usrp1_codec_ctrl_impl::set_tx_pga_gain(float gain){ - int gain_word = int(mtpgw*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); + int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); this->send_reg(16); } float usrp1_codec_ctrl_impl::get_tx_pga_gain(void){ - return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/mtpgw) + tx_pga_gain_range.min; + return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.stop() - tx_pga_gain_range.start())/mtpgw) + tx_pga_gain_range.start(); } static const int mrpgw = 0x14; //maximum rx pga gain word void usrp1_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ - int gain_word = int(mrpgw*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); + int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); gain_word = std::clip(gain_word, 0, mrpgw); switch(which){ case 'A': @@ -194,7 +194,7 @@ float usrp1_codec_ctrl_impl::get_rx_pga_gain(char which){ case 'B': gain_word = _ad9862_regs.rx_pga_b; break; default: UHD_THROW_INVALID_CODE_PATH(); } - return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/mrpgw) + rx_pga_gain_range.min; + return (gain_word*(rx_pga_gain_range.stop() - rx_pga_gain_range.start())/mrpgw) + rx_pga_gain_range.start(); } /*********************************************************************** diff --git a/host/lib/usrp/wrapper_utils.hpp b/host/lib/usrp/wrapper_utils.hpp index 6f9fdbfca..a7b5c5da6 100644 --- a/host/lib/usrp/wrapper_utils.hpp +++ b/host/lib/usrp/wrapper_utils.hpp @@ -30,7 +30,7 @@ static inline uhd::freq_range_t add_dsp_shift( wax::obj dsp ){ double codec_rate = dsp[uhd::usrp::DSP_PROP_CODEC_RATE].as(); - return uhd::freq_range_t(range.min - codec_rate/2.0, range.max + codec_rate/2.0); + return uhd::freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0); } static inline void do_samp_rate_warning_message( diff --git a/host/lib/utils/gain_group.cpp b/host/lib/utils/gain_group.cpp index 54146726a..11bbb8c0a 100644 --- a/host/lib/utils/gain_group.cpp +++ b/host/lib/utils/gain_group.cpp @@ -32,7 +32,7 @@ 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; + return fcns.at(rhs).get_range().step() > fcns.at(lhs).get_range().step(); } /*! @@ -69,11 +69,11 @@ public: 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; + overall_min += range.start(); + overall_max += range.stop(); //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); + 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); } @@ -97,7 +97,7 @@ public: //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); + max_step = std::max(max_step, fcns.get_range().step()); } //create gain bucket to distribute power @@ -108,7 +108,7 @@ public: 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( - gain_left_to_distribute, range.min, range.max + gain_left_to_distribute, range.start(), range.stop() ), max_step)); gain_left_to_distribute -= gain_bucket.back(); } @@ -123,8 +123,8 @@ public: 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 + 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) @@ -132,8 +132,8 @@ public: 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_bucket.at(i) + gain_left_to_distribute, range.min, range.max - ), range.step) - gain_bucket.at(i); + gain_bucket.at(i) + gain_left_to_distribute, range.start(), range.stop() + ), range.step()) - gain_bucket.at(i); gain_bucket.at(i) += additional_gain; gain_left_to_distribute -= additional_gain; } diff --git a/host/test/gain_group_test.cpp b/host/test/gain_group_test.cpp index 555ccaed3..dbb585987 100644 --- a/host/test/gain_group_test.cpp +++ b/host/test/gain_group_test.cpp @@ -40,7 +40,7 @@ public: } void set_value(float gain){ - float step = get_range().step; + float step = get_range().step(); _gain = step*rint(gain/step); } @@ -60,7 +60,7 @@ public: } void set_value(float gain){ - float step = get_range().step; + float step = get_range().step(); _gain = step*rint(gain/step); } @@ -102,9 +102,9 @@ BOOST_AUTO_TEST_CASE(test_gain_group_overall){ //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_CHECK_CLOSE(gg->get_range().start(), float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().stop(), float(100), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().step(), float(0.1), tolerance); } BOOST_AUTO_TEST_CASE(test_gain_group_priority){ @@ -113,10 +113,10 @@ BOOST_AUTO_TEST_CASE(test_gain_group_priority){ //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_CHECK_CLOSE(gg->get_range().start(), float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().stop(), 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); + BOOST_CHECK_CLOSE(g2.get_value(), g2.get_range().stop(), tolerance); } diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 8cea52fa6..5cba7c362 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -81,13 +81,13 @@ static std::string get_subdev_pp_string(const std::string &type, wax::obj subdev ss << boost::format("Antennas: %s") % prop_names_to_pp_string(ant_names) << std::endl; freq_range_t freq_range(subdev[usrp::SUBDEV_PROP_FREQ_RANGE].as()); - ss << boost::format("Freq range: %.3f to %.3f Mhz") % (freq_range.min/1e6) % (freq_range.max/1e6) << std::endl; + ss << boost::format("Freq range: %.3f to %.3f Mhz") % (freq_range.start()/1e6) % (freq_range.stop()/1e6) << std::endl; prop_names_t gain_names(subdev[usrp::SUBDEV_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(subdev[named_prop_t(usrp::SUBDEV_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; + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; } ss << boost::format("Connection Type: %c") % char(subdev[usrp::SUBDEV_PROP_CONNECTION].as()) << std::endl; @@ -104,7 +104,7 @@ static std::string get_codec_pp_string(const std::string &type, wax::obj codec){ 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; + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; } return ss.str(); } -- cgit v1.2.3 From 775383e635cdf27ede64f5936a649570b74d7c70 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 1 Nov 2010 20:57:09 -0700 Subject: uhd: added meta-range clip and implemented in dboards, fixed step calculation --- host/include/uhd/types/ranges.hpp | 8 ++++ host/include/uhd/types/ranges.ipp | 78 ++++++++++++++++++++++++++---------- host/lib/usrp/dboard/db_dbsrx.cpp | 6 +-- host/lib/usrp/dboard/db_rfx.cpp | 2 +- host/lib/usrp/dboard/db_tvrx.cpp | 6 +-- host/lib/usrp/dboard/db_wbx.cpp | 9 ++--- host/lib/usrp/dboard/db_xcvr2450.cpp | 10 +++-- 7 files changed, 82 insertions(+), 37 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp index 0811fc4c8..206c64726 100644 --- a/host/include/uhd/types/ranges.hpp +++ b/host/include/uhd/types/ranges.hpp @@ -93,6 +93,14 @@ namespace uhd{ //! Get the overall step value for this meta-range. const T step(void) const; + /*! + * Clip the target value to a possible range value. + * \param value the value to clip to this range + * \param clip_step if true, clip to steps as well + * \return a value that is in one of the ranges + */ + const T clip(const T &value, bool clip_step = false) const; + }; typedef meta_range_t gain_range_t; diff --git a/host/include/uhd/types/ranges.ipp b/host/include/uhd/types/ranges.ipp index cb1628c53..7fd1bf2eb 100644 --- a/host/include/uhd/types/ranges.ipp +++ b/host/include/uhd/types/ranges.ipp @@ -19,6 +19,7 @@ #define INCLUDED_UHD_TYPES_RANGES_IPP #include +#include #include #include #include @@ -69,6 +70,21 @@ namespace uhd{ * meta_range_t implementation code ******************************************************************/ + namespace /*anon*/{ + template inline + 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"); + } + } + } + } //namespace /*anon*/ + + template meta_range_t::meta_range_t(void){ /* NOP */ } @@ -91,42 +107,60 @@ namespace uhd{ } template const T meta_range_t::start(void) const{ - if (this->empty()){ - throw std::runtime_error("cannot calculate overall start on empty meta-range"); - } - T min_start = this->at(0).start(); - for (size_t i = 1; i < this->size(); i++){ - min_start = std::min(min_start, this->at(i).start()); + check_meta_range_monotonic(*this); + T min_start = this->front().start(); + BOOST_FOREACH(const range_t &r, (*this)){ + min_start = std::min(min_start, r.start()); } return min_start; } template const T meta_range_t::stop(void) const{ - if (this->empty()){ - throw std::runtime_error("cannot calculate overall stop on empty meta-range"); - } - T max_stop = this->at(0).stop(); - for (size_t i = 1; i < this->size(); i++){ - max_stop = std::max(max_stop, this->at(i).stop()); + check_meta_range_monotonic(*this); + T max_stop = this->front().stop(); + BOOST_FOREACH(const range_t &r, (*this)){ + max_stop = std::max(max_stop, r.stop()); } return max_stop; } template const T meta_range_t::step(void) const{ - if (this->empty()){ - throw std::runtime_error("cannot calculate overall step on empty meta-range"); + check_meta_range_monotonic(*this); + std::vector non_zero_steps; + range_t last = this->front(); + BOOST_FOREACH(const range_t &r, (*this)){ + //steps at each range + if (r.step() != T(0)) non_zero_steps.push_back(r.step()); + //and steps in-between ranges + T ibtw_step = r.start() - last.stop(); + if (ibtw_step != T(0)) non_zero_steps.push_back(ibtw_step); + //store ref to last + last = r; } - T min_step = this->at(0).step(); - for (size_t i = 1; i < this->size(); i++){ - if (this->at(i).start() < this->at(i-1).stop()){ - throw std::runtime_error("cannot calculate overall range when start(n) < stop(n-1) "); + if (non_zero_steps.empty()) return T(0); //all zero steps, its zero... + return *std::min_element(non_zero_steps.begin(), non_zero_steps.end()); + } + + template const T meta_range_t::clip( + const T &value, bool clip_step + ) const{ + check_meta_range_monotonic(*this); + T 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; } - if (this->at(i).start() != this->at(i).stop()){ - min_step = std::min(min_step, this->at(i).step()); + //in this range, clip here + if (value <= r.stop()){ + if (not clip_step or r.step() == T(0)) return value; + return boost::math::round((value - r.start())/r.step())*r.step() + r.start(); } - min_step = std::min(min_step, this->at(i).start() - this->at(i-1).stop()); + //continue on to the next range + last_stop = r.stop(); } - return min_step; + return last_stop; } } //namespace uhd diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 70bf03158..5316fb952 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -229,7 +229,7 @@ dbsrx::~dbsrx(void){ * Tuning **********************************************************************/ void dbsrx::set_lo_freq(double target_freq){ - target_freq = std::clip(target_freq, dbsrx_freq_range.start(), dbsrx_freq_range.stop()); + target_freq = dbsrx_freq_range.clip(target_freq); double actual_freq=0.0, pfd_freq=0.0, ref_clock=0.0; int R=0, N=0, r=0, m=0; @@ -417,7 +417,7 @@ void dbsrx::set_lo_freq(double target_freq){ */ static int gain_to_gc2_vga_reg(float &gain){ int reg = 0; - gain = std::clip(gain, dbsrx_gain_ranges["GC2"].start(), dbsrx_gain_ranges["GC2"].stop()); + gain = dbsrx_gain_ranges["GC2"].clip(gain); // Half dB steps from 0-5dB, 1dB steps from 5-24dB if (gain < 5) { @@ -443,7 +443,7 @@ static int gain_to_gc2_vga_reg(float &gain){ */ static float gain_to_gc1_rfvga_dac(float &gain){ //clip the input - gain = std::clip(gain, dbsrx_gain_ranges["GC1"].start(), dbsrx_gain_ranges["GC1"].stop()); + gain = dbsrx_gain_ranges["GC1"].clip(gain); //voltage level constants static const float max_volts = float(1.2), min_volts = float(2.7); diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index bb9e19708..4e73fb3a3 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -292,7 +292,7 @@ double rfx_xcvr::set_lo_freq( ) % (target_freq/1e6) << std::endl; //clip the input - target_freq = std::clip(target_freq, _freq_range.start(), _freq_range.stop()); + target_freq = _freq_range.clip(target_freq); if (_div2[unit]) target_freq *= 2; //map prescalers to the register enums diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index 94ab86898..17fdad74a 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -277,7 +277,7 @@ static double gain_interp(double gain, boost::array db_vector, boost static float rf_gain_to_voltage(float gain, double lo_freq){ //clip the input - gain = std::clip(gain, get_tvrx_gain_ranges()["RF"].start(), get_tvrx_gain_ranges()["RF"].stop()); + gain = get_tvrx_gain_ranges()["RF"].clip(gain); //first we need to find out what band we're in, because gains are different across different bands std::string band = get_band(lo_freq + tvrx_if_freq); @@ -305,7 +305,7 @@ static float rf_gain_to_voltage(float gain, double lo_freq){ static float if_gain_to_voltage(float gain){ //clip the input - gain = std::clip(gain, get_tvrx_gain_ranges()["IF"].start(), get_tvrx_gain_ranges()["IF"].stop()); + gain = get_tvrx_gain_ranges()["IF"].clip(gain); double gain_volts = gain_interp(gain, tvrx_if_gains_db, tvrx_gains_volts); double dac_volts = gain_volts / opamp_gain; @@ -337,7 +337,7 @@ void tvrx::set_gain(float gain, const std::string &name){ */ void tvrx::set_freq(double freq) { - freq = std::clip(freq, tvrx_freq_range.start(), tvrx_freq_range.stop()); + freq = tvrx_freq_range.clip(freq); std::string prev_band = get_band(_lo_freq - tvrx_if_freq); std::string new_band = get_band(freq); diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index d68cd4eaa..dd5bd600b 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -198,16 +198,15 @@ wbx_xcvr::~wbx_xcvr(void){ **********************************************************************/ static int rx_pga0_gain_to_iobits(float &gain){ //clip the input - gain = std::clip(gain, wbx_rx_gain_ranges["PGA0"].start(), wbx_rx_gain_ranges["PGA0"].stop()); + gain = wbx_rx_gain_ranges["PGA0"].clip(gain); //convert to attenuation and update iobits for atr float attn = wbx_rx_gain_ranges["PGA0"].stop() - gain; //calculate the attenuation - int attn_code = int(floor(attn*2)); + int attn_code = boost::math::iround(attn*2); int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; - if (wbx_debug) std::cerr << boost::format( "WBX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" ) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK << std::endl; @@ -220,7 +219,7 @@ static int rx_pga0_gain_to_iobits(float &gain){ static float tx_pga0_gain_to_dac_volts(float &gain){ //clip the input - gain = std::clip(gain, wbx_tx_gain_ranges["PGA0"].start(), wbx_tx_gain_ranges["PGA0"].stop()); + gain = wbx_tx_gain_ranges["PGA0"].clip(gain); //voltage level constants static const float max_volts = float(0.5), min_volts = float(1.4); @@ -328,7 +327,7 @@ double wbx_xcvr::set_lo_freq( ) % (target_freq/1e6) << std::endl; //clip the input - target_freq = std::clip(target_freq, wbx_freq_range.start(), wbx_freq_range.stop()); + target_freq = wbx_freq_range.clip(target_freq); //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler) static const uhd::dict prescaler_to_min_int_div = map_list_of diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index d3084b0a0..a3a1e6242 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -84,7 +84,11 @@ static const uhd::dict xcvr_tx_gain_ranges = map_list ("BB", gain_range_t(0, 5, 1.5)) ; static const uhd::dict xcvr_rx_gain_ranges = map_list_of - ("LNA", gain_range_t(0, 30.5, 15)) + ("LNA", gain_range_t(list_of + (range_t(0)) + (range_t(15)) + (range_t(30.5)) + )) ("VGA", gain_range_t(0, 62, 2.0)) ; @@ -262,8 +266,8 @@ void xcvr2450::update_atr(void){ **********************************************************************/ void xcvr2450::set_lo_freq(double target_freq){ - //clip the input to the range (TODO FIXME not right) - target_freq = std::clip(target_freq, xcvr_freq_range.start(), xcvr_freq_range.stop()); + //clip the input to the range + target_freq = xcvr_freq_range.clip(target_freq); //variables used in the calculation below double scaler = xcvr2450::is_highband(target_freq)? (4.0/5.0) : (4.0/3.0); -- cgit v1.2.3 From 24517fa9226a0da8ca297476ea159b230a06ff56 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 10 Nov 2010 19:41:40 -0800 Subject: dbsrx2: updated code for ranges use --- host/lib/usrp/dboard/db_dbsrx2.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp index 5a65e6123..bf5528688 100644 --- a/host/lib/usrp/dboard/db_dbsrx2.cpp +++ b/host/lib/usrp/dboard/db_dbsrx2.cpp @@ -195,15 +195,15 @@ dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args){ //for (boost::uint8_t addr=0; addr<=12; addr++) this->send_reg(addr, addr); //set defaults for LO, gains - set_lo_freq(dbsrx2_freq_range.min); + set_lo_freq(dbsrx2_freq_range.start()); BOOST_FOREACH(const std::string &name, dbsrx2_gain_ranges.keys()){ - set_gain(dbsrx2_gain_ranges[name].min, name); + set_gain(dbsrx2_gain_ranges[name].start(), name); } set_bandwidth(40e6); // default bandwidth from datasheet get_locked(); - _max2112_write_regs.bbg = boost::math::iround(std::clip(0, dbsrx2_gain_ranges["BBG"].min, dbsrx2_gain_ranges["BBG"].max)); + _max2112_write_regs.bbg = dbsrx2_gain_ranges["BBG"].start(); send_reg(0x9, 0x9); } @@ -270,7 +270,7 @@ void dbsrx2::set_lo_freq(double target_freq){ * \return 4 bit the register value */ static int gain_to_bbg_vga_reg(float &gain){ - int reg = boost::math::iround(std::clip(gain, dbsrx2_gain_ranges["BBG"].min, dbsrx2_gain_ranges["BBG"].max)); + int reg = boost::math::iround(dbsrx2_gain_ranges["BBG"].clip(gain)); gain = float(reg); @@ -290,11 +290,11 @@ static int gain_to_bbg_vga_reg(float &gain){ */ static float gain_to_gc1_rfvga_dac(float &gain){ //clip the input - gain = std::clip(gain, dbsrx2_gain_ranges["GC1"].min, dbsrx2_gain_ranges["GC1"].max); + gain = dbsrx2_gain_ranges["GC1"].clip(gain); //voltage level constants static const float max_volts = float(0.5), min_volts = float(2.7); - static const float slope = (max_volts-min_volts)/dbsrx2_gain_ranges["GC1"].max; + static const float slope = (max_volts-min_volts)/dbsrx2_gain_ranges["GC1"].stop(); //calculate the voltage for the aux dac float dac_volts = gain*slope + min_volts; -- cgit v1.2.3 From e0d84e8c8b4f0bb9fec22b48b7c61b9ca3eb8dbd Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 11 Nov 2010 12:19:03 -0800 Subject: uhd: pulled in some worthwhile changes from flow control branch --- host/include/uhd/transport/udp_simple.hpp | 4 +-- host/lib/transport/udp_simple.cpp | 44 +++++++++++++++---------------- host/lib/transport/udp_zero_copy_asio.cpp | 31 ++++++++++++++-------- host/lib/transport/vrt_packet_handler.hpp | 16 ++++++++--- host/lib/usrp/dboard/db_basic_and_lf.cpp | 5 ++++ host/lib/usrp/dboard/db_dbsrx.cpp | 3 +++ 6 files changed, 65 insertions(+), 38 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp index c84393ecf..83f895ba9 100644 --- a/host/include/uhd/transport/udp_simple.hpp +++ b/host/include/uhd/transport/udp_simple.hpp @@ -73,10 +73,10 @@ public: * Receive into the provided buffer. * Blocks until data is received or a timeout occurs. * \param buff a mutable buffer to receive into - * \param timeout_ms the timeout in milliseconds + * \param timeout the timeout in seconds * \return the number of bytes received or zero on timeout */ - virtual size_t recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms) = 0; + virtual size_t recv(const boost::asio::mutable_buffer &buff, double timeout = 0.1) = 0; }; }} //namespace diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index 89750f99d..5829b462b 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -27,23 +27,25 @@ using namespace uhd::transport; * Helper Functions **********************************************************************/ /*! - * A receive timeout for a socket: - * - * It seems that asio cannot have timeouts with synchronous io. - * However, we can implement a polling loop that will timeout. - * This is okay bacause this is the slow-path implementation. - * + * Wait for available data or timeout. * \param socket the asio socket - * \param timeout_ms the timeout in milliseconds + * \param timeout the timeout in seconds + * \return false for timeout, true for data */ -static void reasonable_recv_timeout( - boost::asio::ip::udp::socket &socket, size_t timeout_ms +static bool wait_available( + boost::asio::ip::udp::socket &socket, double timeout ){ - boost::asio::deadline_timer timer(socket.get_io_service()); - timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms)); - while (not (socket.available() or timer.expires_from_now().is_negative())){ - boost::this_thread::sleep(boost::posix_time::milliseconds(1)); - } + //setup timeval for timeout + timeval tv; + tv.tv_sec = 0; + tv.tv_usec = long(timeout*1e6); + + //setup rset for timeout + fd_set rset; + FD_ZERO(&rset); + FD_SET(socket.native(), &rset); + + return ::select(socket.native()+1, &rset, NULL, NULL, &tv) > 0; } /*********************************************************************** @@ -57,7 +59,7 @@ public: //send/recv size_t send(const boost::asio::const_buffer &); - size_t recv(const boost::asio::mutable_buffer &, size_t); + size_t recv(const boost::asio::mutable_buffer &, double); private: boost::asio::ip::udp::socket *_socket; @@ -86,9 +88,8 @@ size_t udp_connected_impl::send(const boost::asio::const_buffer &buff){ return _socket->send(boost::asio::buffer(buff)); } -size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){ - reasonable_recv_timeout(*_socket, timeout_ms); - if (not _socket->available()) return 0; +size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){ + if (not wait_available(*_socket, timeout)) return 0; return _socket->receive(boost::asio::buffer(buff)); } @@ -103,7 +104,7 @@ public: //send/recv size_t send(const boost::asio::const_buffer &); - size_t recv(const boost::asio::mutable_buffer &, size_t); + size_t recv(const boost::asio::mutable_buffer &, double); private: boost::asio::ip::udp::socket *_socket; @@ -137,9 +138,8 @@ size_t udp_broadcast_impl::send(const boost::asio::const_buffer &buff){ return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint); } -size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){ - reasonable_recv_timeout(*_socket, timeout_ms); - if (not _socket->available()) return 0; +size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){ + if (not wait_available(*_socket, timeout)) return 0; boost::asio::ip::udp::endpoint sender_endpoint; return _socket->receive_from(boost::asio::buffer(buff), sender_endpoint); } diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index ed29864e9..c758fa894 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -59,16 +59,23 @@ static const size_t DEFAULT_NUM_RECV_FRAMES = 32; #else static const size_t DEFAULT_NUM_RECV_FRAMES = MIN_RECV_SOCK_BUFF_SIZE/udp_simple::mtu; #endif + //The non-async send only ever requires a single frame //because the buffer will be committed before a new get. #ifdef USE_ASIO_ASYNC_SEND static const size_t DEFAULT_NUM_SEND_FRAMES = 32; #else -static const size_t DEFAULT_NUM_SEND_FRAMES = MIN_SEND_SOCK_BUFF_SIZE/udp_simple::mtu;; +static const size_t DEFAULT_NUM_SEND_FRAMES = MIN_SEND_SOCK_BUFF_SIZE/udp_simple::mtu; #endif -//a single concurrent thread for io_service seems to be the fastest +//The number of service threads to spawn for async ASIO: +//A single concurrent thread for io_service seems to be the fastest. +//Threads are disabled when no async implementations are enabled. +#if defined(USE_ASIO_ASYNC_RECV) || defined(USE_ASIO_ASYNC_SEND) static const size_t CONCURRENCY_HINT = 1; +#else +static const size_t CONCURRENCY_HINT = 0; +#endif /*********************************************************************** * Zero Copy UDP implementation with ASIO: @@ -86,11 +93,12 @@ public: const std::string &port, const device_addr_t &hints ): - _io_service(hints.cast("concurrency_hint", CONCURRENCY_HINT)), _recv_frame_size(size_t(hints.cast("recv_frame_size", udp_simple::mtu))), _num_recv_frames(size_t(hints.cast("num_recv_frames", DEFAULT_NUM_RECV_FRAMES))), _send_frame_size(size_t(hints.cast("send_frame_size", udp_simple::mtu))), - _num_send_frames(size_t(hints.cast("num_send_frames", DEFAULT_NUM_SEND_FRAMES))) + _num_send_frames(size_t(hints.cast("num_send_frames", DEFAULT_NUM_SEND_FRAMES))), + _concurrency_hint(hints.cast("concurrency_hint", CONCURRENCY_HINT)), + _io_service(_concurrency_hint) { //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; @@ -129,7 +137,7 @@ public: //spawn the service threads that will run the io service _work = new asio::io_service::work(_io_service); //new work to delete later - for (size_t i = 0; i < CONCURRENCY_HINT; i++) _thread_group.create_thread( + for (size_t i = 0; i < _concurrency_hint; i++) _thread_group.create_thread( boost::bind(&udp_zero_copy_asio_impl::service, this) ); } @@ -292,12 +300,6 @@ public: size_t get_send_frame_size(void) const {return _send_frame_size;} private: - //asio guts -> socket and service - asio::ip::udp::socket *_socket; - asio::io_service _io_service; - asio::io_service::work *_work; - int _sock_fd; - //memory management -> buffers and fifos boost::thread_group _thread_group; boost::shared_array _send_buffer, _recv_buffer; @@ -305,6 +307,13 @@ private: pending_buffs_type::sptr _pending_recv_buffs, _pending_send_buffs; const size_t _recv_frame_size, _num_recv_frames; const size_t _send_frame_size, _num_send_frames; + + //asio guts -> socket and service + size_t _concurrency_hint; + asio::io_service _io_service; + asio::ip::udp::socket *_socket; + asio::io_service::work *_work; + int _sock_fd; }; /*********************************************************************** diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index 939517411..278bcfeaa 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -318,7 +318,7 @@ template UHD_INLINE T get_context_code( ){ //load the rest of the if_packet_info in here if_packet_info.num_payload_words32 = (num_samps*chans_per_otw_buff*otw_type.get_sample_size())/sizeof(boost::uint32_t); - if_packet_info.packet_count = state.next_packet_seq++; + if_packet_info.packet_count = state.next_packet_seq; //get send buffers for each channel managed_send_buffs_t send_buffs(buffs.size()/chans_per_otw_buff); @@ -345,6 +345,7 @@ template UHD_INLINE T get_context_code( size_t num_bytes_total = (vrt_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t); send_buffs[i]->commit(num_bytes_total); } + state.next_packet_seq++; //increment sequence after commits return num_samps; } @@ -387,10 +388,19 @@ template UHD_INLINE T get_context_code( if_packet_info.sob = metadata.start_of_burst; if_packet_info.eob = metadata.end_of_burst; + //TODO remove this code when sample counts of zero are supported by hardware + std::vector buffs_(buffs); + size_t total_num_samps_(total_num_samps); + if (total_num_samps == 0){ + static const boost::uint64_t zeros = 0; //max size of a host sample + buffs_ = std::vector(buffs.size(), &zeros); + total_num_samps_ = 1; + } + return _send1( state, - buffs, 0, - std::min(total_num_samps, max_samples_per_packet), + buffs_, 0, + std::min(total_num_samps_, max_samples_per_packet), if_packet_info, io_type, otw_type, vrt_packer, diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index f03dd43d1..73f894374 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -106,6 +106,11 @@ UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){ **********************************************************************/ basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args){ _max_freq = max_freq; + + //set GPIOs to output 0x0000 to decrease noise pickup + this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0000); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0xFFFF); + this->get_iface()->write_gpio(dboard_iface::UNIT_RX, 0x0000); } basic_rx::~basic_rx(void){ diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 85251bdf9..aa3eeb6b5 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -374,6 +374,9 @@ void dbsrx::set_lo_freq(double target_freq){ //update vco selection and check vtune send_reg(0x2, 0x2); read_reg(0x0, 0x0); + + //allow for setup time before checking condition again + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } if(dbsrx_debug) std::cerr << boost::format( -- cgit v1.2.3 From 314efb09459582b39ea2985bd8f9beba703076e4 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 11 Nov 2010 12:23:33 -0800 Subject: usrp2: switch the timeout to units of seconds --- host/lib/usrp/usrp2/usrp2_iface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host/lib/usrp') diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 09f3432d6..f237d6377 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -41,7 +41,7 @@ using namespace uhd::transport; * This will be fixed when host-based flow control is implemented, * along with larger incoming send buffers using the on-board SRAM. */ -static const size_t CONTROL_TIMEOUT_MS = 3000; //3 seconds +static const double CONTROL_TIMEOUT = 3.0; //seconds class usrp2_iface_impl : public usrp2_iface{ public: @@ -190,7 +190,7 @@ public: boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast(usrp2_ctrl_data_in_mem); while(true){ - size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CONTROL_TIMEOUT_MS); + size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CONTROL_TIMEOUT); if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_FW_COMPAT_NUM){ throw std::runtime_error(str(boost::format( "Expected protocol compatibility number %d, but got %d:\n" -- cgit v1.2.3