From 86c86ede9775824411262e36f104489bcd171e21 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Fri, 13 Aug 2010 13:40:13 -0700 Subject: usrp1: Add libusb-1.0 implementations of USB interfaces --- host/lib/transport/libusb1_control.cpp | 238 +++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 host/lib/transport/libusb1_control.cpp (limited to 'host/lib/transport/libusb1_control.cpp') diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp new file mode 100644 index 000000000..2903d943d --- /dev/null +++ b/host/lib/transport/libusb1_control.cpp @@ -0,0 +1,238 @@ +// +// 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 . +// + +#include +#include +#include +#include +#include +#include + +using namespace uhd::transport; + +static int libusb_debug_level = 0; +static int libusb_timeout = 0; + +/*********************************************************************** + * libusb-1.0 implementation of USB control transport + **********************************************************************/ +class libusb_control_impl : public usb_control { +public: + libusb_control_impl(uhd::usb_descriptor_t descriptor); + ~libusb_control_impl(); + + size_t submit(boost::uint8_t request_type, + boost::uint8_t request, + boost::uint16_t value, + boost::uint16_t index, + unsigned char *buff, + boost::uint16_t length); + + static uhd::usb_descriptor_t create_descriptor(libusb_device *dev); + static std::string get_serial(libusb_device *dev); + +private: + uhd::usb_descriptor_t _descriptor; + + libusb_context *_ctx; + libusb_device_handle *_dev_handle; + + bool open_device(); + bool open_interface(); + bool compare_device(libusb_device *dev, uhd::usb_descriptor_t descriptor); +}; + + +libusb_control_impl::libusb_control_impl(uhd::usb_descriptor_t descriptor) + : _descriptor(descriptor), _ctx(NULL), _dev_handle(NULL) +{ + if (libusb_init(&_ctx) < 0) + UHD_THROW_SITE_INFO("USB: failed to initialize libusb"); + + libusb_set_debug(_ctx, libusb_debug_level); + + if (!open_device()) + UHD_THROW_SITE_INFO("USB: failed to open device"); + + if (!open_interface()) + UHD_THROW_SITE_INFO("USB: failed to open device interface"); +} + + +libusb_control_impl::~libusb_control_impl() +{ + libusb_close(_dev_handle); + libusb_exit(_ctx); +} + + +uhd::usb_descriptor_t libusb_control_impl::create_descriptor(libusb_device *dev) +{ + libusb_device_descriptor desc; + + if (libusb_get_device_descriptor(dev, &desc) < 0) + UHD_THROW_SITE_INFO("USB: failed to get device descriptor"); + + uhd::usb_descriptor_t descriptor; + + descriptor.serial = get_serial(dev); + descriptor.product_id = desc.idProduct; + descriptor.vendor_id = desc.idVendor; + descriptor.device_addr = libusb_get_device_address(dev); + + return descriptor; +} + + +std::string libusb_control_impl::get_serial(libusb_device *dev) +{ + unsigned char buff[32]; + + libusb_device_descriptor desc; + if (libusb_get_device_descriptor(dev, &desc) < 0) + return ""; + + if (desc.iSerialNumber == 0) + return ""; + + //open the device because we have to + libusb_device_handle *dev_handle; + if (libusb_open(dev, &dev_handle) < 0) + return ""; + + if (libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, + buff, sizeof(buff)) < 0) { + return ""; + } + + libusb_close(dev_handle); + + return (char*) buff; +} + + +bool libusb_control_impl::open_device() +{ + libusb_device **list; + libusb_device *dev; + + ssize_t cnt = libusb_get_device_list(_ctx, &list); + + if (cnt < 0) + return cnt; + + ssize_t i = 0; + for (i = 0; i < cnt; i++) { + dev = list[i]; + if (compare_device(dev, _descriptor)) + goto found; + } + return false; + +found: + int ret; + if ((ret = libusb_open(dev, &_dev_handle)) < 0) + return false; + else + return true; +} + + +bool libusb_control_impl::compare_device(libusb_device *dev, + uhd::usb_descriptor_t descriptor) +{ + std::string serial = descriptor.serial; + boost::uint16_t vendor_id = descriptor.vendor_id; + boost::uint16_t product_id = descriptor.product_id; + boost::uint8_t device_addr = descriptor.device_addr; + + libusb_device_descriptor libusb_desc; + if (libusb_get_device_descriptor(dev, &libusb_desc) < 0) + return false; + if (serial != get_serial(dev)) + return false; + if (vendor_id != libusb_desc.idVendor) + return false; + if (product_id != libusb_desc.idProduct) + return false; + if (device_addr != libusb_get_device_address(dev)) + return false; + + return true; +} + + +bool libusb_control_impl::open_interface() +{ + if (libusb_claim_interface(_dev_handle, 0) < 0) + return false; + else + return true; +} + + +size_t libusb_control_impl::submit(boost::uint8_t request_type, + boost::uint8_t request, + boost::uint16_t value, + boost::uint16_t index, + unsigned char *buff, + boost::uint16_t length) +{ + return libusb_control_transfer(_dev_handle, + request_type, + request, + value, + index, + buff, + length, + libusb_timeout); +} + + +/*********************************************************************** + * USB control public make functions + **********************************************************************/ +usb_control::sptr usb_control::make(uhd::usb_descriptor_t descriptor) +{ + return sptr(new libusb_control_impl(descriptor)); +} + +uhd::usb_descriptors_t usb_control::get_device_list() +{ + libusb_device **list; + uhd::usb_descriptors_t descriptors; + + if (libusb_init(NULL) < 0) + UHD_THROW_SITE_INFO("USB: failed to initialize libusb"); + + ssize_t cnt = libusb_get_device_list(NULL, &list); + + if (cnt < 0) + UHD_THROW_SITE_INFO("USB: failed to get device list"); + + ssize_t i = 0; + for (i = 0; i < cnt; i++) { + libusb_device *dev = list[i]; + descriptors.push_back(libusb_control_impl::create_descriptor(dev)); + } + + libusb_free_device_list(list, 0); + libusb_exit(NULL); + return descriptors; +} + + -- cgit v1.2.3 From 2e978d8835b8f954b7c34c42138b64d3a5767f81 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 15 Aug 2010 12:40:37 -0700 Subject: usrp1: compiling off next branch made usb checking changes implemented named_prop_t::extract change copied the remainder of the codec pga gain control --- host/lib/transport/CMakeLists.txt | 1 + host/lib/transport/libusb1_control.cpp | 14 ++++----- host/lib/usrp/usrp1/CMakeLists.txt | 56 ++++++++++++++++++++++------------ host/lib/usrp/usrp1/codec_ctrl.cpp | 8 ++--- host/lib/usrp/usrp1/codec_ctrl.hpp | 16 ++++++++++ host/lib/usrp/usrp1/codec_impl.cpp | 33 +++++++++----------- host/lib/usrp/usrp1/dboard_iface.cpp | 7 +++-- host/lib/usrp/usrp1/dboard_impl.cpp | 14 ++++----- host/lib/usrp/usrp1/mboard_impl.cpp | 12 +++----- host/lib/usrp/usrp1/usrp1_impl.cpp | 5 ++- 10 files changed, 98 insertions(+), 68 deletions(-) (limited to 'host/lib/transport/libusb1_control.cpp') diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt index d6e1ff7ba..627d2d806 100644 --- a/host/lib/transport/CMakeLists.txt +++ b/host/lib/transport/CMakeLists.txt @@ -30,6 +30,7 @@ IF(LIBUSB_FOUND) ${CMAKE_SOURCE_DIR}/lib/transport/libusb1_control.cpp ${CMAKE_SOURCE_DIR}/lib/transport/libusb1_zero_copy.cpp ) + SET(HAVE_USB_SUPPORT TRUE) ENDIF(LIBUSB_FOUND) ######################################################################## diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp index 2903d943d..c2f7060e8 100644 --- a/host/lib/transport/libusb1_control.cpp +++ b/host/lib/transport/libusb1_control.cpp @@ -16,10 +16,10 @@ // #include -#include #include #include #include +#include #include using namespace uhd::transport; @@ -61,15 +61,15 @@ libusb_control_impl::libusb_control_impl(uhd::usb_descriptor_t descriptor) : _descriptor(descriptor), _ctx(NULL), _dev_handle(NULL) { if (libusb_init(&_ctx) < 0) - UHD_THROW_SITE_INFO("USB: failed to initialize libusb"); + throw std::runtime_error("USB: failed to initialize libusb"); libusb_set_debug(_ctx, libusb_debug_level); if (!open_device()) - UHD_THROW_SITE_INFO("USB: failed to open device"); + throw std::runtime_error("USB: failed to open device"); if (!open_interface()) - UHD_THROW_SITE_INFO("USB: failed to open device interface"); + throw std::runtime_error("USB: failed to open device interface"); } @@ -85,7 +85,7 @@ uhd::usb_descriptor_t libusb_control_impl::create_descriptor(libusb_device *dev) libusb_device_descriptor desc; if (libusb_get_device_descriptor(dev, &desc) < 0) - UHD_THROW_SITE_INFO("USB: failed to get device descriptor"); + throw std::runtime_error("USB: failed to get device descriptor"); uhd::usb_descriptor_t descriptor; @@ -217,12 +217,12 @@ uhd::usb_descriptors_t usb_control::get_device_list() uhd::usb_descriptors_t descriptors; if (libusb_init(NULL) < 0) - UHD_THROW_SITE_INFO("USB: failed to initialize libusb"); + throw std::runtime_error("USB: failed to initialize libusb"); ssize_t cnt = libusb_get_device_list(NULL, &list); if (cnt < 0) - UHD_THROW_SITE_INFO("USB: failed to get device list"); + throw std::runtime_error("USB: failed to get device list"); ssize_t i = 0; for (i = 0; i < cnt; i++) { diff --git a/host/lib/usrp/usrp1/CMakeLists.txt b/host/lib/usrp/usrp1/CMakeLists.txt index eb7bd4b06..229a4ce63 100644 --- a/host/lib/usrp/usrp1/CMakeLists.txt +++ b/host/lib/usrp/usrp1/CMakeLists.txt @@ -17,23 +17,41 @@ #This file will be included by cmake, use absolute paths! -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../firmware/fx2/include) +######################################################################## +# Conditionally configure the USRP1 support +######################################################################## +MESSAGE(STATUS "Configuring usrp1 support...") -LIBUHD_APPEND_SOURCES( - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/clock_ctrl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/clock_ctrl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/codec_ctrl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/codec_ctrl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/codec_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/dboard_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/dboard_iface.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/dsp_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/io_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/mboard_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_iface.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_iface.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_impl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_ctrl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_ctrl.hpp -) +IF(HAVE_USB_SUPPORT) + MESSAGE(STATUS "Has USB support - found") +ELSE(HAVE_USB_SUPPORT) + MESSAGE(STATUS "Has USB support - not found") +ENDIF(HAVE_USB_SUPPORT) + +#TODO check for usrp1 enable/disable option flag + +IF(HAVE_USB_SUPPORT) + MESSAGE(STATUS " Building usrp1 support.") + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/../firmware/fx2/include) + + LIBUHD_APPEND_SOURCES( + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/clock_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/clock_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/codec_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/codec_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/codec_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/dboard_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/dboard_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/dsp_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/io_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/mboard_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_iface.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_impl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_ctrl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp1/usrp1_ctrl.hpp + ) +ELSE(HAVE_USB_SUPPORT) + MESSAGE(STATUS " Skipping usrp1 support.") +ENDIF(HAVE_USB_SUPPORT) diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp index 866650c2c..d0576a769 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.cpp +++ b/host/lib/usrp/usrp1/codec_ctrl.cpp @@ -25,12 +25,12 @@ #include #include #include +#include #include #include #include #include #include -#include using namespace uhd; @@ -335,9 +335,9 @@ unsigned int usrp1_codec_ctrl_impl::compute_freq_control_word_9862( int v = (int) rint (fabs (target_freq) / master_freq * pow (2.0, 24.0)); *actual_freq = v * master_freq / pow (2.0, 24.0) * sign; - fprintf(stdout, - "compute_freq_control_word_9862: target = %g actual = %g delta = %g v = %8d\n", - target_freq, *actual_freq, *actual_freq - target_freq, v); + std::cout << boost::format( + "compute_freq_control_word_9862: target = %g actual = %g delta = %g v = %8d\n" + ) % target_freq % *actual_freq % (*actual_freq - target_freq) % v; return (unsigned int) v; } diff --git a/host/lib/usrp/usrp1/codec_ctrl.hpp b/host/lib/usrp/usrp1/codec_ctrl.hpp index 51e29345a..0605e3228 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.hpp +++ b/host/lib/usrp/usrp1/codec_ctrl.hpp @@ -19,6 +19,7 @@ #define INCLUDED_USRP1_CODEC_CTRL_HPP #include "usrp1_iface.hpp" +#include #include #include @@ -31,6 +32,9 @@ class usrp1_codec_ctrl : boost::noncopyable{ public: typedef boost::shared_ptr sptr; + static const uhd::gain_range_t tx_pga_gain_range; + static const uhd::gain_range_t rx_pga_gain_range; + /*! * Make a new clock control object. * \param iface the usrp1 iface object @@ -70,6 +74,18 @@ public: */ virtual void write_aux_dac(aux_dac_t which, float volts) = 0; + //! Set the TX PGA gain + virtual void set_tx_pga_gain(float gain) = 0; + + //! Get the TX PGA gain + virtual float get_tx_pga_gain(void) = 0; + + //! Set the RX PGA gain ('A' or 'B') + virtual void set_rx_pga_gain(float gain, char which) = 0; + + //! Get the RX PGA gain ('A' or 'B') + virtual float get_rx_pga_gain(char which) = 0; + virtual bool set_duc_freq(double freq) = 0; }; diff --git a/host/lib/usrp/usrp1/codec_impl.cpp b/host/lib/usrp/usrp1/codec_impl.cpp index 9253c06ba..7bf5631fb 100644 --- a/host/lib/usrp/usrp1/codec_impl.cpp +++ b/host/lib/usrp/usrp1/codec_impl.cpp @@ -16,6 +16,7 @@ // #include "usrp1_impl.hpp" +#include #include #include @@ -44,8 +45,7 @@ static const std::string ad9862_pga_gain_name = "ad9862 pga"; void usrp1_impl::rx_codec_get(const wax::obj &key_, wax::obj &val) { - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()) { @@ -62,17 +62,17 @@ void usrp1_impl::rx_codec_get(const wax::obj &key_, wax::obj &val) return; case CODEC_PROP_GAIN_RANGE: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = usrp1_codec_ctrl::rx_pga_gain_range; return; case CODEC_PROP_GAIN_I: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = _codec_ctrl->get_rx_pga_gain('A'); return; case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = _codec_ctrl->get_rx_pga_gain('B'); return; @@ -80,20 +80,19 @@ void usrp1_impl::rx_codec_get(const wax::obj &key_, wax::obj &val) } } -void usrp1_impl::rx_codec_set(const wax::obj &, const wax::obj &) +void usrp1_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val) { - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key switch(key.as()) { case CODEC_PROP_GAIN_I: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); _codec_ctrl->set_rx_pga_gain(val.as(), 'A'); return; case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); _codec_ctrl->set_rx_pga_gain(val.as(), 'B'); return; @@ -106,8 +105,7 @@ void usrp1_impl::rx_codec_set(const wax::obj &, const wax::obj &) **********************************************************************/ void usrp1_impl::tx_codec_get(const wax::obj &key_, wax::obj &val) { - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()) { @@ -124,13 +122,13 @@ void usrp1_impl::tx_codec_get(const wax::obj &key_, wax::obj &val) return; case CODEC_PROP_GAIN_RANGE: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = usrp1_codec_ctrl::tx_pga_gain_range; return; case CODEC_PROP_GAIN_I: //only one gain for I and Q case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); val = _codec_ctrl->get_tx_pga_gain(); return; @@ -138,16 +136,15 @@ void usrp1_impl::tx_codec_get(const wax::obj &key_, wax::obj &val) } } -void usrp1_impl::tx_codec_set(const wax::obj &, const wax::obj &) +void usrp1_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val) { - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key switch(key.as()){ case CODEC_PROP_GAIN_I: //only one gain for I and Q case CODEC_PROP_GAIN_Q: - UHD_ASSERT_THROW(name == ad9862_pga_gain_name); + UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); _codec_ctrl->set_tx_pga_gain(val.as()); return; diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp index 11ad3fe8a..ef6a1e67b 100644 --- a/host/lib/usrp/usrp1/dboard_iface.cpp +++ b/host/lib/usrp/usrp1/dboard_iface.cpp @@ -51,9 +51,12 @@ public: /* NOP */ } - std::string get_mboard_name() + special_props_t get_special_props() { - return "usrp1"; + special_props_t props; + props.soft_clock_divider = true; + props.mangle_i2c_addrs = false; //TODO true on side B + return props; } void write_aux_dac(unit_t, aux_dac_t, float); diff --git a/host/lib/usrp/usrp1/dboard_impl.cpp b/host/lib/usrp/usrp1/dboard_impl.cpp index 4f2836ea9..9df87432d 100644 --- a/host/lib/usrp/usrp1/dboard_impl.cpp +++ b/host/lib/usrp/usrp1/dboard_impl.cpp @@ -82,8 +82,7 @@ void usrp1_impl::dboard_init(void) **********************************************************************/ void usrp1_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val) { - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -92,7 +91,7 @@ void usrp1_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val) return; case DBOARD_PROP_SUBDEV: - val = _dboard_manager->get_rx_subdev(name); + val = _dboard_manager->get_rx_subdev(key.name); return; case DBOARD_PROP_SUBDEV_NAMES: @@ -112,7 +111,7 @@ void usrp1_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val) return; case DBOARD_PROP_GAIN_GROUP: - val = make_gain_group(_dboard_manager->get_rx_subdev(name), + val = make_gain_group(_dboard_manager->get_rx_subdev(key.name), _rx_codec_proxy->get_link()); return; @@ -142,8 +141,7 @@ void usrp1_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val) **********************************************************************/ void usrp1_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val) { - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -152,7 +150,7 @@ void usrp1_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val) return; case DBOARD_PROP_SUBDEV: - val = _dboard_manager->get_tx_subdev(name); + val = _dboard_manager->get_tx_subdev(key.name); return; case DBOARD_PROP_SUBDEV_NAMES: @@ -172,7 +170,7 @@ void usrp1_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val) return; case DBOARD_PROP_GAIN_GROUP: - val = make_gain_group(_dboard_manager->get_tx_subdev(name), + val = make_gain_group(_dboard_manager->get_tx_subdev(key.name), _tx_codec_proxy->get_link()); return; diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp index ee1ba305b..2514072e0 100644 --- a/host/lib/usrp/usrp1/mboard_impl.cpp +++ b/host/lib/usrp/usrp1/mboard_impl.cpp @@ -111,9 +111,7 @@ void usrp1_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd) **********************************************************************/ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val) { - wax::obj key; - std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -126,7 +124,7 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val) return; case MBOARD_PROP_RX_DBOARD: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _rx_dboard_proxy->get_link(); return; @@ -135,7 +133,7 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val) return; case MBOARD_PROP_TX_DBOARD: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _tx_dboard_proxy->get_link(); return; @@ -144,7 +142,7 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val) return; case MBOARD_PROP_RX_DSP: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _rx_ddc_proxy->get_link(); return; @@ -153,7 +151,7 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val) return; case MBOARD_PROP_TX_DSP: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _tx_duc_proxy->get_link(); return; diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 4cb286354..1435b981c 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -165,8 +165,7 @@ usrp1_impl::~usrp1_impl(void){ **********************************************************************/ void usrp1_impl::get(const wax::obj &key_, wax::obj &val) { - wax::obj key; std::string name; - boost::tie(key, name) = extract_named_prop(key_); + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as()){ @@ -175,7 +174,7 @@ void usrp1_impl::get(const wax::obj &key_, wax::obj &val) return; case DEVICE_PROP_MBOARD: - UHD_ASSERT_THROW(name == ""); + UHD_ASSERT_THROW(key.name == ""); val = _mboard_proxy->get_link(); return; -- cgit v1.2.3 From fe7df530e69834e974108d2c3e682f38b8a75524 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Thu, 26 Aug 2010 12:21:50 -0700 Subject: usrp1: Modifiy USB transport implementations to use new interface Common libusb1 code is consolidated in the libusb base file. --- host/lib/transport/CMakeLists.txt | 2 + host/lib/transport/libusb1_base.cpp | 118 +++++++++++++++++++ host/lib/transport/libusb1_base.hpp | 42 +++++++ host/lib/transport/libusb1_control.cpp | 170 ++------------------------- host/lib/transport/libusb1_device_handle.cpp | 114 ++++++++++++++++++ host/lib/transport/libusb1_zero_copy.cpp | 153 +++--------------------- host/lib/usrp/usrp1/usrp1_impl.cpp | 37 +++--- 7 files changed, 322 insertions(+), 314 deletions(-) create mode 100644 host/lib/transport/libusb1_base.cpp create mode 100644 host/lib/transport/libusb1_base.hpp create mode 100644 host/lib/transport/libusb1_device_handle.cpp (limited to 'host/lib/transport/libusb1_control.cpp') diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt index 627d2d806..753fd5e85 100644 --- a/host/lib/transport/CMakeLists.txt +++ b/host/lib/transport/CMakeLists.txt @@ -29,6 +29,8 @@ IF(LIBUSB_FOUND) LIBUHD_APPEND_SOURCES( ${CMAKE_SOURCE_DIR}/lib/transport/libusb1_control.cpp ${CMAKE_SOURCE_DIR}/lib/transport/libusb1_zero_copy.cpp + ${CMAKE_SOURCE_DIR}/lib/transport/libusb1_base.cpp + ${CMAKE_SOURCE_DIR}/lib/transport/libusb1_device_handle.cpp ) SET(HAVE_USB_SUPPORT TRUE) ENDIF(LIBUSB_FOUND) diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp new file mode 100644 index 000000000..6965de214 --- /dev/null +++ b/host/lib/transport/libusb1_base.cpp @@ -0,0 +1,118 @@ +// +// 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 . +// + +#include "libusb1_base.hpp" +#include + +using namespace uhd::transport; + +void libusb::init(libusb_context **ctx, int debug_level) +{ + if (libusb_init(ctx) < 0) + std::cerr << "error: libusb_init" << std::endl; + + libusb_set_debug(*ctx, debug_level); +} + + +libusb_device_handle *libusb::open_device(libusb_context *ctx, + usb_device_handle::sptr handle) +{ + libusb_device **dev_list; + libusb_device_handle *dev_handle; + + ssize_t dev_cnt = libusb_get_device_list(ctx, &dev_list); + + //find and open the receive device + for (ssize_t i = 0; i < dev_cnt; i++) { + libusb_device *dev = dev_list[i]; + + if (compare_device(dev, handle)) { + libusb_open(dev, &dev_handle); + break; + } + } + + libusb_free_device_list(dev_list, 0); + + return dev_handle; +} + + +bool libusb::compare_device(libusb_device *dev, + usb_device_handle::sptr handle) +{ + std::string serial = handle->get_serial(); + boost::uint16_t vendor_id = handle->get_vendor_id(); + boost::uint16_t product_id = handle->get_product_id(); + boost::uint8_t device_addr = handle->get_device_addr(); + + libusb_device_descriptor libusb_desc; + if (libusb_get_device_descriptor(dev, &libusb_desc) < 0) + return false; + if (serial != get_serial(dev)) + return false; + if (vendor_id != libusb_desc.idVendor) + return false; + if (product_id != libusb_desc.idProduct) + return false; + if (device_addr != libusb_get_device_address(dev)) + return false; + + return true; +} + + +bool libusb::open_interface(libusb_device_handle *dev_handle, + int interface) +{ + int ret = libusb_claim_interface(dev_handle, interface); + if (ret < 0) { + std::cerr << "error: libusb_claim_interface() " << ret << std::endl; + return false; + } + else { + return true; + } +} + + +std::string libusb::get_serial(libusb_device *dev) +{ + unsigned char buff[32]; + + libusb_device_descriptor desc; + if (libusb_get_device_descriptor(dev, &desc) < 0) + return ""; + + if (desc.iSerialNumber == 0) + return ""; + + //open the device because we have to + libusb_device_handle *dev_handle; + if (libusb_open(dev, &dev_handle) < 0) + return ""; + + if (libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, + buff, sizeof(buff)) < 0) { + return ""; + } + + libusb_close(dev_handle); + + return (char*) buff; +} diff --git a/host/lib/transport/libusb1_base.hpp b/host/lib/transport/libusb1_base.hpp new file mode 100644 index 000000000..ae560cd52 --- /dev/null +++ b/host/lib/transport/libusb1_base.hpp @@ -0,0 +1,42 @@ +// +// 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 . +// + +#ifndef INCLUDED_TRANSPORT_LIBUSB_HPP +#define INCLUDED_TRANSPORT_LIBUSB_HPP + +#include +#include +#include + +namespace uhd { namespace transport { + +namespace libusb { + void init(libusb_context **ctx, int debug_level); + + libusb_device_handle *open_device(libusb_context *ctx, + usb_device_handle::sptr handle); + + bool compare_device(libusb_device *dev, usb_device_handle::sptr handle); + + bool open_interface(libusb_device_handle *dev_handle, int interface); + + std::string get_serial(libusb_device *dev); +} + +}} //namespace + +#endif /* INCLUDED_TRANSPORT_LIBUSB_HPP */ diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp index c2f7060e8..8bf271256 100644 --- a/host/lib/transport/libusb1_control.cpp +++ b/host/lib/transport/libusb1_control.cpp @@ -15,24 +15,20 @@ // along with this program. If not, see . // -#include +#include "libusb1_base.hpp" #include -#include -#include -#include -#include using namespace uhd::transport; -static int libusb_debug_level = 0; -static int libusb_timeout = 0; +const int libusb_debug_level = 3; +const int libusb_timeout = 0; /*********************************************************************** * libusb-1.0 implementation of USB control transport **********************************************************************/ class libusb_control_impl : public usb_control { public: - libusb_control_impl(uhd::usb_descriptor_t descriptor); + libusb_control_impl(usb_device_handle::sptr handle); ~libusb_control_impl(); size_t submit(boost::uint8_t request_type, @@ -42,34 +38,19 @@ public: unsigned char *buff, boost::uint16_t length); - static uhd::usb_descriptor_t create_descriptor(libusb_device *dev); - static std::string get_serial(libusb_device *dev); - private: - uhd::usb_descriptor_t _descriptor; - libusb_context *_ctx; libusb_device_handle *_dev_handle; - - bool open_device(); - bool open_interface(); - bool compare_device(libusb_device *dev, uhd::usb_descriptor_t descriptor); }; -libusb_control_impl::libusb_control_impl(uhd::usb_descriptor_t descriptor) - : _descriptor(descriptor), _ctx(NULL), _dev_handle(NULL) +libusb_control_impl::libusb_control_impl(usb_device_handle::sptr handle) { - if (libusb_init(&_ctx) < 0) - throw std::runtime_error("USB: failed to initialize libusb"); + libusb::init(&_ctx, libusb_debug_level); - libusb_set_debug(_ctx, libusb_debug_level); + _dev_handle = libusb::open_device(_ctx, handle); - if (!open_device()) - throw std::runtime_error("USB: failed to open device"); - - if (!open_interface()) - throw std::runtime_error("USB: failed to open device interface"); + libusb::open_interface(_dev_handle, 0); } @@ -80,111 +61,6 @@ libusb_control_impl::~libusb_control_impl() } -uhd::usb_descriptor_t libusb_control_impl::create_descriptor(libusb_device *dev) -{ - libusb_device_descriptor desc; - - if (libusb_get_device_descriptor(dev, &desc) < 0) - throw std::runtime_error("USB: failed to get device descriptor"); - - uhd::usb_descriptor_t descriptor; - - descriptor.serial = get_serial(dev); - descriptor.product_id = desc.idProduct; - descriptor.vendor_id = desc.idVendor; - descriptor.device_addr = libusb_get_device_address(dev); - - return descriptor; -} - - -std::string libusb_control_impl::get_serial(libusb_device *dev) -{ - unsigned char buff[32]; - - libusb_device_descriptor desc; - if (libusb_get_device_descriptor(dev, &desc) < 0) - return ""; - - if (desc.iSerialNumber == 0) - return ""; - - //open the device because we have to - libusb_device_handle *dev_handle; - if (libusb_open(dev, &dev_handle) < 0) - return ""; - - if (libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, - buff, sizeof(buff)) < 0) { - return ""; - } - - libusb_close(dev_handle); - - return (char*) buff; -} - - -bool libusb_control_impl::open_device() -{ - libusb_device **list; - libusb_device *dev; - - ssize_t cnt = libusb_get_device_list(_ctx, &list); - - if (cnt < 0) - return cnt; - - ssize_t i = 0; - for (i = 0; i < cnt; i++) { - dev = list[i]; - if (compare_device(dev, _descriptor)) - goto found; - } - return false; - -found: - int ret; - if ((ret = libusb_open(dev, &_dev_handle)) < 0) - return false; - else - return true; -} - - -bool libusb_control_impl::compare_device(libusb_device *dev, - uhd::usb_descriptor_t descriptor) -{ - std::string serial = descriptor.serial; - boost::uint16_t vendor_id = descriptor.vendor_id; - boost::uint16_t product_id = descriptor.product_id; - boost::uint8_t device_addr = descriptor.device_addr; - - libusb_device_descriptor libusb_desc; - if (libusb_get_device_descriptor(dev, &libusb_desc) < 0) - return false; - if (serial != get_serial(dev)) - return false; - if (vendor_id != libusb_desc.idVendor) - return false; - if (product_id != libusb_desc.idProduct) - return false; - if (device_addr != libusb_get_device_address(dev)) - return false; - - return true; -} - - -bool libusb_control_impl::open_interface() -{ - if (libusb_claim_interface(_dev_handle, 0) < 0) - return false; - else - return true; -} - - size_t libusb_control_impl::submit(boost::uint8_t request_type, boost::uint8_t request, boost::uint16_t value, @@ -206,33 +82,7 @@ size_t libusb_control_impl::submit(boost::uint8_t request_type, /*********************************************************************** * USB control public make functions **********************************************************************/ -usb_control::sptr usb_control::make(uhd::usb_descriptor_t descriptor) +usb_control::sptr usb_control::make(usb_device_handle::sptr handle) { - return sptr(new libusb_control_impl(descriptor)); + return sptr(new libusb_control_impl(handle)); } - -uhd::usb_descriptors_t usb_control::get_device_list() -{ - libusb_device **list; - uhd::usb_descriptors_t descriptors; - - if (libusb_init(NULL) < 0) - throw std::runtime_error("USB: failed to initialize libusb"); - - ssize_t cnt = libusb_get_device_list(NULL, &list); - - if (cnt < 0) - throw std::runtime_error("USB: failed to get device list"); - - ssize_t i = 0; - for (i = 0; i < cnt; i++) { - libusb_device *dev = list[i]; - descriptors.push_back(libusb_control_impl::create_descriptor(dev)); - } - - libusb_free_device_list(list, 0); - libusb_exit(NULL); - return descriptors; -} - - diff --git a/host/lib/transport/libusb1_device_handle.cpp b/host/lib/transport/libusb1_device_handle.cpp new file mode 100644 index 000000000..f80090f15 --- /dev/null +++ b/host/lib/transport/libusb1_device_handle.cpp @@ -0,0 +1,114 @@ +// +// 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 . +// + +#include "libusb1_base.hpp" +#include + +using namespace uhd::transport; + +const int libusb_debug_level = 3; + +class libusb1_device_handle_impl : public usb_device_handle { +public: + libusb1_device_handle_impl(std::string serial, + boost::uint32_t product_id, + boost::uint32_t vendor_id, + boost::uint32_t device_addr) + : _serial(serial), _product_id(product_id), + _vendor_id(vendor_id), _device_addr(device_addr) + { + /* NOP */ + } + + ~libusb1_device_handle_impl() + { + /* NOP */ + } + + std::string get_serial() const + { + return _serial; + } + + boost::uint16_t get_vendor_id() const + { + return _vendor_id; + } + + + boost::uint16_t get_product_id() const + { + return _product_id; + } + + boost::uint16_t get_device_addr() const + { + return _device_addr; + } + +private: + std::string _serial; + boost::uint32_t _product_id; + boost::uint32_t _vendor_id; + boost::uint32_t _device_addr; +}; + + +usb_device_handle::sptr make_usb_device_handle(libusb_device *dev) +{ + libusb_device_descriptor desc; + + if (libusb_get_device_descriptor(dev, &desc) < 0) { + UHD_ASSERT_THROW("USB: failed to get device descriptor"); + } + + std::string serial = libusb::get_serial(dev); + boost::uint32_t product_id = desc.idProduct; + boost::uint32_t vendor_id = desc.idVendor; + boost::uint32_t device_addr = libusb_get_device_address(dev); + + return usb_device_handle::sptr(new libusb1_device_handle_impl( + serial, + product_id, + vendor_id, + device_addr)); +} + + +std::vector usb_device_handle::get_device_list() +{ + libusb_context *ctx = NULL; + libusb_device **list; + std::vector device_list; + + libusb::init(&ctx, libusb_debug_level); + + ssize_t cnt = libusb_get_device_list(ctx, &list); + + if (cnt < 0) + throw std::runtime_error("USB: enumeration failed"); + + ssize_t i = 0; + for (i = 0; i < cnt; i++) { + libusb_device *dev = list[i]; + device_list.push_back(make_usb_device_handle(dev)); + } + + libusb_free_device_list(list, 0); + libusb_exit(ctx); + return device_list; +} diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 39617e4dd..55aa10cbb 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -15,10 +15,9 @@ // along with this program. If not, see . // - +#include "libusb1_base.hpp" #include #include -#include #include #include #include @@ -26,7 +25,8 @@ using namespace uhd::transport; -static int libusb_debug_level = 3; +const int libusb_debug_level = 3; +const int libusb_timeout = 0; /*********************************************************************** * Helper functions @@ -347,7 +347,7 @@ void usb_endpoint::print_transfer_status(libusb_transfer *lut) std::cerr << "USB: transfer timed out" << std::endl; break; case LIBUSB_TRANSFER_STALL: - std::cerr << "USB: halt condition detected (endpoint stalled)" << std::endl; + std::cerr << "USB: halt condition detected (stalled)" << std::endl; break; case LIBUSB_TRANSFER_ERROR: std::cerr << "USB: transfer failed" << std::endl; @@ -606,26 +606,17 @@ private: libusb_device_handle *_rx_dev_handle; libusb_device_handle *_tx_dev_handle; - int _rx_endpoint; - int _tx_endpoint; - size_t _recv_buff_size; size_t _send_buff_size; size_t _num_frames; - bool open_device(uhd::usb_descriptor_t descriptor); - bool open_interface(libusb_device_handle *dev_handle, int interface); - bool compare_device(libusb_device *dev, uhd::usb_descriptor_t descriptor); - - std::string get_serial(libusb_device *dev); - public: typedef boost::shared_ptr sptr; /* * Structors */ - libusb_zero_copy_impl(uhd::usb_descriptor_t descriptor, + libusb_zero_copy_impl(usb_device_handle::sptr handle, unsigned int rx_endpoint, unsigned int tx_endpoint, size_t recv_buff_size, @@ -641,7 +632,7 @@ public: }; -libusb_zero_copy_impl::libusb_zero_copy_impl(uhd::usb_descriptor_t descriptor, +libusb_zero_copy_impl::libusb_zero_copy_impl(usb_device_handle::sptr handle, unsigned int rx_endpoint, unsigned int tx_endpoint, size_t buff_size, @@ -650,19 +641,16 @@ libusb_zero_copy_impl::libusb_zero_copy_impl(uhd::usb_descriptor_t descriptor, _recv_buff_size(block_size), _send_buff_size(block_size), _num_frames(buff_size / block_size) { - if (libusb_init(&_rx_ctx) < 0) - std::cerr << "error: libusb_init" << std::endl; + libusb::init(&_rx_ctx, libusb_debug_level); + libusb::init(&_tx_ctx, libusb_debug_level); - if (libusb_init(&_tx_ctx) < 0) - std::cerr << "error: libusb_init" << std::endl; + UHD_ASSERT_THROW((_rx_ctx != NULL) && (_tx_ctx != NULL)); - libusb_set_debug(_rx_ctx, libusb_debug_level); - libusb_set_debug(_tx_ctx, libusb_debug_level); + _rx_dev_handle = libusb::open_device(_rx_ctx, handle); + _tx_dev_handle = libusb::open_device(_tx_ctx, handle); - open_device(descriptor); - - open_interface(_rx_dev_handle, 2); - open_interface(_tx_dev_handle, 1); + libusb::open_interface(_rx_dev_handle, 2); + libusb::open_interface(_tx_dev_handle, 1); _rx_ep = new usb_endpoint(_rx_dev_handle, _rx_ctx, @@ -693,117 +681,6 @@ libusb_zero_copy_impl::~libusb_zero_copy_impl() } -bool libusb_zero_copy_impl::open_device(uhd::usb_descriptor_t descriptor) -{ - libusb_device **rx_list; - libusb_device **tx_list; - - bool rx_found = false; - bool tx_found = false; - - ssize_t rx_cnt = libusb_get_device_list(_rx_ctx, &rx_list); - ssize_t tx_cnt = libusb_get_device_list(_tx_ctx, &tx_list); - - if ((rx_cnt < 0) | (tx_cnt < 0) | (rx_cnt != tx_cnt)) - return false; - - //find and open the receive device - for (ssize_t i = 0; i < rx_cnt; i++) { - libusb_device *dev = rx_list[i]; - - if (compare_device(dev, descriptor)) { - libusb_open(dev, &_rx_dev_handle); - rx_found = true; - break; - } - } - - //find and open the transmit device - for (ssize_t i = 0; i < tx_cnt; i++) { - libusb_device *dev = tx_list[i]; - - if (compare_device(dev, descriptor)) { - libusb_open(dev, &_tx_dev_handle); - tx_found = true; - } - } - - libusb_free_device_list(rx_list, 0); - libusb_free_device_list(tx_list, 0); - - if (tx_found && rx_found) - return true; - else - return false; -} - -bool libusb_zero_copy_impl::compare_device(libusb_device *dev, - uhd::usb_descriptor_t descriptor) -{ - std::string serial = descriptor.serial; - boost::uint16_t vendor_id = descriptor.vendor_id; - boost::uint16_t product_id = descriptor.product_id; - boost::uint8_t device_addr = descriptor.device_addr; - - libusb_device_descriptor desc; - libusb_get_device_descriptor(dev, &desc); - - if (serial.compare(get_serial(dev))) - return false; - if (vendor_id != desc.idVendor) - return false; - if (product_id != desc.idProduct) - return false; - if (device_addr != libusb_get_device_address(dev)) - return false; - - return true; -} - -bool libusb_zero_copy_impl::open_interface(libusb_device_handle *dev_handle, - int interface) -{ - int ret = libusb_claim_interface(dev_handle, interface); - if (ret < 0) { - std::cerr << "error: libusb_claim_interface() " << ret << std::endl; - return false; - } - else { - return true; - } -} - -std::string libusb_zero_copy_impl::get_serial(libusb_device *dev) -{ - unsigned char buff[32]; - - libusb_device_descriptor desc; - if (libusb_get_device_descriptor(dev, &desc) < 0) { - std::cerr << "error: libusb_get_device_descriptor()" << std::endl; - return ""; - } - - if (desc.iSerialNumber == 0) - return ""; - - //open the device because we have to - libusb_device_handle *dev_handle; - if (libusb_open(dev, &dev_handle) < 0) { - return ""; - } - - if (libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, - buff, sizeof(buff)) < 0) { - std::cerr << "error: libusb_get_string_descriptor_ascii()" << std::endl; - return ""; - } - - libusb_close(dev_handle); - - return (char*) buff; -} - - managed_recv_buffer::sptr libusb_zero_copy_impl::get_recv_buff() { libusb_transfer *lut = _rx_ep->get_completed_transfer(); @@ -836,14 +713,14 @@ managed_send_buffer::sptr libusb_zero_copy_impl::get_send_buff() /*********************************************************************** * USB zero_copy make functions **********************************************************************/ -usb_zero_copy::sptr usb_zero_copy::make(uhd::usb_descriptor_t descriptor, +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) { - return sptr(new libusb_zero_copy_impl(descriptor, + return sptr(new libusb_zero_copy_impl(handle, rx_endpoint, tx_endpoint, buff_size, diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index ee6fe6e99..a4effb907 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -48,13 +48,15 @@ static device_addrs_t usrp1_find(const device_addr_t &hint) if (hint.has_key("type") and hint["type"] != "usrp1") return usrp1_addrs; //see what we got on the USB bus - usb_descriptors_t usb_descriptors; - usb_descriptors = usb_control::get_device_list(); + std::vector device_list = + usb_device_handle::get_device_list(); //find the usrps and load firmware - BOOST_FOREACH(usb_descriptor_t desc, usb_descriptors) { - if (desc.vendor_id == 0xfffe && desc.product_id == 0x0002) { - usb_control::sptr ctrl_transport = usb_control::make(desc); + BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { + if (handle->get_vendor_id() == 0xfffe && + handle->get_product_id() == 0x0002) { + + usb_control::sptr ctrl_transport = usb_control::make(handle); usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport); usrp_ctrl->usrp_load_firmware(filename); } @@ -64,13 +66,15 @@ static device_addrs_t usrp1_find(const device_addr_t &hint) sleep(1); //get descriptors again with serial number - usb_descriptors = usb_control::get_device_list(); + device_list = usb_device_handle::get_device_list(); + + BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { + if (handle->get_vendor_id() == 0xfffe && + handle->get_product_id() == 0x0002) { - BOOST_FOREACH(usb_descriptor_t desc, usb_descriptors) { - if (desc.vendor_id == 0xfffe && desc.product_id == 0x0002) { device_addr_t new_addr; new_addr["type"] = "usrp1"; - new_addr["serial"] = desc.serial; + new_addr["serial"] = handle->get_serial(); usrp1_addrs.push_back(new_addr); } } @@ -93,22 +97,23 @@ static device::sptr usrp1_make(const device_addr_t &device_addr) std::cout << "Make usrp1 with " << filename << std::endl; //try to match the given device address with something on the USB bus - usb_descriptors_t usb_descriptors; - usb_descriptors = usb_control::get_device_list(); + std::vector device_list = + usb_device_handle::get_device_list(); //create data and control transports usb_zero_copy::sptr data_transport; usrp_ctrl::sptr usrp_ctrl; - BOOST_FOREACH(usb_descriptor_t desc, usb_descriptors) { - if (desc.serial == device_addr["serial"] - && desc.vendor_id == 0xfffe && desc.product_id == 0x0002) { + BOOST_FOREACH(usb_device_handle::sptr handle, device_list) { + if (handle->get_vendor_id() == 0xfffe && + handle->get_product_id() == 0x0002 && + handle->get_serial() == device_addr["serial"]) { - usb_control::sptr ctrl_transport = usb_control::make(desc); + usb_control::sptr ctrl_transport = usb_control::make(handle); usrp_ctrl = usrp_ctrl::make(ctrl_transport); usrp_ctrl->usrp_load_fpga(filename); - data_transport = usb_zero_copy::make(desc, // identifier + data_transport = usb_zero_copy::make(handle, // identifier 6, // IN endpoint 2, // OUT endpoint 2 * (1 << 20), // buffer size -- cgit v1.2.3 From 72fc20bc8ba4cb636a04de78210aac483f4ffaf3 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Fri, 27 Aug 2010 13:46:22 -0700 Subject: usrp1: Disable default debug output for libusb implementations --- host/lib/transport/libusb1_control.cpp | 2 +- host/lib/transport/libusb1_device_handle.cpp | 2 +- host/lib/transport/libusb1_zero_copy.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'host/lib/transport/libusb1_control.cpp') diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp index 8bf271256..4b827c350 100644 --- a/host/lib/transport/libusb1_control.cpp +++ b/host/lib/transport/libusb1_control.cpp @@ -20,7 +20,7 @@ using namespace uhd::transport; -const int libusb_debug_level = 3; +const int libusb_debug_level = 0; const int libusb_timeout = 0; /*********************************************************************** diff --git a/host/lib/transport/libusb1_device_handle.cpp b/host/lib/transport/libusb1_device_handle.cpp index 4885099eb..3476fdc4e 100644 --- a/host/lib/transport/libusb1_device_handle.cpp +++ b/host/lib/transport/libusb1_device_handle.cpp @@ -20,7 +20,7 @@ using namespace uhd::transport; -const int libusb_debug_level = 3; +const int libusb_debug_level = 0; class libusb1_device_handle_impl : public usb_device_handle { public: diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 55aa10cbb..2149625f9 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -25,7 +25,7 @@ using namespace uhd::transport; -const int libusb_debug_level = 3; +const int libusb_debug_level = 0; const int libusb_timeout = 0; /*********************************************************************** -- cgit v1.2.3 From ad55e25aeb273fb7278c6d5175cd0df01fc90924 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Fri, 27 Aug 2010 23:46:16 -0700 Subject: usrp1: Additional comments on libusb transport implemenation --- host/lib/transport/libusb1_base.cpp | 12 ++++++ host/lib/transport/libusb1_base.hpp | 60 ++++++++++++++++++++++++++++ host/lib/transport/libusb1_control.cpp | 7 ++++ host/lib/transport/libusb1_device_handle.cpp | 3 ++ host/lib/transport/libusb1_zero_copy.cpp | 8 ++-- 5 files changed, 87 insertions(+), 3 deletions(-) (limited to 'host/lib/transport/libusb1_control.cpp') diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp index 493d4eff3..92dcd969f 100644 --- a/host/lib/transport/libusb1_base.cpp +++ b/host/lib/transport/libusb1_base.cpp @@ -21,6 +21,15 @@ using namespace uhd::transport; +/********************************************************** + * Helper Methods + **********************************************************/ +/* + * Check for FSF device + * Compare the device's descriptor Vendor ID + * \param dev pointer to libusb_device + * \return true if Vendor ID matches 0xfffe + */ bool check_fsf_device(libusb_device *dev) { libusb_device_descriptor desc; @@ -32,6 +41,9 @@ bool check_fsf_device(libusb_device *dev) return desc.idVendor == 0xfffe; } +/********************************************************** + * libusb namespace + **********************************************************/ void libusb::init(libusb_context **ctx, int debug_level) { if (libusb_init(ctx) < 0) diff --git a/host/lib/transport/libusb1_base.hpp b/host/lib/transport/libusb1_base.hpp index 708a42c73..442f89ded 100644 --- a/host/lib/transport/libusb1_base.hpp +++ b/host/lib/transport/libusb1_base.hpp @@ -25,17 +25,77 @@ namespace uhd { namespace transport { namespace libusb { + /* + * Initialize libusb and set debug level + * Takes a pointer to context pointer because that's + * how libusb rolls. Debug levels. + * + * Level 0: no messages ever printed by the library (default) + * Level 1: error messages are printed to stderr + * Level 2: warning and error messages are printed to stderr + * Level 3: informational messages are printed to stdout, warning + * and error messages are printed to stderr + * + * \param ctx pointer to context pointer + * \param debug_level + */ void init(libusb_context **ctx, int debug_level); + /* + * Get a list of Free Software Foundation devices (Vendor ID 0xfffe) + * As opposed to the public USB device handle interface, which returns + * generic identifiers, this call returns device pointers speficic + * to libusb. + * \param ctx the libusb context used for init + * \return a vector of libusb devices + */ std::vector get_fsf_device_list(libusb_context *ctx); + /* + * Open the device specified by a generic handle + * Find the libusb_device cooresponding to the generic handle + * and open it for I/O, which returns a libusb_device_handle + * ready for an interface + * \param ctx the libusb context used for init + * \return a libusb_device_handle ready for action + */ libusb_device_handle *open_device(libusb_context *ctx, usb_device_handle::sptr handle); + /* + * Compare a libusb device with a generic handle + * Check the descriptors and open the device to check the + * serial number string. Compare values against the given + * handle. The libusb context is already implied in the + * libusb_device. + * \param dev a libusb_device pointer + * \param handle a generic handle specifier + * \return true if handle and device match, false otherwise + */ bool compare_device(libusb_device *dev, usb_device_handle::sptr handle); + /* + * Open an interface to the device + * This is a logical operation for operating system housekeeping as + * nothing is sent over the bus. The interface much correspond + * to the USB device descriptors. + * \param dev_handle libusb handle to an opened device + * \param interface integer of the interface to use + * \return true on success, false on error + */ bool open_interface(libusb_device_handle *dev_handle, int interface); + /* + * Get serial number + * The standard USB device descriptor contains an index to an + * actual serial number string descriptor. The index is readily + * readble, but the string descriptor requires probing the device. + * Because this call attempts to open the device, it may not + * succeed because not all USB devices are readily opened. + * The default language is used for the request (English). + * \param dev a libusb_device pointer + * \return string serial number or 0 on error or unavailablity + */ std::string get_serial(libusb_device *dev); } diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp index 4b827c350..3531128b2 100644 --- a/host/lib/transport/libusb1_control.cpp +++ b/host/lib/transport/libusb1_control.cpp @@ -48,8 +48,15 @@ libusb_control_impl::libusb_control_impl(usb_device_handle::sptr handle) { libusb::init(&_ctx, libusb_debug_level); + // Find and open the libusb_device corresponding to the + // given handle and return the libusb_device_handle + // that can be used for I/O purposes. _dev_handle = libusb::open_device(_ctx, handle); + // Open USB interfaces for control using magic value + // IN interface: 2 + // OUT interface: 1 + // Control interface: 0 libusb::open_interface(_dev_handle, 0); } diff --git a/host/lib/transport/libusb1_device_handle.cpp b/host/lib/transport/libusb1_device_handle.cpp index 3476fdc4e..5d9d8faf0 100644 --- a/host/lib/transport/libusb1_device_handle.cpp +++ b/host/lib/transport/libusb1_device_handle.cpp @@ -22,6 +22,9 @@ using namespace uhd::transport; const int libusb_debug_level = 0; +/**************************************************************** + * libusb USB device handle implementation class + ***************************************************************/ class libusb1_device_handle_impl : public usb_device_handle { public: libusb1_device_handle_impl(std::string serial, diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp index 518b8baf0..b890a87f9 100644 --- a/host/lib/transport/libusb1_zero_copy.cpp +++ b/host/lib/transport/libusb1_zero_copy.cpp @@ -30,9 +30,11 @@ const int libusb_timeout = 0; /*********************************************************************** * Helper functions - * - * Print to stdout the values of a libusb_transfer struct ***********************************************************************/ +/* + * Print the values of a libusb_transfer struct + * http://libusb.sourceforge.net/api-1.0/structlibusb__transfer.html + */ void pp_transfer(libusb_transfer *lut) { std::cout << "Libusb transfer" << std::endl; @@ -46,7 +48,7 @@ void pp_transfer(libusb_transfer *lut) } /*********************************************************************** - * USB asynchronous phony zero_copy endpoint + * USB asynchronous zero_copy endpoint * This endpoint implementation provides asynchronous I/O to libusb-1.0 * devices. Each endpoint is directional and two can be combined to * create a bidirectional interface. It is a zero copy implementation -- cgit v1.2.3