aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-11-21 16:20:04 -0800
committerMartin Braun <martin.braun@ettus.com>2019-11-26 12:21:34 -0800
commit66a9df7b16ee230dc010443ea67d637cfaf44265 (patch)
treebfb0d587363424822d47a9ce58c48a3e3981a608 /host/lib/usrp
parent911ca16adc9222be11d1cbf134bf547daa16806f (diff)
downloaduhd-66a9df7b16ee230dc010443ea67d637cfaf44265.tar.gz
uhd-66a9df7b16ee230dc010443ea67d637cfaf44265.tar.bz2
uhd-66a9df7b16ee230dc010443ea67d637cfaf44265.zip
mg: Always set MCR on both daughterboards
The N310 cannot set the MCR for its daughterboards separately. This patch modifies the radio block controller such that any block controller, when requested to change the master clock rate, will first change Radio 0, and then Radio 1. This fixes the following issues: - In multi_usrp, calling set_master_clock_rate() will not necessarily call set_rate() on the radios in any particular order, which will break when calling Radio 1 first - In RFNoC apps, it wasn't possible to run off of slot B alone without this change. Note: When calling set_rate() on one radio, the other radio is in an invalid state until its set_rate() is also called.
Diffstat (limited to 'host/lib/usrp')
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp9
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp2
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp34
3 files changed, 33 insertions, 12 deletions
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp
index d7d1b43de..f71b1aa4e 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.cpp
@@ -60,15 +60,6 @@ double magnesium_ad9371_iface::set_gain(
// return 0.0;
}
-
-double magnesium_ad9371_iface::set_master_clock_rate(const double freq)
-{
- const auto actual_freq = request<double>("set_master_clock_rate", freq);
- UHD_LOG_TRACE(
- _log_prefix, _rpc_prefix << "set_master_clock_rate returned successfully");
- return actual_freq;
-}
-
double magnesium_ad9371_iface::set_bandwidth(
const double bandwidth, const size_t chan, const direction_t dir)
{
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp
index 63972a54c..2374a4503 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_ad9371_iface.hpp
@@ -28,8 +28,6 @@ public:
double get_gain(const size_t chan, const uhd::direction_t dir);
- double set_master_clock_rate(const double freq);
-
double set_bandwidth(
const double bandwidth, const size_t chan, const uhd::direction_t dir);
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
index 32c16adc6..71e59891c 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp
@@ -156,7 +156,39 @@ double magnesium_radio_control_impl::set_rate(double requested_rate)
// Now commit to device. First, disable LOs.
_lo_disable(_tx_lo);
_lo_disable(_rx_lo);
- _master_clock_rate = _ad9371->set_master_clock_rate(rate);
+ // DANGER ZONE! The only way we can change the master clock rate on N310 is
+ // if we first change the master clock rate on side A, then side B. We can't
+ // do it in the other order.
+ // When we change the other radio's clock rate, however, the other radio
+ // block controller doesn't know about that. So, we need to call set_rate()
+ // on both radios every time we call it on any radio, unless the other radio
+ // block is not participating in the graph.
+ // Note: Updating the master clock rate is a no-op on the second call.
+ const size_t num_dboards =
+ _rpcc->request<std::vector<std::map<std::string, std::string>>>("get_dboard_info")
+ .size();
+ // Explicitly go and update rate on radio 0
+ RFNOC_LOG_DEBUG("Setting master clock rate on DB0 to " << (rate / 1e6) << " MHz...");
+ _master_clock_rate = _rpcc->request_with_token<double>(
+ MAGNESIUM_TUNE_TIMEOUT, "db_0_set_master_clock_rate", rate);
+ // Now go to the other side
+ if (num_dboards == 2) {
+ RFNOC_LOG_DEBUG(
+ "Setting master clock rate on DB1 to " << (rate / 1e6) << " MHz...");
+ const double sideB_rate = _rpcc->request_with_token<double>(
+ MAGNESIUM_TUNE_TIMEOUT, "db_1_set_master_clock_rate", rate);
+ if (!math::frequencies_are_equal(sideB_rate, _master_clock_rate)) {
+ RFNOC_LOG_ERROR("set_rate(): Error updating rates. Slot A now has rate "
+ << (_master_clock_rate / 1e6) << " MHz, but slot B has "
+ << (sideB_rate / 1e6)
+ << " MHz. They should always be the same.");
+ throw uhd::runtime_error("Different rates on radios 0 and 1!");
+ }
+ }
+ RFNOC_LOG_DEBUG("Set MCR on both radios.");
+ // Now, both radios are running at the new rate. Update all dependent
+ // settings for this radio block. The other radio block needs to call
+ // set_rate() too before it is in a valid state.
_n3xx_timekeeper->update_tick_rate(_master_clock_rate);
radio_control_impl::set_rate(_master_clock_rate);
// Frequency settings apply to both channels, no loop needed. Will also