summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2013-12-13 15:06:46 -0800
committerBen Hilburn <ben.hilburn@ettus.com>2013-12-13 15:06:46 -0800
commitd80a5b6bea659607b16cd3ece8d248dd8cd788ee (patch)
treed3f5a27108fd987e60e7bd83098cd2eb8b0c7ec4
parent03a1828944aebea34114634f885fdd46471cd211 (diff)
parent92b0b7ab6b8fcc795612054a07064351aa969e3a (diff)
downloaduhd-003_006_002_rc2.tar.gz
uhd-003_006_002_rc2.tar.bz2
uhd-003_006_002_rc2.zip
Merge branch 'master' into next003_006_002_rc2
-rw-r--r--host/CMakeLists.txt12
-rw-r--r--host/cmake/Modules/NSIS.template.in4
-rw-r--r--host/cmake/Modules/UHDUnitTest.cmake6
-rw-r--r--host/cmake/Toolchains/armv7athf_native.cmake8
-rw-r--r--host/cmake/Toolchains/oe-sdk_cross.cmake13
-rw-r--r--host/examples/network_relay.cpp3
-rw-r--r--host/include/uhd/utils/msg_task.hpp9
-rw-r--r--host/lib/convert/sse2_fc32_to_sc16.cpp2
-rw-r--r--host/lib/usrp/b200/b200_iface.cpp60
-rw-r--r--host/lib/usrp/b200/b200_iface.hpp2
-rw-r--r--host/lib/usrp/common/fx2_ctrl.cpp4
-rw-r--r--host/utils/CMakeLists.txt2
-rw-r--r--host/utils/b2xx_fx3_utils.cpp246
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;