diff options
Diffstat (limited to 'usrp/host')
-rw-r--r-- | usrp/host/apps/test_usrp_standard_rx.cc | 1 | ||||
-rw-r--r-- | usrp/host/apps/test_usrp_standard_tx.cc | 1 | ||||
-rw-r--r-- | usrp/host/apps/usrp_cal_dc_offset.cc | 1 | ||||
-rw-r--r-- | usrp/host/apps/usrper.cc | 6 | ||||
-rw-r--r-- | usrp/host/include/usrp/usrp_basic.h | 20 | ||||
-rw-r--r-- | usrp/host/include/usrp/usrp_prims.h | 90 | ||||
-rw-r--r-- | usrp/host/lib/Makefile.am | 13 | ||||
-rw-r--r-- | usrp/host/lib/fusb.cc | 2 | ||||
-rw-r--r-- | usrp/host/lib/fusb.h | 10 | ||||
-rw-r--r-- | usrp/host/lib/fusb_libusb1.cc | 679 | ||||
-rw-r--r-- | usrp/host/lib/fusb_libusb1.h | 127 | ||||
-rw-r--r-- | usrp/host/lib/fusb_sysconfig_libusb1.cc | 49 | ||||
-rw-r--r-- | usrp/host/lib/usrp_basic.cc | 42 | ||||
-rw-r--r-- | usrp/host/lib/usrp_prims.cc | 310 | ||||
-rw-r--r-- | usrp/host/swig/usrp_prims.i | 78 |
15 files changed, 1135 insertions, 294 deletions
diff --git a/usrp/host/apps/test_usrp_standard_rx.cc b/usrp/host/apps/test_usrp_standard_rx.cc index f6897ed23..4098decda 100644 --- a/usrp/host/apps/test_usrp_standard_rx.cc +++ b/usrp/host/apps/test_usrp_standard_rx.cc @@ -28,7 +28,6 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <usb.h> /* needed for usb functions */ #include <getopt.h> #include <assert.h> #include <math.h> diff --git a/usrp/host/apps/test_usrp_standard_tx.cc b/usrp/host/apps/test_usrp_standard_tx.cc index 3f8817373..cc9f9edfc 100644 --- a/usrp/host/apps/test_usrp_standard_tx.cc +++ b/usrp/host/apps/test_usrp_standard_tx.cc @@ -29,7 +29,6 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <usb.h> /* needed for usb functions */ #include <getopt.h> #include <assert.h> #include <math.h> diff --git a/usrp/host/apps/usrp_cal_dc_offset.cc b/usrp/host/apps/usrp_cal_dc_offset.cc index 22d427dff..5f708d672 100644 --- a/usrp/host/apps/usrp_cal_dc_offset.cc +++ b/usrp/host/apps/usrp_cal_dc_offset.cc @@ -28,7 +28,6 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <usb.h> /* needed for usb functions */ #include <getopt.h> #include <assert.h> #include <math.h> diff --git a/usrp/host/apps/usrper.cc b/usrp/host/apps/usrper.cc index fe8ff90d2..1c4beb713 100644 --- a/usrp/host/apps/usrper.cc +++ b/usrp/host/apps/usrper.cc @@ -23,7 +23,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <usb.h> /* needed for usb functions */ +#include <libusb-1.0/libusb.h> /* needed for usb functions */ #include <getopt.h> #include <assert.h> #include <errno.h> @@ -194,7 +194,7 @@ main (int argc, char **argv) usrp_one_time_init (); - struct usb_device *udev = usrp_find_device (which_board, fx2_ok_p); + struct libusb_device *udev = usrp_find_device (which_board, fx2_ok_p); if (udev == 0){ fprintf (stderr, "%s: failed to find usrp[%d]\n", prog_name, which_board); exit (1); @@ -208,7 +208,7 @@ main (int argc, char **argv) fprintf (stderr, "%s: found unconfigured FX2; needs firmware.\n", prog_name); } - struct usb_dev_handle *udh = usrp_open_cmd_interface (udev); + struct libusb_device_handle *udh = usrp_open_cmd_interface (udev); if (udh == 0){ fprintf (stderr, "%s: failed to open_cmd_interface\n", prog_name); exit (1); diff --git a/usrp/host/include/usrp/usrp_basic.h b/usrp/host/include/usrp/usrp_basic.h index fbbf49d57..c79908a86 100644 --- a/usrp/host/include/usrp/usrp_basic.h +++ b/usrp/host/include/usrp/usrp_basic.h @@ -46,7 +46,7 @@ #include <boost/utility.hpp> #include <usrp/usrp_subdev_spec.h> -struct usb_dev_handle; +struct libusb_device_handle; class fusb_devhandle; class fusb_ephandle; @@ -65,16 +65,16 @@ protected: void shutdown_daughterboards(); protected: - struct usb_dev_handle *d_udh; - int d_usb_data_rate; // bytes/sec - int d_bytes_per_poll; // how often to poll for overruns - bool d_verbose; - long d_fpga_master_clock_freq; + struct libusb_device_handle *d_udh; + int d_usb_data_rate; // bytes/sec + int d_bytes_per_poll; // how often to poll for overruns + bool d_verbose; + long d_fpga_master_clock_freq; - static const int MAX_REGS = 128; - unsigned int d_fpga_shadows[MAX_REGS]; + static const int MAX_REGS = 128; + unsigned int d_fpga_shadows[MAX_REGS]; - int d_dbid[2]; // daughterboard ID's (side A, side B) + int d_dbid[2]; // daughterboard ID's (side A, side B) /*! * Shared pointers to subclasses of db_base. @@ -91,7 +91,7 @@ protected: usrp_basic (int which_board, - struct usb_dev_handle *open_interface (struct usb_device *dev), + struct libusb_device_handle *open_interface (struct libusb_device *dev), const std::string fpga_filename = "", const std::string firmware_filename = ""); diff --git a/usrp/host/include/usrp/usrp_prims.h b/usrp/host/include/usrp/usrp_prims.h index aa0887050..df410b408 100644 --- a/usrp/host/include/usrp/usrp_prims.h +++ b/usrp/host/include/usrp/usrp_prims.h @@ -41,8 +41,8 @@ static const int USRP_HASH_SIZE = 16; enum usrp_load_status_t { ULS_ERROR = 0, ULS_OK, ULS_ALREADY_LOADED }; -struct usb_dev_handle; -struct usb_device; +struct libusb_device_handle; +struct libusb_device; /*! * \brief initialize libusb; probe busses and devices. @@ -65,21 +65,21 @@ void usrp_rescan (); * configured USRP (firmware loaded) * unconfigured Cypress FX2 (only if fx2_ok_p is true) */ -struct usb_device *usrp_find_device (int nth, bool fx2_ok_p = false); +struct libusb_device *usrp_find_device (int nth, bool fx2_ok_p = false); -bool usrp_usrp_p (struct usb_device *q); //< is this a USRP -bool usrp_usrp0_p (struct usb_device *q); //< is this a USRP Rev 0 -bool usrp_usrp1_p (struct usb_device *q); //< is this a USRP Rev 1 -bool usrp_usrp2_p (struct usb_device *q); //< is this a USRP Rev 2 -int usrp_hw_rev (struct usb_device *q); //< return h/w rev code +bool usrp_usrp_p (struct libusb_device *q); //< is this a USRP +bool usrp_usrp0_p (struct libusb_device *q); //< is this a USRP Rev 0 +bool usrp_usrp1_p (struct libusb_device *q); //< is this a USRP Rev 1 +bool usrp_usrp2_p (struct libusb_device *q); //< is this a USRP Rev 2 +int usrp_hw_rev (struct libusb_device *q); //< return h/w rev code -bool usrp_fx2_p (struct usb_device *q); //< is this an unconfigured Cypress FX2 +bool usrp_fx2_p (struct libusb_device *q); //< is this an unconfigured Cypress FX2 -bool usrp_unconfigured_usrp_p (struct usb_device *q); //< some kind of unconfigured USRP -bool usrp_configured_usrp_p (struct usb_device *q); //< some kind of configured USRP +bool usrp_unconfigured_usrp_p (struct libusb_device *q); //< some kind of unconfigured USRP +bool usrp_configured_usrp_p (struct libusb_device *q); //< some kind of configured USRP /*! - * \brief given a usb_device return an instance of the appropriate usb_dev_handle + * \brief given a libusb_device return an instance of the appropriate libusb_device_handle * * These routines claim the specified interface and select the * correct alternate interface. (USB nomenclature is totally screwed!) @@ -87,14 +87,14 @@ bool usrp_configured_usrp_p (struct usb_device *q); //< some kind of configured * If interface can't be opened, or is already claimed by some other * process, 0 is returned. */ -struct usb_dev_handle *usrp_open_cmd_interface (struct usb_device *dev); -struct usb_dev_handle *usrp_open_rx_interface (struct usb_device *dev); -struct usb_dev_handle *usrp_open_tx_interface (struct usb_device *dev); +struct libusb_device_handle *usrp_open_cmd_interface (struct libusb_device *dev); +struct libusb_device_handle *usrp_open_rx_interface (struct libusb_device *dev); +struct libusb_device_handle *usrp_open_tx_interface (struct libusb_device *dev); /*! * \brief close interface. */ -bool usrp_close_interface (struct usb_dev_handle *udh); +bool usrp_close_interface (struct libusb_device_handle *udh); /*! * \brief load intel hex format file into USRP/Cypress FX2 (8051). @@ -106,7 +106,7 @@ bool usrp_close_interface (struct usb_dev_handle *udh); */ usrp_load_status_t -usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, bool force); +usrp_load_firmware (struct libusb_device_handle *udh, const char *filename, bool force); /*! * \brief load intel hex format file into USRP FX2 (8051). @@ -125,7 +125,7 @@ usrp_load_firmware_nth (int nth, const char *filename, bool force); * \brief load fpga configuration bitstream */ usrp_load_status_t -usrp_load_fpga (struct usb_dev_handle *udh, const char *filename, bool force); +usrp_load_fpga (struct libusb_device_handle *udh, const char *filename, bool force); /*! * \brief load the regular firmware and fpga bitstream in the Nth USRP. @@ -140,54 +140,54 @@ bool usrp_load_standard_bits (int nth, bool force, * \brief copy the given \p hash into the USRP hash slot \p which. * The usrp implements two hash slots, 0 and 1. */ -bool usrp_set_hash (struct usb_dev_handle *udh, int which, +bool usrp_set_hash (struct libusb_device_handle *udh, int which, const unsigned char hash[USRP_HASH_SIZE]); /*! * \brief retrieve the \p hash from the USRP hash slot \p which. * The usrp implements two hash slots, 0 and 1. */ -bool usrp_get_hash (struct usb_dev_handle *udh, int which, +bool usrp_get_hash (struct libusb_device_handle *udh, int which, unsigned char hash[USRP_HASH_SIZE]); -bool usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value); -bool usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value); -bool usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on); -bool usrp_set_led (struct usb_dev_handle *udh, int which, bool on); +bool usrp_write_fpga_reg (struct libusb_device_handle *udh, int reg, int value); +bool usrp_read_fpga_reg (struct libusb_device_handle *udh, int reg, int *value); +bool usrp_set_fpga_reset (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_tx_enable (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_rx_enable (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_tx_reset (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_rx_reset (struct libusb_device_handle *udh, bool on); +bool usrp_set_led (struct libusb_device_handle *udh, int which, bool on); -bool usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p); -bool usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p); +bool usrp_check_rx_overrun (struct libusb_device_handle *udh, bool *overrun_p); +bool usrp_check_tx_underrun (struct libusb_device_handle *udh, bool *underrun_p); // i2c_read and i2c_write are limited to a maximum len of 64 bytes. -bool usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr, +bool usrp_i2c_write (struct libusb_device_handle *udh, int i2c_addr, const void *buf, int len); -bool usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr, +bool usrp_i2c_read (struct libusb_device_handle *udh, int i2c_addr, void *buf, int len); // spi_read and spi_write are limited to a maximum of 64 bytes // See usrp_spi_defs.h for more info -bool usrp_spi_write (struct usb_dev_handle *udh, +bool usrp_spi_write (struct libusb_device_handle *udh, int optional_header, int enables, int format, const void *buf, int len); -bool usrp_spi_read (struct usb_dev_handle *udh, +bool usrp_spi_read (struct libusb_device_handle *udh, int optional_header, int enables, int format, void *buf, int len); -bool usrp_9862_write (struct usb_dev_handle *udh, +bool usrp_9862_write (struct libusb_device_handle *udh, int which_codec, // [0, 1] int regno, // [0, 63] int value); // [0, 255] -bool usrp_9862_read (struct usb_dev_handle *udh, +bool usrp_9862_read (struct libusb_device_handle *udh, int which_codec, // [0, 1] int regno, // [0, 63] unsigned char *value); // [0, 255] @@ -198,28 +198,28 @@ bool usrp_9862_read (struct usb_dev_handle *udh, * \p buf contains alternating register_number, register_value pairs. * \p len must be even and is the length of buf in bytes. */ -bool usrp_9862_write_many (struct usb_dev_handle *udh, int which_codec, +bool usrp_9862_write_many (struct libusb_device_handle *udh, int which_codec, const unsigned char *buf, int len); /*! * \brief write specified regs to all 9862's in the system */ -bool usrp_9862_write_many_all (struct usb_dev_handle *udh, +bool usrp_9862_write_many_all (struct libusb_device_handle *udh, const unsigned char *buf, int len); // Write 24LC024 / 24LC025 EEPROM on motherboard or daughterboard. // Which EEPROM is determined by i2c_addr. See i2c_addr.h -bool usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr, +bool usrp_eeprom_write (struct libusb_device_handle *udh, int i2c_addr, int eeprom_offset, const void *buf, int len); // Read 24LC024 / 24LC025 EEPROM on motherboard or daughterboard. // Which EEPROM is determined by i2c_addr. See i2c_addr.h -bool usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr, +bool usrp_eeprom_read (struct libusb_device_handle *udh, int i2c_addr, int eeprom_offset, void *buf, int len); @@ -241,7 +241,7 @@ bool usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr, * binary values. Although dacs 0, 1 and 2 are 8-bit and dac 3 is 12-bit, * the interface is in terms of 12-bit values [0,4095] */ -bool usrp_write_aux_dac (struct usb_dev_handle *uhd, int slot, +bool usrp_write_aux_dac (struct libusb_device_handle *uhd, int slot, int which_dac, int value); /*! @@ -251,7 +251,7 @@ bool usrp_write_aux_dac (struct usb_dev_handle *uhd, int slot, * \p which_adc: [0,1] which of the two adcs to read * \p *value: return value, 12-bit straight binary. */ -bool usrp_read_aux_adc (struct usb_dev_handle *udh, int slot, +bool usrp_read_aux_adc (struct libusb_device_handle *udh, int slot, int which_adc, int *value); @@ -274,13 +274,13 @@ struct usrp_dboard_eeprom { * \brief Read and return parsed daughterboard eeprom */ usrp_dbeeprom_status_t -usrp_read_dboard_eeprom (struct usb_dev_handle *udh, +usrp_read_dboard_eeprom (struct libusb_device_handle *udh, int slot_id, usrp_dboard_eeprom *eeprom); /*! * \brief write ADC/DAC offset calibration constants to d'board eeprom */ -bool usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id, +bool usrp_write_dboard_offsets (struct libusb_device_handle *udh, int slot_id, short offset0, short offset1); /*! @@ -289,6 +289,6 @@ bool usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id, * Note that this only works on a configured usrp. * \returns non-zero length string iff successful. */ -std::string usrp_serial_number(struct usb_dev_handle *udh); +std::string usrp_serial_number(struct libusb_device_handle *udh); #endif /* _USRP_PRIMS_H_ */ diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am index 8e40692a5..e7c3f34c4 100644 --- a/usrp/host/lib/Makefile.am +++ b/usrp/host/lib/Makefile.am @@ -84,6 +84,9 @@ ra_wb_CODE = \ fusb_ra_wb.cc \ fusb_sysconfig_ra_wb.cc +libusb1_CODE = \ + fusb_libusb1.cc \ + fusb_sysconfig_libusb1.cc # # include each <foo>_CODE entry here... @@ -93,8 +96,8 @@ EXTRA_libusrp_la_SOURCES = \ $(darwin_CODE) \ $(win32_CODE) \ $(linux_CODE) \ - $(ra_wb_CODE) - + $(ra_wb_CODE) \ + $(libusb1_CODE) # work around automake deficiency libusrp_la_common_SOURCES = \ @@ -141,6 +144,11 @@ if FUSB_TECH_ra_wb libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(ra_wb_CODE) endif +if FUSB_TECH_libusb1 +libusrp_la_SOURCES = $(libusrp_la_common_SOURCES) $(libusb1_CODE) +endif + + noinst_HEADERS = \ ad9862.h \ db_base_impl.h \ @@ -150,6 +158,7 @@ noinst_HEADERS = \ fusb_darwin.h \ fusb_generic.h \ fusb_linux.h \ + fusb_libusb1.h \ fusb_ra_wb.h \ fusb_win32.h \ md5.h \ diff --git a/usrp/host/lib/fusb.cc b/usrp/host/lib/fusb.cc index 6e4358f5f..ce4bb7aa9 100644 --- a/usrp/host/lib/fusb.cc +++ b/usrp/host/lib/fusb.cc @@ -31,7 +31,7 @@ // device handle // ------------------------------------------------------------------------ -fusb_devhandle::fusb_devhandle (usb_dev_handle *udh) +fusb_devhandle::fusb_devhandle (libusb_device_handle *udh) : d_udh (udh) { // that's it diff --git a/usrp/host/lib/fusb.h b/usrp/host/lib/fusb.h index 769e51cca..bfe34d5b8 100644 --- a/usrp/host/lib/fusb.h +++ b/usrp/host/lib/fusb.h @@ -26,7 +26,7 @@ #define _FUSB_H_ -struct usb_dev_handle; +struct libusb_device_handle; class fusb_ephandle; /*! @@ -39,11 +39,11 @@ private: fusb_devhandle &operator= (const fusb_devhandle &rhs); // no assignment operator protected: - usb_dev_handle *d_udh; + libusb_device_handle *d_udh; public: // CREATORS - fusb_devhandle (usb_dev_handle *udh); + fusb_devhandle (libusb_device_handle *udh); virtual ~fusb_devhandle (); // MANIPULATORS @@ -55,7 +55,7 @@ public: int block_size = 0, int nblocks = 0) = 0; // ACCESSORS - usb_dev_handle *get_usb_dev_handle () const { return d_udh; } + libusb_device_handle *get_libusb_device_handle () const { return d_udh; } }; @@ -116,7 +116,7 @@ public: /*! * \brief returns fusb_devhandle or throws if trouble */ - static fusb_devhandle *make_devhandle (usb_dev_handle *udh); + static fusb_devhandle *make_devhandle (libusb_device_handle *udh); /*! * \brief Returns max block size in bytes (hard limit). diff --git a/usrp/host/lib/fusb_libusb1.cc b/usrp/host/lib/fusb_libusb1.cc new file mode 100644 index 000000000..07e05c230 --- /dev/null +++ b/usrp/host/lib/fusb_libusb1.cc @@ -0,0 +1,679 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <fusb_libusb1.h> +#include <libusb-1.0/libusb.h> +#include <stdexcept> +#include <cstdio> +#include <assert.h> +#include <string.h> +#include <algorithm> +#include <errno.h> +#include <string.h> + +#define MINIMIZE_TX_BUFFERING true + +static const int MAX_BLOCK_SIZE = fusb_sysconfig::max_block_size(); +static const int DEFAULT_BLOCK_SIZE = MAX_BLOCK_SIZE; +static const int DEFAULT_BUFFER_SIZE = 4 * (1L << 20); // 4 MB endpoint +static const int LIBUSB_TIMEOUT = 0; // no timeout + +inline static fusb_ephandle_libusb1* +lut_get_ephandle (libusb_transfer *lut) +{ + return (fusb_ephandle_libusb1 *) lut->user_data; +} + +// ------------------------------------------------------------------------ +// libusb_transfer allocation, deallocation, and callback +// ------------------------------------------------------------------------ + +static void +free_lut (libusb_transfer *lut) +{ + + // if this was an input transfer, free the buffer + if (lut->endpoint & 0x80) + delete [] ((unsigned char *) lut->buffer); + + libusb_free_transfer(lut); + +} + +/* + * The callback means the libusb_transfer is completed whether sent, cancelled, + * or failed. Move the libusb_transfer from the pending list to the + * completed list. If the cancel is from the destructor then free the + * transfer instead; normally this won't happen since all endpoints should be + * destroyed first leaving the pending list empty. + */ + +static void +generic_callback(struct libusb_transfer *lut) +{ + + // Fish out devhandle from endpoint + fusb_devhandle_libusb1* dev_handle = + lut_get_ephandle(lut)->get_fusb_devhandle_libusb1(); + + dev_handle->pending_remove(lut); + + if (lut->status == LIBUSB_TRANSFER_CANCELLED && dev_handle->_teardown() == 1) + { + free_lut (lut); + return; + } + + lut_get_ephandle(lut)->completed_list_add(lut); + +} + +static libusb_transfer* +alloc_lut (fusb_ephandle_libusb1 *self, int buffer_length, int endpoint, + bool input_p, unsigned char *write_buffer, + fusb_devhandle_libusb1 *dh) +{ + + struct libusb_transfer* lut = libusb_alloc_transfer(0); + + endpoint = (endpoint & 0x7f) | (input_p ? 0x80 : 0); + + if (input_p) + write_buffer = new unsigned char [buffer_length]; + + // We need the base class libusb_device_handle + libusb_device_handle *dev_handle = dh->get_libusb_device_handle(); + + // Load the libusb_transfer for bulk transfer + libusb_fill_bulk_transfer (lut, // transfer + dev_handle, // dev_handle + endpoint, // endpoint + write_buffer, // buffer + buffer_length, // length + generic_callback, // callback + self, // user_data + LIBUSB_TIMEOUT); // timeout + + return lut; +} + +// ------------------------------------------------------------------------ +// device handle +// ------------------------------------------------------------------------ + +fusb_devhandle_libusb1::fusb_devhandle_libusb1 (libusb_device_handle *udh) + : fusb_devhandle (udh), d_teardown (false) +{ + // that's it +} + +fusb_devhandle_libusb1::~fusb_devhandle_libusb1 () +{ + d_teardown = true; + + std::list<libusb_transfer*>::reverse_iterator it; + + // After cancellation the libusb_transfer is still active so delay freeing + // transfer until callback occurs. In most cases the pending list should + // already be empty by the time this destructor is called. + + for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++) { + _cancel_lut (*it); + } + + // Wait for pending list to empty + _wait_for_completion (); + +} + +fusb_ephandle* +fusb_devhandle_libusb1::make_ephandle (int endpoint, bool input_p, + int block_size, int nblocks) +{ + return new fusb_ephandle_libusb1 (this, endpoint, input_p, + block_size, nblocks); +} + +/* + * devhandle list manipulators + */ + +void +fusb_devhandle_libusb1::pending_add (libusb_transfer *lut) +{ + d_pending_rqsts.push_back (lut); +} + + +/* + * Attempt to cancel all transations associated with eph + */ + +void +fusb_devhandle_libusb1::_cancel_pending_rqsts (fusb_ephandle_libusb1 *eph) +{ + std::list<libusb_transfer*>::reverse_iterator it; + + for (it = d_pending_rqsts.rbegin (); it != d_pending_rqsts.rend (); it++){ + if (lut_get_ephandle (*it) == eph) + _cancel_lut (*it); + } +} + +/* + * Pull from the pending list + */ + +libusb_transfer * +fusb_devhandle_libusb1::pending_get () +{ + if (d_pending_rqsts.empty ()) + return 0; + + libusb_transfer *lut = d_pending_rqsts.front (); + d_pending_rqsts.pop_front (); + return lut; +} + +/* + * Match libusb_tranfer with the pending list and erase + * Return true if found, false otherwise + */ + +bool +fusb_devhandle_libusb1::pending_remove (libusb_transfer *lut) +{ + std::list<libusb_transfer*>::iterator result; + result = find (d_pending_rqsts.begin (), d_pending_rqsts.end (), lut); + + if (result == d_pending_rqsts.end ()) { + fprintf (stderr, "fusb::pending_remove: failed to find lut in pending_rqsts: %p\n", lut); + + return false; + } + d_pending_rqsts.erase (result); + return true; +} + +/* + * Submit the libusb_transfer to libusb + * iff successful, the transfer will be placed on the devhandle pending list. + */ + +bool +fusb_devhandle_libusb1::_submit_lut (libusb_transfer *lut) +{ + + int ret = libusb_submit_transfer (lut); + if (ret < 0) { + fprintf(stderr, "fusb::_submit_lut %d", ret); + return false; + } + + pending_add(lut); + return true; + +} + +/* + * Attempt to cancel any pending libusb_transfer transactions. + * Return true in the absence of errors, which does not mean that the transfer + * is cancelled. Cancellation can be checked after the callback is fired off + * by libusb. + */ + +bool +fusb_devhandle_libusb1::_cancel_lut (libusb_transfer *lut) +{ + + int ret = libusb_cancel_transfer (lut); + if (ret < 0) { + fprintf (stderr, "fusb::_cancel_lut"); + return false; + } + return true; + +} + +void +fusb_devhandle_libusb1::_wait_for_completion () +{ + + int ret; + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + + // The regular libusb_handle_events sets a hardcoded timeout of 2 + // seconds. Most of these calls should be changed to appropriate block / non- + // blocking version using libusb_handle_events_timeout. This was just a test + // usage. + + while (!d_pending_rqsts.empty ()) { + if ((ret = libusb_handle_events_timeout(NULL, &tv)) < 0) { + fprintf (stderr, "fusb: libusb_handle_events error %d\n", ret); + break; + } + } + +} + +// ------------------------------------------------------------------------ +// endpoint handle +// ------------------------------------------------------------------------ + +fusb_ephandle_libusb1::fusb_ephandle_libusb1 (fusb_devhandle_libusb1 *dh, + int endpoint, bool input_p, + int block_size, int nblocks) + : fusb_ephandle (endpoint, input_p, block_size, nblocks), + d_devhandle (dh), + d_write_work_in_progress (0), d_write_buffer (0), + d_read_work_in_progress (0), d_read_buffer (0), d_read_buffer_end (0) +{ + + if (d_block_size < 0 || d_block_size > MAX_BLOCK_SIZE) + throw std::out_of_range ("fusb_ephandle_libusb1: block_size"); + + if (d_nblocks < 0) + throw std::out_of_range ("fusb_ephandle_libusb1: nblocks"); + + if (d_block_size == 0) + d_block_size = DEFAULT_BLOCK_SIZE; + + if (d_nblocks == 0) + d_nblocks = std::max (1, DEFAULT_BUFFER_SIZE / d_block_size); + + if (!d_input_p) + if (!MINIMIZE_TX_BUFFERING) + d_write_buffer = new unsigned char [d_block_size]; + + if (0) + fprintf(stderr, "fusb_ephandle_libusb1::ctor: d_block_size = %d d_nblocks = %d\n", + d_block_size, d_nblocks); + + // allocate libusb_transfers + for (int i = 0; i < d_nblocks; i++) + d_free_list.push_back (alloc_lut (this, d_block_size, d_endpoint, + d_input_p, d_write_buffer, d_devhandle)); +} + +fusb_ephandle_libusb1::~fusb_ephandle_libusb1 () +{ + + stop (); + + libusb_transfer *lut; + + while ((lut = free_list_get ()) != 0) + free_lut (lut); + + while ((lut = completed_list_get ()) != 0) + free_lut (lut); + + if (d_write_work_in_progress) + free_lut (d_write_work_in_progress); + + delete [] d_write_buffer; + + if (d_read_work_in_progress) + free_lut (d_read_work_in_progress); + +} + +bool +fusb_ephandle_libusb1::start () +{ + + if (d_started) + return true; + + d_started = true; + + if (d_input_p) { + libusb_transfer *lut; + + int nerrors = 0; + while ((lut = free_list_get ()) !=0 && nerrors < d_nblocks) { + if (!submit_lut (lut)) + nerrors++; + } + } + + return true; + +} + +/* + * Cancel all transfers in progress or pending and return to initial state + */ + +bool +fusb_ephandle_libusb1::stop () +{ + + if (!d_started) + return true; + + if (d_write_work_in_progress){ + free_list_add (d_write_work_in_progress); + d_write_work_in_progress = 0; + } + + if (d_read_work_in_progress){ + free_list_add (d_read_work_in_progress); + d_read_work_in_progress = 0; + d_read_buffer = 0; + d_read_buffer_end = 0; + } + + d_devhandle->_cancel_pending_rqsts (this); + + // Do work, reap transfers, etc. + if (libusb_handle_events(NULL) < 0) { + perror ("fusb::libusb_handle_events"); + return false; + } + + while (1) { + libusb_transfer *lut; + while ((lut = completed_list_get ()) != 0) + free_list_add (lut); + + if (d_free_list.size () == (unsigned) d_nblocks) + break; + + if (libusb_handle_events(NULL) < 0) { + perror ("fusb::libusb_handle_events"); + return false; + } + } + + d_started = false; + return true; + +} + +// ------------------------------------------------------------------------ +// routines for writing +// ------------------------------------------------------------------------ + +#if (MINIMIZE_TX_BUFFERING) + +int +fusb_ephandle_libusb1::write (const void *buffer, int nbytes) +{ + + if (!d_started) // doesn't matter here, but keeps semantics constant + return -1; + + if (d_input_p) + return -1; + + assert(nbytes % 512 == 0); + + unsigned char *src = (unsigned char *) buffer; + + int n = 0; + while (n < nbytes){ + + struct libusb_transfer *lut = get_write_work_in_progress(); + if (!lut) + return -1; + assert(lut->actual_length == 0); + int m = std::min(nbytes - n, MAX_BLOCK_SIZE); + lut->buffer = src; + lut->length = m; + + n += m; + src += m; + + if (!submit_lut(lut)) + return -1; + + d_write_work_in_progress = 0; + } + + return nbytes; +} + +#else + +int +fusb_ephandle_libusb1::write (const void *buffer, int nbytes) +{ + if (!d_started) + return -1; + + if (d_input_p) + return -1; + + unsigned char *src = (unsigned char *) buffer; + + int n = 0; + while (n < nbytes){ + + libusb_transfer *lut = get_write_work_in_progress (); + if (!lut) + return -1; + unsigned char *dst = (unsigned char *) lut->buffer; + int m = std::min (nbytes - n, lut->length - lut->actual_length); + + memcpy (&dst[lut->actual_length], &src[n], m); + lut->actual_length += m; + n += m; + + if (lut->actual_length == lut->length){ + if (!submit_lut (lut)) + return -1; + d_write_work_in_progress = 0; + } + } + + return n; +} + +#endif + +struct libusb_transfer * +fusb_ephandle_libusb1::get_write_work_in_progress () +{ + if (d_write_work_in_progress) + return d_write_work_in_progress; + + while (1) { + + reap_complete_writes (); + + struct libusb_transfer *lut = free_list_get (); + + if (lut != 0){ + assert (lut->actual_length == 0); + d_write_work_in_progress = lut; + return lut; + } + + // Do work, reap transfers, etc. + libusb_handle_events(NULL); + } +} + +void +fusb_ephandle_libusb1::reap_complete_writes () +{ + // take a look at the completed list and xfer to free list after + // checking for errors. + + libusb_transfer *lut; + + while ((lut = completed_list_get ()) != 0) { + + // Check for any errors or short writes that were reporetd in the transfer. + // libusb1 sets status, actual_length. + + if (lut->status != LIBUSB_TRANSFER_COMPLETED) { + fprintf (stderr, "fusb: (status %d) \n", lut->status ); + } + else if (lut->actual_length != lut->length){ + fprintf (stderr, "fusb: short write xfer: %d != %d\n", + lut->actual_length, lut->length); + } + + free_list_add (lut); + } +} + +void +fusb_ephandle_libusb1::wait_for_completion () +{ + d_devhandle->_wait_for_completion (); +} + +// ------------------------------------------------------------------------ +// routines for reading +// ------------------------------------------------------------------------ + +int +fusb_ephandle_libusb1::read (void *buffer, int nbytes) +{ + if (!d_started) // doesn't matter here, but keeps semantics constant + return -1; + + if (!d_input_p) + return -1; + + unsigned char *dst = (unsigned char *) buffer; + + int n = 0; + while (n < nbytes) { + + if (d_read_buffer >= d_read_buffer_end) + if (!reload_read_buffer ()) + return -1; + + int m = std::min (nbytes - n, (int) (d_read_buffer_end - d_read_buffer)); + + memcpy (&dst[n], d_read_buffer, m); + d_read_buffer += m; + n += m; + } + + return n; + +} + +bool +fusb_ephandle_libusb1::reload_read_buffer () +{ + assert (d_read_buffer >= d_read_buffer_end); + + libusb_transfer *lut; + + if (d_read_work_in_progress) { + lut = d_read_work_in_progress; + d_read_work_in_progress = 0; + d_read_buffer = 0; + d_read_buffer_end = 0; + lut->actual_length = 0; + if (!submit_lut (lut)) + return false; + } + + while (1) { + + while ((lut = completed_list_get ()) == 0 ) { + if (libusb_handle_events(NULL) < 0) + fprintf (stderr, "fusb: libusb_handle_events\n"); + } + + if (lut->status != LIBUSB_TRANSFER_COMPLETED) { + fprintf (stderr, "fust: (rd status %d) %s\n", lut->status, + strerror (-lut->status)); + lut->actual_length = 0; + free_list_add (lut); + return false; + } + + d_read_work_in_progress = lut; + d_read_buffer = (unsigned char *) lut->buffer; + d_read_buffer_end = d_read_buffer + lut->actual_length; + + return true; + } +} + + +/* + * ephandle list manipulation + */ + + +void +fusb_ephandle_libusb1::free_list_add (libusb_transfer *lut) +{ + assert (lut_get_ephandle (lut) == this); + lut->actual_length = 0; + d_free_list.push_back (lut); +} + +libusb_transfer * +fusb_ephandle_libusb1::free_list_get () +{ + if (d_free_list.empty ()) + return 0; + + libusb_transfer *lut = d_free_list.front (); + d_free_list.pop_front (); + return lut; +} + +void +fusb_ephandle_libusb1::completed_list_add (libusb_transfer *lut) +{ + assert (lut_get_ephandle (lut) == this); + d_completed_list.push_back (lut); +} + +libusb_transfer * +fusb_ephandle_libusb1::completed_list_get () +{ + if (d_completed_list.empty ()) + return 0; + + libusb_transfer *lut = d_completed_list.front (); + d_completed_list.pop_front (); + return lut; +} + +bool +fusb_ephandle_libusb1::submit_lut (libusb_transfer *lut) +{ + if (!d_devhandle->_submit_lut (lut)) { + fprintf (stderr, "_submit_lut failed\n"); + free_list_add (lut); + return false; + } + return true; +} diff --git a/usrp/host/lib/fusb_libusb1.h b/usrp/host/lib/fusb_libusb1.h new file mode 100644 index 000000000..1661b7ab8 --- /dev/null +++ b/usrp/host/lib/fusb_libusb1.h @@ -0,0 +1,127 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _FUSB_LIBUSB1_H_ +#define _FUSB_LIBUSB1_H_ + +#include <fusb.h> +#include <list> + +struct libusb_transfer; +class fusb_ephandle_libusb1; + +/*! + * \brief libusb1 implementation of fusb_devhandle + */ +class fusb_devhandle_libusb1 : public fusb_devhandle +{ +private: + std::list<libusb_transfer*> d_pending_rqsts; + + void pending_add (struct libusb_transfer *lut); + struct libusb_transfer * pending_get (); + + bool d_teardown; + +public: + // CREATORS + fusb_devhandle_libusb1 (libusb_device_handle *udh); + virtual ~fusb_devhandle_libusb1 (); + + // MANIPULATORS + virtual fusb_ephandle *make_ephandle (int endpoint, bool input_p, + int block_size = 0, int nblocks = 0); + // internal use only + bool _submit_lut (libusb_transfer *); + bool _cancel_lut (libusb_transfer *); + void _cancel_pending_rqsts (fusb_ephandle_libusb1 *eph); + void _wait_for_completion (); + + // accessors to work from callback context + bool pending_remove (struct libusb_transfer *lut); + inline bool _teardown() { return d_teardown; } + +}; + + +/*! + * \brief libusb1 implementation of fusb_ephandle + */ +class fusb_ephandle_libusb1 : public fusb_ephandle +{ +private: + fusb_devhandle_libusb1 *d_devhandle; + std::list<libusb_transfer*> d_free_list; + std::list<libusb_transfer*> d_completed_list; + libusb_transfer *d_write_work_in_progress; + unsigned char *d_write_buffer; + libusb_transfer *d_read_work_in_progress; + unsigned char *d_read_buffer; + unsigned char *d_read_buffer_end; + + libusb_transfer *get_write_work_in_progress (); + void reap_complete_writes (); + bool reload_read_buffer (); + bool submit_lut (libusb_transfer *lut); + +public: + // CREATORS + fusb_ephandle_libusb1 (fusb_devhandle_libusb1 *dh, int endpoint, bool input_p, + int block_size = 0, int nblocks = 0); + virtual ~fusb_ephandle_libusb1 (); + + // MANIPULATORS + + virtual bool start (); //!< begin streaming i/o + virtual bool stop (); //!< stop streaming i/o + + /*! + * \returns \p nbytes if write was successfully enqueued, else -1. + * Will block if no free buffers available. + */ + virtual int write (const void *buffer, int nbytes); + + /*! + * \returns number of bytes read or -1 if error. + * number of bytes read will be <= nbytes. + * Will block if no input available. + */ + virtual int read (void *buffer, int nbytes); + + /* + * block until all outstanding writes have completed + */ + virtual void wait_for_completion (); + + void free_list_add (struct libusb_transfer *lut); + void completed_list_add (struct libusb_transfer *lut); + struct libusb_transfer *free_list_get (); + struct libusb_transfer *completed_list_get (); + + // accessor to work from callback context + fusb_devhandle_libusb1* get_fusb_devhandle_libusb1 () const { + return d_devhandle; + } +}; + +#endif /* _FUSB_LINUX1_H_ */ + diff --git a/usrp/host/lib/fusb_sysconfig_libusb1.cc b/usrp/host/lib/fusb_sysconfig_libusb1.cc new file mode 100644 index 000000000..e0d9458e1 --- /dev/null +++ b/usrp/host/lib/fusb_sysconfig_libusb1.cc @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <fusb.h> +#include <fusb_libusb1.h> + +static const int MAX_BLOCK_SIZE = 16 * 1024; // hard limit +static const int DEFAULT_BLOCK_SIZE = 4 * 1024; +static const int FUSB_BUFFER_SIZE = 2 * (1L << 20); // 2 MB + +fusb_devhandle * +fusb_sysconfig::make_devhandle (libusb_device_handle *udh) +{ + return new fusb_devhandle_libusb1 (udh); +} + +int fusb_sysconfig::max_block_size () +{ + return MAX_BLOCK_SIZE; +} + +int fusb_sysconfig::default_block_size () +{ + return DEFAULT_BLOCK_SIZE; +} + +int fusb_sysconfig::default_buffer_size () +{ + return FUSB_BUFFER_SIZE; +} diff --git a/usrp/host/lib/usrp_basic.cc b/usrp/host/lib/usrp_basic.cc index 4f3df5212..a8b44edab 100644 --- a/usrp/host/lib/usrp_basic.cc +++ b/usrp/host/lib/usrp_basic.cc @@ -31,7 +31,7 @@ #include "fpga_regs_standard.h" #include "fusb.h" #include "db_boards.h" -#include <usb.h> +#include <libusb-1.0/libusb.h> #include <stdexcept> #include <assert.h> #include <math.h> @@ -55,24 +55,22 @@ static const double POLLING_INTERVAL = 0.1; // seconds //////////////////////////////////////////////////////////////// -static struct usb_dev_handle * -open_rx_interface (struct usb_device *dev) +static struct libusb_device_handle * +open_rx_interface (struct libusb_device *dev) { - struct usb_dev_handle *udh = usrp_open_rx_interface (dev); + struct libusb_device_handle *udh = usrp_open_rx_interface (dev); if (udh == 0){ fprintf (stderr, "usrp_basic_rx: can't open rx interface\n"); - usb_strerror (); } return udh; } -static struct usb_dev_handle * -open_tx_interface (struct usb_device *dev) +static struct libusb_device_handle * +open_tx_interface (struct libusb_device *dev) { - struct usb_dev_handle *udh = usrp_open_tx_interface (dev); + struct libusb_device_handle *udh = usrp_open_tx_interface (dev); if (udh == 0){ fprintf (stderr, "usrp_basic_tx: can't open tx interface\n"); - usb_strerror (); } return udh; } @@ -106,8 +104,8 @@ static unsigned char common_regs[] = { usrp_basic::usrp_basic (int which_board, - struct usb_dev_handle * - open_interface (struct usb_device *dev), + struct libusb_device_handle * + open_interface (struct libusb_device *dev), const std::string fpga_filename, const std::string firmware_filename) : d_udh (0), @@ -132,7 +130,7 @@ usrp_basic::usrp_basic (int which_board, if (!usrp_load_standard_bits (which_board, false, fpga_filename, firmware_filename)) throw std::runtime_error ("usrp_basic/usrp_load_standard_bits"); - struct usb_device *dev = usrp_find_device (which_board); + struct libusb_device *dev = usrp_find_device (which_board); if (dev == 0){ fprintf (stderr, "usrp_basic: can't find usrp[%d]\n", which_board); throw std::runtime_error ("usrp_basic/usrp_find_device"); @@ -175,7 +173,14 @@ usrp_basic::~usrp_basic () d_db.resize(0); // forget db shared ptrs if (d_udh) - usb_close (d_udh); + libusb_close (d_udh); + + // There's no reference count on the number of times libusb is initialized. + // libusb_init can be called multiple times, but libusb_exit shuts down + // everything. Leave libusb running for now. Need to add a count so that it + // exits nicely. + + //libusb_exit (NULL); } void @@ -834,7 +839,6 @@ usrp_basic_rx::~usrp_basic_rx () { if (!set_rx_enable (false)){ fprintf (stderr, "usrp_basic_rx: set_fpga_rx_enable failed\n"); - usb_strerror (); } d_ephandle->stop (); @@ -859,13 +863,11 @@ usrp_basic_rx::start () if (!d_ephandle->start ()){ fprintf (stderr, "usrp_basic_rx: failed to start end point streaming"); - usb_strerror (); return false; } if (!set_rx_enable (true)){ fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n"); - usb_strerror (); return false; } @@ -879,13 +881,11 @@ usrp_basic_rx::stop () if (!set_rx_enable(false)){ fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n"); - usb_strerror (); ok = false; } if (!d_ephandle->stop()){ fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming"); - usb_strerror (); ok = false; } @@ -959,7 +959,6 @@ usrp_basic_rx::read (void *buf, int len, bool *overrun) d_bytes_seen = 0; if (!usrp_check_rx_overrun (d_udh, overrun)){ fprintf (stderr, "usrp_basic_rx: usrp_check_rx_overrun failed\n"); - usb_strerror (); } } @@ -1264,13 +1263,11 @@ usrp_basic_tx::start () if (!set_tx_enable (true)){ fprintf (stderr, "usrp_basic_tx: set_tx_enable failed\n"); - usb_strerror (); return false; } if (!d_ephandle->start ()){ fprintf (stderr, "usrp_basic_tx: failed to start end point streaming"); - usb_strerror (); return false; } @@ -1284,13 +1281,11 @@ usrp_basic_tx::stop () if (!d_ephandle->stop ()){ fprintf (stderr, "usrp_basic_tx: failed to stop end point streaming"); - usb_strerror (); ok = false; } if (!set_tx_enable (false)){ fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n"); - usb_strerror (); ok = false; } @@ -1364,7 +1359,6 @@ usrp_basic_tx::write (const void *buf, int len, bool *underrun) d_bytes_seen = 0; if (!usrp_check_tx_underrun (d_udh, underrun)){ fprintf (stderr, "usrp_basic_tx: usrp_check_tx_underrun failed\n"); - usb_strerror (); } } diff --git a/usrp/host/lib/usrp_prims.cc b/usrp/host/lib/usrp_prims.cc index 3d87d2459..e1e3e3074 100644 --- a/usrp/host/lib/usrp_prims.cc +++ b/usrp/host/lib/usrp_prims.cc @@ -30,7 +30,7 @@ #include "usrp_i2c_addr.h" #include "fpga_regs_common.h" #include "fpga_regs_standard.h" -#include <usb.h> +#include <libusb-1.0/libusb.h> #include <errno.h> #include <stdio.h> #include <unistd.h> @@ -101,7 +101,7 @@ get_proto_filename(const std::string user_filename, const char *env_var, const c } -static void power_down_9862s (struct usb_dev_handle *udh); +static void power_down_9862s (struct libusb_device_handle *udh); void usrp_one_time_init () @@ -110,35 +110,14 @@ usrp_one_time_init () if (first){ first = false; - usb_init (); // usb library init - usb_find_busses (); - usb_find_devices (); + libusb_init (NULL); // usb library init } } void usrp_rescan () { - usb_find_busses (); - usb_find_devices (); -} - - -// ---------------------------------------------------------------- -// Danger, big, fragile KLUDGE. The problem is that we want to be -// able to get from a usb_dev_handle back to a usb_device, and the -// right way to do this is buried in a non-installed include file. - -static struct usb_device * -dev_handle_to_dev (usb_dev_handle *udh) -{ - struct usb_dev_handle_kludge { - int fd; - struct usb_bus *bus; - struct usb_device *device; - }; - - return ((struct usb_dev_handle_kludge *) udh)->device; + // deprecated? } // ---------------------------------------------------------------- @@ -147,171 +126,176 @@ dev_handle_to_dev (usb_dev_handle *udh) * q must be a real USRP, not an FX2. Return its hardware rev number. */ int -usrp_hw_rev (struct usb_device *q) +usrp_hw_rev (struct libusb_device *q) { - return q->descriptor.bcdDevice & 0x00FF; + struct libusb_device_descriptor desc; + if (libusb_get_device_descriptor(q, &desc) < 0) + fprintf (stderr, "usrp: libusb_get_device_descriptor failed\n"); + + return desc.bcdDevice & 0x00FF; } /* * q must be a real USRP, not an FX2. Return true if it's configured. */ static bool -_usrp_configured_p (struct usb_device *q) +_usrp_configured_p (struct libusb_device *q) { - return (q->descriptor.bcdDevice & 0xFF00) != 0; + struct libusb_device_descriptor desc; + if (libusb_get_device_descriptor(q, &desc) < 0) + fprintf (stderr, "usrp: libusb_get_device_descriptor failed\n"); + + return (desc.bcdDevice & 0xFF00) != 0; } bool -usrp_usrp_p (struct usb_device *q) +usrp_usrp_p (struct libusb_device *q) { - return (q->descriptor.idVendor == USB_VID_FSF - && q->descriptor.idProduct == USB_PID_FSF_USRP); + struct libusb_device_descriptor desc; + if (libusb_get_device_descriptor(q, &desc) < 0) + fprintf (stderr, "usrp: libusb_get_device_descriptor failed\n"); + + return (desc.idVendor == USB_VID_FSF + && desc.idProduct == USB_PID_FSF_USRP); } bool -usrp_fx2_p (struct usb_device *q) +usrp_fx2_p (struct libusb_device *q) { - return (q->descriptor.idVendor == USB_VID_CYPRESS - && q->descriptor.idProduct == USB_PID_CYPRESS_FX2); + struct libusb_device_descriptor desc; + if (libusb_get_device_descriptor(q, &desc) < 0) + fprintf (stderr, "usrp: libusb_get_device_descriptor failed\n"); + + return (desc.idVendor == USB_VID_CYPRESS + && desc.idProduct == USB_PID_CYPRESS_FX2); } bool -usrp_usrp0_p (struct usb_device *q) +usrp_usrp0_p (struct libusb_device *q) { return usrp_usrp_p (q) && usrp_hw_rev (q) == 0; } bool -usrp_usrp1_p (struct usb_device *q) +usrp_usrp1_p (struct libusb_device *q) { return usrp_usrp_p (q) && usrp_hw_rev (q) == 1; } bool -usrp_usrp2_p (struct usb_device *q) +usrp_usrp2_p (struct libusb_device *q) { return usrp_usrp_p (q) && usrp_hw_rev (q) == 2; } bool -usrp_unconfigured_usrp_p (struct usb_device *q) +usrp_unconfigured_usrp_p (struct libusb_device *q) { return usrp_usrp_p (q) && !_usrp_configured_p (q); } bool -usrp_configured_usrp_p (struct usb_device *q) +usrp_configured_usrp_p (struct libusb_device *q) { return usrp_usrp_p (q) && _usrp_configured_p (q); } // ---------------------------------------------------------------- -struct usb_device * +struct libusb_device * usrp_find_device (int nth, bool fx2_ok_p) { - struct usb_bus *p; - struct usb_device *q; + libusb_device **list; + + struct libusb_device *q; int n_found = 0; usrp_one_time_init (); - - p = usb_get_busses(); - while (p != NULL){ - q = p->devices; - while (q != NULL){ - if (usrp_usrp_p (q) || (fx2_ok_p && usrp_fx2_p (q))){ + + size_t cnt = libusb_get_device_list(NULL, &list); + size_t i = 0; + + if (cnt < 0) + fprintf(stderr, "usrp: libusb_get_device_list failed %d\n", cnt); + + for (i = 0; i < cnt; i++) { + q = list[i]; + if (usrp_usrp_p (q) || (fx2_ok_p && usrp_fx2_p (q))) { if (n_found == nth) // return this one return q; n_found++; // keep looking - } - q = q->next; } - p = p->next; } + + libusb_free_device_list(list, 1); return 0; // not found } -static struct usb_dev_handle * -usrp_open_interface (struct usb_device *dev, int interface, int altinterface) +static struct libusb_device_handle * +usrp_open_interface (struct libusb_device *dev, int interface, int altinterface) { - struct usb_dev_handle *udh = usb_open (dev); - if (udh == 0) + struct libusb_device_handle *udh; + int ret; + + if (libusb_open (dev, &udh) < 0) return 0; - if (dev != dev_handle_to_dev (udh)){ + if (dev != libusb_get_device (udh)){ fprintf (stderr, "%s:%d: internal error!\n", __FILE__, __LINE__); abort (); } -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) - // There's no get get_configuration function, and with some of the newer kernels - // setting the configuration, even if to the same value, hoses any other processes - // that have it open. Hence we opt to not set it at all (We've only - // got a single configuration anyway). This may hose the win32 stuff... - - // Appears to be required for libusb-win32 and Cygwin -- dew 09/20/06 - if (usb_set_configuration (udh, 1) < 0){ - /* - * Ignore this error. - * - * Seems that something changed in drivers/usb/core/devio.c:proc_setconfig such that - * it returns -EBUSY if _any_ of the interfaces of a device are open. - * We've only got a single configuration, so setting it doesn't even seem - * like it should be required. - */ - } -#endif - - if (usb_claim_interface (udh, interface) < 0){ + if ((ret = libusb_claim_interface (udh, interface)) < 0) { fprintf (stderr, "%s:usb_claim_interface: failed interface %d\n", __FUNCTION__,interface); - fprintf (stderr, "%s\n", usb_strerror()); - usb_close (udh); + fprintf (stderr, "%d\n", ret); + libusb_close (udh); return 0; } - if (usb_set_altinterface (udh, altinterface) < 0){ + if ((ret = libusb_set_interface_alt_setting (udh, interface, + altinterface)) < 0) { fprintf (stderr, "%s:usb_set_alt_interface: failed\n", __FUNCTION__); - fprintf (stderr, "%s\n", usb_strerror()); - usb_release_interface (udh, interface); - usb_close (udh); + fprintf (stderr, "%d\n", ret); + libusb_release_interface (udh, interface); + libusb_close (udh); return 0; } return udh; } -struct usb_dev_handle * -usrp_open_cmd_interface (struct usb_device *dev) +struct libusb_device_handle * +usrp_open_cmd_interface (struct libusb_device *dev) { return usrp_open_interface (dev, USRP_CMD_INTERFACE, USRP_CMD_ALTINTERFACE); } -struct usb_dev_handle * -usrp_open_rx_interface (struct usb_device *dev) +struct libusb_device_handle * +usrp_open_rx_interface (struct libusb_device *dev) { return usrp_open_interface (dev, USRP_RX_INTERFACE, USRP_RX_ALTINTERFACE); } -struct usb_dev_handle * -usrp_open_tx_interface (struct usb_device *dev) +struct libusb_device_handle * +usrp_open_tx_interface (struct libusb_device *dev) { return usrp_open_interface (dev, USRP_TX_INTERFACE, USRP_TX_ALTINTERFACE); } bool -usrp_close_interface (struct usb_dev_handle *udh) +usrp_close_interface (struct libusb_device_handle *udh) { - // we're assuming that closing an interface automatically releases it. - return usb_close (udh) == 0; + // returns void + libusb_close(udh); + return 0; } // ---------------------------------------------------------------- // write internal ram using Cypress vendor extension static bool -write_internal_ram (struct usb_dev_handle *udh, unsigned char *buf, +write_internal_ram (struct libusb_device_handle *udh, unsigned char *buf, int start_addr, size_t len) { int addr; @@ -324,11 +308,11 @@ write_internal_ram (struct usb_dev_handle *udh, unsigned char *buf, if (n > quanta) n = quanta; - a = usb_control_msg (udh, 0x40, 0xA0, - addr, 0, (char *)(buf + (addr - start_addr)), n, 1000); + a = libusb_control_transfer (udh, 0x40, 0xA0, + addr, 0, (unsigned char *)(buf + (addr - start_addr)), n, 1000); if (a < 0){ - fprintf(stderr,"write_internal_ram failed: %s\n", usb_strerror()); + fprintf(stderr,"write_internal_ram failed: %u\n", a); return false; } } @@ -339,7 +323,7 @@ write_internal_ram (struct usb_dev_handle *udh, unsigned char *buf, // whack the CPUCS register using the upload RAM vendor extension static bool -reset_cpu (struct usb_dev_handle *udh, bool reset_p) +reset_cpu (struct libusb_device_handle *udh, bool reset_p) { unsigned char v; @@ -355,7 +339,7 @@ reset_cpu (struct usb_dev_handle *udh, bool reset_p) // Load intel format file into cypress FX2 (8051) static bool -_usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, +_usrp_load_firmware (struct libusb_device_handle *udh, const char *filename, unsigned char hash[USRP_HASH_SIZE]) { FILE *f = fopen (filename, "ra"); @@ -437,18 +421,20 @@ _usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, // write vendor extension command to USRP static int -write_cmd (struct usb_dev_handle *udh, +write_cmd (struct libusb_device_handle *udh, int request, int value, int index, unsigned char *bytes, int len) { int requesttype = (request & 0x80) ? VRT_VENDOR_IN : VRT_VENDOR_OUT; - int r = usb_control_msg (udh, requesttype, request, value, index, - (char *) bytes, len, 1000); + int r = libusb_control_transfer(udh, requesttype, request, value, index, + (unsigned char *) bytes, len, 1000); + if (r < 0){ // we get EPIPE if the firmware stalls the endpoint. - if (errno != EPIPE) - fprintf (stderr, "usb_control_msg failed: %s\n", usb_strerror ()); + if (r != LIBUSB_ERROR_PIPE) { + fprintf (stderr, "libusb_control_transfer failed: %i\n", r); + } } return r; @@ -458,7 +444,7 @@ write_cmd (struct usb_dev_handle *udh, // load fpga static bool -_usrp_load_fpga (struct usb_dev_handle *udh, const char *filename, +_usrp_load_fpga (struct libusb_device_handle *udh, const char *filename, unsigned char hash[USRP_HASH_SIZE]) { bool ok = true; @@ -536,7 +522,7 @@ _usrp_load_fpga (struct usb_dev_handle *udh, const char *filename, // ---------------------------------------------------------------- bool -usrp_set_led (struct usb_dev_handle *udh, int which, bool on) +usrp_set_led (struct libusb_device_handle *udh, int which, bool on) { int r = write_cmd (udh, VRQ_SET_LED, on, which, 0, 0); @@ -544,38 +530,38 @@ usrp_set_led (struct usb_dev_handle *udh, int which, bool on) } bool -usrp_set_hash (struct usb_dev_handle *udh, int which, +usrp_set_hash (struct libusb_device_handle *udh, int which, const unsigned char hash[USRP_HASH_SIZE]) { which &= 1; // we use the Cypress firmware down load command to jam it in. - int r = usb_control_msg (udh, 0x40, 0xa0, hash_slot_addr[which], 0, - (char *) hash, USRP_HASH_SIZE, 1000); + int r = libusb_control_transfer (udh, 0x40, 0xa0, hash_slot_addr[which], 0, + (unsigned char *) hash, USRP_HASH_SIZE, 1000); return r == USRP_HASH_SIZE; } bool -usrp_get_hash (struct usb_dev_handle *udh, int which, +usrp_get_hash (struct libusb_device_handle *udh, int which, unsigned char hash[USRP_HASH_SIZE]) { which &= 1; // we use the Cypress firmware upload command to fetch it. - int r = usb_control_msg (udh, 0xc0, 0xa0, hash_slot_addr[which], 0, - (char *) hash, USRP_HASH_SIZE, 1000); + int r = libusb_control_transfer (udh, 0xc0, 0xa0, hash_slot_addr[which], 0, + (unsigned char *) hash, USRP_HASH_SIZE, 1000); return r == USRP_HASH_SIZE; } static bool -usrp_set_switch (struct usb_dev_handle *udh, int cmd_byte, bool on) +usrp_set_switch (struct libusb_device_handle *udh, int cmd_byte, bool on) { return write_cmd (udh, cmd_byte, on, 0, 0, 0) == 0; } static bool -usrp1_fpga_write (struct usb_dev_handle *udh, +usrp1_fpga_write (struct libusb_device_handle *udh, int regno, int value) { // on the rev1 usrp, we use the generic spi_write interface @@ -594,7 +580,7 @@ usrp1_fpga_write (struct usb_dev_handle *udh, } static bool -usrp1_fpga_read (struct usb_dev_handle *udh, +usrp1_fpga_read (struct libusb_device_handle *udh, int regno, int *value) { *value = 0; @@ -613,9 +599,9 @@ usrp1_fpga_read (struct usb_dev_handle *udh, bool -usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value) +usrp_write_fpga_reg (struct libusb_device_handle *udh, int reg, int value) { - switch (usrp_hw_rev (dev_handle_to_dev (udh))){ + switch (usrp_hw_rev (libusb_get_device (udh))){ case 0: // not supported ;) abort(); @@ -625,9 +611,9 @@ usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value) } bool -usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value) +usrp_read_fpga_reg (struct libusb_device_handle *udh, int reg, int *value) { - switch (usrp_hw_rev (dev_handle_to_dev (udh))){ + switch (usrp_hw_rev (libusb_get_device (udh))){ case 0: // not supported ;) abort(); @@ -637,31 +623,31 @@ usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg, int *value) } bool -usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on) +usrp_set_fpga_reset (struct libusb_device_handle *udh, bool on) { return usrp_set_switch (udh, VRQ_FPGA_SET_RESET, on); } bool -usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on) +usrp_set_fpga_tx_enable (struct libusb_device_handle *udh, bool on) { return usrp_set_switch (udh, VRQ_FPGA_SET_TX_ENABLE, on); } bool -usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on) +usrp_set_fpga_rx_enable (struct libusb_device_handle *udh, bool on) { return usrp_set_switch (udh, VRQ_FPGA_SET_RX_ENABLE, on); } bool -usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on) +usrp_set_fpga_tx_reset (struct libusb_device_handle *udh, bool on) { return usrp_set_switch (udh, VRQ_FPGA_SET_TX_RESET, on); } bool -usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on) +usrp_set_fpga_rx_reset (struct libusb_device_handle *udh, bool on) { return usrp_set_switch (udh, VRQ_FPGA_SET_RX_RESET, on); } @@ -688,11 +674,11 @@ compute_hash (const char *filename, unsigned char hash[USRP_HASH_SIZE]) } static usrp_load_status_t -usrp_conditionally_load_something (struct usb_dev_handle *udh, +usrp_conditionally_load_something (struct libusb_device_handle *udh, const char *filename, bool force, int slot, - bool loader (struct usb_dev_handle *, + bool loader (struct libusb_device_handle *, const char *, unsigned char [USRP_HASH_SIZE])) { @@ -721,7 +707,7 @@ usrp_conditionally_load_something (struct usb_dev_handle *udh, } usrp_load_status_t -usrp_load_firmware (struct usb_dev_handle *udh, +usrp_load_firmware (struct libusb_device_handle *udh, const char *filename, bool force) { @@ -731,7 +717,7 @@ usrp_load_firmware (struct usb_dev_handle *udh, } usrp_load_status_t -usrp_load_fpga (struct usb_dev_handle *udh, +usrp_load_fpga (struct libusb_device_handle *udh, const char *filename, bool force) { @@ -740,23 +726,22 @@ usrp_load_fpga (struct usb_dev_handle *udh, _usrp_load_fpga); } -static usb_dev_handle * +static libusb_device_handle * open_nth_cmd_interface (int nth) { - struct usb_device *udev = usrp_find_device (nth); + struct libusb_device *udev = usrp_find_device (nth); if (udev == 0){ fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth); return 0; } - struct usb_dev_handle *udh; + struct libusb_device_handle *udh; udh = usrp_open_cmd_interface (udev); if (udh == 0){ // FIXME this could be because somebody else has it open. // We should delay and retry... fprintf (stderr, "open_nth_cmd_interface: open_cmd_interface failed\n"); - usb_strerror (); return 0; } @@ -793,7 +778,7 @@ mdelay (int millisecs) usrp_load_status_t usrp_load_firmware_nth (int nth, const char *filename, bool force){ - struct usb_dev_handle *udh = open_nth_cmd_interface (nth); + struct libusb_device_handle *udh = open_nth_cmd_interface (nth); if (udh == 0) return ULS_ERROR; @@ -820,9 +805,6 @@ usrp_load_firmware_nth (int nth, const char *filename, bool force){ t.tv_nsec = 0; our_nanosleep (&t); - usb_find_busses (); // rescan busses and devices - usb_find_devices (); - return ULS_OK; default: @@ -866,7 +848,7 @@ usrp_load_standard_bits (int nth, bool force, // first, figure out what hardware rev we're dealing with { - struct usb_device *udev = usrp_find_device (nth); + struct libusb_device *udev = usrp_find_device (nth); if (udev == 0){ fprintf (stderr, "usrp: failed to find usrp[%d]\n", nth); return false; @@ -904,7 +886,7 @@ usrp_load_standard_bits (int nth, bool force, return false; } - struct usb_dev_handle *udh = open_nth_cmd_interface (nth); + struct libusb_device_handle *udh = open_nth_cmd_interface (nth); if (udh == 0) return false; @@ -919,7 +901,7 @@ usrp_load_standard_bits (int nth, bool force, } bool -_usrp_get_status (struct usb_dev_handle *udh, int which, bool *trouble) +_usrp_get_status (struct libusb_device_handle *udh, int which, bool *trouble) { unsigned char status; *trouble = true; @@ -933,20 +915,20 @@ _usrp_get_status (struct usb_dev_handle *udh, int which, bool *trouble) } bool -usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p) +usrp_check_rx_overrun (struct libusb_device_handle *udh, bool *overrun_p) { return _usrp_get_status (udh, GS_RX_OVERRUN, overrun_p); } bool -usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p) +usrp_check_tx_underrun (struct libusb_device_handle *udh, bool *underrun_p) { return _usrp_get_status (udh, GS_TX_UNDERRUN, underrun_p); } bool -usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr, +usrp_i2c_write (struct libusb_device_handle *udh, int i2c_addr, const void *buf, int len) { if (len < 1 || len > MAX_EP0_PKTSIZE) @@ -958,7 +940,7 @@ usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr, bool -usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr, +usrp_i2c_read (struct libusb_device_handle *udh, int i2c_addr, void *buf, int len) { if (len < 1 || len > MAX_EP0_PKTSIZE) @@ -969,7 +951,7 @@ usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr, } bool -usrp_spi_write (struct usb_dev_handle *udh, +usrp_spi_write (struct libusb_device_handle *udh, int optional_header, int enables, int format, const void *buf, int len) { @@ -984,7 +966,7 @@ usrp_spi_write (struct usb_dev_handle *udh, bool -usrp_spi_read (struct usb_dev_handle *udh, +usrp_spi_read (struct libusb_device_handle *udh, int optional_header, int enables, int format, void *buf, int len) { @@ -998,7 +980,7 @@ usrp_spi_read (struct usb_dev_handle *udh, } bool -usrp_9862_write (struct usb_dev_handle *udh, int which_codec, +usrp_9862_write (struct libusb_device_handle *udh, int which_codec, int regno, int value) { if (0) @@ -1016,7 +998,7 @@ usrp_9862_write (struct usb_dev_handle *udh, int which_codec, } bool -usrp_9862_read (struct usb_dev_handle *udh, int which_codec, +usrp_9862_read (struct libusb_device_handle *udh, int which_codec, int regno, unsigned char *value) { return usrp_spi_read (udh, 0x80 | (regno & 0x3f), @@ -1026,7 +1008,7 @@ usrp_9862_read (struct usb_dev_handle *udh, int which_codec, } bool -usrp_9862_write_many (struct usb_dev_handle *udh, +usrp_9862_write_many (struct libusb_device_handle *udh, int which_codec, const unsigned char *buf, int len) @@ -1047,7 +1029,7 @@ usrp_9862_write_many (struct usb_dev_handle *udh, bool -usrp_9862_write_many_all (struct usb_dev_handle *udh, +usrp_9862_write_many_all (struct libusb_device_handle *udh, const unsigned char *buf, int len) { // FIXME handle 2/2 and 4/4 versions @@ -1059,7 +1041,7 @@ usrp_9862_write_many_all (struct usb_dev_handle *udh, } static void -power_down_9862s (struct usb_dev_handle *udh) +power_down_9862s (struct libusb_device_handle *udh) { static const unsigned char regs[] = { REG_RX_PWR_DN, 0x01, // everything @@ -1067,7 +1049,7 @@ power_down_9862s (struct usb_dev_handle *udh) REG_TX_MODULATOR, 0x00 // coarse & fine modulators disabled }; - switch (usrp_hw_rev (dev_handle_to_dev (udh))){ + switch (usrp_hw_rev (libusb_get_device (udh))){ case 0: break; @@ -1082,7 +1064,7 @@ power_down_9862s (struct usb_dev_handle *udh) static const int EEPROM_PAGESIZE = 16; bool -usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr, +usrp_eeprom_write (struct libusb_device_handle *udh, int i2c_addr, int eeprom_offset, const void *buf, int len) { unsigned char cmd[2]; @@ -1107,7 +1089,7 @@ usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr, } bool -usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr, +usrp_eeprom_read (struct libusb_device_handle *udh, int i2c_addr, int eeprom_offset, void *buf, int len) { unsigned char *p = (unsigned char *) buf; @@ -1169,7 +1151,7 @@ tx_slot_p (int slot) } bool -usrp_write_aux_dac (struct usb_dev_handle *udh, int slot, +usrp_write_aux_dac (struct libusb_device_handle *udh, int slot, int which_dac, int value) { int which_codec; @@ -1200,7 +1182,7 @@ usrp_write_aux_dac (struct usb_dev_handle *udh, int slot, bool -usrp_read_aux_adc (struct usb_dev_handle *udh, int slot, +usrp_read_aux_adc (struct libusb_device_handle *udh, int slot, int which_adc, int *value) { *value = 0; @@ -1279,7 +1261,7 @@ set_chksum (unsigned char *buf) } static usrp_dbeeprom_status_t -read_dboard_eeprom (struct usb_dev_handle *udh, +read_dboard_eeprom (struct libusb_device_handle *udh, int slot_id, unsigned char *buf) { int i2c_addr = slot_to_i2c_addr (slot_id); @@ -1303,7 +1285,7 @@ read_dboard_eeprom (struct usb_dev_handle *udh, } usrp_dbeeprom_status_t -usrp_read_dboard_eeprom (struct usb_dev_handle *udh, +usrp_read_dboard_eeprom (struct libusb_device_handle *udh, int slot_id, usrp_dboard_eeprom *eeprom) { unsigned char buf[DB_EEPROM_CLEN]; @@ -1323,7 +1305,7 @@ usrp_read_dboard_eeprom (struct usb_dev_handle *udh, } bool -usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id, +usrp_write_dboard_offsets (struct libusb_device_handle *udh, int slot_id, short offset0, short offset1) { unsigned char buf[DB_EEPROM_CLEN]; @@ -1343,15 +1325,19 @@ usrp_write_dboard_offsets (struct usb_dev_handle *udh, int slot_id, } std::string -usrp_serial_number(struct usb_dev_handle *udh) +usrp_serial_number(struct libusb_device_handle *udh) { - unsigned char iserial = usb_device(udh)->descriptor.iSerialNumber; + struct libusb_device_descriptor desc; + if (libusb_get_device_descriptor(libusb_get_device(udh), &desc) < 0) + fprintf (stderr, "usrp: libusb_get_device_descriptor failed\n"); + + unsigned char iserial = desc.iSerialNumber; if (iserial == 0) return ""; - char buf[1024]; - if (usb_get_string_simple(udh, iserial, buf, sizeof(buf)) < 0) + unsigned char buf[1024]; + if (libusb_get_string_descriptor_ascii(udh, iserial, buf, sizeof(buf)) < 0) return ""; - return buf; + return (char*) buf; } diff --git a/usrp/host/swig/usrp_prims.i b/usrp/host/swig/usrp_prims.i index 78a775cf1..25a3968a8 100644 --- a/usrp/host/swig/usrp_prims.i +++ b/usrp/host/swig/usrp_prims.i @@ -42,8 +42,8 @@ enum usrp_load_status_t { ULS_ERROR = 0, ULS_OK, ULS_ALREADY_LOADED }; -struct usb_dev_handle; -struct usb_device; +struct libusb_device_handle; +struct libusb_device; /*! * \brief initialize libusb; probe busses and devices. @@ -63,20 +63,20 @@ void usrp_rescan (); * configured USRP (firmware loaded) * unconfigured Cypress FX2 (only if fx2_ok_p is true) */ -struct usb_device *usrp_find_device (int nth, bool fx2_ok_p = false); +struct libusb_device *usrp_find_device (int nth, bool fx2_ok_p = false); -bool usrp_usrp_p (struct usb_device *q); //< is this a USRP -bool usrp_usrp0_p (struct usb_device *q); //< is this a USRP Rev 0 -bool usrp_usrp1_p (struct usb_device *q); //< is this a USRP Rev 1 -bool usrp_usrp2_p (struct usb_device *q); //< is this a USRP Rev 2 -int usrp_hw_rev (struct usb_device *q); //< return h/w rev code -bool usrp_fx2_p (struct usb_device *q); //< is this an unconfigured Cypress FX2 +bool usrp_usrp_p (struct libusb_device *q); //< is this a USRP +bool usrp_usrp0_p (struct libusb_device *q); //< is this a USRP Rev 0 +bool usrp_usrp1_p (struct libusb_device *q); //< is this a USRP Rev 1 +bool usrp_usrp2_p (struct libusb_device *q); //< is this a USRP Rev 2 +int usrp_hw_rev (struct libusb_device *q); //< return h/w rev code +bool usrp_fx2_p (struct libusb_device *q); //< is this an unconfigured Cypress FX2 -bool usrp_unconfigured_usrp_p (struct usb_device *q); //< some kind of unconfigured USRP -bool usrp_configured_usrp_p (struct usb_device *q); //< some kind of configured USRP +bool usrp_unconfigured_usrp_p (struct libusb_device *q); //< some kind of unconfigured USRP +bool usrp_configured_usrp_p (struct libusb_device *q); //< some kind of configured USRP /*! - * \brief given a usb_device return an instance of the appropriate usb_dev_handle + * \brief given a libusb_device return an instance of the appropriate libusb_device_handle * * These routines claim the specified interface and select the * correct alternate interface. (USB nomenclature is totally screwed!) @@ -84,14 +84,14 @@ bool usrp_configured_usrp_p (struct usb_device *q); //< some kind of configured * If interface can't be opened, or is already claimed by some other * process, 0 is returned. */ -struct usb_dev_handle *usrp_open_cmd_interface (struct usb_device *dev); -struct usb_dev_handle *usrp_open_rx_interface (struct usb_device *dev); -struct usb_dev_handle *usrp_open_tx_interface (struct usb_device *dev); +struct libusb_device_handle *usrp_open_cmd_interface (struct libusb_device *dev); +struct libusb_device_handle *usrp_open_rx_interface (struct libusb_device *dev); +struct libusb_device_handle *usrp_open_tx_interface (struct libusb_device *dev); /*! * \brief close interface. */ -bool usrp_close_interface (struct usb_dev_handle *udh); +bool usrp_close_interface (struct libusb_device_handle *udh); /*! * \brief load intel hex format file into USRP/Cypress FX2 (8051). @@ -103,7 +103,7 @@ bool usrp_close_interface (struct usb_dev_handle *udh); */ usrp_load_status_t -usrp_load_firmware (struct usb_dev_handle *udh, const char *filename, bool force); +usrp_load_firmware (struct libusb_device_handle *udh, const char *filename, bool force); /*! * \brief load intel hex format file into USRP FX2 (8051). @@ -122,7 +122,7 @@ usrp_load_firmware_nth (int nth, const char *filename, bool force); * \brief load fpga configuration bitstream */ usrp_load_status_t -usrp_load_fpga (struct usb_dev_handle *udh, const char *filename, bool force); +usrp_load_fpga (struct libusb_device_handle *udh, const char *filename, bool force); /*! * \brief load the regular firmware and fpga bitstream in the Nth USRP. @@ -136,12 +136,12 @@ bool usrp_load_standard_bits (int nth, bool force); %include <fpga_regs_standard.h> -bool usrp_write_fpga_reg (struct usb_dev_handle *udh, int reg, int value); +bool usrp_write_fpga_reg (struct libusb_device_handle *udh, int reg, int value); %inline %{ int -usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg) +usrp_read_fpga_reg (struct libusb_device_handle *udh, int reg) { int value; bool ok = usrp_read_fpga_reg (udh, reg, &value); @@ -153,37 +153,37 @@ usrp_read_fpga_reg (struct usb_dev_handle *udh, int reg) %} -bool usrp_set_fpga_reset (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_tx_enable (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_rx_enable (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_tx_reset (struct usb_dev_handle *udh, bool on); -bool usrp_set_fpga_rx_reset (struct usb_dev_handle *udh, bool on); -bool usrp_set_led (struct usb_dev_handle *udh, int which, bool on); +bool usrp_set_fpga_reset (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_tx_enable (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_rx_enable (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_tx_reset (struct libusb_device_handle *udh, bool on); +bool usrp_set_fpga_rx_reset (struct libusb_device_handle *udh, bool on); +bool usrp_set_led (struct libusb_device_handle *udh, int which, bool on); -bool usrp_check_rx_overrun (struct usb_dev_handle *udh, bool *overrun_p); -bool usrp_check_tx_underrun (struct usb_dev_handle *udh, bool *underrun_p); +bool usrp_check_rx_overrun (struct libusb_device_handle *udh, bool *overrun_p); +bool usrp_check_tx_underrun (struct libusb_device_handle *udh, bool *underrun_p); // i2c_read and i2c_write are limited to a maximum len of 64 bytes. -bool usrp_i2c_write (struct usb_dev_handle *udh, int i2c_addr, +bool usrp_i2c_write (struct libusb_device_handle *udh, int i2c_addr, void *buf, int len); -bool usrp_i2c_read (struct usb_dev_handle *udh, int i2c_addr, +bool usrp_i2c_read (struct libusb_device_handle *udh, int i2c_addr, void *buf, int len); // spi_read and spi_write are limited to a maximum of 64 bytes // See usrp_spi_defs.h for more info -bool usrp_spi_write (struct usb_dev_handle *udh, +bool usrp_spi_write (struct libusb_device_handle *udh, int optional_header, int enables, int format, unsigned char *buf, int len); -bool usrp_spi_read (struct usb_dev_handle *udh, +bool usrp_spi_read (struct libusb_device_handle *udh, int optional_header, int enables, int format, unsigned char *buf, int len); -bool usrp_9862_write (struct usb_dev_handle *udh, +bool usrp_9862_write (struct libusb_device_handle *udh, int which_codec, // [0, 1] int regno, // [0, 63] int value); // [0, 255] @@ -191,7 +191,7 @@ bool usrp_9862_write (struct usb_dev_handle *udh, %inline %{ int -usrp_9862_read (struct usb_dev_handle *udh, int which_codec, int reg) +usrp_9862_read (struct libusb_device_handle *udh, int which_codec, int reg) { unsigned char value; bool ok = usrp_9862_read (udh, which_codec, reg, &value); @@ -206,7 +206,7 @@ usrp_9862_read (struct usb_dev_handle *udh, int which_codec, int reg) %inline %{ bool -usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr, +usrp_eeprom_write (struct libusb_device_handle *udh, int i2c_addr, int eeprom_offset, const std::string buf) { return usrp_eeprom_write (udh, i2c_addr, eeprom_offset, @@ -214,7 +214,7 @@ usrp_eeprom_write (struct usb_dev_handle *udh, int i2c_addr, } std::string -usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr, +usrp_eeprom_read (struct libusb_device_handle *udh, int i2c_addr, int eeprom_offset, int len) { if (len <= 0) @@ -230,12 +230,12 @@ usrp_eeprom_read (struct usb_dev_handle *udh, int i2c_addr, %} -bool usrp_write_aux_dac (struct usb_dev_handle *uhd, int slot, +bool usrp_write_aux_dac (struct libusb_device_handle *uhd, int slot, int which_dac, int value); %inline %{ -int usrp_read_aux_adc (struct usb_dev_handle *udh, int slot, int which_adc) +int usrp_read_aux_adc (struct libusb_device_handle *udh, int slot, int which_adc) { int value; bool ok = usrp_read_aux_adc (udh, slot, which_adc, &value); @@ -253,7 +253,7 @@ int usrp_read_aux_adc (struct usb_dev_handle *udh, int slot, int which_adc) * Note that this only works on a configured usrp. * \returns non-zero length string iff successful. */ -std::string usrp_serial_number(struct usb_dev_handle *udh); +std::string usrp_serial_number(struct libusb_device_handle *udh); /*! * \brief usrp daughterboard id to name mapping |