diff options
author | Martin Braun <martin.braun@ettus.com> | 2018-03-26 14:48:12 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-03-28 14:21:35 -0700 |
commit | 18cda8029ff7ab1255579d81b0b27de68dacc88e (patch) | |
tree | 7edbad8e0b648a6557daa720d6847cb3f65b5650 /host/lib/usrp/usrp2/usrp2_impl.cpp | |
parent | 92a6c10979a2dea341349a44acbed43dc892dffc (diff) | |
download | uhd-18cda8029ff7ab1255579d81b0b27de68dacc88e.tar.gz uhd-18cda8029ff7ab1255579d81b0b27de68dacc88e.tar.bz2 uhd-18cda8029ff7ab1255579d81b0b27de68dacc88e.zip |
usrp2: Re-add ability to modulate in the DAC
This partially reverts b29e80cc. That commit fixed a bug with numerical
overflows, but also removed the ability to tune using the DAC,
effectively reducing the DSP tuning range.
This commit allows to tune within +/- 200 MHz using a combination of
both the DAC and the DSP tuning in the FPGA.
Reviewed-by: Derek Kozek <derek.kozel@ettus.com>
Diffstat (limited to 'host/lib/usrp/usrp2/usrp2_impl.cpp')
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 80 |
1 files changed, 73 insertions, 7 deletions
diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 88591333a..d6ab11969 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -622,21 +622,44 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr) : // create tx dsp control objects //////////////////////////////////////////////////////////////// _mbc[mb].tx_dsp = tx_dsp_core_200::make( - _mbc[mb].wbiface, U2_REG_SR_ADDR(SR_TX_DSP), U2_REG_SR_ADDR(SR_TX_CTRL), USRP2_TX_ASYNC_SID + _mbc[mb].wbiface, + U2_REG_SR_ADDR(SR_TX_DSP), + U2_REG_SR_ADDR(SR_TX_CTRL), + USRP2_TX_ASYNC_SID ); _mbc[mb].tx_dsp->set_link_rate(USRP2_LINK_RATE_BPS); + { // This scope can be removed once we're able to do named captures + auto this_tx_dsp = _mbc[mb].tx_dsp; // This can then also go away _tree->access<double>(mb_path / "tick_rate") - .add_coerced_subscriber(boost::bind(&tx_dsp_core_200::set_tick_rate, _mbc[mb].tx_dsp, _1)); + .add_coerced_subscriber([this_tx_dsp](const double rate){ + this_tx_dsp->set_tick_rate(rate); + }) + ; _tree->create<meta_range_t>(mb_path / "tx_dsps/0/rate/range") - .set_publisher(boost::bind(&tx_dsp_core_200::get_host_rates, _mbc[mb].tx_dsp)); + .set_publisher([this_tx_dsp](){ + return this_tx_dsp->get_host_rates(); + }) + ; _tree->create<double>(mb_path / "tx_dsps/0/rate/value") .set(1e6) //some default - .set_coercer(boost::bind(&tx_dsp_core_200::set_host_rate, _mbc[mb].tx_dsp, _1)) - .add_coerced_subscriber(boost::bind(&usrp2_impl::update_tx_samp_rate, this, mb, 0, _1)); + .set_coercer([this_tx_dsp](const double rate){ + return this_tx_dsp->set_host_rate(rate); + }) + .add_coerced_subscriber([this, mb](const double rate){ + this->update_tx_samp_rate(mb, 0, rate); + }) + ; + } // End of non-C++14 scope (to release reference to this_tx_dsp) _tree->create<double>(mb_path / "tx_dsps/0/freq/value") - .set_coercer(boost::bind(&tx_dsp_core_200::set_freq, _mbc[mb].tx_dsp, _1)); + .set_coercer([this, mb](const double rate){ + return this->set_tx_dsp_freq(mb, rate); + }) + ; _tree->create<meta_range_t>(mb_path / "tx_dsps/0/freq/range") - .set_publisher(boost::bind(&tx_dsp_core_200::get_freq_range, _mbc[mb].tx_dsp)); + .set_publisher([this, mb](){ + return this->get_tx_dsp_freq_range(mb); + }) + ; //setup dsp flow control const double ups_per_sec = device_args_i.cast<double>("ups_per_sec", 20); @@ -810,6 +833,49 @@ void usrp2_impl::set_tx_fe_corrections(const std::string &mb, const double lo_fr } } +double usrp2_impl::set_tx_dsp_freq( + const std::string &mb, + const double freq_ +) { + double new_freq = freq_; + const double tick_rate = + _tree->access<double>("/mboards/"+mb+"/tick_rate").get(); + + //calculate the DAC shift (multiples of rate) + const int sign = boost::math::sign(new_freq); + const int zone = std::min(boost::math::iround(new_freq/tick_rate), 2); + const double dac_shift = sign*zone*tick_rate; + new_freq -= dac_shift; //update FPGA DSP target freq + UHD_LOG_TRACE("USRP2", + "DSP Tuning: Requested " + std::to_string(freq_/1e6) + " MHz, Using " + "Nyquist zone " + std::to_string(sign*zone) + ", leftover DSP tuning: " + + std::to_string(new_freq/1e6) + " MHz."); + + //set the DAC shift (modulation mode) + if (zone == 0) { + _mbc[mb].codec->set_tx_mod_mode(0); //no shift + } else { + _mbc[mb].codec->set_tx_mod_mode(sign*4/zone); //DAC interp = 4 + } + + return _mbc[mb].tx_dsp->set_freq(new_freq) + dac_shift; //actual freq +} + +meta_range_t usrp2_impl::get_tx_dsp_freq_range(const std::string &mb) +{ + const double dac_rate = + _tree->access<double>("/mboards/" + mb + "/tick_rate").get() + * _mbc[mb].codec->get_tx_interpolation(); + const auto dsp_range_step = _mbc[mb].tx_dsp->get_freq_range().step(); + // The DSP tuning rate is the entire range of the DAC clock rate. The step + // size is determined by the FPGA IP, however. + return meta_range_t( + -dac_rate / 2, + +dac_rate / 2, + dsp_range_step + ); +} + #include <boost/math/special_functions/round.hpp> #include <boost/math/special_functions/sign.hpp> |