diff options
| author | Nick Foster <nick@nerdnetworks.org> | 2010-11-11 14:06:56 -0800 | 
|---|---|---|
| committer | Nick Foster <nick@nerdnetworks.org> | 2010-11-11 14:06:56 -0800 | 
| commit | 5a3b5a06082e90a68b993a765b91a7c288ab19c0 (patch) | |
| tree | 5219c55ea239203514fc0a699f7f7ceb21c48781 /host | |
| parent | 6eef331543022efa5723e677cd3140e652ea67d7 (diff) | |
| parent | 5da1e3e2d683eecce1f0e888d90caef40661e98e (diff) | |
| download | uhd-5a3b5a06082e90a68b993a765b91a7c288ab19c0.tar.gz uhd-5a3b5a06082e90a68b993a765b91a7c288ab19c0.tar.bz2 uhd-5a3b5a06082e90a68b993a765b91a7c288ab19c0.zip | |
Merge branch 'master' of ettus.sourcerepo.com:ettus/uhdpriv into usrp2p
Diffstat (limited to 'host')
26 files changed, 473 insertions, 177 deletions
| 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/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 <typename Key, typename Val> -    template <typename InputIterator> -    dict<Key, Val>::dict(InputIterator first, InputIterator last){ -        for(InputIterator it = first; it != last; it++){ -            _map.push_back(*it); -        } +    template <typename Key, typename Val> template <typename InputIterator> +    dict<Key, Val>::dict(InputIterator first, InputIterator last): +        _map(first, last) +    { +        /* NOP */      }      template <typename Key, typename Val> diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp index a2057d1c8..206c64726 100644 --- a/host/include/uhd/types/ranges.hpp +++ b/host/include/uhd/types/ranges.hpp @@ -19,28 +19,95 @@  #define INCLUDED_UHD_TYPES_RANGES_HPP  #include <uhd/config.hpp> +#include <uhd/utils/pimpl.hpp> +#include <vector>  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 <typename T> 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 <typename T> struct meta_range_t : std::vector<range_t<T> >{ + +        //! 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 <typename InputIterator> +        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; + +        /*! +         * 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<float> gain_range_t; +    typedef meta_range_t<double> freq_range_t; +  } //namespace uhd +#include <uhd/types/ranges.ipp> +  #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..8b602a24d --- /dev/null +++ b/host/include/uhd/types/ranges.ipp @@ -0,0 +1,168 @@ +// +// 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/>. +// + +#ifndef INCLUDED_UHD_TYPES_RANGES_IPP +#define INCLUDED_UHD_TYPES_RANGES_IPP + +#include <boost/math/special_functions/round.hpp> +#include <boost/foreach.hpp> +#include <algorithm> +#include <stdexcept> +#include <iostream> + +namespace uhd{ + +    /******************************************************************* +     * range_t implementation code +     ******************************************************************/ +    template <typename T> struct range_t<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 <typename T> range_t<T>::range_t(const T &value): +        _impl(UHD_PIMPL_MAKE(impl, (value, value, T(0)))) +    { +        /* NOP */ +    } + +    template <typename T> range_t<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 <typename T> const T range_t<T>::start(void) const{ +        return _impl->start; +    } + +    template <typename T> const T range_t<T>::stop(void) const{ +        return _impl->stop; +    } + +    template <typename T> const T range_t<T>::step(void) const{ +        return _impl->step; +    } + +    /******************************************************************* +     * meta_range_t implementation code +     ******************************************************************/ + +    namespace /*anon*/{ +        template <typename T> inline +        void check_meta_range_monotonic(const meta_range_t<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 <typename T> meta_range_t<T>::meta_range_t(void){ +        /* NOP */ +    } + +    template <typename T> template <typename InputIterator> +    meta_range_t<T>::meta_range_t( +        InputIterator first, InputIterator last +    ): +        std::vector<range_t<T> >(first, last) +    { +        /* NOP */ +    } + +    template <typename T> meta_range_t<T>::meta_range_t( +        const T &start, const T &stop, const T &step +    ): +        std::vector<range_t<T> > (1, range_t<T>(start, stop, step)) +    { +        /* NOP */ +    } + +    template <typename T> const T meta_range_t<T>::start(void) const{ +        check_meta_range_monotonic(*this); +        T min_start = this->front().start(); +        BOOST_FOREACH(const range_t<T> &r, (*this)){ +            min_start = std::min(min_start, r.start()); +        } +        return min_start; +    } + +    template <typename T> const T meta_range_t<T>::stop(void) const{ +        check_meta_range_monotonic(*this); +        T max_stop = this->front().stop(); +        BOOST_FOREACH(const range_t<T> &r, (*this)){ +            max_stop = std::max(max_stop, r.stop()); +        } +        return max_stop; +    } + +    template <typename T> const T meta_range_t<T>::step(void) const{ +        check_meta_range_monotonic(*this); +        std::vector<T> non_zero_steps; +        range_t<T> last = this->front(); +        BOOST_FOREACH(const range_t<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; +        } +        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 <typename T> const T meta_range_t<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<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() == T(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; +    } + +} //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<double>(); -    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/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<size_t>("concurrency_hint", CONCURRENCY_HINT)),          _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", udp_simple::mtu))),          _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_RECV_FRAMES))),          _send_frame_size(size_t(hints.cast<double>("send_frame_size", udp_simple::mtu))), -        _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_SEND_FRAMES))) +        _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_SEND_FRAMES))), +        _concurrency_hint(hints.cast<size_t>("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<char> _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 <typename T> 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 <typename T> 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 <typename T> 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<const void *> 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<const void *>(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/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 <uhd/utils/assert.hpp> -#include <uhd/types/ranges.hpp>  #include <uhd/types/tune_request.hpp>  #include <uhd/types/tune_result.hpp>  #include <uhd/types/clock_config.hpp> @@ -41,24 +40,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   **********************************************************************/  tune_request_t::tune_request_t(double target_freq): 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..7edc1822c 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 = 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; @@ -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( @@ -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( @@ -417,7 +420,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>(float(boost::math::iround(gain)), dbsrx_gain_ranges["GC2"].min, dbsrx_gain_ranges["GC2"].max); +    gain = dbsrx_gain_ranges["GC2"].clip(gain);      // Half dB steps from 0-5dB, 1dB steps from 5-24dB      if (gain < 5) { @@ -443,11 +446,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<float>(gain, dbsrx_gain_ranges["GC1"].min, dbsrx_gain_ranges["GC1"].max); +    gain = dbsrx_gain_ranges["GC1"].clip(gain);      //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_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<float>(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<float>(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<float>(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; diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 152198c3a..4e73fb3a3 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<std::string, gain_range_t> _rx_gain_ranges; -    uhd::dict<dboard_iface::unit_t, bool> _div2; +    const freq_range_t _freq_range; +    const uhd::dict<std::string, gain_range_t> _rx_gain_ranges; +    const uhd::dict<dboard_iface::unit_t, bool> _div2;      double       _rx_lo_freq, _tx_lo_freq;      std::string  _rx_ant;      uhd::dict<std::string, float> _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 = _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 2873e3d54..17fdad74a 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<double, 17> db_vector, boost  static float rf_gain_to_voltage(float gain, double lo_freq){      //clip the input -    gain = std::clip<float>(gain, get_tvrx_gain_ranges()["RF"].min, get_tvrx_gain_ranges()["RF"].max); +    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<float>(gain, get_tvrx_gain_ranges()["IF"].min, get_tvrx_gain_ranges()["IF"].max); +    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<double>(freq, tvrx_freq_range.min, tvrx_freq_range.max); +    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 572f5de97..dd5bd600b 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,33 +198,32 @@ wbx_xcvr::~wbx_xcvr(void){   **********************************************************************/  static int rx_pga0_gain_to_iobits(float &gain){      //clip the input -    gain = std::clip<float>(gain, wbx_rx_gain_ranges["PGA0"].min, wbx_rx_gain_ranges["PGA0"].max); +    gain = wbx_rx_gain_ranges["PGA0"].clip(gain);      //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)); +    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;      //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<float>(gain, wbx_tx_gain_ranges["PGA0"].min, wbx_tx_gain_ranges["PGA0"].max); +    gain = wbx_tx_gain_ranges["PGA0"].clip(gain);      //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 +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.min, wbx_freq_range.max); +    target_freq = wbx_freq_range.clip(target_freq);      //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler)      static const uhd::dict<int, int> 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..a3a1e6242 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<double>(2.4e9, 2.5e9)) +    (range_t<double>(4.9e9, 6.0e9)) +;  static const prop_names_t xcvr_antennas = list_of("J1")("J2"); @@ -82,7 +84,11 @@ static const uhd::dict<std::string, gain_range_t> xcvr_tx_gain_ranges = map_list      ("BB", gain_range_t(0, 5, 1.5))  ;  static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = map_list_of -    ("LNA", gain_range_t(0, 30.5, 15)) +    ("LNA", gain_range_t(list_of +        (range_t<float>(0)) +        (range_t<float>(15)) +        (range_t<float>(30.5)) +    ))      ("VGA", gain_range_t(0, 62, 2.0))  ; @@ -212,10 +218,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 +265,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 +    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); 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<std::string, boost::uint8_t> USRP_B000_OFFSETS = boost::assign::map_list_of      ("serial", 0xf8) @@ -149,7 +149,7 @@ static const uhd::dict<std::string, boost::uint8_t> 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 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/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 147b968b4..10cb86962 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -42,7 +42,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: @@ -244,7 +244,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<const usrp2_ctrl_data_t *>(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" 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<double>(); -    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<gain_fcns_t> &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/CMakeLists.txt b/host/test/CMakeLists.txt index d67399e5b..5d7433c67 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -26,6 +26,7 @@ SET(test_sources      dict_test.cpp      error_test.cpp      gain_group_test.cpp +    ranges_test.cpp      subdev_spec_test.cpp      time_spec_test.cpp      tune_helper_test.cpp 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/test/ranges_test.cpp b/host/test/ranges_test.cpp new file mode 100644 index 000000000..ad61867e1 --- /dev/null +++ b/host/test/ranges_test.cpp @@ -0,0 +1,57 @@ +// +// 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 <boost/test/unit_test.hpp> +#include <uhd/types/ranges.hpp> +#include <iostream> + +using namespace uhd; + +static const double tolerance = 0.001; + +BOOST_AUTO_TEST_CASE(test_ranges_bounds){ +    meta_range_t<double> mr; +    mr.push_back(range_t<double>(-1.0, +1.0, 0.1)); +    BOOST_CHECK_CLOSE(mr.start(), -1.0, tolerance); +    BOOST_CHECK_CLOSE(mr.stop(), +1.0, tolerance); +    BOOST_CHECK_CLOSE(mr.step(), 0.1, tolerance); + +    mr.push_back(range_t<double>(40.0, 60.0, 1.0)); +    BOOST_CHECK_CLOSE(mr.start(), -1.0, tolerance); +    BOOST_CHECK_CLOSE(mr.stop(), 60.0, tolerance); +    BOOST_CHECK_CLOSE(mr.step(), 0.1, tolerance); + +    BOOST_CHECK_EQUAL(mr.size(), 2); + +    BOOST_CHECK_CLOSE(mr[0].start(), -1.0, tolerance); +    BOOST_CHECK_CLOSE(mr[0].stop(), +1.0, tolerance); +    BOOST_CHECK_CLOSE(mr[0].step(), 0.1, tolerance); +} + +BOOST_AUTO_TEST_CASE(test_ranges_clip){ +    meta_range_t<double> mr; +    mr.push_back(range_t<double>(-1.0, +1.0, 0.1)); +    mr.push_back(range_t<double>(40.0, 60.0, 1.0)); + +    BOOST_CHECK_CLOSE(mr.clip(-30.0), -1.0, tolerance); +    BOOST_CHECK_CLOSE(mr.clip(70.0), 60.0, tolerance); +    BOOST_CHECK_CLOSE(mr.clip(20.0), 1.0, tolerance); +    BOOST_CHECK_CLOSE(mr.clip(50.0), 50.0, tolerance); + +    BOOST_CHECK_CLOSE(mr.clip(50.9, false), 50.9, tolerance); +    BOOST_CHECK_CLOSE(mr.clip(50.9, true), 51.0, 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<freq_range_t>()); -    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<prop_names_t>());      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<gain_range_t>()); -        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<usrp::subdev_conn_t>()) << 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<gain_range_t>()); -        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();  } | 
