diff options
| -rw-r--r-- | host/examples/benchmark_rx_rate.cpp | 2 | ||||
| -rw-r--r-- | host/examples/rx_timed_samples.cpp | 2 | ||||
| -rw-r--r-- | host/examples/tx_timed_samples.cpp | 2 | ||||
| -rw-r--r-- | host/include/uhd/usrp/mimo_usrp.hpp | 41 | ||||
| -rw-r--r-- | host/include/uhd/usrp/simple_usrp.hpp | 16 | ||||
| -rw-r--r-- | host/lib/usrp/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/lib/usrp/mimo_usrp.cpp | 149 | ||||
| -rw-r--r-- | host/lib/usrp/simple_usrp.cpp | 12 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 3 | 
9 files changed, 208 insertions, 20 deletions
| diff --git a/host/examples/benchmark_rx_rate.cpp b/host/examples/benchmark_rx_rate.cpp index 53f4a3c68..e7e358e4c 100644 --- a/host/examples/benchmark_rx_rate.cpp +++ b/host/examples/benchmark_rx_rate.cpp @@ -124,7 +124,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;      uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); -    std::cout << boost::format("Using Device: %s") % sdev->get_name() << std::endl; +    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl;      sdev->set_rx_rate(500e3); //initial rate      while(true){ diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 8db312690..3c3c3fdc6 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -59,7 +59,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;      uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args);      uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_name() << std::endl; +    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl;      //set properties on the device      std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl; diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index 333f03fbe..846d9b6f4 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -61,7 +61,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl;      uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args);      uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_name() << std::endl; +    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl;      //set properties on the device      std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl; diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp index 2262b324e..8820c91c1 100644 --- a/host/include/uhd/usrp/mimo_usrp.hpp +++ b/host/include/uhd/usrp/mimo_usrp.hpp @@ -58,9 +58,46 @@ public:       * Get a printable name for this mimo usrp.       * \return a printable string       */ -    virtual std::string get_name(void) = 0; +    virtual std::string get_pp_string(void) = 0; -    //TODO +    /*! +     * Get the number of channels in this mimo configuration. +     * The number of rx channels == the number of tx channels. +     * \return the number of channels +     */ +    virtual size_t get_num_channels(void) = 0; + +    /******************************************************************* +     * Misc +     ******************************************************************/ +    /*! +     * Set the time registers on the usrp at the next pps tick. +     * The values will not be latched in until the pulse occurs. +     * It is recommended that the user sleep(1) after calling to ensure +     * that the time registers will be in a known state prior to use. +     * +     * Note: Because this call sets the time on the "next" pps, +     * the seconds in the time spec should be current seconds + 1. +     * +     * \param time_spec the time to latch into the usrp device +     */ +    virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; + +    /*! +     * Issue a stream command to the usrp device. +     * This tells the usrp to send samples into the host. +     * See the documentation for stream_cmd_t for more info. +     * \param stream_cmd the stream command to issue +     */ +    virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; + +    /******************************************************************* +     * RX methods +     ******************************************************************/ + +    /******************************************************************* +     * TX methods +     ******************************************************************/  }; diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp index 6ba1b90dd..1d817e030 100644 --- a/host/include/uhd/usrp/simple_usrp.hpp +++ b/host/include/uhd/usrp/simple_usrp.hpp @@ -58,7 +58,7 @@ public:       * Get a printable name for this simple usrp.       * \return a printable string       */ -    virtual std::string get_name(void) = 0; +    virtual std::string get_pp_string(void) = 0;      /*******************************************************************       * Misc @@ -98,13 +98,6 @@ public:       */      virtual void set_clock_config(const clock_config_t &clock_config) = 0; -    /*! -     * Read the RSSI value from a usrp device. -     * Or throw if the dboard does not support an RSSI readback. -     * \return the rssi in dB -     */ -    virtual float read_rssi(void) = 0; -      /*******************************************************************       * RX methods       ******************************************************************/ @@ -125,6 +118,13 @@ public:      virtual bool get_rx_lo_locked(void) = 0; +    /*! +     * Read the RSSI value from a usrp device. +     * Or throw if the dboard does not support an RSSI readback. +     * \return the rssi in dB +     */ +    virtual float read_rssi(void) = 0; +      /*******************************************************************       * TX methods       ******************************************************************/ diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt index 3e12c087e..814affdd0 100644 --- a/host/lib/usrp/CMakeLists.txt +++ b/host/lib/usrp/CMakeLists.txt @@ -23,6 +23,7 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_id.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_manager.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/dsp_utils.hpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/mimo_usrp.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/simple_usrp.cpp      ${CMAKE_SOURCE_DIR}/lib/usrp/tune_helper.cpp  ) diff --git a/host/lib/usrp/mimo_usrp.cpp b/host/lib/usrp/mimo_usrp.cpp new file mode 100644 index 000000000..54c921ac7 --- /dev/null +++ b/host/lib/usrp/mimo_usrp.cpp @@ -0,0 +1,149 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/usrp/mimo_usrp.hpp> +#include <uhd/usrp/tune_helper.hpp> +#include <uhd/utils/assert.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/foreach.hpp> +#include <boost/format.hpp> +#include <stdexcept> + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * MIMO USRP Implementation + **********************************************************************/ +class mimo_usrp_impl : public mimo_usrp{ +public: +    mimo_usrp_impl(const device_addr_t &addr){ +        _dev = device::make(addr); + +        //extract each mboard and its sub-devices +        BOOST_FOREACH(const std::string &name, (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>()){ +            _mboards.push_back((*_dev)[named_prop_t(DEVICE_PROP_MBOARD, name)]); +            _rx_dsps.push_back(_mboards.back()[MBOARD_PROP_RX_DSP]); +            _tx_dsps.push_back(_mboards.back()[MBOARD_PROP_TX_DSP]); + +            //extract rx subdevice +            _rx_dboards.push_back(_mboards.back()[MBOARD_PROP_RX_DBOARD]); +            std::string rx_subdev_in_use = _rx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0); +            _rx_subdevs.push_back(_rx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, rx_subdev_in_use)]); + +            //extract tx subdevice +            _tx_dboards.push_back(_mboards.back()[MBOARD_PROP_TX_DBOARD]); +            std::string tx_subdev_in_use = _tx_dboards.back()[DBOARD_PROP_USED_SUBDEVS].as<prop_names_t>().at(0); +            _tx_subdevs.push_back(_tx_dboards.back()[named_prop_t(DBOARD_PROP_SUBDEV, tx_subdev_in_use)]); +        } + +        //set the clock config across all mboards (TODO set through api) +        clock_config_t clock_config; +        clock_config.ref_source = clock_config_t::REF_SMA; +        clock_config.pps_source = clock_config_t::PPS_SMA; +        BOOST_FOREACH(wax::obj mboard, _mboards){ +            mboard[MBOARD_PROP_CLOCK_CONFIG] = clock_config; +        } + +    } + +    ~mimo_usrp_impl(void){ +        /* NOP */ +    } + +    device::sptr get_device(void){ +        return _dev; +    } + +    std::string get_pp_string(void){ +        std::string buff = str(boost::format( +            "MIMO USRP:\n" +            "  Device: %s\n" +        ) +            % (*_dev)[DEVICE_PROP_NAME].as<std::string>() +        ); +        for (size_t i = 0; i < get_num_channels(); i++){ +            buff += str(boost::format( +                "  Channel: %u\n" +                "    Mboard: %s\n" +                "    RX DSP: %s\n" +                "    RX Dboard: %s\n" +                "    RX Subdev: %s\n" +                "    TX DSP: %s\n" +                "    TX Dboard: %s\n" +                "    TX Subdev: %s\n" +            ) % i +                % _mboards.at(i)[MBOARD_PROP_NAME].as<std::string>() +                % _rx_dsps.at(i)[DSP_PROP_NAME].as<std::string>() +                % _rx_dboards.at(i)[DBOARD_PROP_NAME].as<std::string>() +                % _rx_subdevs.at(i)[SUBDEV_PROP_NAME].as<std::string>() +                % _tx_dsps.at(i)[DSP_PROP_NAME].as<std::string>() +                % _tx_dboards.at(i)[DBOARD_PROP_NAME].as<std::string>() +                % _tx_subdevs.at(i)[SUBDEV_PROP_NAME].as<std::string>() +            ); +        } +        return buff; +    } + +    size_t get_num_channels(void){ +        return _mboards.size(); +    } + +    /******************************************************************* +     * Misc +     ******************************************************************/ +    void set_time_next_pps(const time_spec_t &time_spec){ +        BOOST_FOREACH(wax::obj mboard, _mboards){ +            mboard[MBOARD_PROP_TIME_NEXT_PPS] = time_spec; +        } +    } + +    void issue_stream_cmd(const stream_cmd_t &stream_cmd){ +        BOOST_FOREACH(wax::obj mboard, _mboards){ +            mboard[MBOARD_PROP_STREAM_CMD] = stream_cmd; +        } +    } + +    /******************************************************************* +     * RX methods +     ******************************************************************/ + +    /******************************************************************* +     * TX methods +     ******************************************************************/ + +private: +    device::sptr _dev; +    std::vector<wax::obj> _mboards; +    std::vector<wax::obj> _rx_dsps; +    std::vector<wax::obj> _tx_dsps; +    std::vector<wax::obj> _rx_dboards; +    std::vector<wax::obj> _tx_dboards; +    std::vector<wax::obj> _rx_subdevs; +    std::vector<wax::obj> _tx_subdevs; +}; + +/*********************************************************************** + * The Make Function + **********************************************************************/ +mimo_usrp::sptr mimo_usrp::make(const device_addr_t &dev_addr){ +    return sptr(new mimo_usrp_impl(dev_addr)); +} diff --git a/host/lib/usrp/simple_usrp.cpp b/host/lib/usrp/simple_usrp.cpp index f4aa82669..4a5171cf7 100644 --- a/host/lib/usrp/simple_usrp.cpp +++ b/host/lib/usrp/simple_usrp.cpp @@ -31,7 +31,7 @@ using namespace uhd;  using namespace uhd::usrp;  /*********************************************************************** - * Simple Device Implementation + * Simple USRP Implementation   **********************************************************************/  class simple_usrp_impl : public simple_usrp{  public: @@ -60,7 +60,7 @@ public:          return _dev;      } -    std::string get_name(void){ +    std::string get_pp_string(void){          return str(boost::format(              "Simple USRP:\n"              "  Device: %s\n" @@ -102,10 +102,6 @@ public:          _mboard[MBOARD_PROP_CLOCK_CONFIG] = clock_config;      } -    float read_rssi(void){ -        return _rx_subdev[SUBDEV_PROP_RSSI].as<float>(); -    } -      /*******************************************************************       * RX methods       ******************************************************************/ @@ -157,6 +153,10 @@ public:          return _rx_subdev[SUBDEV_PROP_LO_LOCKED].as<bool>();      } +    float read_rssi(void){ +        return _rx_subdev[SUBDEV_PROP_RSSI].as<float>(); +    } +      /*******************************************************************       * TX methods       ******************************************************************/ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index cdba19f50..3402c26b1 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -199,7 +199,8 @@ void usrp2_impl::get(const wax::obj &key_, wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<device_prop_t>()){      case DEVICE_PROP_NAME: -        val = std::string("usrp2 device"); +        if (_mboards.size() > 1) val = std::string("usrp2 mimo device"); +        else                     val = std::string("usrp2 device");          return;      case DEVICE_PROP_MBOARD: | 
