aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp1
-rw-r--r--host/lib/usrp/common/ad9361_ctrl.cpp9
-rw-r--r--host/lib/usrp/common/ad9361_ctrl.hpp3
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.cpp23
-rw-r--r--host/lib/usrp/common/ad9361_driver/ad9361_device.h14
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp1
-rw-r--r--host/lib/usrp/e300/e300_network.cpp3
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.cpp14
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.hpp2
-rw-r--r--host/lib/usrp/x300/x300_clock_ctrl.cpp44
10 files changed, 90 insertions, 24 deletions
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;