diff options
| -rw-r--r-- | host/include/uhd/usrp/mimo_usrp.hpp | 40 | ||||
| -rw-r--r-- | host/include/uhd/utils/algorithm.hpp | 29 | ||||
| -rw-r--r-- | host/lib/usrp/mimo_usrp.cpp | 118 | 
3 files changed, 187 insertions, 0 deletions
| diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp index 8820c91c1..483feca29 100644 --- a/host/include/uhd/usrp/mimo_usrp.hpp +++ b/host/include/uhd/usrp/mimo_usrp.hpp @@ -94,10 +94,50 @@ public:      /*******************************************************************       * RX methods       ******************************************************************/ +    virtual void set_rx_rate_all(double rate) = 0; +    virtual double get_rx_rate_all(void) = 0; + +    virtual tune_result_t set_rx_freq(size_t chan, double freq) = 0; +    virtual tune_result_t set_rx_freq(size_t chan, double freq, double lo_off) = 0; +    virtual freq_range_t get_rx_freq_range(size_t chan) = 0; + +    virtual void set_rx_gain(size_t chan, float gain) = 0; +    virtual float get_rx_gain(size_t chan) = 0; +    virtual gain_range_t get_rx_gain_range(size_t chan) = 0; + +    virtual void set_rx_antenna(size_t chan, const std::string &ant) = 0; +    virtual std::string get_rx_antenna(size_t chan) = 0; +    virtual std::vector<std::string> get_rx_antennas(size_t chan) = 0; + +    virtual bool get_rx_lo_locked(size_t chan) = 0; + +    /*! +     * Read the RSSI value from a usrp device. +     * Or throw if the dboard does not support an RSSI readback. +     * \param chan which mimo channel 0 to N-1 +     * \return the rssi in dB +     */ +    virtual float read_rssi(size_t chan) = 0;      /*******************************************************************       * TX methods       ******************************************************************/ +    virtual void set_tx_rate_all(double rate) = 0; +    virtual double get_tx_rate_all(void) = 0; + +    virtual tune_result_t set_tx_freq(size_t chan, double freq) = 0; +    virtual tune_result_t set_tx_freq(size_t chan, double freq, double lo_off) = 0; +    virtual freq_range_t get_tx_freq_range(size_t chan) = 0; + +    virtual void set_tx_gain(size_t chan, float gain) = 0; +    virtual float get_tx_gain(size_t chan) = 0; +    virtual gain_range_t get_tx_gain_range(size_t chan) = 0; + +    virtual void set_tx_antenna(size_t chan, const std::string &ant) = 0; +    virtual std::string get_tx_antenna(size_t chan) = 0; +    virtual std::vector<std::string> get_tx_antennas(size_t chan) = 0; + +    virtual bool get_tx_lo_locked(size_t chan) = 0;  }; diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp index 08977a69f..b52edc6b5 100644 --- a/host/include/uhd/utils/algorithm.hpp +++ b/host/include/uhd/utils/algorithm.hpp @@ -83,6 +83,35 @@ namespace std{      }      /*! +     * Count the number of appearances of a value in a range. +     * +     * Uses std::count to count the appearances in the range. +     * +     * \param range the elements to iterate through +     * \param value the value to count in the range +     * \return the number of appearances of the value +     */ +    template<typename Range, typename T> inline +    size_t count(const Range &range, const T &value){ +        return std::count(boost::begin(range), boost::end(range), value); +    } + +    /*! +     * Are the ranges equal (are their elements equivalent)? +     * +     * Uses std::equal to search the iterable for an element. +     * +     * \param range1 the first range of elements +     * \param range2 the second range of elements +     * \return true when the elements are equivalent +     */ +    template<typename Range> inline +    bool equal(const Range &range1, const Range &range2){ +        return (boost::size(range1) == boost::size(range2)) and +        std::equal(boost::begin(range1), boost::end(range1), boost::begin(range2)); +    } + +    /*!       * A templated signum implementation.       * \param n the comparable to process       * \return -1 when n negative, +1 when n positive, otherwise 0 diff --git a/host/lib/usrp/mimo_usrp.cpp b/host/lib/usrp/mimo_usrp.cpp index 54c921ac7..3c9788388 100644 --- a/host/lib/usrp/mimo_usrp.cpp +++ b/host/lib/usrp/mimo_usrp.cpp @@ -18,6 +18,7 @@  #include <uhd/usrp/mimo_usrp.hpp>  #include <uhd/usrp/tune_helper.hpp>  #include <uhd/utils/assert.hpp> +#include <uhd/utils/algorithm.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/usrp/mboard_props.hpp>  #include <uhd/usrp/device_props.hpp> @@ -125,10 +126,124 @@ public:      /*******************************************************************       * RX methods       ******************************************************************/ +    void set_rx_rate_all(double rate){ +        std::vector<double> _actual_rates; +        BOOST_FOREACH(wax::obj rx_dsp, _rx_dsps){ +            rx_dsp[DSP_PROP_HOST_RATE] = rate; +            _actual_rates.push_back(rx_dsp[DSP_PROP_HOST_RATE].as<double>()); +        } +        _rx_rate = _actual_rates.front(); +        if (std::count(_actual_rates, _rx_rate) != _actual_rates.size()) throw std::runtime_error( +            "MIMO configuratio error: rx rate inconsistent across mboards" +        ); +    } + +    double get_rx_rate_all(void){ +        return _rx_rate; +    } + +    tune_result_t set_rx_freq(size_t chan, double target_freq){ +        return tune_rx_subdev_and_ddc(_rx_subdevs.at(chan), _rx_dsps.at(chan), target_freq); +    } + +    tune_result_t set_rx_freq(size_t chan, double target_freq, double lo_off){ +        return tune_rx_subdev_and_ddc(_rx_subdevs.at(chan), _rx_dsps.at(chan), target_freq, lo_off); +    } + +    freq_range_t get_rx_freq_range(size_t chan){ +        return _rx_subdevs.at(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(); +    } + +    void set_rx_gain(size_t chan, float gain){ +        _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN] = gain; +    } + +    float get_rx_gain(size_t chan){ +        return _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN].as<float>(); +    } + +    gain_range_t get_rx_gain_range(size_t chan){ +        return _rx_subdevs.at(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); +    } + +    void set_rx_antenna(size_t chan, const std::string &ant){ +        _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA] = ant; +    } + +    std::string get_rx_antenna(size_t chan){ +        return _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA].as<std::string>(); +    } + +    std::vector<std::string> get_rx_antennas(size_t chan){ +        return _rx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>(); +    } + +    bool get_rx_lo_locked(size_t chan){ +        return _rx_subdevs.at(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>(); +    } + +    float read_rssi(size_t chan){ +        return _rx_subdevs.at(chan)[SUBDEV_PROP_RSSI].as<float>(); +    }      /*******************************************************************       * TX methods       ******************************************************************/ +    void set_tx_rate_all(double rate){ +        std::vector<double> _actual_rates; +        BOOST_FOREACH(wax::obj tx_dsp, _tx_dsps){ +            tx_dsp[DSP_PROP_HOST_RATE] = rate; +            _actual_rates.push_back(tx_dsp[DSP_PROP_HOST_RATE].as<double>()); +        } +        _tx_rate = _actual_rates.front(); +        if (std::count(_actual_rates, _tx_rate) != _actual_rates.size()) throw std::runtime_error( +            "MIMO configuratio error: tx rate inconsistent across mboards" +        ); +    } + +    double get_tx_rate_all(void){ +        return _rx_rate; +    } + +    tune_result_t set_tx_freq(size_t chan, double target_freq){ +        return tune_tx_subdev_and_duc(_tx_subdevs.at(chan), _tx_dsps.at(chan), target_freq); +    } + +    tune_result_t set_tx_freq(size_t chan, double target_freq, double lo_off){ +        return tune_tx_subdev_and_duc(_tx_subdevs.at(chan), _tx_dsps.at(chan), target_freq, lo_off); +    } + +    freq_range_t get_tx_freq_range(size_t chan){ +        return _tx_subdevs.at(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(); +    } + +    void set_tx_gain(size_t chan, float gain){ +        _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN] = gain; +    } + +    float get_tx_gain(size_t chan){ +        return _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN].as<float>(); +    } + +    gain_range_t get_tx_gain_range(size_t chan){ +        return _tx_subdevs.at(chan)[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); +    } + +    void set_tx_antenna(size_t chan, const std::string &ant){ +        _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA] = ant; +    } + +    std::string get_tx_antenna(size_t chan){ +        return _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA].as<std::string>(); +    } + +    std::vector<std::string> get_tx_antennas(size_t chan){ +        return _tx_subdevs.at(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>(); +    } + +    bool get_tx_lo_locked(size_t chan){ +        return _tx_subdevs.at(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>(); +    }  private:      device::sptr _dev; @@ -139,6 +254,9 @@ private:      std::vector<wax::obj> _tx_dboards;      std::vector<wax::obj> _rx_subdevs;      std::vector<wax::obj> _tx_subdevs; + +    //shadows +    double _rx_rate, _tx_rate;  };  /*********************************************************************** | 
