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/lib | |
| 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/lib')
| -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;  } | 
