diff options
| author | Josh Blum <josh@joshknows.com> | 2011-06-29 10:54:28 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2011-06-29 10:54:28 -0700 | 
| commit | adbe1a0efe7598a9e0433675e2852aad2e280c62 (patch) | |
| tree | 3ff0bec87ff979f091e3233bf06118670e2535fe | |
| parent | d2f79c07281604c1b48ec81f1cdb2754e97bbe65 (diff) | |
| download | uhd-adbe1a0efe7598a9e0433675e2852aad2e280c62.tar.gz uhd-adbe1a0efe7598a9e0433675e2852aad2e280c62.tar.bz2 uhd-adbe1a0efe7598a9e0433675e2852aad2e280c62.zip | |
uhd: loopback working on usrp2
| -rw-r--r-- | host/include/uhd/property_tree.ipp | 10 | ||||
| -rw-r--r-- | host/lib/usrp/cores/rx_dsp_core_200.cpp | 15 | ||||
| -rw-r--r-- | host/lib/usrp/cores/rx_dsp_core_200.hpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/cores/tx_dsp_core_200.cpp | 9 | ||||
| -rw-r--r-- | host/lib/usrp/cores/tx_dsp_core_200.hpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/multi_usrp.cpp | 130 | ||||
| -rw-r--r-- | host/lib/usrp2/usrp2_impl.cpp | 10 | ||||
| -rw-r--r-- | host/lib/usrp2/usrp2_impl.hpp | 1 | ||||
| -rw-r--r-- | host/utils/uhd_usrp_probe.cpp | 3 | 
9 files changed, 149 insertions, 35 deletions
| diff --git a/host/include/uhd/property_tree.ipp b/host/include/uhd/property_tree.ipp index 1c61d4937..3dba6fb28 100644 --- a/host/include/uhd/property_tree.ipp +++ b/host/include/uhd/property_tree.ipp @@ -19,7 +19,6 @@  #define INCLUDED_UHD_PROPERTY_TREE_IPP  #include <boost/foreach.hpp> -#include <boost/any.hpp>  #include <vector>  /*********************************************************************** @@ -51,23 +50,22 @@ public:      }      property<T> &set(const T &value){ -        T new_value(_master.empty()? value : _master(value)); -        _value = new_value; //shadow it +        _value = boost::shared_ptr<T>(new T(_master.empty()? value : _master(value)));          BOOST_FOREACH(typename property<T>::subscriber_type &subscriber, _subscribers){ -            subscriber(new_value); //let errors propagate +            subscriber(*_value); //let errors propagate          }          return *this;      }      T get(void) const{ -        return _publisher.empty()? boost::any_cast<T>(_value) : _publisher(); +        return _publisher.empty()? *_value : _publisher();      }  private:      std::vector<typename property<T>::subscriber_type> _subscribers;      typename property<T>::publisher_type _publisher;      typename property<T>::master_type _master; -    boost::any _value; //any type so we can assign structs w/ const members +    boost::shared_ptr<T> _value;  };  }} //namespace uhd::/*anon*/ diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp index 3215bea15..8fcf4df96 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp @@ -22,12 +22,12 @@  #include <boost/math/special_functions/round.hpp>  #include <boost/math/special_functions/sign.hpp>  #include <algorithm> -#include <algorithm>  #include <cmath>  #define REG_DSP_RX_FREQ       _dsp_base + 0 -#define REG_DSP_RX_DECIM      _dsp_base + 4 -#define REG_DSP_RX_MUX        _dsp_base + 8 +//skip one right here +#define REG_DSP_RX_DECIM      _dsp_base + 8 +#define REG_DSP_RX_MUX        _dsp_base + 12  #define FLAG_DSP_RX_MUX_SWAP_IQ   (1 << 0)  #define FLAG_DSP_RX_MUX_REAL_MODE (1 << 1) @@ -123,7 +123,8 @@ public:      }      double set_host_rate(const double rate){ -        int decim = boost::math::iround(_tick_rate/rate); +        const size_t decim_rate = boost::math::iround(_tick_rate/rate); +        size_t decim = decim_rate;          //determine which half-band filters are activated          int hb0 = 0, hb1 = 0; @@ -138,7 +139,7 @@ public:          _iface->poke32(REG_DSP_RX_DECIM, (hb1 << 9) | (hb0 << 8) | (decim & 0xff)); -        return _tick_rate/decim; +        return _tick_rate/decim_rate;      }      double set_freq(const double freq_){ @@ -160,6 +161,10 @@ public:          return actual_freq;      } +    uhd::meta_range_t get_freq_range(void){ +        return uhd::meta_range_t(-_tick_rate/2, +_tick_rate/2, _tick_rate/std::pow(2.0, 32)); +    } +      void handle_overflow(void){          if (_continuous_streaming) issue_stream_command(stream_cmd_t::STREAM_MODE_START_CONTINUOUS);      } diff --git a/host/lib/usrp/cores/rx_dsp_core_200.hpp b/host/lib/usrp/cores/rx_dsp_core_200.hpp index c496fca76..e0b6e18e4 100644 --- a/host/lib/usrp/cores/rx_dsp_core_200.hpp +++ b/host/lib/usrp/cores/rx_dsp_core_200.hpp @@ -19,6 +19,7 @@  #define INCLUDED_LIBUHD_USRP_RX_DSP_CORE_200_HPP  #include <uhd/config.hpp> +#include <uhd/types/ranges.hpp>  #include <boost/utility.hpp>  #include <boost/shared_ptr.hpp>  #include <uhd/types/stream_cmd.hpp> @@ -45,6 +46,8 @@ public:      virtual double set_host_rate(const double rate) = 0; +    virtual uhd::meta_range_t get_freq_range(void) = 0; +      virtual double set_freq(const double freq) = 0;      virtual void handle_overflow(void) = 0; diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp index 293b0b447..d2981bbdb 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.cpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp @@ -69,7 +69,8 @@ public:      }      double set_host_rate(const double rate){ -        int interp = boost::math::iround(_tick_rate/rate); +        const size_t interp_rate = boost::math::iround(_tick_rate/rate); +        size_t interp = interp_rate;          //determine which half-band filters are activated          int hb0 = 0, hb1 = 0; @@ -90,7 +91,7 @@ public:          const boost::int16_t scale = boost::math::iround((4096*std::pow(2, ceil_log2(rate_cubed)))/(1.65*rate_cubed));          _iface->poke32(REG_DSP_TX_SCALE_IQ, (boost::uint32_t(scale) << 16) | (boost::uint32_t(scale) << 0)); -        return _tick_rate/interp; +        return _tick_rate/interp_rate;      }      double set_freq(const double freq_){ @@ -112,6 +113,10 @@ public:          return actual_freq;      } +    uhd::meta_range_t get_freq_range(void){ +        return uhd::meta_range_t(-_tick_rate/2, +_tick_rate/2, _tick_rate/std::pow(2.0, 32)); +    } +      void set_updates(const size_t cycles_per_up, const size_t packets_per_up){          _iface->poke32(REG_TX_CTRL_CYCLES_PER_UP,  (cycles_per_up  == 0)? 0 : (FLAG_TX_CTRL_UP_ENB | cycles_per_up));          _iface->poke32(REG_TX_CTRL_PACKETS_PER_UP, (packets_per_up == 0)? 0 : (FLAG_TX_CTRL_UP_ENB | packets_per_up)); diff --git a/host/lib/usrp/cores/tx_dsp_core_200.hpp b/host/lib/usrp/cores/tx_dsp_core_200.hpp index f218fe8c9..f74ec0bdb 100644 --- a/host/lib/usrp/cores/tx_dsp_core_200.hpp +++ b/host/lib/usrp/cores/tx_dsp_core_200.hpp @@ -19,6 +19,7 @@  #define INCLUDED_LIBUHD_USRP_TX_DSP_CORE_200_HPP  #include <uhd/config.hpp> +#include <uhd/types/ranges.hpp>  #include <boost/utility.hpp>  #include <boost/shared_ptr.hpp>  #include "wb_iface.hpp" @@ -37,6 +38,8 @@ public:      virtual double set_host_rate(const double rate) = 0; +    virtual uhd::meta_range_t get_freq_range(void) = 0; +      virtual double set_freq(const double freq) = 0;      virtual void set_updates(const size_t cycles_per_up, const size_t packets_per_up) = 0; diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 935419c18..4c16772b3 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -23,11 +23,6 @@  #include <uhd/exception.hpp>  #include <uhd/utils/msg.hpp>  #include <uhd/utils/gain_group.hpp> -#include <uhd/usrp/subdev_props.hpp> -#include <uhd/usrp/mboard_props.hpp> -#include <uhd/usrp/device_props.hpp> -#include <uhd/usrp/dboard_props.hpp> -#include <uhd/usrp/dsp_props.hpp>  #include <boost/thread.hpp>  #include <boost/foreach.hpp>  #include <boost/format.hpp> @@ -71,6 +66,9 @@ static void do_tune_freq_warning_message(      }  } +/*********************************************************************** + * Gain helper functions + **********************************************************************/  static double get_gain_value(property_tree::sptr tree, const property_tree::path_type &path){      return tree->access<double>(path / "value").get();  } @@ -92,6 +90,100 @@ static gain_fcns_t make_gain_fcns_from_path(property_tree::sptr tree, const prop  }  /*********************************************************************** + * Tune Helper Functions + **********************************************************************/ +static const double RX_SIGN = +1.0; +static const double TX_SIGN = -1.0; + +static tune_result_t tune_xx_subdev_and_dsp( +    const double xx_sign, +    property_tree::sptr tree, +    const property_tree::path_type &dsp_path, +    const property_tree::path_type &rf_fe_path, +    const tune_request_t &tune_request +){ +    //------------------------------------------------------------------ +    //-- calculate the LO offset, only used with automatic policy +    //------------------------------------------------------------------ +    double lo_offset = 0.0; +    if (tree->access<bool>(rf_fe_path / "use_lo_offset").get()){ +        //If the local oscillator will be in the passband, use an offset. +        //But constrain the LO offset by the width of the filter bandwidth. +        const double rate = tree->access<double>(dsp_path / "rate" / "value").get(); +        const double bw = tree->access<double>(rf_fe_path / "bandwidth" / "value").get(); +        if (bw > rate) lo_offset = std::min((bw - rate)/2, rate/2); +    } + +    //------------------------------------------------------------------ +    //-- set the RF frequency depending upon the policy +    //------------------------------------------------------------------ +    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; +        tree->access<double>(rf_fe_path / "freq" / "value").set(target_rf_freq); +        break; + +    case tune_request_t::POLICY_MANUAL: +        target_rf_freq = tune_request.rf_freq; +        tree->access<double>(rf_fe_path / "freq" / "value").set(target_rf_freq); +        break; + +    case tune_request_t::POLICY_NONE: break; //does not set +    } +    const double actual_rf_freq = tree->access<double>(rf_fe_path / "freq" / "value").get(); + +    //------------------------------------------------------------------ +    //-- calculate the dsp freq, only used with automatic policy +    //------------------------------------------------------------------ +    double target_dsp_freq = actual_rf_freq - tune_request.target_freq; + +    //invert the sign on the dsp freq for transmit +    target_dsp_freq *= xx_sign; + +    //------------------------------------------------------------------ +    //-- set the dsp frequency depending upon the dsp frequency policy +    //------------------------------------------------------------------ +    switch (tune_request.dsp_freq_policy){ +    case tune_request_t::POLICY_AUTO: +        tree->access<double>(dsp_path / "freq" / "value").set(target_dsp_freq); +        break; + +    case tune_request_t::POLICY_MANUAL: +        target_dsp_freq = tune_request.dsp_freq; +        tree->access<double>(dsp_path / "freq" / "value").set(target_dsp_freq); +        break; + +    case tune_request_t::POLICY_NONE: break; //does not set +    } +    const double actual_dsp_freq = tree->access<double>(dsp_path / "freq" / "value").get(); + +    //------------------------------------------------------------------ +    //-- load and return the tune result +    //------------------------------------------------------------------ +    tune_result_t tune_result; +    tune_result.target_rf_freq = target_rf_freq; +    tune_result.actual_rf_freq = actual_rf_freq; +    tune_result.target_dsp_freq = target_dsp_freq; +    tune_result.actual_dsp_freq = actual_dsp_freq; +    return tune_result; +} + +static double derive_freq_from_xx_subdev_and_dsp( +    const double xx_sign, +    property_tree::sptr tree, +    const property_tree::path_type &dsp_path, +    const property_tree::path_type &rf_fe_path +){ +    //extract actual dsp and IF frequencies +    const double actual_rf_freq = tree->access<double>(rf_fe_path / "freq" / "value").get(); +    const double actual_dsp_freq = tree->access<double>(dsp_path / "freq" / "value").get(); + +    //invert the sign on the dsp freq for transmit +    return actual_rf_freq - actual_dsp_freq * xx_sign; +} + +/***********************************************************************   * Multi USRP Implementation   **********************************************************************/  class multi_usrp_impl : public multi_usrp{ @@ -296,21 +388,19 @@ public:      }      tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){ -        //TODO must invent for tree -        //tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), tune_request); -        //do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX"); -        //return r; +        tune_result_t r = tune_xx_subdev_and_dsp(RX_SIGN, _tree, rx_dsp_root(chan), rx_rf_fe_root(chan), tune_request); +        do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX"); +        return r;      }      double get_rx_freq(size_t chan){ -        //TODO must invent for tree -        //return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan)); +        return derive_freq_from_xx_subdev_and_dsp(RX_SIGN, _tree, rx_dsp_root(chan), rx_rf_fe_root(chan));      }      freq_range_t get_rx_freq_range(size_t chan){          meta_range_t range = _tree->access<meta_range_t>(rx_rf_fe_root(chan) / "freq" / "range").get(); -        const double tick_rate = get_master_clock_rate(0); //ASSUME -        return meta_range_t(range.start() - tick_rate/2.0, range.stop() + tick_rate/2.0); +        meta_range_t dsp_range = _tree->access<meta_range_t>(rx_dsp_root(chan) / "freq" / "range").get(); +        return meta_range_t(range.start() + dsp_range.start(), range.stop() + dsp_range.stop(), dsp_range.step());      }      void set_rx_gain(double gain, const std::string &name, size_t chan){ @@ -406,21 +496,19 @@ public:      }      tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){ -        //TODO must invent for tree -        //tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), tune_request); -        //do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "TX"); -        //return r; +        tune_result_t r = tune_xx_subdev_and_dsp(TX_SIGN, _tree, tx_dsp_root(chan), tx_rf_fe_root(chan), tune_request); +        do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "RX"); +        return r;      }      double get_tx_freq(size_t chan){ -        //TODO must invent for tree -        //return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan)); +        return derive_freq_from_xx_subdev_and_dsp(TX_SIGN, _tree, tx_dsp_root(chan), tx_rf_fe_root(chan));      }      freq_range_t get_tx_freq_range(size_t chan){          meta_range_t range = _tree->access<meta_range_t>(tx_rf_fe_root(chan) / "freq" / "range").get(); -        const double tick_rate = get_master_clock_rate(0); //ASSUME -        return meta_range_t(range.start() - tick_rate/2.0, range.stop() + tick_rate/2.0); +        meta_range_t dsp_range = _tree->access<meta_range_t>(tx_dsp_root(chan) / "freq" / "range").get(); +        return meta_range_t(range.start() + dsp_range.start(), range.stop() + dsp_range.stop(), dsp_range.step());      }      void set_tx_gain(double gain, const std::string &name, size_t chan){ diff --git a/host/lib/usrp2/usrp2_impl.cpp b/host/lib/usrp2/usrp2_impl.cpp index 50d1eb2e2..e65461103 100644 --- a/host/lib/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp2/usrp2_impl.cpp @@ -437,6 +437,8 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){                  .subscribe(boost::bind(&usrp2_impl::update_rx_samp_rate, this, _1));              _tree->create<double>(rx_dsp_path / "freq/value")                  .subscribe_master(boost::bind(&rx_dsp_core_200::set_freq, _mbc[mb].rx_dsps[dspno], _1)); +            _tree->create<meta_range_t>(rx_dsp_path / "freq/range") +                .publish(boost::bind(&rx_dsp_core_200::get_freq_range, _mbc[mb].rx_dsps[dspno]));              _tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd")                  .subscribe(boost::bind(&rx_dsp_core_200::issue_stream_command, _mbc[mb].rx_dsps[dspno], _1));          } @@ -454,6 +456,8 @@ usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){              .subscribe(boost::bind(&usrp2_impl::update_tx_samp_rate, this, _1));          _tree->create<double>(mb_path / "tx_dsps/0/freq/value")              .subscribe_master(boost::bind(&usrp2_impl::set_tx_dsp_freq, this, mb, _1)); +        _tree->create<meta_range_t>(mb_path / "tx_dsps/0/freq/range") +            .publish(boost::bind(&usrp2_impl::get_tx_dsp_freq_range, this, mb));          //setup dsp flow control          const double ups_per_sec = device_args_i.cast<double>("ups_per_sec", 20); @@ -605,6 +609,12 @@ double usrp2_impl::set_tx_dsp_freq(const std::string &mb, const double freq_){      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 tick_rate = _tree->access<double>("/mboards/"+mb+"/tick_rate").get(); +    const meta_range_t dsp_range = _mbc[mb].tx_dsp->get_freq_range(); +    return meta_range_t(dsp_range.start() - tick_rate*2, dsp_range.stop() + tick_rate*2, dsp_range.step()); +} +  void usrp2_impl::update_ref_source(const std::string &mb, const std::string &source){      //clock source ref 10mhz      switch(_mbc[mb].iface->get_rev()){ diff --git a/host/lib/usrp2/usrp2_impl.hpp b/host/lib/usrp2/usrp2_impl.hpp index 8ec61f739..ad203079b 100644 --- a/host/lib/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp2/usrp2_impl.hpp @@ -127,6 +127,7 @@ private:      void update_rx_subdev_spec(const std::string &, const uhd::usrp::subdev_spec_t &);      void update_tx_subdev_spec(const std::string &, const uhd::usrp::subdev_spec_t &);      double set_tx_dsp_freq(const std::string &, const double); +    uhd::meta_range_t get_tx_dsp_freq_range(const std::string &);      void update_ref_source(const std::string &, const std::string &);  }; diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index e90f82ee8..caf419719 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -55,7 +55,8 @@ static std::string get_dsp_pp_string(const std::string &type, property_tree::spt      std::stringstream ss;      ss << boost::format("%s DSP: %s") % type % path.leaf() << std::endl;      //ss << std::endl; -    ss << boost::format("DSP Rate: %f Msps") % (tree->access<double>(path.branch_path().branch_path() / "tick_rate").get()/1e6) << std::endl; +    meta_range_t freq_range = tree->access<meta_range_t>(path / "freq/range").get(); +    ss << boost::format("Freq range: %.3f to %.3f Mhz") % (freq_range.start()/1e6) % (freq_range.stop()/1e6) << std::endl;;      return ss.str();  } | 
