diff options
| -rw-r--r-- | host/examples/init_usrp/.gitignore | 1 | ||||
| -rw-r--r-- | host/examples/init_usrp/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_impl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_ctrl.cpp | 9 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_ctrl.hpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_driver/ad9361_device.cpp | 23 | ||||
| -rw-r--r-- | host/lib/usrp/common/ad9361_driver/ad9361_device.h | 14 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_impl.cpp | 1 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_network.cpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_remote_codec_ctrl.cpp | 14 | ||||
| -rw-r--r-- | host/lib/usrp/e300/e300_remote_codec_ctrl.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/x300/x300_clock_ctrl.cpp | 44 | 
12 files changed, 99 insertions, 24 deletions
diff --git a/host/examples/init_usrp/.gitignore b/host/examples/init_usrp/.gitignore new file mode 100644 index 000000000..567609b12 --- /dev/null +++ b/host/examples/init_usrp/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/host/examples/init_usrp/CMakeLists.txt b/host/examples/init_usrp/CMakeLists.txt index 3560dbd45..8705b4a8d 100644 --- a/host/examples/init_usrp/CMakeLists.txt +++ b/host/examples/init_usrp/CMakeLists.txt @@ -55,6 +55,14 @@ link_directories(${Boost_LIBRARY_DIRS})  ### Make the executable #######################################################  add_executable(init_usrp init_usrp.cpp) +SET(CMAKE_BUILD_TYPE "Release") +MESSAGE(STATUS "******************************************************************************") +MESSAGE(STATUS "* NOTE: When building your own app, you probably need all kinds of different  ") +MESSAGE(STATUS "* compiler flags. This is just an example, so it's unlikely these settings    ") +MESSAGE(STATUS "* exactly matchh what you require. Make sure to double-check compiler and     ") +MESSAGE(STATUS "* linker flags to make sure your specific requirements are included.          ") +MESSAGE(STATUS "******************************************************************************") +  # Shared library case: All we need to do is link against the library, and  # anything else we need (in this case, some Boost libraries):  if(NOT UHD_USE_STATIC_LIBS) diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp index feb5a2d04..768fde313 100644 --- a/host/lib/usrp/b200/b200_impl.cpp +++ b/host/lib/usrp/b200/b200_impl.cpp @@ -743,6 +743,7 @@ void b200_impl::setup_radio(const size_t dspno)          _tree->create<meta_range_t>(rf_fe_path / "bandwidth" / "range")              .publish(boost::bind(&ad9361_ctrl::get_bw_filter_range, key));          _tree->create<double>(rf_fe_path / "freq" / "value") +            .publish(boost::bind(&ad9361_ctrl::get_freq, _codec_ctrl, key))              .coerce(boost::bind(&ad9361_ctrl::tune, _codec_ctrl, key, _1))              .subscribe(boost::bind(&b200_impl::update_bandsel, this, key, _1))              .set(B200_DEFAULT_FREQ); diff --git a/host/lib/usrp/common/ad9361_ctrl.cpp b/host/lib/usrp/common/ad9361_ctrl.cpp index f3ab36247..2d9f297b3 100644 --- a/host/lib/usrp/common/ad9361_ctrl.cpp +++ b/host/lib/usrp/common/ad9361_ctrl.cpp @@ -169,6 +169,15 @@ public:          return _device.tune(direction, value);      } +    //! get the current frequency for the given frontend +    double get_freq(const std::string &which) +    { +        boost::lock_guard<boost::mutex> lock(_mutex); + +        ad9361_device_t::direction_t direction = _get_direction_from_antenna(which); +        return _device.get_freq(direction); +    } +      //! turn on/off data port loopback      void data_port_loopback(const bool on)      { diff --git a/host/lib/usrp/common/ad9361_ctrl.hpp b/host/lib/usrp/common/ad9361_ctrl.hpp index a6d65ad11..ac0404b24 100644 --- a/host/lib/usrp/common/ad9361_ctrl.hpp +++ b/host/lib/usrp/common/ad9361_ctrl.hpp @@ -122,6 +122,9 @@ public:      //! enable or disable the quadrature calibration      virtual void set_iq_balance_auto(const std::string &which, const bool on) = 0; +    //! get the current frequency for the given frontend +    virtual double get_freq(const std::string &which) = 0; +      //! turn on/off Catalina's data port loopback      virtual void data_port_loopback(const bool on) = 0; diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp index 8737837b3..85e81cf97 100644 --- a/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp +++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.cpp @@ -1140,7 +1140,7 @@ double ad9361_device_t::_tune_bbvco(const double rate)      const double vcomin = 672e6;      double vcorate;      int vcodiv; -  +      /* Iterate over VCO dividers until appropriate divider is found. */      int i = 1;      for (; i <= 6; i++) { @@ -1337,7 +1337,7 @@ double ad9361_device_t::_setup_rates(const double rate)      /* If we make it into this function, then we are tuning to a new rate.       * Store the new rate. */      _req_clock_rate = rate; -    UHD_LOG << boost::format("[ad9361_device_t::_setup_rates] rate=%d\n") % rate; +    UHD_LOG << boost::format("[ad9361_device_t::_setup_rates] rate=%.6d\n") % rate;      /* Set the decimation and interpolation values in the RX and TX chains.       * This also switches filters in / out. Note that all transmitters and @@ -1734,7 +1734,9 @@ double ad9361_device_t::set_clock_rate(const double req_rate)       * starts up. This prevents that, and any bugs in user code that request       * the same rate over and over. */      if (freq_is_nearly_equal(req_rate, _req_clock_rate)) { -        return _baseband_bw; // IJB. Should this not return req_rate? +        // We return _baseband_bw, because that's closest to the +        // actual value we're currently running. +        return _baseband_bw;      }      /* We must be in the SLEEP / WAIT state to do this. If we aren't already @@ -1966,10 +1968,21 @@ double ad9361_device_t::tune(direction_t direction, const double value)      return tune_freq;  } +/* Get the current RX or TX frequency. */ +double ad9361_device_t::get_freq(direction_t direction) +{ +    boost::lock_guard<boost::recursive_mutex> lock(_mutex); + +    if (direction == RX) +        return _rx_freq; +    else +        return _tx_freq; +} +  /* Set the gain of RX1, RX2, TX1, or TX2.   * - * Note that the 'value' passed to this function is the gain index  - * for RX. Also note that the RX chains are done in terms of gain, and  + * Note that the 'value' passed to this function is the gain index + * for RX. Also note that the RX chains are done in terms of gain, and   * the TX chains  are done in terms of attenuation. */  double ad9361_device_t::set_gain(direction_t direction, chain_t chain, const double value)  { diff --git a/host/lib/usrp/common/ad9361_driver/ad9361_device.h b/host/lib/usrp/common/ad9361_driver/ad9361_device.h index 0c7a7e4f7..1c5c97829 100644 --- a/host/lib/usrp/common/ad9361_driver/ad9361_device.h +++ b/host/lib/usrp/common/ad9361_driver/ad9361_device.h @@ -81,6 +81,9 @@ public:       * After tuning, it runs any appropriate calibrations. */      double tune(direction_t direction, const double value); +    /* Get the current RX or TX frequency. */ +    double get_freq(direction_t direction); +      /* Set the gain of RX1, RX2, TX1, or TX2.       *       * Note that the 'value' passed to this function is the actual gain value, @@ -213,10 +216,17 @@ private:    //Members      //Intermediate state      double              _rx_freq, _tx_freq, _req_rx_freq, _req_tx_freq;      double              _last_calibration_freq; -    double              _baseband_bw, _bbpll_freq, _adcclock_freq;      double              _rx_analog_bw, _tx_analog_bw, _rx_bb_lp_bw, _tx_bb_lp_bw;      double              _rx_tia_lp_bw, _tx_sec_lp_bw; -    double              _req_clock_rate, _req_coreclk; +    //! Current baseband sampling rate (this is the actual rate the device is +    //  is running at) +    double              _baseband_bw; +    double              _bbpll_freq, _adcclock_freq; +    //! This was the last clock rate value that was requested. +    //  It is cached so we don't need to re-set the clock rate +    //  if another call to set_clock_rate() actually has the same value. +    double              _req_clock_rate; +    double              _req_coreclk;      boost::uint16_t     _rx_bbf_tunediv;      boost::uint8_t      _curr_gain_table;      double              _rx1_gain, _rx2_gain, _tx1_gain, _tx2_gain; diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp index c7c007a20..231816fe8 100644 --- a/host/lib/usrp/e300/e300_impl.cpp +++ b/host/lib/usrp/e300/e300_impl.cpp @@ -1068,6 +1068,7 @@ void e300_impl::_setup_radio(const size_t dspno)          _tree->create<meta_range_t>(rf_fe_path / "bandwidth" / "range")              .publish(boost::bind(&ad9361_ctrl::get_bw_filter_range, key));          _tree->create<double>(rf_fe_path / "freq" / "value") +            .publish(boost::bind(&ad9361_ctrl::get_freq, _codec_ctrl, key))              .coerce(boost::bind(&ad9361_ctrl::tune, _codec_ctrl, key, _1))              .subscribe(boost::bind(&e300_impl::_update_fe_lo_freq, this, key, _1))              .set(e300::DEFAULT_FE_FREQ); diff --git a/host/lib/usrp/e300/e300_network.cpp b/host/lib/usrp/e300/e300_network.cpp index 2a63abc25..d68dc4541 100644 --- a/host/lib/usrp/e300/e300_network.cpp +++ b/host/lib/usrp/e300/e300_network.cpp @@ -220,6 +220,9 @@ static void e300_codec_ctrl_tunnel(              case codec_xact_t::ACTION_TUNE:                  out->freq = _codec_ctrl->tune(which_str, in->freq);                  break; +            case codec_xact_t::ACTION_GET_FREQ: +                    out->freq = _codec_ctrl->get_freq(which_str); +                break;              case codec_xact_t::ACTION_SET_LOOPBACK:                  _codec_ctrl->data_port_loopback(                      uhd::ntohx<boost::uint32_t>(in->bits) & 1); diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp index d3efdb812..9708634dd 100644 --- a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp +++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp @@ -96,6 +96,20 @@ public:          return _retval.freq;      } +    double get_freq(const std::string &which) +    { +        _clear(); +        _args.action = uhd::htonx<boost::uint32_t>(transaction_t::ACTION_GET_FREQ); +        if (which == "TX1")      _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX1); +        else if (which == "TX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_TX2); +        else if (which == "RX1") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX1); +        else if (which == "RX2") _args.which = uhd::htonx<boost::uint32_t>(transaction_t::CHAIN_RX2); +        else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string."); + +        _transact(); +        return _retval.freq; +    } +      void data_port_loopback(const bool on)      {          _clear(); diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp index 065c5e7a0..43723e0d5 100644 --- a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp +++ b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp @@ -56,7 +56,7 @@ public:          static const boost::uint32_t ACTION_SET_AGC             = 19;          static const boost::uint32_t ACTION_SET_AGC_MODE        = 20;          static const boost::uint32_t ACTION_SET_BW              = 21; - +        static const boost::uint32_t ACTION_GET_FREQ            = 22;          //Values for "which"          static const boost::uint32_t CHAIN_NONE = 0; diff --git a/host/lib/usrp/x300/x300_clock_ctrl.cpp b/host/lib/usrp/x300/x300_clock_ctrl.cpp index 04a9e4bec..e182f649b 100644 --- a/host/lib/usrp/x300/x300_clock_ctrl.cpp +++ b/host/lib/usrp/x300/x300_clock_ctrl.cpp @@ -1,5 +1,5 @@  // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 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 @@ -18,6 +18,7 @@  #include "lmk04816_regs.hpp"  #include "x300_clock_ctrl.hpp"  #include <uhd/utils/safe_call.hpp> +#include <uhd/utils/math.hpp>  #include <boost/cstdint.hpp>  #include <boost/format.hpp>  #include <stdexcept> @@ -96,7 +97,7 @@ public:          boost::uint8_t addr = 0xFF;          // Make sure requested rate is an even divisor of the VCO frequency -        if (not doubles_are_equal(_vco_freq / div, rate)) +        if (not math::frequencies_are_equal(_vco_freq / div, rate))              throw uhd::value_error("invalid dboard rate requested");          switch (which) @@ -236,27 +237,42 @@ private:           * clock, in zero-delay mode. */          opmode_t clocking_mode = INVALID; -        if(doubles_are_equal(_system_ref_rate, 10e6)) { -            if(doubles_are_equal(_master_clock_rate, 184.32e6)) { +        if (math::frequencies_are_equal(_system_ref_rate, 10e6)) { +            if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) {                  /* 10MHz reference, 184.32 MHz master clock out, NOT Zero Delay. */                  clocking_mode = m10M_184_32M_NOZDEL; -            } else if(doubles_are_equal(_master_clock_rate, 200e6)) { +            } else if (math::frequencies_are_equal(_master_clock_rate, 200e6)) {                  /* 10MHz reference, 200 MHz master clock out, Zero Delay */                  clocking_mode = m10M_200M_ZDEL; -            } else if(doubles_are_equal(_master_clock_rate, 120e6)) { +            } else if (math::frequencies_are_equal(_master_clock_rate, 120e6)) {                  /* 10MHz reference, 120 MHz master clock rate, Zero Delay */                  clocking_mode = m10M_120M_ZDEL; +            } else { +                throw uhd::runtime_error(str( +                    boost::format("Invalid master clock rate: %.2f MHz.\n" +                                  "Valid master clock rates when using a %f MHz reference clock are:\n" +                                  "120 MHz, 184.32 MHz and 200 MHz.") +                    % (_master_clock_rate / 1e6)  % (_system_ref_rate / 1e6) +                ));              } -        } else if(doubles_are_equal(_system_ref_rate, 30.72e6)) { -            if(doubles_are_equal(_master_clock_rate, 184.32e6)) { +        } else if (math::frequencies_are_equal(_system_ref_rate, 30.72e6)) { +            if (math::frequencies_are_equal(_master_clock_rate, 184.32e6)) {                  /* 30.72MHz reference, 184.32 MHz master clock out, Zero Delay */                  clocking_mode = m30_72M_184_32M_ZDEL; +            } else { +                throw uhd::runtime_error(str( +                    boost::format("Invalid master clock rate: %.2f MHz.\n" +                                  "Valid master clock rate when using a %.2f MHz reference clock is: 184.32 MHz.") +                    % (_master_clock_rate / 1e6)  % (_system_ref_rate / 1e6) +                ));              } +        } else { +            throw uhd::runtime_error(str( +                boost::format("Invalid system reference rate: %.2f MHz.\nValid reference frequencies are: 10 MHz, 30.72 MHz.") +                % (_system_ref_rate / 1e6) +            ));          } - -        if(clocking_mode == INVALID) { -            throw uhd::runtime_error(str(boost::format("A master clock rate of %f cannot be derived from a system reference rate of %f") % _master_clock_rate % _system_ref_rate)); -        } +        UHD_ASSERT_THROW(clocking_mode != INVALID);          // For 200 MHz output, the VCO is run at 2400 MHz          // For the LTE/CPRI rate of 184.32 MHz, the VCO runs at 2580.48 MHz @@ -501,10 +517,6 @@ private:          this->sync_clocks();      } -    UHD_INLINE bool doubles_are_equal(double a, double b) { -        return  (std::fabs(a - b) < std::numeric_limits<double>::epsilon()); -    } -      const spi_iface::sptr _spiface;      const size_t _slaveno;      const size_t _hw_rev;  | 
