diff options
| -rw-r--r-- | host/docs/build.rst | 21 | ||||
| -rw-r--r-- | host/docs/usrp1.rst | 35 | ||||
| -rw-r--r-- | host/docs/usrp2.rst | 2 | ||||
| -rw-r--r-- | host/include/uhd/transport/usb_control.hpp | 4 | ||||
| -rw-r--r-- | host/include/uhd/transport/usb_zero_copy.hpp | 24 | ||||
| -rw-r--r-- | host/include/uhd/usrp/dboard_iface.hpp | 9 | ||||
| -rw-r--r-- | host/lib/transport/libusb1_control.cpp | 2 | ||||
| -rw-r--r-- | host/lib/transport/libusb1_zero_copy.cpp | 140 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/dboard_iface.cpp | 5 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_ctrl.cpp | 11 | ||||
| -rw-r--r-- | host/lib/usrp/usrp1/usrp1_impl.cpp | 41 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/dboard_iface.cpp | 4 | 
12 files changed, 197 insertions, 101 deletions
diff --git a/host/docs/build.rst b/host/docs/build.rst index f37b5dce7..9cf37db4a 100644 --- a/host/docs/build.rst +++ b/host/docs/build.rst @@ -58,7 +58,8 @@ LibUSB  * **Purpose:** USB-based hardware support  * **Version:** at least 1.0  * **Usage:** build time + run time (optional) -* **Download URL:** http://www.libusb.org/ +* **Download URL:** http://sourceforge.net/projects/libusb/files/libusb-1.0/ +* **Download URL (windows binaries):** http://www.libusb.org/wiki/windows_backend#LatestBinarySnapshots  ^^^^^^^^^^^^^^^^  Python @@ -152,6 +153,19 @@ Generate the project with cmake  * Click generate and a project file will be created in the build directory.  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LibUSB cmake notes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +On Windows, cmake does not have the advantage of pkg-config, +so we must manually tell cmake how to locate the LibUSB header and lib. + +From the cmake gui, select "Advanded View": + +* Set LIBUSB_INCLUDE_DIR to the directory with "libusb.h". +* Set LIBUSB_LIBRARIES to the full path for "libusb-1.0.lib". + +Then check the boxes to enable USRP1 support, click configure and generate. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  Build the project in MSVC  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  * Open the generated project file in MSVC. @@ -177,3 +191,8 @@ Setup the PATH environment variable  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  * Add the boost library path to %PATH% (usually c:\\program files\\boost\\<version>\\lib)  * Add the uhd library path to %PATH% (usually c:\\program files\\uhd\\lib) +* Add the libusb library to %PATH% (if using usb support) + +**Note:** +The interface for editing environment variable paths in Windows is very poor. +I recommend using "Rapid Environment Editor" (http://www.rapidee.com) over the default editor. diff --git a/host/docs/usrp1.rst b/host/docs/usrp1.rst index 3c1431d30..0baa93a45 100644 --- a/host/docs/usrp1.rst +++ b/host/docs/usrp1.rst @@ -60,6 +60,29 @@ Example device address string representations to specify non-standard firmware a      fpga=usrp1_fpga_4rx.rbf, fw=usrp1_fw_custom.ihx +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Change USB transfer parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The advanced user may manipulate parameters of the usb bulk transfers +for various reasons, such as lowering latency or increasing buffer size. +By default, the UHD will use values for these parameters +that are known to perform well on a variety of systems. +The following device address parameters can be used to manipulate USB bulk transfers: + +* **recv_xfer_size:** the size of each receive bulk transfer in bytes +* **recv_num_xfers:** the number of simultaneous receive bulk transfers +* **send_xfer_size:** the size of each send bulk transfer in bytes +* **send_num_xfers:** the number of simultaneous send bulk transfers + +Example usage, set the device address markup string to the following: +:: + +    serial=12345678, recv_num_xfers=16 + +   -- OR -- + +    serial=12345678, recv_xfer_size=2048, recv_num_xfers=16 +  ------------------------------------------------------------------------  Specifying the subdevice to use  ------------------------------------------------------------------------ @@ -100,10 +123,10 @@ OS Specific Notes  ------------------------------------------------------------------------  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Setup Udev on Linux +Linux - setup udev  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -On Linux, Udev handles USB plug and unplug events. -The following command creates a Udev rule for the USRP1 +On Linux, udev handles USB plug and unplug events. +The following commands create a udev rule for the USRP1  so that non-root users may access the device:  :: @@ -113,3 +136,9 @@ so that non-root users may access the device:      sudo mv tmpfile /etc/udev/rules.d/10-usrp.rules      sudo udevadm control --reload-rules +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Windows - install driver +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +On Windows, a driver must be installed the first time the USRP1 is attached to the host computer. +A download link for this driver can be found on the UHD wiki page. +Download and unpack the driver, and direct the Windows driver install wizard to the .inf file. diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index 72a919d1a..70e5ea28b 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -201,7 +201,7 @@ Each parameter will accept a numeric value for the number of bytes.  * recv_buff_size  * send_buff_size -Example, set the args string to the following: +Example usage, set the device address markup string to the following:  ::      addr=192.168.10.2, recv_buff_size=100e6 diff --git a/host/include/uhd/transport/usb_control.hpp b/host/include/uhd/transport/usb_control.hpp index 6137ecf84..f9829c3ec 100644 --- a/host/include/uhd/transport/usb_control.hpp +++ b/host/include/uhd/transport/usb_control.hpp @@ -50,9 +50,9 @@ public:       * \param index        2-byte (wIndex)       * \param buff         buffer to hold send or receive data       * \param length       2-byte (wLength) -     * \return             number of bytes submitted +     * \return             number of bytes submitted or error code       */ -    virtual size_t submit(boost::uint8_t request_type, +    virtual ssize_t submit(boost::uint8_t request_type,                            boost::uint8_t request,                            boost::uint16_t value,                            boost::uint16_t index,  diff --git a/host/include/uhd/transport/usb_zero_copy.hpp b/host/include/uhd/transport/usb_zero_copy.hpp index 75232c22a..61bf380ba 100644 --- a/host/include/uhd/transport/usb_zero_copy.hpp +++ b/host/include/uhd/transport/usb_zero_copy.hpp @@ -45,16 +45,22 @@ public:       * The underlying implementation may be platform specific.       *       * \param handle a device handle that uniquely identifying the device -     * \param rx_endpoint an integer specifiying an IN endpoint number  -     * \param tx_endpoint an integer specifiying an OUT endpoint number -     * \param buff_size total number of bytes of buffer space to allocate  -     * \param block_size number of bytes allocated for each I/O transaction  +     * \param recv_endpoint an integer specifiying an IN endpoint number +     * \param send_endpoint an integer specifiying an OUT endpoint number +     * \param recv_xfer_size the number of bytes for each receive transfer +     * \param recv_num_xfers the number of simultaneous receive transfers +     * \param send_xfer_size the number of bytes for each send transfer +     * \param send_num_xfers the number of simultaneous send transfers       */ -    static sptr make(usb_device_handle::sptr handle, -                     unsigned int rx_endpoint, -                     unsigned int tx_endpoint, -                     size_t buff_size = 0, -                     size_t block_size = 0); +    static sptr make( +        usb_device_handle::sptr handle, +        unsigned int recv_endpoint, +        unsigned int send_endpoint, +        size_t recv_xfer_size = 0, +        size_t recv_num_xfers = 0, +        size_t send_xfer_size = 0, +        size_t send_num_xfers = 0 +    );  };  }} //namespace diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp index c7db244f2..c430ecd3f 100644 --- a/host/include/uhd/usrp/dboard_iface.hpp +++ b/host/include/uhd/usrp/dboard_iface.hpp @@ -242,6 +242,15 @@ public:       * \param enb true for enabled       */      virtual void set_clock_enabled(unit_t unit, bool enb) = 0; + +    /*! +     * Get the rate of the codec. +     * For rx, this is the rate the ADC feeds the DSP. +     * For tx, this is the rate the DSP feeds the DAC. +     * \param unit which unit rx or tx +     * \return the codec rate in Hz +     */ +    virtual double get_codec_rate(unit_t unit) = 0;  };  }} //namespace diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp index c989a788c..f903907d0 100644 --- a/host/lib/transport/libusb1_control.cpp +++ b/host/lib/transport/libusb1_control.cpp @@ -33,7 +33,7 @@ public:          _handle->claim_interface(0 /* control interface */);      } -    size_t submit(boost::uint8_t request_type, +    ssize_t submit(boost::uint8_t request_type,                    boost::uint8_t request,                    boost::uint16_t value,                    boost::uint16_t index, diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index b089d11e0..f2dcff6b5 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -30,6 +30,9 @@ using namespace uhd::transport;  const int libusb_timeout = 0; +static const size_t DEFAULT_NUM_XFERS = 16;     //num xfers +static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes +  /***********************************************************************   * Helper functions   ***********************************************************************/ @@ -56,7 +59,7 @@ void pp_transfer(libusb_transfer *lut)   *   create a bidirectional interface. It is a zero copy implementation   *   with respect to libusb, however, each send and recv requires a copy   *   operation from kernel to userspace; this is due to the usbfs - *   interface provided by the kernel.  + *   interface provided by the kernel.   **********************************************************************/  class usb_endpoint {  public: @@ -107,7 +110,7 @@ private:      //! a list of shared arrays for the transfer buffers      std::vector<boost::shared_array<boost::uint8_t> > _buffers; -    // Calls for processing asynchronous I/O  +    // Calls for processing asynchronous I/O      libusb_transfer *allocate_transfer(int buff_len);      void print_transfer_status(libusb_transfer *lut);  }; @@ -142,7 +145,7 @@ void usb_endpoint::callback_handle_transfer(libusb_transfer *lut){   * Constructor   * Allocate libusb transfers and mark as free.  For IN endpoints,   * submit the transfers so that they're ready to return when - * data is available.  + * data is available.   */  usb_endpoint::usb_endpoint(      libusb::device_handle::sptr handle, @@ -194,7 +197,7 @@ usb_endpoint::~usb_endpoint(void){  /* - * Allocate a libusb transfer  + * Allocate a libusb transfer   * The allocated transfer - and buffer it contains - is repeatedly   * submitted, reaped, and reused and should not be freed until shutdown.   * \param buff_len size of the individual buffer held by each transfer @@ -225,7 +228,7 @@ libusb_transfer *usb_endpoint::allocate_transfer(int buff_len){   * Asynchonous transfer submission   * Submit a libusb transfer to libusb add pending status   * \param lut pointer to libusb_transfer - * \return true on success or false on error  + * \return true on success or false on error   */  void usb_endpoint::submit(libusb_transfer *lut){      UHD_ASSERT_THROW(libusb_submit_transfer(lut) == 0); @@ -281,14 +284,14 @@ libusb_transfer *usb_endpoint::get_lut_with_wait(size_t timeout_ms){  }  /*********************************************************************** - * Managed buffers  + * Managed buffers   **********************************************************************/  /*   * Libusb managed receive buffer   * Construct a recv buffer from a libusb transfer. The memory held by   * the libusb transfer is exposed through the managed buffer interface.   * Upon destruction, the transfer and buffer are resubmitted to the - * endpoint for further use.  + * endpoint for further use.   */  class libusb_managed_recv_buffer_impl : public managed_recv_buffer {  public: @@ -307,7 +310,7 @@ public:  private:      const boost::asio::const_buffer &get() const      { -        return _buff;  +        return _buff;      }      libusb_transfer *_lut; @@ -327,9 +330,8 @@ private:  class libusb_managed_send_buffer_impl : public managed_send_buffer {  public:      libusb_managed_send_buffer_impl(libusb_transfer *lut, -                                    usb_endpoint::sptr endpoint, -                                    size_t buff_size) -        : _buff(lut->buffer, buff_size), _committed(false) +                                    usb_endpoint::sptr endpoint) +        : _buff(lut->buffer, lut->length), _committed(false)      {          _lut = lut;          _endpoint = endpoint; @@ -349,7 +351,7 @@ public:              std::cerr << "UHD: send buffer already committed" << std::endl;              return 0;          } -         +          UHD_ASSERT_THROW(num_bytes <= boost::asio::buffer_size(_buff));          _lut->length = num_bytes; @@ -369,7 +371,7 @@ public:  private:      const boost::asio::mutable_buffer &get() const      { -        return _buff;  +        return _buff;      }      libusb_transfer *_lut; @@ -385,61 +387,71 @@ private:  class libusb_zero_copy_impl : public usb_zero_copy  {  private: -    usb_endpoint::sptr _rx_ep, _tx_ep; -      libusb::device_handle::sptr _handle; - -    size_t _recv_buff_size; -    size_t _send_buff_size; -    size_t _num_frames; +    size_t _recv_num_frames, _send_num_frames; +    usb_endpoint::sptr _recv_ep, _send_ep;  public:      typedef boost::shared_ptr<libusb_zero_copy_impl> sptr; -    libusb_zero_copy_impl(libusb::device_handle::sptr handle, -                          unsigned int rx_endpoint, -                          unsigned int tx_endpoint, -                          size_t recv_buff_size, -                          size_t send_buff_size); +    libusb_zero_copy_impl( +		libusb::device_handle::sptr handle, +		unsigned int recv_endpoint, unsigned int send_endpoint, +		size_t recv_xfer_size, size_t recv_num_xfers, +		size_t send_xfer_size, size_t send_num_xfers +	);      managed_recv_buffer::sptr get_recv_buff(void);      managed_send_buffer::sptr get_send_buff(void); -    size_t get_num_recv_frames(void) const { return _num_frames; } -    size_t get_num_send_frames(void) const { return _num_frames; } +    size_t get_num_recv_frames(void) const { return _recv_num_frames; } +    size_t get_num_send_frames(void) const { return _send_num_frames; }  };  /*   * Constructor   * Initializes libusb, opens devices, and sets up interfaces for I/O. - * Finally, creates endpoints for asynchronous I/O.  + * Finally, creates endpoints for asynchronous I/O.   */ -libusb_zero_copy_impl::libusb_zero_copy_impl(libusb::device_handle::sptr handle, -                                             unsigned int rx_endpoint, -                                             unsigned int tx_endpoint, -                                             size_t buff_size, -                                             size_t block_size) - : _handle(handle), -   _recv_buff_size(block_size), _send_buff_size(block_size), -   _num_frames(buff_size / block_size) -{ -    _handle->claim_interface(2 /*in interface*/); +libusb_zero_copy_impl::libusb_zero_copy_impl( +    libusb::device_handle::sptr handle, +    unsigned int recv_endpoint, unsigned int send_endpoint, +    size_t recv_xfer_size, size_t recv_num_xfers, +    size_t send_xfer_size, size_t send_num_xfers +){ +	_handle = handle; + +	//if the sizes are left at 0 (automatic) -> use the defaults +	if (recv_xfer_size == 0) recv_xfer_size = DEFAULT_XFER_SIZE; +	if (recv_num_xfers == 0) recv_num_xfers = DEFAULT_NUM_XFERS; +	if (send_xfer_size == 0) send_xfer_size = DEFAULT_XFER_SIZE; +	if (send_num_xfers == 0) send_num_xfers = DEFAULT_NUM_XFERS; + +    //sanity check the transfer sizes +    UHD_ASSERT_THROW(recv_xfer_size % 512 == 0); +    UHD_ASSERT_THROW(send_xfer_size % 512 == 0); + +	//store the num xfers for the num frames count +	_recv_num_frames = recv_num_xfers; +	_send_num_frames = send_num_xfers; + +	_handle->claim_interface(2 /*in interface*/);      _handle->claim_interface(1 /*out interface*/); -    _rx_ep = usb_endpoint::sptr(new usb_endpoint( +    _recv_ep = usb_endpoint::sptr(new usb_endpoint(                                _handle,         // libusb device_handle -                              rx_endpoint,     // USB endpoint number +                              recv_endpoint,   // USB endpoint number                                true,            // IN endpoint -                              _recv_buff_size, // buffer size per transfer  -                              _num_frames      // number of libusb transfers +                              recv_xfer_size,  // buffer size per transfer +                              recv_num_xfers   // number of libusb transfers      )); -    _tx_ep = usb_endpoint::sptr(new usb_endpoint( +    _send_ep = usb_endpoint::sptr(new usb_endpoint(                                _handle,         // libusb device_handle -                              tx_endpoint,     // USB endpoint number +                              send_endpoint,   // USB endpoint number                                false,           // OUT endpoint -                              _send_buff_size, // buffer size per transfer -                              _num_frames      // number of libusb transfers +                              send_xfer_size,  // buffer size per transfer +                              send_num_xfers   // number of libusb transfers      ));  } @@ -447,17 +459,17 @@ libusb_zero_copy_impl::libusb_zero_copy_impl(libusb::device_handle::sptr handle,   * Construct a managed receive buffer from a completed libusb transfer   * (happy with buffer full of data) obtained from the receive endpoint.   * Return empty pointer if no transfer is available (timeout or error). - * \return pointer to a managed receive buffer  + * \return pointer to a managed receive buffer   */  managed_recv_buffer::sptr libusb_zero_copy_impl::get_recv_buff(void){ -    libusb_transfer *lut = _rx_ep->get_lut_with_wait(/* TODO timeout API */); +    libusb_transfer *lut = _recv_ep->get_lut_with_wait(/* TODO timeout API */);      if (lut == NULL) {          return managed_recv_buffer::sptr();      }      else {          return managed_recv_buffer::sptr(              new libusb_managed_recv_buffer_impl(lut, -                                                _rx_ep)); +                                                _recv_ep));      }  } @@ -466,38 +478,36 @@ managed_recv_buffer::sptr libusb_zero_copy_impl::get_recv_buff(void){   * Construct a managed send buffer from a free libusb transfer (with   * empty buffer). Return empty pointer of no transfer is available   * (timeout or error). - * \return pointer to a managed send buffer  + * \return pointer to a managed send buffer   */  managed_send_buffer::sptr libusb_zero_copy_impl::get_send_buff(void){ -    libusb_transfer *lut = _tx_ep->get_lut_with_wait(/* TODO timeout API */); +    libusb_transfer *lut = _send_ep->get_lut_with_wait(/* TODO timeout API */);      if (lut == NULL) {          return managed_send_buffer::sptr();      }      else {          return managed_send_buffer::sptr(              new libusb_managed_send_buffer_impl(lut, -                                                _tx_ep, -                                                _send_buff_size)); +                                                _send_ep));      }  } -  /***********************************************************************   * USB zero_copy make functions   **********************************************************************/ -usb_zero_copy::sptr usb_zero_copy::make(usb_device_handle::sptr handle, -                                        unsigned int rx_endpoint, -                                        unsigned int tx_endpoint, -                                        size_t buff_size, -                                        size_t block_size) - -{ +usb_zero_copy::sptr usb_zero_copy::make( +	usb_device_handle::sptr handle, +    unsigned int recv_endpoint, unsigned int send_endpoint, +	size_t recv_xfer_size, size_t recv_num_xfers, +	size_t send_xfer_size, size_t send_num_xfers +){      libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle(          boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()      )); -    return sptr(new libusb_zero_copy_impl(dev_handle, -                                          rx_endpoint, -                                          tx_endpoint, -                                          buff_size,  -                                          block_size)); +    return sptr(new libusb_zero_copy_impl( +		dev_handle, +		recv_endpoint,  send_endpoint, +		recv_xfer_size, recv_num_xfers, +		send_xfer_size, send_num_xfers +    ));  } diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp index 4791b55ce..4f0549a37 100644 --- a/host/lib/usrp/usrp1/dboard_iface.cpp +++ b/host/lib/usrp/usrp1/dboard_iface.cpp @@ -93,6 +93,7 @@ public:      std::vector<double> get_clock_rates(unit_t);      double get_clock_rate(unit_t);      void set_clock_enabled(unit_t, bool); +    double get_codec_rate(unit_t);  private:      usrp1_iface::sptr _iface; @@ -170,6 +171,10 @@ void usrp1_dboard_iface::set_clock_enabled(unit_t, bool)      //TODO we can only enable for special case anyway...  } +double usrp1_dboard_iface::get_codec_rate(unit_t){ +    return _clock->get_master_clock_freq(); +} +  /***********************************************************************   * GPIO   **********************************************************************/ diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp index 76e8ce368..5043aed7d 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp @@ -180,7 +180,7 @@ public:          unsigned char reset_n = 0;          //hit the reset line -        if (load_img_msg) std::cout << "Loading firmware image " << filestring << "..." << std::flush; +        if (load_img_msg) std::cout << "Loading firmware image: " << filestring << "..." << std::flush;          usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,                             &reset_y, 1); @@ -209,9 +209,9 @@ public:              }                //type 0x01 is end               else if (type == 0x01) { +                usrp_set_firmware_hash(hash); //set hash before reset                  usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,                                     &reset_n, 1); -                usrp_set_firmware_hash(hash);                  file.close();                  //wait for things to settle @@ -267,11 +267,12 @@ public:              return -1;          } -        ssize_t n; -        while ((n = file.readsome((char *)buf, sizeof(buf))) > 0) { +        while (not file.eof()) { +            file.read((char *)buf, sizeof(buf)); +            size_t n = file.gcount();              ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER,                                       buf, n); -            if (ret != n) { +            if (ret < 0 or size_t(ret) != n) {                  std::cerr << "fpga load error " << ret << std::endl;                  file.close();                  return -1; diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 80ea49e9d..793e3027d 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -30,6 +30,7 @@  #include <boost/assign/list_of.hpp>  #include <boost/filesystem.hpp>  #include <boost/thread/thread.hpp> +#include <boost/lexical_cast.hpp>  #include <iostream>  using namespace uhd; @@ -74,14 +75,14 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)      boost::uint16_t vid = hint.has_key("uninit") ? FX2_VENDOR_ID : USRP1_VENDOR_ID;      boost::uint16_t pid = hint.has_key("uninit") ? FX2_PRODUCT_ID : USRP1_PRODUCT_ID; -    //see what we got on the USB bus -    std::vector<usb_device_handle::sptr> device_list = -        usb_device_handle::get_device_list(vid, pid); - -    if(device_list.size() == 0) return usrp1_addrs; //return nothing if no USRPs found +    // Important note: +    // The get device list calls are nested inside the for loop. +    // This allows the usb guts to decontruct when not in use, +    // so that re-enumeration after fw load can occur successfully. +    // This requirement is a courtesy of libusb1.0 on windows.      //find the usrps and load firmware -    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { +    BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {              usb_control::sptr ctrl_transport = usb_control::make(handle);              usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);              usrp_ctrl->usrp_load_firmware(usrp1_fw_image); @@ -90,9 +91,8 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)      //get descriptors again with serial number, but using the initialized VID/PID now since we have firmware      vid = USRP1_VENDOR_ID;      pid = USRP1_PRODUCT_ID; -    device_list = usb_device_handle::get_device_list(vid, pid); -    BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { +    BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {              device_addr_t new_addr;              new_addr["type"] = "usrp1";              new_addr["serial"] = handle->get_serial(); @@ -108,6 +108,15 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)  /***********************************************************************   * Make   **********************************************************************/ +template<typename output_type> static output_type cast_from_dev_addr( +	const device_addr_t &device_addr, +	const std::string &key, +	output_type def_val +){ +	return (device_addr.has_key(key))? +		boost::lexical_cast<output_type>(device_addr[key]) : def_val; +} +  static device::sptr usrp1_make(const device_addr_t &device_addr)  {      //extract the FPGA path for the USRP1 @@ -131,11 +140,15 @@ static device::sptr usrp1_make(const device_addr_t &device_addr)              usrp_ctrl = usrp_ctrl::make(ctrl_transport);              usrp_ctrl->usrp_load_fpga(usrp1_fpga_image); -            data_transport = usb_zero_copy::make(handle,        // identifier -                                                 6,             // IN endpoint -                                                 2,             // OUT endpoint -                                                 2 * (1 << 20), // buffer size -                                                 16384);        // transfer size +            data_transport = usb_zero_copy::make( +                handle,        // identifier +                6,             // IN endpoint +                2,             // OUT endpoint +                size_t(cast_from_dev_addr<double>(device_addr, "recv_xfer_size", 0)), +                size_t(cast_from_dev_addr<double>(device_addr, "recv_num_xfers", 0)), +                size_t(cast_from_dev_addr<double>(device_addr, "send_xfer_size", 0)), +                size_t(cast_from_dev_addr<double>(device_addr, "send_num_xfers", 0)) +            );              break;          }      } @@ -174,7 +187,7 @@ usrp1_impl::usrp1_impl(uhd::transport::usb_zero_copy::sptr data_transport,      //initialize the mboard      mboard_init(); -    //initialize the dboards  +    //initialize the dboards      dboard_init();      //initialize the dsps diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index f6d2b718a..fdfbf0d17 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -61,6 +61,7 @@ public:      double get_clock_rate(unit_t);      std::vector<double> get_clock_rates(unit_t);      void set_clock_enabled(unit_t, bool); +    double get_codec_rate(unit_t);      void write_spi(          unit_t unit, @@ -158,6 +159,9 @@ void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){      }  } +double usrp2_dboard_iface::get_codec_rate(unit_t){ +    return _clock_ctrl->get_master_clock_rate(); +}  /***********************************************************************   * GPIO   **********************************************************************/  | 
