diff options
Diffstat (limited to 'host')
| -rw-r--r-- | host/CMakeLists.txt | 12 | ||||
| -rw-r--r-- | host/cmake/Modules/NSIS.template.in | 4 | ||||
| -rw-r--r-- | host/cmake/Modules/UHDUnitTest.cmake | 6 | ||||
| -rw-r--r-- | host/cmake/Toolchains/armv7athf_native.cmake | 8 | ||||
| -rw-r--r-- | host/cmake/Toolchains/oe-sdk_cross.cmake | 13 | ||||
| -rw-r--r-- | host/examples/network_relay.cpp | 3 | ||||
| -rw-r--r-- | host/include/uhd/utils/msg_task.hpp | 9 | ||||
| -rw-r--r-- | host/lib/convert/sse2_fc32_to_sc16.cpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_iface.cpp | 60 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_iface.hpp | 2 | ||||
| -rw-r--r-- | host/lib/usrp/common/fx2_ctrl.cpp | 4 | ||||
| -rw-r--r-- | host/utils/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | host/utils/b2xx_fx3_utils.cpp | 246 | 
13 files changed, 248 insertions, 123 deletions
| diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 103266edd..d4d3591bc 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -84,9 +84,11 @@ SET(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "")  SET(UHD_RELEASE_MODE "${UHD_RELEASE_MODE}" CACHE STRING "UHD Release Mode")  IF(CMAKE_COMPILER_IS_GNUCXX) -    IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") -        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s") -    ENDIF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") +    IF(STRIP_BINARIES) +        IF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") +            set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s") +        ENDIF(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") +    ENDIF(STRIP_BINARIES)      ADD_DEFINITIONS(-Wall)      ADD_DEFINITIONS(-Wextra)      ADD_DEFINITIONS(-Wsign-compare) @@ -211,8 +213,8 @@ UHD_INSTALL(FILES  # Images download directory for utils/uhd_images_downloader.py  ######################################################################## -SET(UHD_IMAGES_MD5SUM "61db1170aaaadd787f5150b3eceab6f2") -SET(UHD_IMAGES_DOWNLOAD_SRC "http://files.ettus.com/binaries/maint_images/archive/uhd-images_003.006.002-rc1.zip") +SET(UHD_IMAGES_MD5SUM "35a522e2c57c61100027702a7d840060") +SET(UHD_IMAGES_DOWNLOAD_SRC "http://files.ettus.com/binaries/maint_images/archive/uhd-images_003.006.002-rc2.zip")  ########################################################################  # Register top level components diff --git a/host/cmake/Modules/NSIS.template.in b/host/cmake/Modules/NSIS.template.in index 3ab55d907..9d9322e27 100644 --- a/host/cmake/Modules/NSIS.template.in +++ b/host/cmake/Modules/NSIS.template.in @@ -695,6 +695,8 @@ Section "-Core installation"    CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\USRP2 Card Burner.lnk" "$INSTDIR\lib\uhd\utils\usrp2_card_burner_gui.py" "" "" "" SW_SHOWMINIMIZED    CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\USRP-N2XX Net Burner.lnk" "$INSTDIR\lib\uhd\utils\usrp_n2xx_net_burner_gui.py" "" "" "" SW_SHOWMINIMIZED    CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\UHD Images Downloader.lnk" "$INSTDIR\lib\uhd\utils\uhd_images_downloader.py" +  CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Application Manual.lnk" "$INSTDIR\share\doc\uhd\manual\html\index.html" +  CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\API Documentation.lnk" "$INSTDIR\share\doc\uhd\doxygen\html\classes.html"    ;Read a value from an InstallOptions INI file    !insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State" @@ -871,6 +873,8 @@ Section "Uninstall"    Delete "$SMPROGRAMS\$MUI_TEMP\USRP2 Card Burner.lnk"    Delete "$SMPROGRAMS\$MUI_TEMP\USRP-N2XX Net Burner.lnk"    Delete "$SMPROGRAMS\$MUI_TEMP\UHD Images Downloader.lnk" +  Delete "$SMPROGRAMS\$MUI_TEMP\Application Manual.lnk" +  Delete "$SMPROGRAMS\$MUI_TEMP\API Documentation.lnk"  @CPACK_NSIS_DELETE_ICONS_EXTRA@    ;Delete empty start menu parent diretories diff --git a/host/cmake/Modules/UHDUnitTest.cmake b/host/cmake/Modules/UHDUnitTest.cmake index 47cddc521..76fec14b8 100644 --- a/host/cmake/Modules/UHDUnitTest.cmake +++ b/host/cmake/Modules/UHDUnitTest.cmake @@ -64,7 +64,11 @@ function(UHD_ADD_TEST test_name)          list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}")          #generate a bat file that sets the environment and runs the test -        find_program(SHELL sh) +        if (CMAKE_CROSSCOMPILING) +                set(SHELL "/bin/sh") +        else(CMAKE_CROSSCOMPILING) +                find_program(SHELL sh) +        endif(CMAKE_CROSSCOMPILING)          set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)          file(WRITE ${sh_file} "#!${SHELL}\n")          #each line sets an environment variable diff --git a/host/cmake/Toolchains/armv7athf_native.cmake b/host/cmake/Toolchains/armv7athf_native.cmake new file mode 100644 index 000000000..d9d1e2598 --- /dev/null +++ b/host/cmake/Toolchains/armv7athf_native.cmake @@ -0,0 +1,8 @@ +######################################################################## +# Toolchain file for building native on a ARM Cortex A8 w/ NEON +# Usage: cmake -DCMAKE_TOOLCHAIN_FILE=<this file> <source directory> +######################################################################## +set(CMAKE_CXX_COMPILER g++) +set(CMAKE_C_COMPILER  gcc) +set(CMAKE_CXX_FLAGS "-march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard" CACHE STRING "" FORCE) +set(CMAKE_C_FLAGS ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE) #same flags for C sources diff --git a/host/cmake/Toolchains/oe-sdk_cross.cmake b/host/cmake/Toolchains/oe-sdk_cross.cmake new file mode 100644 index 000000000..ea77815c9 --- /dev/null +++ b/host/cmake/Toolchains/oe-sdk_cross.cmake @@ -0,0 +1,13 @@ +set( CMAKE_SYSTEM_NAME Linux ) +#set( CMAKE_C_COMPILER  $ENV{CC} ) +#set( CMAKE_CXX_COMPILER  $ENV{CXX} ) +set( CMAKE_CXX_FLAGS $ENV{CXXFLAGS}  CACHE STRING "" FORCE ) +set( CMAKE_C_FLAGS $ENV{CFLAGS} CACHE STRING "" FORCE ) #same flags for C sources +set( CMAKE_LDFLAGS_FLAGS ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE ) #same flags for C sources +set( CMAKE_LIBRARY_PATH ${OECORE_TARGET_SYSROOT}/usr/lib ) +set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_NATIVE_SYSROOT} $ENV{OECORE_TARGET_SYSROOT} ) +set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) +set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) +set ( ORC_INCLUDE_DIRS $ENV{OECORE_TARGET_SYSROOT}/usr/include/orc-0.4 ) +set ( ORC_LIBRARY_DIRS $ENV{OECORE_TARGET_SYSROOT}/usr/lib ) diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp index fc1ebd91d..0a67bbf09 100644 --- a/host/examples/network_relay.cpp +++ b/host/examples/network_relay.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2012 Ettus Research LLC +// Copyright 2010-2013 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 @@ -18,6 +18,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp>  #include <boost/program_options.hpp> +#include <boost/thread/condition_variable.hpp>  #include <boost/thread/thread.hpp>  #include <boost/format.hpp>  #include <boost/asio.hpp> diff --git a/host/include/uhd/utils/msg_task.hpp b/host/include/uhd/utils/msg_task.hpp index ebb29af08..40ee65cb1 100644 --- a/host/include/uhd/utils/msg_task.hpp +++ b/host/include/uhd/utils/msg_task.hpp @@ -24,14 +24,15 @@  #include <boost/function.hpp>  #include <boost/utility.hpp>  #include <boost/optional/optional.hpp> +#include <boost/cstdint.hpp>  #include <vector>  namespace uhd{  	class UHD_API msg_task : boost::noncopyable{          public:              typedef boost::shared_ptr<msg_task> sptr; -            typedef std::vector<uint8_t> msg_payload_t; -            typedef std::pair<uint32_t, msg_payload_t > msg_type_t; +            typedef std::vector<boost::uint8_t> msg_payload_t; +            typedef std::pair<boost::uint32_t, msg_payload_t > msg_type_t;              typedef boost::function<boost::optional<msg_type_t>(void)> task_fcn_type;              /* @@ -41,9 +42,9 @@ namespace uhd{               */              virtual msg_payload_t get_msg_from_dump_queue(boost::uint32_t sid) = 0; -            inline static std::vector<uint8_t> buff_to_vector(uint8_t* p, size_t n) { +            inline static std::vector<boost::uint8_t> buff_to_vector(boost::uint8_t* p, size_t n) {                  if(p and n > 0){ -                    std::vector<uint8_t> v(n); +                    std::vector<boost::uint8_t> v(n);                      memcpy(&v.front(), p, n);                      return v;                  } diff --git a/host/lib/convert/sse2_fc32_to_sc16.cpp b/host/lib/convert/sse2_fc32_to_sc16.cpp index a83e9b46c..69786d7ce 100644 --- a/host/lib/convert/sse2_fc32_to_sc16.cpp +++ b/host/lib/convert/sse2_fc32_to_sc16.cpp @@ -103,6 +103,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){      case 0x0:          // the data is 16-byte aligned, so do the fast processing of the bulk of the samples          convert_fc32_1_to_item32_1_bswap_guts(_) +        break;      case 0x8:          // the first value is 8-byte aligned - process it and prepare the bulk of the data for fast conversion          xx_to_item32_sc16<uhd::htonx>(input, output, 1, scale_factor); @@ -110,7 +111,6 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){          // do faster processing of the remaining samples now that we are 16-byte aligned          convert_fc32_1_to_item32_1_bswap_guts(_)          break; -        break;      default:          // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load          convert_fc32_1_to_item32_1_bswap_guts(u_) diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp index 7809781d8..5d799bf01 100644 --- a/host/lib/usrp/b200/b200_iface.cpp +++ b/host/lib/usrp/b200/b200_iface.cpp @@ -92,7 +92,7 @@ static hash_type generate_hash(const char *filename)  {      if (filename == NULL)          return hash_type(0); -     +      std::ifstream file(filename);      if (not file){          throw uhd::io_error(std::string("cannot open input file ") + filename); @@ -238,7 +238,7 @@ public:                            0, offset | (boost::uint16_t(addr) << 8),                            (unsigned char *) &bytes[0],                            bytes.size()); -         +          if (ret < 0)              throw uhd::io_error((boost::format("Failed to write EEPROM (%d: %s)") % ret % libusb_error_name(ret)).str());          else if ((size_t)ret != bytes.size()) @@ -254,12 +254,12 @@ public:                           0, offset | (boost::uint16_t(addr) << 8),                           (unsigned char*) &recv_bytes[0],                           num_bytes); -         +          if (bytes_read < 0)              throw uhd::io_error((boost::format("Failed to read EEPROM (%d: %s)") % bytes_read % libusb_error_name(bytes_read)).str());          else if ((size_t)bytes_read != num_bytes)              throw uhd::io_error((boost::format("Short read on read EEPROM (expecting: %d, returned: %d)") % num_bytes % bytes_read).str()); -         +          return recv_bytes;      } @@ -302,23 +302,23 @@ public:          const int bytes_to_write = 64;          const int bytes_to_read = 64;          const size_t read_retries = 30; -         +          int ret = fx3_control_write(B200_VREQ_AD9361_CTRL_WRITE, 0x00, 0x00, (unsigned char *)in_buff, bytes_to_write);          if (ret < 0)              throw uhd::io_error((boost::format("Failed to write AD9361 (%d: %s)") % ret % libusb_error_name(ret)).str());          else if (ret != bytes_to_write)              throw uhd::io_error((boost::format("Short write on write AD9361 (expecting: %d, returned: %d)") % bytes_to_write % ret).str()); -         +          for (size_t i = 0; i < read_retries; i++)          {              ret = fx3_control_read(B200_VREQ_AD9361_CTRL_READ, 0x00, 0x00, out_buff, bytes_to_read, 1000);              if (ret < 0)                  throw uhd::io_error((boost::format("Failed to read AD9361 (%d: %s)") % ret % libusb_error_name(ret)).str()); -             +              if (ret == bytes_to_read)                  return;          } -         +          throw uhd::io_error(str(boost::format("Failed to read complete AD9361 (expecting: %d, last read: %d)") % bytes_to_read % ret));      } @@ -456,13 +456,14 @@ public:      void set_fpga_reset_pin(const bool reset) {          unsigned char data[4];          memset(data, (reset)? 0xFF : 0x00, sizeof(data)); -        const int bytes_to_send = sizeof(data);          UHD_THROW_INVALID_CODE_PATH();          // Below is dead code as long as UHD_THROW_INVALID_CODE_PATH(); is declared above.          // It is preserved here in a comment in case it is needed later:          /* +        const int bytes_to_send = sizeof(data); +          int ret = fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, bytes_to_send);          if (ret < 0)              throw uhd::io_error((boost::format("Failed to reset FPGA (%d: %s)") % ret % libusb_error_name(ret)).str()); @@ -520,7 +521,7 @@ public:          const int bytes_to_recv = 4;          if (sizeof(hash_type) != bytes_to_recv)              throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_recv).str()); -             +          int ret = fx3_control_read(B200_VREQ_GET_FW_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_recv, 500);          if (ret < 0)              throw uhd::io_error((boost::format("Failed to get firmware hash (%d: %s)") % ret % libusb_error_name(ret)).str()); @@ -532,7 +533,7 @@ public:          const int bytes_to_send = 4;          if (sizeof(hash_type) != bytes_to_send)              throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_send).str()); -         +          int ret = fx3_control_write(B200_VREQ_SET_FW_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_send);          if (ret < 0)              throw uhd::io_error((boost::format("Failed to set firmware hash (%d: %s)") % ret % libusb_error_name(ret)).str()); @@ -544,7 +545,7 @@ public:          const int bytes_to_recv = 4;          if (sizeof(hash_type) != bytes_to_recv)              throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_recv).str()); -         +          int ret = fx3_control_read(B200_VREQ_GET_FPGA_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_recv, 500);          if (ret < 0)              throw uhd::io_error((boost::format("Failed to get FPGA hash (%d: %s)") % ret % libusb_error_name(ret)).str()); @@ -556,7 +557,7 @@ public:          const int bytes_to_send = 4;          if (sizeof(hash_type) != bytes_to_send)              throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_send).str()); -         +          int ret = fx3_control_write(B200_VREQ_SET_FPGA_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_send);          if (ret < 0)              throw uhd::io_error((boost::format("Failed to set FPGA hash (%d: %s)") % ret % libusb_error_name(ret)).str()); @@ -576,7 +577,7 @@ public:          hash_type hash = generate_hash(filename);          hash_type loaded_hash; usrp_get_fpga_hash(loaded_hash);          if (hash == loaded_hash) return 0; -         +          // Establish default largest possible control request transfer size based on operating USB speed          int transfer_size = VREQ_DEFAULT_SIZE;          int current_usb_speed = get_usb_speed(); @@ -584,11 +585,11 @@ public:              transfer_size = VREQ_MAX_SIZE_USB3;          else if (current_usb_speed != 2)              throw uhd::io_error("load_fpga: get_usb_speed returned invalid USB speed (not 2 or 3)."); -         +          UHD_ASSERT_THROW(transfer_size <= VREQ_MAX_SIZE); -         +          unsigned char out_buff[VREQ_MAX_SIZE]; -         +          // Request loopback read, which will indicate the firmware's current control request buffer size          // Make sure that if operating as USB2, requested length is within spec          int ntoread = std::min(transfer_size, (int)sizeof(out_buff)); @@ -611,7 +612,7 @@ public:          if (!file.good()) {              throw uhd::io_error("load_fpga: cannot open FPGA input file.");          } -         +          // Zero the hash, in case we abort programming another image and revert to the previously programmed image          usrp_set_fpga_hash(0); @@ -715,6 +716,29 @@ private:      usb_control::sptr _usb_ctrl;  }; + +std::string b200_iface::fx3_state_string(boost::uint8_t state) +{ +    switch (state) +    { +    case FX3_STATE_FPGA_READY: +        return std::string("Ready"); +    case FX3_STATE_CONFIGURING_FPGA: +        return std::string("Configuring FPGA"); +    case FX3_STATE_BUSY: +        return std::string("Busy"); +    case FX3_STATE_RUNNING: +        return std::string("Running"); +    case FX3_STATE_UNCONFIGURED: +        return std::string("Unconfigured"); +    case FX3_STATE_ERROR: +        return std::string("Error"); +    default: +        break; +    } +    return std::string("Unknown"); +} +  /***********************************************************************   * Make an instance of the implementation   **********************************************************************/ diff --git a/host/lib/usrp/b200/b200_iface.hpp b/host/lib/usrp/b200/b200_iface.hpp index 5b6eeede4..20b4a7a89 100644 --- a/host/lib/usrp/b200/b200_iface.hpp +++ b/host/lib/usrp/b200/b200_iface.hpp @@ -78,6 +78,8 @@ public:      virtual void write_eeprom(boost::uint16_t addr, boost::uint16_t offset, const uhd::byte_vector_t &bytes) = 0;      virtual uhd::byte_vector_t read_eeprom(boost::uint16_t addr, boost::uint16_t offset, size_t num_bytes) = 0; + +    static std::string fx3_state_string(boost::uint8_t state);  }; diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp index d68bf6058..6552f1b2d 100644 --- a/host/lib/usrp/common/fx2_ctrl.cpp +++ b/host/lib/usrp/common/fx2_ctrl.cpp @@ -184,8 +184,8 @@ public:             std::string record;             file >> record; -        if (!(record.length() > 0)) -            continue; +            if (!(record.length() > 0)) +                continue;              //check for valid record              if (not checksum(&record) or not parse_record(&record, len, addr, type, data)) { diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index f73690475..abf2a546b 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -47,7 +47,7 @@ SET(util_share_sources  IF(ENABLE_USB)      LIST(APPEND util_share_sources          fx2_init_eeprom.cpp -        b2xx_fx3_utils +        b2xx_fx3_utils.cpp      )      INCLUDE_DIRECTORIES(${LIBUSB_INCLUDE_DIRS})      # Additional include directories for b2xx_fx3_utils diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp index adacff9d0..96cd1f3e7 100644 --- a/host/utils/b2xx_fx3_utils.cpp +++ b/host/utils/b2xx_fx3_utils.cpp @@ -44,6 +44,27 @@  namespace po = boost::program_options;  namespace fs = boost::filesystem; +struct vid_pid_t { +    boost::uint16_t vid; +    boost::uint16_t pid; +}; +const static vid_pid_t known_vid_pids[] = { +    {FX3_VID, FX3_DEFAULT_PID}, +    {FX3_VID, FX3_REENUM_PID}, +    {B200_VENDOR_ID, B200_PRODUCT_ID} +    }; +const static std::vector<vid_pid_t> known_vid_pid_vector(known_vid_pids, known_vid_pids + (sizeof(known_vid_pids) / sizeof(known_vid_pids[0]))); +const static boost::uint8_t eeprom_init_values[] = { +    0x43, +    0x59, +    0x14, +    0xB2, +    (B200_PRODUCT_ID & 0xff), +    (B200_PRODUCT_ID >> 8), +    (B200_VENDOR_ID & 0xff), +    (B200_VENDOR_ID >> 8) +    }; +const static uhd::byte_vector_t eeprom_init_value_vector(eeprom_init_values, eeprom_init_values + (sizeof(eeprom_init_values) / sizeof(eeprom_init_values[0])));  //!used with lexical cast to parse a hex string  template <class T> struct to_hex{ @@ -96,6 +117,9 @@ int reset_usb()                  std::string file = fs::path((*it).filename()).string(); +                if (file.length() < 5) +                    continue; +                  if(file.compare(0, 5, "0000:") == 0) {                      /* Un-bind the device. */                      std::fstream unbind((devpath.string() + "unbind").c_str(), @@ -118,22 +142,30 @@ int reset_usb()      return 0;  } -uhd::transport::usb_device_handle::sptr open_device(const boost::uint16_t vid, const boost::uint16_t pid) +uhd::transport::usb_device_handle::sptr open_device(const boost::uint16_t vid, const boost::uint16_t pid, const bool user_supplied = false)  {      std::vector<uhd::transport::usb_device_handle::sptr> handles;      uhd::transport::usb_device_handle::sptr handle; +    vid_pid_t vp = {vid, pid};      try { -        handles = uhd::transport::usb_device_handle::get_device_list(vid, pid);                             // try caller's VID/PID first -        if (handles.size() == 0) -            handles = uhd::transport::usb_device_handle::get_device_list(FX3_VID, FX3_DEFAULT_PID);         // try default Cypress FX3 VID/PID next -        if (handles.size() == 0) -            handles = uhd::transport::usb_device_handle::get_device_list(FX3_VID, FX3_REENUM_PID);          // try reenumerated Cypress FX3 VID/PID next -        if (handles.size() == 0) -            handles = uhd::transport::usb_device_handle::get_device_list(B200_VENDOR_ID, B200_PRODUCT_ID);  // try default B200 VID/PID last +        // try caller's VID/PID first +        handles = uhd::transport::usb_device_handle::get_device_list(vp.vid,vp.pid); +        if (user_supplied && handles.size() == 0) +            std::cerr << (boost::format("Failed to open device with VID 0x%04x and PID 0x%04x - trying other known VID/PIDs") % vid % pid).str() << std::endl; + +        // try known VID/PIDs next +        for (size_t i = 0; handles.size() == 0 && i < known_vid_pid_vector.size(); i++) +        { +            vp = known_vid_pid_vector[i]; +            handles = uhd::transport::usb_device_handle::get_device_list(vp.vid,vp.pid); +        }          if (handles.size() > 0) +        {              handle = handles[0]; +            std::cout << (boost::format("Device opened (VID=0x%04x,PID=0x%04x)") % vp.vid % vp.pid).str() << std::endl; +        }          if (!handle)              std::cerr << "Cannot open device" << std::endl; @@ -141,7 +173,7 @@ uhd::transport::usb_device_handle::sptr open_device(const boost::uint16_t vid, c      catch(const std::exception &e) {          std::cerr << "Failed to communicate with the device!" << std::endl;          #ifdef UHD_PLATFORM_WIN32 -        std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details." << std::endl; +        std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/uhd_docs/manual/html/transport.html" << std::endl;          #endif /* UHD_PLATFORM_WIN32 */          handle.reset();      } @@ -163,7 +195,7 @@ b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr &      catch(const std::exception &e) {          std::cerr << "Failed to communicate with the device!" << std::endl;          #ifdef UHD_PLATFORM_WIN32 -        std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details." << std::endl; +        std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/uhd_docs/manual/html/transport.html" << std::endl;          #endif /* UHD_PLATFORM_WIN32 */          b200.reset();      } @@ -171,9 +203,83 @@ b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr &      return b200;  } +int read_eeprom(b200_iface::sptr& b200, uhd::byte_vector_t& data) +{ +    try { +        data = b200->read_eeprom(0x0, 0x0, 8); +    } catch (std::exception &e) { +        std::cerr << "Exception while reading EEPROM: " << e.what() << std::endl; +        return -1; +    } + +    return 0; +} + +int write_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data) +{ +    try { +        b200->write_eeprom(0x0, 0x0, data); +    } catch (std::exception &e) { +        std::cerr << "Exception while writing EEPROM: " << e.what() << std::endl; +        return -1; +    } + +    return 0; +} + +int verify_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data) +{ +    bool verified = true; +    uhd::byte_vector_t read_bytes; +    if (read_eeprom(b200, read_bytes)) +        return -1; + +    if (data.size() != read_bytes.size()) +    { +        std::cerr << "ERROR:  Only able to verify first " << std::min(data.size(), read_bytes.size()) << " bytes." << std::endl; +        verified = false; +    } + +    for (size_t i = 0; i < std::min(data.size(), read_bytes.size()); i++) { +        if (data[i] != read_bytes[i]) { +            verified = false; +            std::cerr << "Byte " << i << " Expected: " << data[i] << ", Got: " << read_bytes[i] << std::endl; +        } +    } + +    if (!verified) { +        std::cerr << "Verification failed" << std::endl; +        return -1; +    } + +    return 0; +} + +int write_and_verify_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data) +{ +    if (write_eeprom(b200, data)) +        return -1; +    if (verify_eeprom(b200, data)) +        return -1; + +    return 0; +} + +int erase_eeprom(b200_iface::sptr& b200) +{ +    uhd::byte_vector_t bytes(8); + +    memset(&bytes[0], 0xFF, 8); +    if (write_and_verify_eeprom(b200, bytes)) +        return -1; + +    return 0; +} +  boost::int32_t main(boost::int32_t argc, char *argv[]) {      boost::uint16_t vid, pid;      std::string pid_str, vid_str, fw_file, fpga_file; +    bool user_supplied_vid_pid = false;      po::options_description visible("Allowed options");      visible.add_options() @@ -205,15 +311,24 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {      desc.add(hidden);      po::variables_map vm; -    po::store(po::parse_command_line(argc, argv, desc), vm); -    po::notify(vm); + +    try { +        po::store(po::parse_command_line(argc, argv, desc), vm); +        po::notify(vm); +    } catch (std::exception &e) { +        std::cerr << "Exception while parsing arguments: " << e.what() << std::endl; +        std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; +        return ~0; +    }      if (vm.count("help")){          try {              std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl;          } catch(...) {}          return ~0; -    } else if (vm.count("reset-usb")) { +    } + +    if (vm.count("reset-usb")) {          return reset_usb();      } @@ -222,18 +337,20 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {      vid = B200_VENDOR_ID;   // Default      pid = B200_PRODUCT_ID;  // Default -    try { -        if (vm.count("vid")) +    if (vm.count("vid") && vm.count("pid")) +    { +        try {              vid = atoh(vid_str); -        if (vm.count("pid"))              pid = atoh(pid_str); -    } catch (std::exception &e) { -        std::cerr << "Exception while parsing VID and PID: " << e.what() << std:: endl; -        return ~0; +        } catch (std::exception &e) { +            std::cerr << "Exception while parsing VID and PID: " << e.what() << std:: endl; +            return ~0; +        } +        user_supplied_vid_pid = true;      }      // open the device -    handle = open_device(vid, pid); +    handle = open_device(vid, pid, user_supplied_vid_pid);      if (!handle)          return -1;      std::cout << "B2xx detected..." << std::flush; @@ -249,6 +366,13 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {      {          std::cout << "Overwriting existing firmware" << std::endl; +        // before we reset, make sure we have a good firmware file +        if(!(fs::exists(fw_file))) +        { +            std::cerr << "Invalid firmware filepath: " << fw_file << std::endl; +            return -1; +        } +          // reset the device          try {              b200->reset_fx3(); @@ -303,6 +427,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {          b200 = make_b200_iface(handle);          if (!b200)              return -1; + +        std::cout << "Firmware loaded" << std::endl;      }      // Added for testing purposes - not exposed @@ -310,12 +436,9 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {      {          uhd::byte_vector_t data; -        try { -            data = b200->read_eeprom(0x0, 0x0, 8); -        } catch (std::exception &e) { -            std::cerr << "Exception while reading EEPROM: " << e.what() << std::endl; +        if (read_eeprom(b200, data))              return -1; -        } +          for (int i = 0; i < 8; i++)              std::cout << i << ": " << boost::format("0x%X") % (int)data[i] << std::endl; @@ -325,34 +448,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {      // Added for testing purposes - not exposed      if (vm.count("erase-eeprom"))      { -        uhd::byte_vector_t bytes(8); -        memset(&bytes[0], 0xFF, 8); -        try { -            b200->write_eeprom(0x0, 0x0, bytes); -        } catch (uhd::exception &e) { -            std::cerr << "Exception while writing to EEPROM: " << e.what() << std::endl; +        if (erase_eeprom(b200))              return -1; -        } - -        // verify -        uhd::byte_vector_t read_bytes(8); -        try { -            read_bytes = b200->read_eeprom(0x0, 0x0, 8); -        } catch (uhd::exception &e) { -            std::cerr << "Exception while reading from EEPROM: " << e.what() << std::endl; -            return -1; -        } -        bool verified = true; -        for (int i = 0; i < 8; i++) { -            if (bytes[i] != read_bytes[i]) { -                verified = false; -                std::cerr << "Expected: " << bytes[i] << ", Got: " << read_bytes[i] << std::endl; -            } -        } -        if (!verified) { -            std::cerr << "Verification failed" << std::endl; -            return -1; -        }          std::cout << "Erase Successful!" << std::endl; @@ -362,16 +459,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {      // Added for testing purposes - not exposed      if (vm.count("uninit-device"))      { -        // uninitialize the device -        uhd::byte_vector_t bytes(8); -        memset(&bytes[0], 0xFF, 8); - -        try { -            b200->write_eeprom(0x0, 0x0, bytes); -        } catch (uhd::exception &e) { -            std::cerr << "Exception while writing to EEPROM: " << e.what() << std::endl; -            return -1; -        } +        // erase EEPROM +        erase_eeprom(b200);          std::cout << "EEPROM uninitialized, resetting device..."              << std::endl << std::endl; @@ -395,22 +484,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {      if (vm.count("init-device"))      {          /* Now, initialize the device. */ -        uhd::byte_vector_t bytes(8); -        bytes[0] = 0x43; -        bytes[1] = 0x59; -        bytes[2] = 0x14; -        bytes[3] = 0xB2; -        bytes[4] = (B200_PRODUCT_ID & 0xff); -        bytes[5] = (B200_PRODUCT_ID >> 8); -        bytes[6] = (B200_VENDOR_ID & 0xff); -        bytes[7] = (B200_VENDOR_ID >> 8); - -        try { -            b200->write_eeprom(0x0, 0x0, bytes); -        } catch (uhd::exception &e) { -            std::cerr << "Exception while writing to EEPROM: " << e.what() << std::endl; +        if (write_and_verify_eeprom(b200, eeprom_init_value_vector))              return -1; -        }          std::cout << "EEPROM initialized, resetting device..."              << std::endl << std::endl; @@ -439,8 +514,9 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {              return -1;          }          std::cout << "Currently operating at USB " << (int) speed << std::endl; +    } -    } else if (vm.count("reset-device")) { +    if (vm.count("reset-device")) {          try {b200->reset_fx3();}          catch (uhd::exception &e) {              std::cerr << "Exception while resetting FX3: " << e.what() << std::endl; @@ -454,10 +530,6 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {              return -1;          } -    } else if (vm.count("load-fw")) { -        std::cout << "Firmware load complete, releasing USB interface..." -            << std::endl; -      } else if (vm.count("load-fpga")) {          std::cout << "Loading FPGA image (" << fpga_file << ")" << std::endl;          uint32_t fx3_state; @@ -468,19 +540,13 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {          }          if (fx3_state != 0) { -            std::cerr << std::flush << "Error loading FPGA. FX3 state: " -            << fx3_state << std::endl; +            std::cerr << std::flush << "Error loading FPGA. FX3 state (" +                << fx3_state << "): " << b200_iface::fx3_state_string(fx3_state) << std::endl;              return ~0;          }          std::cout << "FPGA load complete, releasing USB interface..."              << std::endl; - -    } else { -        try { -            std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl; -        } catch(...) {} -        return ~0;      }      std::cout << "Operation complete!  I did it!  I did it!" << std::endl; | 
