diff options
author | Ben Hilburn <ben.hilburn@ettus.com> | 2014-06-27 17:24:00 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2014-10-07 14:35:40 +0200 |
commit | 4448843ca7392e2e5fbd44d6af12e69e6d465e00 (patch) | |
tree | 84a481951b8d28fe5e31422af43078a55ea1bad7 /host | |
parent | b29e80cc27e8a3edc958bcb0dbabdbb1772c1302 (diff) | |
download | uhd-4448843ca7392e2e5fbd44d6af12e69e6d465e00.tar.gz uhd-4448843ca7392e2e5fbd44d6af12e69e6d465e00.tar.bz2 uhd-4448843ca7392e2e5fbd44d6af12e69e6d465e00.zip |
uhd: fixed RX and TX DSP cores for 3rd generation products
Diffstat (limited to 'host')
-rw-r--r-- | host/lib/usrp/cores/rx_dsp_core_3000.cpp | 30 | ||||
-rw-r--r-- | host/lib/usrp/cores/tx_dsp_core_3000.cpp | 30 | ||||
-rw-r--r-- | host/lib/usrp/multi_usrp.cpp | 21 |
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; } |