aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2014-06-27 17:24:00 -0700
committerMartin Braun <martin.braun@ettus.com>2014-10-07 14:35:40 +0200
commit4448843ca7392e2e5fbd44d6af12e69e6d465e00 (patch)
tree84a481951b8d28fe5e31422af43078a55ea1bad7
parentb29e80cc27e8a3edc958bcb0dbabdbb1772c1302 (diff)
downloaduhd-4448843ca7392e2e5fbd44d6af12e69e6d465e00.tar.gz
uhd-4448843ca7392e2e5fbd44d6af12e69e6d465e00.tar.bz2
uhd-4448843ca7392e2e5fbd44d6af12e69e6d465e00.zip
uhd: fixed RX and TX DSP cores for 3rd generation products
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_3000.cpp30
-rw-r--r--host/lib/usrp/cores/tx_dsp_core_3000.cpp30
-rw-r--r--host/lib/usrp/multi_usrp.cpp21
3 files changed, 52 insertions, 29 deletions
diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.cpp b/host/lib/usrp/cores/rx_dsp_core_3000.cpp
index fc7c58da8..6ce3c1d32 100644
--- a/host/lib/usrp/cores/rx_dsp_core_3000.cpp
+++ b/host/lib/usrp/cores/rx_dsp_core_3000.cpp
@@ -197,14 +197,36 @@ public:
if (std::abs(freq) > _tick_rate/2.0)
freq -= boost::math::sign(freq)*_tick_rate;
- //calculate the freq register word (signed)
+ //confirm that the target frequency is within range of the CORDIC
UHD_ASSERT_THROW(std::abs(freq) <= _tick_rate/2.0);
+
+ /* Now calculate the frequency word. It is possible for this calculation
+ * to cause an overflow. As the requested DSP frequency approaches the
+ * master clock rate, that ratio multiplied by the scaling factor (2^32)
+ * will generally overflow within the last few kHz of tunable range.
+ * Thus, we check to see if the operation will overflow before doing it,
+ * and if it will, we set it to the integer min or max of this system.
+ */
+ boost::int32_t freq_word = 0;
+
static const double scale_factor = std::pow(2.0, 32);
- const boost::int32_t freq_word = boost::int32_t(boost::math::round((freq / _tick_rate) * scale_factor));
+ static const boost::int32_t int_max = boost::numeric::bounds<boost::int32_t>::highest();
+ static const boost::int32_t int_min = boost::numeric::bounds<boost::int32_t>::lowest();
+ if((freq / _tick_rate) >= (int_max / scale_factor)) {
+ /* Operation would have caused a positive overflow of int32. */
+ freq_word = boost::numeric::bounds<boost::int32_t>::highest();
- //update the actual frequency
- const double actual_freq = (double(freq_word) / scale_factor) * _tick_rate;
+ } else if((freq / _tick_rate) <= (int_min / scale_factor)) {
+ /* Operation would have caused a negative overflow of int32. */
+ freq_word = boost::numeric::bounds<boost::int32_t>::lowest();
+ } else {
+ /* The operation is safe. Perform normally. */
+ freq_word = boost::int32_t(boost::math::round((freq / _tick_rate) * scale_factor));
+ }
+
+ //program the frequency word into the device DSP
+ const double actual_freq = (double(freq_word) / scale_factor) * _tick_rate;
_iface->poke32(REG_DSP_RX_FREQ, boost::uint32_t(freq_word));
return actual_freq;
diff --git a/host/lib/usrp/cores/tx_dsp_core_3000.cpp b/host/lib/usrp/cores/tx_dsp_core_3000.cpp
index 9c2b98ffb..0dc19f2c8 100644
--- a/host/lib/usrp/cores/tx_dsp_core_3000.cpp
+++ b/host/lib/usrp/cores/tx_dsp_core_3000.cpp
@@ -134,14 +134,36 @@ public:
if (std::abs(freq) > _tick_rate/2.0)
freq -= boost::math::sign(freq)*_tick_rate;
- //calculate the freq register word (signed)
+ //confirm that the target frequency is within range of the CORDIC
UHD_ASSERT_THROW(std::abs(freq) <= _tick_rate/2.0);
+
+ /* Now calculate the frequency word. It is possible for this calculation
+ * to cause an overflow. As the requested DSP frequency approaches the
+ * master clock rate, that ratio multiplied by the scaling factor (2^32)
+ * will generally overflow within the last few kHz of tunable range.
+ * Thus, we check to see if the operation will overflow before doing it,
+ * and if it will, we set it to the integer min or max of this system.
+ */
+ boost::int32_t freq_word = 0;
+
static const double scale_factor = std::pow(2.0, 32);
- const boost::int32_t freq_word = boost::int32_t(boost::math::round((freq / _tick_rate) * scale_factor));
+ static const boost::int32_t int_max = boost::numeric::bounds<boost::int32_t>::highest();
+ static const boost::int32_t int_min = boost::numeric::bounds<boost::int32_t>::lowest();
+ if((freq / _tick_rate) >= (int_max / scale_factor)) {
+ /* Operation would have caused a positive overflow of int32. */
+ freq_word = boost::numeric::bounds<boost::int32_t>::highest();
+
+ } else if((freq / _tick_rate) <= (int_min / scale_factor)) {
+ /* Operation would have caused a negative overflow of int32. */
+ freq_word = boost::numeric::bounds<boost::int32_t>::lowest();
+
+ } else {
+ /* The operation is safe. Perform normally. */
+ freq_word = boost::int32_t(boost::math::round((freq / _tick_rate) * scale_factor));
+ }
- //update the actual frequency
+ //program the frequency word into the device DSP
const double actual_freq = (double(freq_word) / scale_factor) * _tick_rate;
-
_iface->poke32(REG_DSP_TX_FREQ, boost::uint32_t(freq_word));
return actual_freq;
diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp
index 53530d05f..471d453c2 100644
--- a/host/lib/usrp/multi_usrp.cpp
+++ b/host/lib/usrp/multi_usrp.cpp
@@ -30,7 +30,6 @@
#include <boost/foreach.hpp>
#include <boost/format.hpp>
#include <cmath>
-#include <iostream>
using namespace uhd;
using namespace uhd::usrp;
@@ -100,11 +99,6 @@ static meta_range_t make_overall_tune_range(
const meta_range_t &dsp_range,
const double bw
){
- std::cout << "Entering make_overall_tune_range..." << std::endl;
- UHD_VAR(dsp_range.start());
- UHD_VAR(dsp_range.stop());
- UHD_VAR(bw);
-
meta_range_t range;
BOOST_FOREACH(const range_t &sub_range, fe_range){
range.push_back(range_t(
@@ -226,19 +220,12 @@ static tune_result_t tune_xx_subdev_and_dsp(
rf_fe_subtree->access<double>("freq/value").set(target_rf_freq);
const double actual_rf_freq = rf_fe_subtree->access<double>("freq/value").get();
- std::cout << "multi_usrp - done tuning FE..." << std::endl;
- UHD_VAR(target_rf_freq);
- UHD_VAR(actual_rf_freq);
-
//------------------------------------------------------------------
//-- set the dsp frequency depending upon the dsp frequency policy
//------------------------------------------------------------------
double target_dsp_freq = 0.0;
double forced_target_rf_freq = target_rf_freq;
- UHD_VAR(tune_range.start());
- UHD_VAR(tune_range.stop());
-
freq_range_t dsp_range = dsp_subtree->access<meta_range_t>("freq/range").get();
switch (tune_request.dsp_freq_policy){
@@ -268,15 +255,10 @@ static tune_result_t tune_xx_subdev_and_dsp(
break; //does not set
}
- UHD_VAR(forced_target_rf_freq);
- UHD_VAR(target_dsp_freq);
-
/* Set the DSP frequency. */
dsp_subtree->access<double>("freq/value").set(target_dsp_freq);
const double actual_dsp_freq = dsp_subtree->access<double>("freq/value").get();
- UHD_VAR(actual_dsp_freq);
-
//------------------------------------------------------------------
//-- load and return the tune result
//------------------------------------------------------------------
@@ -297,9 +279,6 @@ static double derive_freq_from_xx_subdev_and_dsp(
const double actual_rf_freq = rf_fe_subtree->access<double>("freq/value").get();
const double actual_dsp_freq = dsp_subtree->access<double>("freq/value").get();
- UHD_VAR(actual_rf_freq);
- UHD_VAR(actual_dsp_freq);
-
//invert the sign on the dsp freq for transmit
return actual_rf_freq - actual_dsp_freq * xx_sign;
}