aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2014-08-05 14:05:09 -0700
committerMartin Braun <martin.braun@ettus.com>2014-10-07 14:57:03 +0200
commit47534e78f8fe7bf01251afd9ae1f3b70c68f4f29 (patch)
tree7e0c9a2bab9909320bac9bd3ab04bded512c005d /host/lib
parent800f58430fdc577a2edd717d27b5902f75a1b1e4 (diff)
downloaduhd-47534e78f8fe7bf01251afd9ae1f3b70c68f4f29.tar.gz
uhd-47534e78f8fe7bf01251afd9ae1f3b70c68f4f29.tar.bz2
uhd-47534e78f8fe7bf01251afd9ae1f3b70c68f4f29.zip
uhd: Improved tuning code and corresponding outputs/warnings
* Added convenience function for frequency comparisons * ABI change required
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/usrp/multi_usrp.cpp159
1 files changed, 124 insertions, 35 deletions
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 471d453c2..ac1ec116c 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -20,6 +20,7 @@
#include <uhd/utils/msg.hpp>
#include <uhd/exception.hpp>
#include <uhd/utils/log.hpp>
+#include <uhd/utils/math.hpp>
#include <uhd/utils/gain_group.hpp>
#include <uhd/usrp/dboard_id.hpp>
#include <uhd/usrp/mboard_eeprom.hpp>
@@ -68,23 +69,107 @@ static void do_samp_rate_warning_message(
}
}
-static void do_tune_freq_warning_message(
+static void do_tune_freq_results_message(
const tune_request_t &tune_req,
+ const tune_result_t &tune_result,
double actual_freq,
const std::string &xx
){
- //forget the warning when manual policy
- if (tune_req.dsp_freq_policy == tune_request_t::POLICY_MANUAL) return;
+ const double target_freq = tune_req.target_freq;
+ const double clipped_target_freq = tune_result.clipped_rf_freq;
+ const double target_rf_freq = tune_result.target_rf_freq;
+ const double actual_rf_freq = tune_result.actual_rf_freq;
+ const double target_dsp_freq = tune_result.target_dsp_freq;
+ const double actual_dsp_freq = tune_result.actual_dsp_freq;
+
if (tune_req.rf_freq_policy == tune_request_t::POLICY_MANUAL) return;
+ if (tune_req.dsp_freq_policy == tune_request_t::POLICY_MANUAL) return;
- const double target_freq = tune_req.target_freq;
- static const double max_allowed_error = 1.0; //Hz
- if (std::abs(target_freq - actual_freq) > max_allowed_error){
- UHD_MSG(warning) << boost::format(
- "The hardware does not support the requested %s frequency:\n"
- "Target frequency: %f MHz\n"
- "Actual frequency: %f MHz\n"
- ) % xx % (target_freq/1e6) % (actual_freq/1e6);
+ bool requested_freq_success = uhd::math::frequencies_are_equal(target_freq, clipped_target_freq);
+ bool target_freq_success = uhd::math::frequencies_are_equal(clipped_target_freq, actual_freq);
+ bool rf_lo_tune_success = uhd::math::frequencies_are_equal(target_rf_freq, actual_rf_freq);
+ bool dsp_tune_success = uhd::math::frequencies_are_equal(target_dsp_freq, actual_dsp_freq);
+
+ if(requested_freq_success and target_freq_success and rf_lo_tune_success
+ and dsp_tune_success) {
+ UHD_MSG(status) << boost::format(
+ "Successfully tuned to %f MHz\n\n")
+ % (actual_freq / 1e6);
+ } else {
+ boost::format base_message ("Tune Request: %f MHz\n");
+ base_message % (target_freq / 1e6);
+ std::string results_string = base_message.str();
+
+ if(requested_freq_success and (not rf_lo_tune_success)) {
+ boost::format rf_lo_message(
+ " The RF LO does not support the requested frequency:\n"
+ " Requested LO Frequency: %f MHz\n"
+ " RF LO Result: %f MHz\n"
+ " Attempted to use the DSP to reach the requested frequency:\n"
+ " Desired DSP Frequency: %f MHz\n"
+ " DSP Result: %f MHz\n"
+ " Successfully tuned to %f MHz\n\n");
+ rf_lo_message % (target_rf_freq / 1e6) % (actual_rf_freq / 1e6)
+ % (target_dsp_freq / 1e6) % (actual_dsp_freq / 1e6)
+ % (actual_freq / 1e6);
+
+ results_string += rf_lo_message.str();
+
+ UHD_MSG(status) << results_string;
+
+ return;
+ }
+
+ if(not requested_freq_success) {
+ boost::format failure_message(
+ " The requested %s frequency is outside of the system range, and has been clipped:\n"
+ " Target Frequency: %f MHz\n"
+ " Clipped Target Frequency: %f MHz\n");
+ failure_message % xx % (target_freq / 1e6) % (clipped_target_freq / 1e6);
+
+ results_string += failure_message.str();
+ }
+
+ if(not rf_lo_tune_success) {
+ boost::format rf_lo_message(
+ " The RF LO does not support the requested frequency:\n"
+ " Requested LO Frequency: %f MHz\n"
+ " RF LO Result: %f MHz\n"
+ " Attempted to use the DSP to reach the requested frequency:\n"
+ " Desired DSP Frequency: %f MHz\n"
+ " DSP Result: %f MHz\n");
+ rf_lo_message % (target_rf_freq / 1e6) % (actual_rf_freq / 1e6)
+ % (target_dsp_freq / 1e6) % (actual_dsp_freq / 1e6);
+
+ results_string += rf_lo_message.str();
+
+ } else if(not dsp_tune_success) {
+ boost::format dsp_message(
+ " The DSP does not support the requested frequency:\n"
+ " Requested DSP Frequency: %f MHz\n"
+ " DSP Result: %f MHz\n");
+ dsp_message % (target_dsp_freq / 1e6) % (actual_dsp_freq / 1e6);
+
+ results_string += dsp_message.str();
+ }
+
+ if(target_freq_success) {
+ boost::format success_message(
+ " Successfully tuned to %f MHz\n\n");
+ success_message % (actual_freq / 1e6);
+
+ results_string += success_message.str();
+ } else {
+ boost::format failure_message(
+ " Failed to tune to target frequency\n"
+ " Target Frequency: %f MHz\n"
+ " Actual Frequency: %f MHz\n\n");
+ failure_message % (clipped_target_freq / 1e6) % (actual_freq / 1e6);
+
+ results_string += failure_message.str();
+ }
+
+ UHD_MSG(warning) << results_string << std::endl;
}
}
@@ -148,7 +233,7 @@ static tune_result_t tune_xx_subdev_and_dsp(
const tune_request_t &tune_request
){
//------------------------------------------------------------------
- //-- calculate the tunable frequency range of the system
+ //-- calculate the tunable frequency ranges of the system
//------------------------------------------------------------------
freq_range_t tune_range = make_overall_tune_range(
rf_fe_subtree->access<meta_range_t>("freq/range").get(),
@@ -156,6 +241,10 @@ static tune_result_t tune_xx_subdev_and_dsp(
rf_fe_subtree->access<double>("bandwidth/value").get()
);
+ freq_range_t dsp_range = dsp_subtree->access<meta_range_t>("freq/range").get();
+
+ double clipped_requested_freq = tune_range.clip(tune_request.target_freq);
+
//------------------------------------------------------------------
//-- If the RF FE requires an LO offset, build it into the tune request
//------------------------------------------------------------------
@@ -184,8 +273,7 @@ static tune_result_t tune_xx_subdev_and_dsp(
//------------------------------------------------------------------
//-- poke the tune request args into the dboard
//------------------------------------------------------------------
- if (rf_fe_subtree->exists("tune_args"))
- {
+ if (rf_fe_subtree->exists("tune_args")) {
rf_fe_subtree->access<device_addr_t>("tune_args").set(tune_request.args);
}
@@ -195,12 +283,12 @@ static tune_result_t tune_xx_subdev_and_dsp(
double target_rf_freq = 0.0;
switch (tune_request.rf_freq_policy){
case tune_request_t::POLICY_AUTO:
- target_rf_freq = tune_request.target_freq + lo_offset;
+ target_rf_freq = clipped_requested_freq + lo_offset;
break;
case tune_request_t::POLICY_MANUAL:
// If the rf_fe understands lo_offset settings, infer the desired
- // lo_offset and set it Side effect: In TVRX2 for example, after
+ // lo_offset and set it. Side effect: In TVRX2 for example, after
// setting the lo_offset (if_freq) with a POLICY_MANUAL, there is no
// way for the user to automatically get back to default if_freq
// without deconstruct/reconstruct the rf_fe objects.
@@ -216,19 +304,17 @@ static tune_result_t tune_xx_subdev_and_dsp(
break; //does not set
}
- /* Tune the RF front-end. */
+ //------------------------------------------------------------------
+ //-- Tune the RF frontend
+ //------------------------------------------------------------------
rf_fe_subtree->access<double>("freq/value").set(target_rf_freq);
const double actual_rf_freq = rf_fe_subtree->access<double>("freq/value").get();
//------------------------------------------------------------------
- //-- set the dsp frequency depending upon the dsp frequency policy
+ //-- Set the DSP frequency depending upon the DSP frequency policy.
//------------------------------------------------------------------
double target_dsp_freq = 0.0;
- double forced_target_rf_freq = target_rf_freq;
-
- freq_range_t dsp_range = dsp_subtree->access<meta_range_t>("freq/range").get();
-
- switch (tune_request.dsp_freq_policy){
+ switch (tune_request.dsp_freq_policy) {
case tune_request_t::POLICY_AUTO:
/* If we are using the AUTO tuning policy, then we prevent the
* CORDIC from spinning us outside of the range of the baseband
@@ -236,9 +322,7 @@ static tune_result_t tune_xx_subdev_and_dsp(
* if the user requested a center frequency so far outside of the
* tunable range of the FE that the CORDIC would spin outside the
* filtered baseband. */
- forced_target_rf_freq = tune_range.clip(target_rf_freq);
-
- target_dsp_freq = dsp_range.clip(actual_rf_freq - forced_target_rf_freq);
+ target_dsp_freq = actual_rf_freq - clipped_requested_freq;
//invert the sign on the dsp freq for transmit (spinning up vs down)
target_dsp_freq *= xx_sign;
@@ -247,7 +331,9 @@ static tune_result_t tune_xx_subdev_and_dsp(
case tune_request_t::POLICY_MANUAL:
/* If the user has specified a manual tune policy, we will allow
- * tuning outside of the baseband filter. */
+ * tuning outside of the baseband filter, but will still clip the
+ * target DSP frequency to within the bounds of the CORDIC to
+ * prevent undefined behavior (likely an overflow). */
target_dsp_freq = dsp_range.clip(tune_request.dsp_freq);
break;
@@ -255,14 +341,17 @@ static tune_result_t tune_xx_subdev_and_dsp(
break; //does not set
}
- /* Set the DSP frequency. */
+ //------------------------------------------------------------------
+ //-- Tune the DSP
+ //------------------------------------------------------------------
dsp_subtree->access<double>("freq/value").set(target_dsp_freq);
const double actual_dsp_freq = dsp_subtree->access<double>("freq/value").get();
//------------------------------------------------------------------
- //-- load and return the tune result
+ //-- Load and return the tune result
//------------------------------------------------------------------
tune_result_t tune_result;
+ tune_result.clipped_rf_freq = clipped_requested_freq;
tune_result.target_rf_freq = target_rf_freq;
tune_result.actual_rf_freq = actual_rf_freq;
tune_result.target_dsp_freq = target_dsp_freq;
@@ -705,12 +794,12 @@ public:
}
tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){
- tune_result_t r = tune_xx_subdev_and_dsp(RX_SIGN,
+ tune_result_t result = tune_xx_subdev_and_dsp(RX_SIGN,
_tree->subtree(rx_dsp_root(chan)),
_tree->subtree(rx_rf_fe_root(chan)),
tune_request);
- do_tune_freq_warning_message(tune_request, get_rx_freq(chan), "RX");
- return r;
+ do_tune_freq_results_message(tune_request, result, get_rx_freq(chan), "RX");
+ return result;
}
double get_rx_freq(size_t chan){
@@ -906,12 +995,12 @@ public:
}
tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){
- tune_result_t r = tune_xx_subdev_and_dsp(TX_SIGN,
+ tune_result_t result = tune_xx_subdev_and_dsp(TX_SIGN,
_tree->subtree(tx_dsp_root(chan)),
_tree->subtree(tx_rf_fe_root(chan)),
tune_request);
- do_tune_freq_warning_message(tune_request, get_tx_freq(chan), "TX");
- return r;
+ do_tune_freq_results_message(tune_request, result, get_tx_freq(chan), "TX");
+ return result;
}
double get_tx_freq(size_t chan){