aboutsummaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
Diffstat (limited to 'host')
-rw-r--r--host/AUTHORS.txt40
-rw-r--r--host/CMakeLists.txt9
-rw-r--r--host/LICENSE (renamed from host/LICENSE.txt)0
-rw-r--r--host/README.txt43
-rw-r--r--host/apps/omap_debug/README1
-rw-r--r--host/cmake/Modules/FindUSB1.cmake3
-rw-r--r--host/cmake/Modules/NSIS.template.in4
-rw-r--r--host/cmake/Modules/UHDPackage.cmake5
-rw-r--r--host/cmake/Modules/UHDUnitTest.cmake6
-rw-r--r--host/cmake/Modules/UHDVersion.cmake4
-rw-r--r--host/cmake/Toolchains/armv7athf_native.cmake8
-rw-r--r--host/cmake/Toolchains/oe-sdk_cross.cmake13
-rw-r--r--host/docs/uhd_find_devices.13
-rw-r--r--host/docs/uhd_images_downloader.13
-rw-r--r--host/docs/uhd_usrp_probe.12
-rw-r--r--host/examples/network_relay.cpp20
-rw-r--r--host/examples/test_dboard_coercion.cpp18
-rw-r--r--host/examples/test_messages.cpp5
-rw-r--r--host/include/uhd/config.hpp3
-rw-r--r--host/include/uhd/transport/zero_copy.hpp4
-rw-r--r--host/include/uhd/utils/atomic.hpp4
-rw-r--r--host/lib/convert/convert_fc32_item32.cpp17
-rw-r--r--host/lib/convert/convert_pack_sc12.cpp2
-rw-r--r--host/lib/convert/convert_unpack_sc12.cpp2
-rw-r--r--host/lib/convert/sse2_fc32_to_sc16.cpp38
-rw-r--r--host/lib/convert/sse2_sc16_to_fc32.cpp38
-rw-r--r--host/lib/transport/super_recv_packet_handler.hpp3
-rw-r--r--host/lib/transport/super_send_packet_handler.hpp2
-rw-r--r--host/lib/transport/udp_zero_copy.cpp3
-rw-r--r--host/lib/types/tune.cpp7
-rw-r--r--host/lib/usrp/README15
-rw-r--r--host/lib/usrp/b100/usb_zero_copy_wrapper.cpp1
-rw-r--r--host/lib/usrp/b200/b200_iface.cpp299
-rw-r--r--host/lib/usrp/b200/b200_iface.hpp2
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp4
-rw-r--r--host/lib/usrp/b200/b200_io_impl.cpp4
-rw-r--r--host/lib/usrp/common/fx2_ctrl.cpp6
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_200.cpp5
-rw-r--r--host/lib/usrp/cores/rx_dsp_core_3000.cpp5
-rw-r--r--host/lib/usrp/cores/rx_frontend_core_200.cpp2
-rw-r--r--host/lib/usrp/cores/time64_core_200.cpp1
-rw-r--r--host/lib/usrp/cores/tx_dsp_core_200.cpp3
-rw-r--r--host/lib/usrp/cores/tx_dsp_core_3000.cpp3
-rw-r--r--host/lib/usrp/dboard/db_dbsrx.cpp22
-rw-r--r--host/lib/usrp/dboard/db_tvrx.cpp2
-rw-r--r--host/lib/usrp/dboard/db_wbx_common.hpp2
-rw-r--r--host/lib/usrp/gps_ctrl.cpp2
-rw-r--r--host/lib/usrp/usrp1/io_impl.cpp2
-rw-r--r--host/lib/usrp/usrp1/usrp1_iface.cpp12
-rw-r--r--host/lib/usrp/usrp2/usrp2_clk_regs.hpp14
-rw-r--r--host/lib/usrp/usrp2/usrp2_iface.cpp2
-rw-r--r--host/lib/utils/paths.cpp5
-rw-r--r--host/tests/sph_recv_test.cpp8
-rw-r--r--host/tests/time_spec_test.cpp2
-rw-r--r--host/utils/CMakeLists.txt2
-rw-r--r--host/utils/b2xx_fx3_utils.cpp268
-rw-r--r--host/utils/uhd_images_downloader.py.in435
-rw-r--r--host/utils/usrp_n2xx_simple_net_burner.cpp12
58 files changed, 937 insertions, 513 deletions
diff --git a/host/AUTHORS.txt b/host/AUTHORS.txt
deleted file mode 100644
index 44b7516cd..000000000
--- a/host/AUTHORS.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Matt Ettus - matt@ettus.com
- USRP1 FPGA code
- USRP2/N200 FPGA code
- USRP-E100 FPGA code
-
-Josh Blum - josh@ettus.com
- driver framework
- USRP2/N200 firmware
- USRP2/N200 host code
- USRP-E100 host code
- Basic/LF host code
- XCVR2450 host code
- RFX Series host code
-
-Jason Abele - jason@ettus.com
- RFX Series host code
- WBX host code
- DBSRX host code
- DBSRX2 host code
-
-Eric Blossom - eb@comsec.com
- USRP1 firmware
- USRP2 firmware
-
-Tom Tsou - ttsou@vt.edu
- UHD-USB framework
- LIBUSB host code
- USRP1 host code
- USRP1 firmware
-
-Nick Foster - nick@ettus.com
- LIBUSB host code
- USRP1 host code
- TVRX host code
- USRP-N200 firmware
- USRP-N200 host code
-
-Philip Balister - philip@opensdr.com
- USRP-E100 kernel module
- USRP-E100 utilities
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt
index 15fd283f7..103266edd 100644
--- a/host/CMakeLists.txt
+++ b/host/CMakeLists.txt
@@ -201,9 +201,8 @@ ADD_CUSTOM_TARGET(uninstall
# Install Package Docs
########################################################################
UHD_INSTALL(FILES
- ${CMAKE_CURRENT_SOURCE_DIR}/README.txt
- ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt
- ${CMAKE_CURRENT_SOURCE_DIR}/AUTHORS.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/../README.md
+ ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE
DESTINATION ${PKG_DOC_DIR}
COMPONENT readme
)
@@ -212,8 +211,8 @@ UHD_INSTALL(FILES
# Images download directory for utils/uhd_images_downloader.py
########################################################################
-SET(UHD_IMAGES_MD5SUM "50e68637ae6e08b6e2b3557516bc115b")
-SET(UHD_IMAGES_DOWNLOAD_SRC "http://files.ettus.com/binaries/maint_images/archive/uhd-images_003.006.000-release.zip")
+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")
########################################################################
# Register top level components
diff --git a/host/LICENSE.txt b/host/LICENSE
index 9aa03b39b..9aa03b39b 100644
--- a/host/LICENSE.txt
+++ b/host/LICENSE
diff --git a/host/README.txt b/host/README.txt
deleted file mode 100644
index 0e8e62ac1..000000000
--- a/host/README.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-###############################################
-# Ettus Research - USRP Hardware Driver
-###############################################
-The hardware driver for Ettus Research products.
-
-###############################################
-# Supported USRP Motherboards
-###############################################
-USRP1
-USRP2
-N200
-N210
-E100
-E110
-B100
-B200
-
-###############################################
-# Supported USRP Daughterboards
-###############################################
-Basic RX
-Basic TX
-LF RX
-LF TX
-RFX Series
-XCVR 2450
-WBX + Simple GDB
-DBSRX
-DBSRX2
-TVRX
-TVRX2
-SBX
-CBX
-
-###############################################
-# Documentation
-###############################################
-Online documentation available at:
-http://code.ettus.com/redmine/ettus/projects/uhd/wiki
-
-The build system can generate the html for the manual and Doxygen.
-Docutils and Doxygen are required to build the html docs.
-See the docs directory for the manual source (reStructuredText).
diff --git a/host/apps/omap_debug/README b/host/apps/omap_debug/README
deleted file mode 100644
index bbe0c2cc4..000000000
--- a/host/apps/omap_debug/README
+++ /dev/null
@@ -1 +0,0 @@
-OMAP development tools go here
diff --git a/host/cmake/Modules/FindUSB1.cmake b/host/cmake/Modules/FindUSB1.cmake
index a494e1350..b2e4d118c 100644
--- a/host/cmake/Modules/FindUSB1.cmake
+++ b/host/cmake/Modules/FindUSB1.cmake
@@ -8,7 +8,8 @@ PKG_CHECK_MODULES(PC_LIBUSB QUIET libusb-1.0)
FIND_PATH(LIBUSB_INCLUDE_DIRS
NAMES libusb.h
- HINTS $ENV{LIBUSB_DIR}/include ${PC_LIBUSB_INCLUDEDIR}
+ HINTS $ENV{LIBUSB_DIR}/include $ENV{LIBUSB_DIR}/include/libusb-1.0
+ ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDEDIR}/libusb-1.0
PATHS /usr/local/include/libusb-1.0 /usr/local/include
/usr/include/libusb-1.0 /usr/include
/opt/local/include/libusb-1.0
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/UHDPackage.cmake b/host/cmake/Modules/UHDPackage.cmake
index 6af474f7a..4968571b5 100644
--- a/host/cmake/Modules/UHDPackage.cmake
+++ b/host/cmake/Modules/UHDPackage.cmake
@@ -99,9 +99,8 @@ SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Ettus Research - USRP Hardware Driver")
SET(CPACK_PACKAGE_VENDOR "Ettus Research LLC")
SET(CPACK_PACKAGE_CONTACT "Ettus Research <support@ettus.com>")
SET(CPACK_PACKAGE_VERSION "${UHD_VERSION}")
-SET(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_SOURCE_DIR}/README.txt)
-SET(CPACK_RESOURCE_FILE_README ${CMAKE_SOURCE_DIR}/AUTHORS.txt)
-SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt)
+SET(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_SOURCE_DIR}/../README.md)
+SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE)
########################################################################
# Setup CPack Source
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/Modules/UHDVersion.cmake b/host/cmake/Modules/UHDVersion.cmake
index c07b18f01..b0d04fe70 100644
--- a/host/cmake/Modules/UHDVersion.cmake
+++ b/host/cmake/Modules/UHDVersion.cmake
@@ -27,7 +27,7 @@ FIND_PACKAGE(Git QUIET)
########################################################################
SET(UHD_VERSION_MAJOR 003)
SET(UHD_VERSION_MINOR 006)
-SET(UHD_VERSION_PATCH 000)
+SET(UHD_VERSION_PATCH 002)
########################################################################
# Set up trimmed version numbers for DLL resource files and packages
@@ -87,7 +87,7 @@ IF(UHD_RELEASE_MODE)
#Ignore UHD_GIT_COUNT in UHD_VERSION if the string 'release' is in UHD_RELEASE_MODE
EXECUTE_PROCESS(
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
- COMMAND ${PYTHON_EXECUTABLE} -c "print 'release' in '${UHD_RELEASE_MODE}'"
+ COMMAND ${PYTHON_EXECUTABLE} -c "print ('release' in '${UHD_RELEASE_MODE}') or ('rc' in '${UHD_RELEASE_MODE}')"
OUTPUT_VARIABLE TRIM_UHD_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE
)
ENDIF()
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/docs/uhd_find_devices.1 b/host/docs/uhd_find_devices.1
index 7dc0dd470..08f9a789c 100644
--- a/host/docs/uhd_find_devices.1
+++ b/host/docs/uhd_find_devices.1
@@ -9,9 +9,6 @@ The UHD package is the universal hardware driver for Ettus Research
products. The goal is to provide a host driver and API for
current and future Ettus Research products. Users will be able to use
the UHD driver standalone or with 3rd party applications.
-.LP
-Hardware supporting UHD drivers includes the Universal Software Radio
-Peripheral, or USRP, available in several models.
.SH SYNOPSIS
.B uhd_find_devices [OPTIONS]
.SH OPTIONS
diff --git a/host/docs/uhd_images_downloader.1 b/host/docs/uhd_images_downloader.1
index ece826cb5..28310dd37 100644
--- a/host/docs/uhd_images_downloader.1
+++ b/host/docs/uhd_images_downloader.1
@@ -7,9 +7,6 @@ products. The goal of the UHD is to provide a host driver and API for
current and future Ettus Research products. Users will be able to use
the UHD driver standalone or with 3rd party applications.
.LP
-Hardware supporting UHD drivers includes the Universal Software Radio
-Peripheral, or USRP, available in several models.
-.LP
This program installs the firmware and FPGA binaries from Ettus Research
matching this UHD driver release onto the host system. If the uhd-images
package is installed, there is no need to run this installer.
diff --git a/host/docs/uhd_usrp_probe.1 b/host/docs/uhd_usrp_probe.1
index 7e82bf99a..a6c7150ee 100644
--- a/host/docs/uhd_usrp_probe.1
+++ b/host/docs/uhd_usrp_probe.1
@@ -1,6 +1,6 @@
.TH "uhd_usrp_probe" 1 "3.5.1" UHD "User Commands"
.SH NAME
-uhd_usrp_probe \- Universal Hardware Driver Peripheral Report Utility
+uhd_usrp_probe \- USRP Hardware Driver Peripheral Report Utility
.SH DESCRIPTION
Report detailed information on UHD-supported Software Radio Peripherals
attached by USB, network, or embedded configuration.
diff --git a/host/examples/network_relay.cpp b/host/examples/network_relay.cpp
index bb09296b3..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>
@@ -33,8 +34,6 @@ typedef boost::shared_ptr<asio::ip::udp::socket> socket_type;
static const size_t insane_mtu = 9000;
-boost::mutex spawn_mutex;
-
#if defined(UHD_PLATFORM_MACOS)
//limit buffer resize on macos or it will error
const size_t rx_dsp_buff_size = size_t(1e6);
@@ -100,14 +99,11 @@ public:
}
std::cout << "spawning relay threads... " << _port << std::endl;
+ boost::unique_lock<boost::mutex> lock(spawn_mutex); // lock in preparation to wait for threads to spawn
_thread_group.create_thread(boost::bind(&udp_relay_type::server_thread, this));
- spawn_mutex.lock();
- spawn_mutex.lock();
- spawn_mutex.unlock();
+ wait_for_thread.wait(lock); // wait for thread to spin up
_thread_group.create_thread(boost::bind(&udp_relay_type::client_thread, this));
- spawn_mutex.lock();
- spawn_mutex.lock();
- spawn_mutex.unlock();
+ wait_for_thread.wait(lock); // wait for thread to spin up
std::cout << " done!" << std::endl << std::endl;
}
@@ -128,7 +124,7 @@ private:
void server_thread(void){
uhd::set_thread_priority_safe();
std::cout << " entering server_thread..." << std::endl;
- spawn_mutex.unlock();
+ wait_for_thread.notify_one(); // notify constructor that this thread has started
std::vector<char> buff(insane_mtu);
while (not boost::this_thread::interruption_requested()){
if (wait_for_recv_ready(_server_socket->native())){
@@ -154,7 +150,7 @@ private:
void client_thread(void){
uhd::set_thread_priority_safe();
std::cout << " entering client_thread..." << std::endl;
- spawn_mutex.unlock();
+ wait_for_thread.notify_one(); // notify constructor that this thread has started
std::vector<char> buff(insane_mtu);
while (not boost::this_thread::interruption_requested()){
if (wait_for_recv_ready(_client_socket->native())){
@@ -172,6 +168,8 @@ private:
asio::ip::udp::endpoint _endpoint;
boost::mutex _endpoint_mutex;
socket_type _server_socket, _client_socket;
+ boost::mutex spawn_mutex;
+ boost::condition_variable wait_for_thread;
};
diff --git a/host/examples/test_dboard_coercion.cpp b/host/examples/test_dboard_coercion.cpp
index cfc745147..86c59d9d7 100644
--- a/host/examples/test_dboard_coercion.cpp
+++ b/host/examples/test_dboard_coercion.cpp
@@ -53,7 +53,7 @@ std::string return_USRP_config_string(uhd::usrp::multi_usrp::sptr usrp, bool tes
if(test_tx){
if(tx_info.get("tx_serial") != "") tx_serial = tx_info.get("tx_serial");
- else tx_serial = "no serial";
+ else tx_serial = "no serial";
tx_subdev_name = tx_info.get("tx_subdev_name");
tx_subdev_spec = tx_info.get("tx_subdev_spec");
@@ -121,7 +121,7 @@ std::string tx_test(uhd::usrp::multi_usrp::sptr usrp, bool test_gain, bool verbo
gains.push_back(current_gain);
current_gain++;
}
- if(gain_end != *gains.end()) gains.push_back(gain_end);
+ gains.push_back(gain_end);
}
@@ -182,19 +182,19 @@ std::string tx_test(uhd::usrp::multi_usrp::sptr usrp, bool test_gain, bool verbo
}
if(test_gain){
-
+
//Testing for successful gain tune
for(std::vector<double>::iterator g = gains.begin(); g != gains.end(); ++g){
usrp->set_tx_gain(*g);
boost::this_thread::sleep(boost::posix_time::microseconds(1000));
-
+
double actual_gain = usrp->get_tx_gain();
if(*g == 0.0){
if(actual_gain == 0.0){
if(verbose) std::cout << boost::format("TX gain successfully set to %5.2f at TX frequency %s.") % *g % return_MHz_string(*f) << std::endl;
- }
+ }
else{
if(verbose) std::cout << boost::format("TX gain set to %5.2f instead of %5.2f at TX frequency %s.") % actual_gain % *g % return_MHz_string(*f) << std::endl;
std::vector<double> bad_gain_freq;
@@ -313,7 +313,7 @@ std::string rx_test(uhd::usrp::multi_usrp::sptr usrp, bool test_gain, bool verbo
gains.push_back(current_gain);
current_gain++;
}
- if(gain_end != *gains.end()) gains.push_back(gain_end);
+ gains.push_back(gain_end);
}
@@ -518,7 +518,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << "REF must equal internal, external, or mimo." << std::endl;
return ~0;
}
-
+
if(vm.count("tx") + vm.count("rx") == 0){
std::cout << desc << std::endl;
std::cout << "Specify --tx to test for TX frequency coercion\n"
@@ -557,12 +557,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0);
std::cout << boost::format("Checking MIMO lock: %s ...") % mimo_locked.to_pp_string() << std::endl;
UHD_ASSERT_THROW(mimo_locked.to_bool());
- }
+ }
if ((ref == "external") and (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())) {
uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0);
std::cout << boost::format("Checking REF lock: %s ...") % ref_locked.to_pp_string() << std::endl;
UHD_ASSERT_THROW(ref_locked.to_bool());
- }
+ }
usrp_config = return_USRP_config_string(usrp, test_tx, test_rx);
if(test_tx) tx_results = tx_test(usrp, test_tx_gain, verbose);
if(test_rx) rx_results = rx_test(usrp, test_rx_gain, verbose);
diff --git a/host/examples/test_messages.cpp b/host/examples/test_messages.cpp
index e39a8bd30..4240e830b 100644
--- a/host/examples/test_messages.cpp
+++ b/host/examples/test_messages.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2011 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
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include <uhd/config.hpp>
#include <uhd/utils/thread_priority.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/static.hpp>
@@ -84,7 +85,7 @@ bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streame
* Issue a stream command with num samps and more.
* We expect to get an inline broken chain message.
*/
-bool test_broken_chain_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){
+bool test_broken_chain_message(UHD_UNUSED(uhd::usrp::multi_usrp::sptr usrp), uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){
std::cout << "Test broken chain message... " << std::flush;
uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE);
diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp
index 6fd2932cf..619bd0787 100644
--- a/host/include/uhd/config.hpp
+++ b/host/include/uhd/config.hpp
@@ -55,18 +55,21 @@ typedef ptrdiff_t ssize_t;
#define UHD_INLINE __forceinline
#define UHD_DEPRECATED __declspec(deprecated)
#define UHD_ALIGNED(x) __declspec(align(x))
+ #define UHD_UNUSED(x) x
#elif defined(__GNUG__) && __GNUG__ >= 4
#define UHD_EXPORT __attribute__((visibility("default")))
#define UHD_IMPORT __attribute__((visibility("default")))
#define UHD_INLINE inline __attribute__((always_inline))
#define UHD_DEPRECATED __attribute__((deprecated))
#define UHD_ALIGNED(x) __attribute__((aligned(x)))
+ #define UHD_UNUSED(x) x __attribute__((unused))
#else
#define UHD_EXPORT
#define UHD_IMPORT
#define UHD_INLINE inline
#define UHD_DEPRECATED
#define UHD_ALIGNED(x)
+ #define UHD_UNUSED(x) x
#endif
// Define API declaration macro
diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp
index fe2974d09..40d7b8c59 100644
--- a/host/include/uhd/transport/zero_copy.hpp
+++ b/host/include/uhd/transport/zero_copy.hpp
@@ -29,7 +29,9 @@ namespace uhd{ namespace transport{
//! Simple managed buffer with release interface
class UHD_API managed_buffer{
public:
- managed_buffer(void):_ref_count(0){}
+ managed_buffer(void):_ref_count(0),_buffer(NULL),_length(0){}
+
+ virtual ~managed_buffer(void) {}
/*!
* Signal to the transport that we are done with the buffer.
diff --git a/host/include/uhd/utils/atomic.hpp b/host/include/uhd/utils/atomic.hpp
index 8ddee73ca..55769d2fd 100644
--- a/host/include/uhd/utils/atomic.hpp
+++ b/host/include/uhd/utils/atomic.hpp
@@ -78,6 +78,10 @@ namespace uhd{
class UHD_API reusable_barrier{
public:
+ reusable_barrier():_size (0) {}
+
+ reusable_barrier(const size_t size):_size(size) {}
+
//! Resize the barrier for N threads
void resize(const size_t size){
_size = size;
diff --git a/host/lib/convert/convert_fc32_item32.cpp b/host/lib/convert/convert_fc32_item32.cpp
index 29bfefd46..641fc2608 100644
--- a/host/lib/convert/convert_fc32_item32.cpp
+++ b/host/lib/convert/convert_fc32_item32.cpp
@@ -28,7 +28,7 @@ typedef boost::uint32_t (*to32_type)(boost::uint32_t);
template <typename type, to32_type tohost>
struct convert_fc32_item32_1_to_star_1 : public converter
{
- convert_fc32_item32_1_to_star_1(void)
+ convert_fc32_item32_1_to_star_1(void):_scalar(0.0)
{
//NOP
}
@@ -48,9 +48,9 @@ struct convert_fc32_item32_1_to_star_1 : public converter
{
const item32_t i32 = tohost(input[i++]);
const item32_t q32 = tohost(input[i++]);
- const float i_f32 = reinterpret_cast<const float &>(i32);
- const float q_f32 = reinterpret_cast<const float &>(q32);
- output[o] = std::complex<type>(type(i_f32*_scalar), type(q_f32*_scalar));
+ const float *i_f32p = reinterpret_cast<const float *>(&i32);
+ const float *q_f32p = reinterpret_cast<const float *>(&q32);
+ output[o] = std::complex<type>(type((*i_f32p)*_scalar), type((*q_f32p)*_scalar));
}
}
@@ -60,7 +60,7 @@ struct convert_fc32_item32_1_to_star_1 : public converter
template <typename type, to32_type towire>
struct convert_star_1_to_fc32_item32_1 : public converter
{
- convert_star_1_to_fc32_item32_1(void)
+ convert_star_1_to_fc32_item32_1(void):_scalar(0.0)
{
//NOP
}
@@ -80,9 +80,10 @@ struct convert_star_1_to_fc32_item32_1 : public converter
{
const float i_f32 = type(input[i].real()*_scalar);
const float q_f32 = type(input[i].imag()*_scalar);
- const item32_t i32 = towire(reinterpret_cast<const item32_t &>(i_f32));
- const item32_t q32 = towire(reinterpret_cast<const item32_t &>(q_f32));
- output[o++] = i32; output[o++] = q32;
+ const item32_t *i32p = reinterpret_cast<const item32_t *>(&i_f32);
+ const item32_t *q32p = reinterpret_cast<const item32_t *>(&q_f32);
+ output[o++] = towire(*i32p);
+ output[o++] = towire(*q32p);
}
}
diff --git a/host/lib/convert/convert_pack_sc12.cpp b/host/lib/convert/convert_pack_sc12.cpp
index 680814994..92cd5d152 100644
--- a/host/lib/convert/convert_pack_sc12.cpp
+++ b/host/lib/convert/convert_pack_sc12.cpp
@@ -67,7 +67,7 @@ void convert_star_4_to_sc12_item32_3
template <typename type, towire32_type towire>
struct convert_star_1_to_sc12_item32_1 : public converter
{
- convert_star_1_to_sc12_item32_1(void)
+ convert_star_1_to_sc12_item32_1(void):_scalar(0.0)
{
//NOP
}
diff --git a/host/lib/convert/convert_unpack_sc12.cpp b/host/lib/convert/convert_unpack_sc12.cpp
index e98ab73f1..a2aec2ae5 100644
--- a/host/lib/convert/convert_unpack_sc12.cpp
+++ b/host/lib/convert/convert_unpack_sc12.cpp
@@ -84,7 +84,7 @@ void convert_sc12_item32_3_to_star_4
template <typename type, tohost32_type tohost>
struct convert_sc12_item32_1_to_star_1 : public converter
{
- convert_sc12_item32_1_to_star_1(void)
+ convert_sc12_item32_1_to_star_1(void):_scalar(0.0)
{
//NOP
}
diff --git a/host/lib/convert/sse2_fc32_to_sc16.cpp b/host/lib/convert/sse2_fc32_to_sc16.cpp
index 90bf0ed04..69786d7ce 100644
--- a/host/lib/convert/sse2_fc32_to_sc16.cpp
+++ b/host/lib/convert/sse2_fc32_to_sc16.cpp
@@ -27,6 +27,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){
const __m128 scalar = _mm_set_ps1(float(scale_factor));
+ // this macro converts values faster by using SSE intrinsics to convert 4 values at a time
#define convert_fc32_1_to_item32_1_nswap_guts(_al_) \
for (; i+3 < nsamps; i+=4){ \
/* load from input */ \
@@ -48,17 +49,25 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_SIMD){
size_t i = 0;
- //dispatch according to alignment
+ // need to dispatch according to alignment for fastest conversion
switch (size_t(input) & 0xf){
- case 0x8:
- xx_to_item32_sc16<uhd::htowx>(input, output, 1, scale_factor); i++;
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_nswap_guts(_)
+ break;
+ case 0x8:
+ // the first sample is 8-byte aligned - process it to align the remainder of the samples to 16-bytes
+ xx_to_item32_sc16<uhd::htowx>(input, output, 1, scale_factor);
+ i++;
+ // do faster processing of the bulk of the samples now that we are 16-byte aligned
convert_fc32_1_to_item32_1_nswap_guts(_)
break;
- default: convert_fc32_1_to_item32_1_nswap_guts(u_)
+ default:
+ // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load
+ convert_fc32_1_to_item32_1_nswap_guts(u_)
}
- //convert remainder
+ // convert any remaining samples
xx_to_item32_sc16<uhd::htowx>(input+i, output+i, nsamps-i, scale_factor);
}
@@ -68,6 +77,7 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){
const __m128 scalar = _mm_set_ps1(float(scale_factor));
+ // this macro converts values faster by using SSE intrinsics to convert 4 values at a time
#define convert_fc32_1_to_item32_1_bswap_guts(_al_) \
for (; i+3 < nsamps; i+=4){ \
/* load from input */ \
@@ -88,16 +98,24 @@ DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_SIMD){
size_t i = 0;
- //dispatch according to alignment
+ // need to dispatch according to alignment for fastest conversion
switch (size_t(input) & 0xf){
- case 0x8:
- xx_to_item32_sc16<uhd::htonx>(input, output, 1, scale_factor); i++;
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);
+ i++;
+ // do faster processing of the remaining samples now that we are 16-byte aligned
convert_fc32_1_to_item32_1_bswap_guts(_)
break;
- default: convert_fc32_1_to_item32_1_bswap_guts(u_)
+ 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_)
}
- //convert remainder
+ // convert any remaining samples
xx_to_item32_sc16<uhd::htonx>(input+i, output+i, nsamps-i, scale_factor);
}
diff --git a/host/lib/convert/sse2_sc16_to_fc32.cpp b/host/lib/convert/sse2_sc16_to_fc32.cpp
index c03e41585..0ac7f1798 100644
--- a/host/lib/convert/sse2_sc16_to_fc32.cpp
+++ b/host/lib/convert/sse2_sc16_to_fc32.cpp
@@ -28,6 +28,7 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){
const __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16));
const __m128i zeroi = _mm_setzero_si128();
+ // this macro converts values faster by using SSE intrinsics to convert 4 values at a time
#define convert_item32_1_to_fc32_1_nswap_guts(_al_) \
for (; i+3 < nsamps; i+=4){ \
/* load from input */ \
@@ -50,17 +51,25 @@ DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_SIMD){
size_t i = 0;
- //dispatch according to alignment
+ // need to dispatch according to alignment for fastest conversion
switch (size_t(output) & 0xf){
- case 0x8:
- item32_sc16_to_xx<uhd::htowx>(input, output, 1, scale_factor); i++;
case 0x0:
+ // the data is 16-byte aligned, so do the fast processing of the bulk of the samples
+ convert_item32_1_to_fc32_1_nswap_guts(_)
+ break;
+ case 0x8:
+ // the first sample is 8-byte aligned - process it to align the remainder of the samples to 16-bytes
+ item32_sc16_to_xx<uhd::htowx>(input, output, 1, scale_factor);
+ i++;
+ // do faster processing of the bulk of the samples now that we are 16-byte aligned
convert_item32_1_to_fc32_1_nswap_guts(_)
break;
- default: convert_item32_1_to_fc32_1_nswap_guts(u_)
+ default:
+ // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load and store
+ convert_item32_1_to_fc32_1_nswap_guts(u_)
}
- //convert remainder
+ // convert any remaining samples
item32_sc16_to_xx<uhd::htowx>(input+i, output+i, nsamps-i, scale_factor);
}
@@ -71,6 +80,7 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_SIMD){
const __m128 scalar = _mm_set_ps1(float(scale_factor)/(1 << 16));
const __m128i zeroi = _mm_setzero_si128();
+ // this macro converts values faster by using SSE intrinsics to convert 4 values at a time
#define convert_item32_1_to_fc32_1_bswap_guts(_al_) \
for (; i+3 < nsamps; i+=4){ \
/* load from input */ \
@@ -92,16 +102,24 @@ DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_SIMD){
size_t i = 0;
- //dispatch according to alignment
+ // need to dispatch according to alignment for fastest conversion
switch (size_t(output) & 0xf){
- case 0x8:
- item32_sc16_to_xx<uhd::htonx>(input, output, 1, scale_factor); i++;
case 0x0:
+ // the data is 16-byte aligned, so do the fast processing of the bulk of the samples
+ convert_item32_1_to_fc32_1_bswap_guts(_)
+ break;
+ case 0x8:
+ // the first sample is 8-byte aligned - process it to align the remainder of the samples to 16-bytes
+ item32_sc16_to_xx<uhd::htonx>(input, output, 1, scale_factor);
+ i++;
+ // do faster processing of the bulk of the samples now that we are 16-byte aligned
convert_item32_1_to_fc32_1_bswap_guts(_)
break;
- default: convert_item32_1_to_fc32_1_bswap_guts(u_)
+ default:
+ // we are not 8 or 16-byte aligned, so do fast processing with the unaligned load and store
+ convert_item32_1_to_fc32_1_bswap_guts(u_)
}
- //convert remainder
+ // convert any remaining samples
item32_sc16_to_xx<uhd::htonx>(input+i, output+i, nsamps-i, scale_factor);
}
diff --git a/host/lib/transport/super_recv_packet_handler.hpp b/host/lib/transport/super_recv_packet_handler.hpp
index 688228e49..5080182d6 100644
--- a/host/lib/transport/super_recv_packet_handler.hpp
+++ b/host/lib/transport/super_recv_packet_handler.hpp
@@ -246,7 +246,8 @@ private:
struct xport_chan_props_type{
xport_chan_props_type(void):
packet_count(0),
- handle_overflow(&handle_overflow_nop)
+ handle_overflow(&handle_overflow_nop),
+ fc_update_window(0)
{}
get_buff_type get_buff;
issue_stream_cmd_type issue_stream_cmd;
diff --git a/host/lib/transport/super_send_packet_handler.hpp b/host/lib/transport/super_send_packet_handler.hpp
index 41f030ea6..ae483d1f3 100644
--- a/host/lib/transport/super_send_packet_handler.hpp
+++ b/host/lib/transport/super_send_packet_handler.hpp
@@ -239,7 +239,7 @@ private:
size_t _header_offset_words32;
double _tick_rate, _samp_rate;
struct xport_chan_props_type{
- xport_chan_props_type(void):has_sid(false){}
+ xport_chan_props_type(void):has_sid(false),sid(0){}
get_buff_type get_buff;
bool has_sid;
boost::uint32_t sid;
diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp
index 166177177..7b6a476f5 100644
--- a/host/lib/transport/udp_zero_copy.cpp
+++ b/host/lib/transport/udp_zero_copy.cpp
@@ -68,7 +68,7 @@ static void check_registry_for_fast_send_threshold(const size_t mtu){
class udp_zero_copy_asio_mrb : public managed_recv_buffer{
public:
udp_zero_copy_asio_mrb(void *mem, int sock_fd, const size_t frame_size):
- _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size) { /*NOP*/ }
+ _mem(mem), _sock_fd(sock_fd), _frame_size(frame_size), _len(0) { /*NOP*/ }
void release(void){
_claimer.release();
@@ -87,6 +87,7 @@ public:
if (wait_for_recv_ready(_sock_fd, timeout)){
_len = ::recv(_sock_fd, (char *)_mem, _frame_size, 0);
+ UHD_ASSERT_THROW(_len > 0); // TODO: Handle case of recv error
index++; //advances the caller's buffer
return make(this, _mem, size_t(_len));
}
diff --git a/host/lib/types/tune.cpp b/host/lib/types/tune.cpp
index 154f0990f..7697bd966 100644
--- a/host/lib/types/tune.cpp
+++ b/host/lib/types/tune.cpp
@@ -24,7 +24,9 @@ using namespace uhd;
tune_request_t::tune_request_t(double target_freq):
target_freq(target_freq),
rf_freq_policy(POLICY_AUTO),
- dsp_freq_policy(POLICY_AUTO)
+ rf_freq(0.0),
+ dsp_freq_policy(POLICY_AUTO),
+ dsp_freq(0.0)
{
/* NOP */
}
@@ -33,7 +35,8 @@ tune_request_t::tune_request_t(double target_freq, double lo_off):
target_freq(target_freq),
rf_freq_policy(POLICY_MANUAL),
rf_freq(target_freq + lo_off),
- dsp_freq_policy(POLICY_AUTO)
+ dsp_freq_policy(POLICY_AUTO),
+ dsp_freq(0.0)
{
/* NOP */
}
diff --git a/host/lib/usrp/README b/host/lib/usrp/README
deleted file mode 100644
index 344209179..000000000
--- a/host/lib/usrp/README
+++ /dev/null
@@ -1,15 +0,0 @@
-########################################################################
-# lib USRP directories:
-########################################################################
-
-dboard:
- Daughterboard implementation code for all USRP daughterboards
-
-usrp1:
- Implementation code for the USB-based USRP Classic motherboard.
-
-usrp2:
- Implementation code for USRP2, USRP-N200, and USRP-N210.
-
-usrp_e100:
- Implementation code for USRP-E100.
diff --git a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp
index 2096e4ef4..451cdae50 100644
--- a/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp
+++ b/host/lib/usrp/b100/usb_zero_copy_wrapper.cpp
@@ -167,6 +167,7 @@ public:
usb_zero_copy_wrapper(zero_copy_if::sptr usb_zc, const size_t frame_boundary):
_internal_zc(usb_zc),
_frame_boundary(frame_boundary),
+ _last_recv_offset(0),
_next_recv_buff_index(0)
{
for (size_t i = 0; i < this->get_num_recv_frames(); i++){
diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp
index bb46fbfce..5d799bf01 100644
--- a/host/lib/usrp/b200/b200_iface.cpp
+++ b/host/lib/usrp/b200/b200_iface.cpp
@@ -17,6 +17,7 @@
#include "b200_iface.hpp"
+#include <uhd/config.hpp>
#include <uhd/utils/msg.hpp>
#include <uhd/exception.hpp>
#include <boost/functional/hash.hpp>
@@ -62,6 +63,7 @@ const static boost::uint8_t B200_VREQ_FX3_RESET = 0x99;
const static boost::uint8_t B200_VREQ_EEPROM_WRITE = 0xBA;
const static boost::uint8_t B200_VREQ_EEPROM_READ = 0xBB;
+const static boost::uint8_t FX3_STATE_UNDEFINED = 0x00;
const static boost::uint8_t FX3_STATE_FPGA_READY = 0x01;
const static boost::uint8_t FX3_STATE_CONFIGURING_FPGA = 0x02;
const static boost::uint8_t FX3_STATE_BUSY = 0x03;
@@ -88,6 +90,9 @@ typedef boost::uint32_t hash_type;
*/
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);
@@ -120,15 +125,15 @@ static hash_type generate_hash(const char *filename)
* \param record a line from an Intel HEX file
* \return true if record is valid, false otherwise
*/
-bool checksum(std::string *record) {
+bool checksum(const std::string& record) {
- size_t len = record->length();
+ size_t len = record.length();
unsigned int i;
unsigned char sum = 0;
unsigned int val;
for (i = 1; i < len; i += 2) {
- std::istringstream(record->substr(i, 2)) >> std::hex >> val;
+ std::istringstream(record.substr(i, 2)) >> std::hex >> val;
sum += val;
}
@@ -149,22 +154,25 @@ bool checksum(std::string *record) {
* \param data output data
* \return true if record is sucessfully read, false on error
*/
-bool parse_record(std::string *record, boost::uint16_t &len, \
+bool parse_record(const std::string& record, boost::uint16_t &len, \
boost::uint16_t &addr, boost::uint16_t &type, unsigned char* data) {
unsigned int i;
std::string _data;
unsigned int val;
- if (record->substr(0, 1) != ":")
+ if (record.substr(0, 1) != ":")
return false;
- std::istringstream(record->substr(1, 2)) >> std::hex >> len;
- std::istringstream(record->substr(3, 4)) >> std::hex >> addr;
- std::istringstream(record->substr(7, 2)) >> std::hex >> type;
+ std::istringstream(record.substr(1, 2)) >> std::hex >> len;
+ std::istringstream(record.substr(3, 4)) >> std::hex >> addr;
+ std::istringstream(record.substr(7, 2)) >> std::hex >> type;
+
+ if (len > (2 * (record.length() - 9))) // sanity check to prevent buffer overrun
+ return false;
for (i = 0; i < len; i++) {
- std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val;
+ std::istringstream(record.substr(9 + 2 * i, 2)) >> std::hex >> val;
data[i] = (unsigned char) val;
}
@@ -179,19 +187,16 @@ class b200_iface_impl : public b200_iface{
public:
b200_iface_impl(usb_control::sptr usb_ctrl):
- _usb_ctrl(usb_ctrl)
- {
+ _usb_ctrl(usb_ctrl) {
//NOP
}
-
int fx3_control_write(boost::uint8_t request,
boost::uint16_t value,
boost::uint16_t index,
unsigned char *buff,
boost::uint16_t length,
- boost::int32_t timeout = 0)
- {
+ boost::int32_t timeout = 0) {
return _usb_ctrl->submit(VRT_VENDOR_OUT, // bmReqeustType
request, // bRequest
value, // wValue
@@ -201,14 +206,12 @@ public:
timeout); // timeout
}
-
int fx3_control_read(boost::uint8_t request,
boost::uint16_t value,
boost::uint16_t index,
unsigned char *buff,
boost::uint16_t length,
- boost::int32_t timeout = 0)
- {
+ boost::int32_t timeout = 0) {
return _usb_ctrl->submit(VRT_VENDOR_IN, // bmReqeustType
request, // bRequest
value, // wValue
@@ -218,39 +221,45 @@ public:
timeout); // timeout
}
-
- void write_i2c(boost::uint16_t addr, const byte_vector_t &bytes)
+ void write_i2c(UHD_UNUSED(boost::uint16_t addr), UHD_UNUSED(const byte_vector_t &bytes))
{
throw uhd::not_implemented_error("b200 write i2c");
}
- byte_vector_t read_i2c(boost::uint16_t addr, size_t num_bytes)
+ byte_vector_t read_i2c(UHD_UNUSED(boost::uint16_t addr), UHD_UNUSED(size_t num_bytes))
{
throw uhd::not_implemented_error("b200 read i2c");
}
void write_eeprom(boost::uint16_t addr, boost::uint16_t offset,
- const byte_vector_t &bytes)
- {
- fx3_control_write(B200_VREQ_EEPROM_WRITE,
+ const byte_vector_t &bytes) {
+ int ret = fx3_control_write(B200_VREQ_EEPROM_WRITE,
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())
+ throw uhd::io_error((boost::format("Short write on write EEPROM (expecting: %d, returned: %d)") % bytes.size() % ret).str());
}
byte_vector_t read_eeprom(
boost::uint16_t addr,
boost::uint16_t offset,
- size_t num_bytes
- ){
+ size_t num_bytes) {
byte_vector_t recv_bytes(num_bytes);
int bytes_read = fx3_control_read(B200_VREQ_EEPROM_READ,
0, offset | (boost::uint16_t(addr) << 8),
(unsigned char*) &recv_bytes[0],
num_bytes);
- if (bytes_read != num_bytes)
- throw uhd::io_error("Failed to read data from EEPROM.");
+
+ 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;
}
@@ -258,8 +267,7 @@ public:
unsigned char *tx_data,
size_t num_tx_bits,
unsigned char *rx_data,
- size_t num_rx_bits
- ){
+ size_t num_rx_bits) {
int ret = 0;
boost::uint16_t tx_length = num_tx_bits / 8;
@@ -271,9 +279,10 @@ public:
0x00, tx_data, tx_length);
}
- if(ret < 0) {
- throw uhd::io_error("transact_spi: fx3_control_write failed!");
- }
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to write SPI (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != tx_length)
+ throw uhd::io_error((boost::format("Short write on write SPI (expecting: %d, returned: %d)") % tx_length % ret).str());
if(num_rx_bits) {
@@ -282,25 +291,38 @@ public:
ret = fx3_control_read(B200_VREQ_LOOP, 0x00, \
0x00, rx_data, total_length);
- if(ret < 0) {
- throw uhd::io_error("transact_spi: readback failed!");
- }
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to readback (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != total_length)
+ throw uhd::io_error((boost::format("Short read on readback (expecting: %d, returned: %d)") % total_length % ret).str());
}
}
void ad9361_transact(const unsigned char in_buff[64], unsigned char out_buff[64]) {
- fx3_control_write(B200_VREQ_AD9361_CTRL_WRITE, 0x00, 0x00, (unsigned char *)in_buff, 64);
- int ret = 0;
- for (size_t i = 0; i < 30; i++)
+ 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, 64, 1000);
- if (ret == 64) return;
+ 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("ad9361_transact failed with usb error: %d") % ret));
- }
+ throw uhd::io_error(str(boost::format("Failed to read complete AD9361 (expecting: %d, last read: %d)") % bytes_to_read % ret));
+ }
- void load_firmware(const std::string filestring, bool force = false)
+ void load_firmware(const std::string filestring, UHD_UNUSED(bool force) = false)
{
const char *filename = filestring.c_str();
@@ -330,8 +352,11 @@ public:
std::string record;
file >> record;
+ if (!(record.length() > 0))
+ continue;
+
/* Check for valid Intel HEX record. */
- if (!checksum(&record) || !parse_record(&record, len, \
+ if (!checksum(record) || !parse_record(record, len, \
lower_address_bits, type, data)) {
throw uhd::io_error("fx3_load_firmware: bad intel hex record checksum");
}
@@ -404,46 +429,75 @@ public:
throw uhd::io_error("fx3_load_firmware: No EOF record found.");
}
-
void reset_fx3(void) {
unsigned char data[4];
memset(data, 0x00, sizeof(data));
+ const int bytes_to_send = sizeof(data);
- fx3_control_write(B200_VREQ_FX3_RESET, 0x00, 0x00, data, 4);
+ int ret = fx3_control_write(B200_VREQ_FX3_RESET, 0x00, 0x00, data, bytes_to_send);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to reset FX3 (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on reset FX3 (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
void reset_gpif(void) {
unsigned char data[4];
memset(data, 0x00, sizeof(data));
+ const int bytes_to_send = sizeof(data);
- fx3_control_write(B200_VREQ_GPIF_RESET, 0x00, 0x00, data, 4);
+ int ret = fx3_control_write(B200_VREQ_GPIF_RESET, 0x00, 0x00, data, bytes_to_send);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to reset GPIF (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on reset GPIF (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
- void set_fpga_reset_pin(const bool reset)
- {
+ void set_fpga_reset_pin(const bool reset) {
unsigned char data[4];
memset(data, (reset)? 0xFF : 0x00, sizeof(data));
UHD_THROW_INVALID_CODE_PATH();
- fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, 4);
+ // 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());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on reset FPGA (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
+ */
}
boost::uint8_t get_usb_speed(void) {
unsigned char rx_data[1];
+ memset(rx_data, 0x00, sizeof(rx_data));
+ const int bytes_to_recv = sizeof(rx_data);
- fx3_control_read(B200_VREQ_GET_USB, 0x00, 0x00, rx_data, 1);
+ int ret = fx3_control_read(B200_VREQ_GET_USB, 0x00, 0x00, rx_data, bytes_to_recv);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get USB speed (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get USB speed (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
return boost::lexical_cast<boost::uint8_t>(rx_data[0]);
}
-
boost::uint8_t get_fx3_status(void) {
unsigned char rx_data[1];
+ memset(rx_data, 0x00, sizeof(rx_data));
+ const int bytes_to_recv = sizeof(rx_data);
- fx3_control_read(B200_VREQ_GET_STATUS, 0x00, 0x00, &rx_data[0], 1);
+ int ret = fx3_control_read(B200_VREQ_GET_STATUS, 0x00, 0x00, rx_data, bytes_to_recv);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get FX3 status (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get FX3 status (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
return boost::lexical_cast<boost::uint8_t>(rx_data[0]);
}
@@ -451,47 +505,79 @@ public:
boost::uint16_t get_compat_num(void) {
unsigned char rx_data[2];
+ memset(rx_data, 0x00, sizeof(rx_data));
+ const int bytes_to_recv = sizeof(rx_data);
- fx3_control_read(B200_VREQ_GET_COMPAT , 0x00, 0x00, rx_data, 2);
+ int ret = fx3_control_read(B200_VREQ_GET_COMPAT , 0x00, 0x00, rx_data, bytes_to_recv);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get compat num (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get compat num (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
- boost::uint16_t compat = 0x0000;
- compat |= (((uint16_t) rx_data[0]) << 8);
- compat |= (rx_data[1] & 0x00FF);
-
- return compat;
+ return (((uint16_t)rx_data[0]) << 8) | rx_data[1];
}
void usrp_get_firmware_hash(hash_type &hash) {
- fx3_control_read(B200_VREQ_GET_FW_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4, 500);
+ 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());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get firmware hash (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
}
void usrp_set_firmware_hash(hash_type hash) {
- fx3_control_write(B200_VREQ_SET_FW_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4);
+ 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());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on set firmware hash (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
void usrp_get_fpga_hash(hash_type &hash) {
- fx3_control_read(B200_VREQ_GET_FPGA_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4, 500);
+ 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());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get FPGA hash (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
}
void usrp_set_fpga_hash(hash_type hash) {
- fx3_control_write(B200_VREQ_SET_FPGA_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4);
+ 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());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on set FPGA hash (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
boost::uint32_t load_fpga(const std::string filestring) {
boost::uint8_t fx3_state = 0;
boost::uint32_t wait_count;
+ int ret = 0;
+ int bytes_to_xfer = 0;
const char *filename = filestring.c_str();
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();
@@ -499,16 +585,19 @@ 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 nread = fx3_control_read(B200_VREQ_LOOP, 0, 0, out_buff, std::min(transfer_size, (int)sizeof(out_buff)), 1000);
- if (nread <= 0)
- throw uhd::io_error("load_fpga: unable to complete firmware loopback request.");
+ int ntoread = std::min(transfer_size, (int)sizeof(out_buff));
+ int nread = fx3_control_read(B200_VREQ_LOOP, 0, 0, out_buff, ntoread, 1000);
+ if (nread < 0)
+ throw uhd::io_error((boost::format("load_fpga: unable to complete firmware loopback request (%d: %s)") % nread % libusb_error_name(nread)).str());
+ else if (nread != ntoread)
+ throw uhd::io_error((boost::format("load_fpga: short read on firmware loopback request (expecting: %d, returned: %d)") % ntoread % nread).str());
transfer_size = std::min(transfer_size, nread); // Select the smaller value
size_t file_size = 0;
@@ -520,18 +609,26 @@ public:
std::ifstream file;
file.open(filename, std::ios::in | std::ios::binary);
- if(!file.good()) {
+ 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);
+
memset(out_buff, 0x00, sizeof(out_buff));
- fx3_control_write(B200_VREQ_FPGA_CONFIG, 0, 0, out_buff, 1, 1000);
+ bytes_to_xfer = 1;
+ ret = fx3_control_write(B200_VREQ_FPGA_CONFIG, 0, 0, out_buff, bytes_to_xfer, 1000);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to start FPGA config (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_xfer)
+ throw uhd::io_error((boost::format("Short write on start FPGA config (expecting: %d, returned: %d)") % bytes_to_xfer % ret).str());
wait_count = 0;
do {
fx3_state = get_fx3_status();
- if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR)) {
+ if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) {
return fx3_state;
}
@@ -543,13 +640,18 @@ public:
if (load_img_msg) UHD_MSG(status) << "Loading FPGA image: " \
<< filestring << "..." << std::flush;
- fx3_control_write(B200_VREQ_FPGA_START, 0, 0, out_buff, 1, 1000);
+ bytes_to_xfer = 1;
+ ret = fx3_control_write(B200_VREQ_FPGA_START, 0, 0, out_buff, bytes_to_xfer, 1000);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to start FPGA bitstream (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_xfer)
+ throw uhd::io_error((boost::format("Short write on start FPGA bitstream (expecting: %d, returned: %d)") % bytes_to_xfer % ret).str());
wait_count = 0;
do {
fx3_state = get_fx3_status();
- if((wait_count >= 1000) || (fx3_state == FX3_STATE_ERROR)) {
+ if((wait_count >= 1000) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) {
return fx3_state;
}
@@ -559,19 +661,20 @@ public:
} while(fx3_state != FX3_STATE_CONFIGURING_FPGA);
size_t bytes_sent = 0;
- while(!file.eof()) {
+ while (!file.eof()) {
file.read((char *) out_buff, transfer_size);
const std::streamsize n = file.gcount();
- if(n == 0) continue;
+ if(n == 0)
+ continue;
boost::uint16_t transfer_count = boost::uint16_t(n);
/* Send the data to the device. */
int nwritten = fx3_control_write(B200_VREQ_FPGA_DATA, 0, 0, out_buff, transfer_count, 5000);
- if (nwritten <= 0)
- throw uhd::io_error("load_fpga: cannot write bitstream to FX3.");
+ if (nwritten < 0)
+ throw uhd::io_error((boost::format("load_fpga: cannot write bitstream to FX3 (%d: %s)") % nwritten % libusb_error_name(nwritten)).str());
else if (nwritten != transfer_count)
- throw uhd::io_error("load_fpga: short write while transferring bitstream to FX3.");
+ throw uhd::io_error((boost::format("load_fpga: short write while transferring bitstream to FX3 (expecting: %d, returned: %d)") % transfer_count % nwritten).str());
if (load_img_msg)
{
@@ -592,7 +695,7 @@ public:
do {
fx3_state = get_fx3_status();
- if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR)) {
+ if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) {
return fx3_state;
}
@@ -603,7 +706,8 @@ public:
usrp_set_fpga_hash(hash);
- if (load_img_msg) UHD_MSG(status) << "\b\b\b\b done" << std::endl;
+ if (load_img_msg)
+ UHD_MSG(status) << "\b\b\b\b done" << std::endl;
return 0;
}
@@ -612,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/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index 362c45347..bee42679b 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -44,9 +44,9 @@
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/weak_ptr.hpp>
#include "recv_packet_demuxer_3000.hpp"
-static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 0x03;
+static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 0x04;
static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0x00;
-static const boost::uint16_t B200_FPGA_COMPAT_NUM = 0x02;
+static const boost::uint16_t B200_FPGA_COMPAT_NUM = 0x03;
static const double B200_LINK_RATE_BPS = (5e9)/8; //practical link rate (5 Gbps)
static const double B200_BUS_CLOCK_RATE = 100e6;
static const double B200_DEFAULT_TICK_RATE = 32e6;
diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp
index 4fe90bd4a..4768aa37b 100644
--- a/host/lib/usrp/b200/b200_io_impl.cpp
+++ b/host/lib/usrp/b200/b200_io_impl.cpp
@@ -249,14 +249,14 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_)
//calculate packet size
static const size_t hdr_size = 0
+ vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
- //+ sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer
+ //+ sizeof(vrt::if_packet_info_t().tlr) //no longer using trailer
- sizeof(vrt::if_packet_info_t().cid) //no class id ever used
- sizeof(vrt::if_packet_info_t().tsi) //no int time ever used
;
const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size;
const size_t bpi = convert::get_bytes_per_item(args.otw_format);
size_t spp = unsigned(args.args.cast<double>("spp", bpp/bpi));
- spp = std::min<size_t>(2000, spp); //magic maximum for framing at full rate
+ spp = std::min<size_t>(4092, spp); //FPGA FIFO maximum for framing at full rate
//make the new streamer given the samples per packet
if (not my_streamer) my_streamer = boost::make_shared<sph::recv_packet_streamer>(spp);
diff --git a/host/lib/usrp/common/fx2_ctrl.cpp b/host/lib/usrp/common/fx2_ctrl.cpp
index 6111efea9..6552f1b2d 100644
--- a/host/lib/usrp/common/fx2_ctrl.cpp
+++ b/host/lib/usrp/common/fx2_ctrl.cpp
@@ -119,6 +119,9 @@ bool parse_record(std::string *record, unsigned int &len,
std::istringstream(record->substr(3, 4)) >> std::hex >> addr;
std::istringstream(record->substr(7, 2)) >> std::hex >> type;
+ if (len > (2 * (record->length() - 9))) // sanity check to prevent buffer overrun
+ return false;
+
for (i = 0; i < len; i++) {
std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val;
data[i] = (unsigned char) val;
@@ -181,6 +184,9 @@ public:
std::string record;
file >> record;
+ if (!(record.length() > 0))
+ continue;
+
//check for valid record
if (not checksum(&record) or not parse_record(&record, len, addr, type, data)) {
throw uhd::io_error("usrp_load_firmware: bad record checksum");
diff --git a/host/lib/usrp/cores/rx_dsp_core_200.cpp b/host/lib/usrp/cores/rx_dsp_core_200.cpp
index ef6b85de9..2fdc220b5 100644
--- a/host/lib/usrp/cores/rx_dsp_core_200.cpp
+++ b/host/lib/usrp/cores/rx_dsp_core_200.cpp
@@ -59,8 +59,11 @@ public:
const size_t dsp_base, const size_t ctrl_base,
const boost::uint32_t sid, const bool lingering_packet
):
- _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid)
+ _iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid)
{
+ // previously uninitialized - assuming zero for all
+ _tick_rate = _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0;
+
//init to something so update method has reasonable defaults
_scaling_adjustment = 1.0;
_dsp_extra_scaling = 1.0;
diff --git a/host/lib/usrp/cores/rx_dsp_core_3000.cpp b/host/lib/usrp/cores/rx_dsp_core_3000.cpp
index 7b3324f74..525916032 100644
--- a/host/lib/usrp/cores/rx_dsp_core_3000.cpp
+++ b/host/lib/usrp/cores/rx_dsp_core_3000.cpp
@@ -50,10 +50,13 @@ public:
):
_iface(iface), _dsp_base(dsp_base)
{
+ // previously uninitialized - assuming zero for all
+ _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0;
+
//init to something so update method has reasonable defaults
_scaling_adjustment = 1.0;
_dsp_extra_scaling = 1.0;
- this->set_tick_rate(1.0);
+ _tick_rate = 1.0;
}
~rx_dsp_core_3000_impl(void)
diff --git a/host/lib/usrp/cores/rx_frontend_core_200.cpp b/host/lib/usrp/cores/rx_frontend_core_200.cpp
index 09b36c1a6..864b5cc53 100644
--- a/host/lib/usrp/cores/rx_frontend_core_200.cpp
+++ b/host/lib/usrp/cores/rx_frontend_core_200.cpp
@@ -38,7 +38,7 @@ static boost::uint32_t fs_to_bits(const double num, const size_t bits){
class rx_frontend_core_200_impl : public rx_frontend_core_200{
public:
rx_frontend_core_200_impl(wb_iface::sptr iface, const size_t base):
- _iface(iface), _base(base)
+ _i_dc_off(0), _q_dc_off(0), _iface(iface), _base(base)
{
//NOP
}
diff --git a/host/lib/usrp/cores/time64_core_200.cpp b/host/lib/usrp/cores/time64_core_200.cpp
index 11b310362..ad5e6477c 100644
--- a/host/lib/usrp/cores/time64_core_200.cpp
+++ b/host/lib/usrp/cores/time64_core_200.cpp
@@ -48,6 +48,7 @@ public:
):
_iface(iface), _base(base),
_readback_bases(readback_bases),
+ _tick_rate(0.0),
_mimo_delay_cycles(mimo_delay_cycles)
{
_sources.push_back("none");
diff --git a/host/lib/usrp/cores/tx_dsp_core_200.cpp b/host/lib/usrp/cores/tx_dsp_core_200.cpp
index 808f13028..f8aa87aa3 100644
--- a/host/lib/usrp/cores/tx_dsp_core_200.cpp
+++ b/host/lib/usrp/cores/tx_dsp_core_200.cpp
@@ -60,6 +60,9 @@ public:
):
_iface(iface), _dsp_base(dsp_base), _ctrl_base(ctrl_base), _sid(sid)
{
+ // previously uninitialized - assuming zero for all
+ _tick_rate = _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0;
+
//init to something so update method has reasonable defaults
_scaling_adjustment = 1.0;
_dsp_extra_scaling = 1.0;
diff --git a/host/lib/usrp/cores/tx_dsp_core_3000.cpp b/host/lib/usrp/cores/tx_dsp_core_3000.cpp
index feb749cd9..93c8702bc 100644
--- a/host/lib/usrp/cores/tx_dsp_core_3000.cpp
+++ b/host/lib/usrp/cores/tx_dsp_core_3000.cpp
@@ -45,6 +45,9 @@ public:
):
_iface(iface), _dsp_base(dsp_base)
{
+ // previously uninitialized - assuming zero for all
+ _link_rate = _host_extra_scaling = _fxpt_scalar_correction = 0.0;
+
//init to something so update method has reasonable defaults
_scaling_adjustment = 1.0;
_dsp_extra_scaling = 1.0;
diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp
index b1cee4aa7..9d04d8e16 100644
--- a/host/lib/usrp/dboard/db_dbsrx.cpp
+++ b/host/lib/usrp/dboard/db_dbsrx.cpp
@@ -179,7 +179,7 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){
"DBSRX: incorrect dbid\n"
"Expected dbid 0x0002 and R193\n"
"found dbid == %d\n"
- "Please see the daughterboard app notes"
+ "Please see the daughterboard app notes"
) % this->get_rx_id().to_pp_string();
//warn user about incorrect DBID on non-USRP1, requires R194 populated
@@ -188,7 +188,7 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){
"DBSRX: incorrect dbid\n"
"Expected dbid 0x000D and R194\n"
"found dbid == %d\n"
- "Please see the daughterboard app notes"
+ "Please see the daughterboard app notes"
) % this->get_rx_id().to_pp_string();
//send initial register settings
@@ -305,13 +305,13 @@ double dbsrx::set_lo_freq(double target_freq){
goto done_loop;
}
- }
+ }
done_loop:
- //Assert because we failed to find a suitable combination of ref_clock, R and N
+ //Assert because we failed to find a suitable combination of ref_clock, R and N
UHD_ASSERT_THROW(ref_clock <= 27.0e6 and ref_clock >= 0.0);
- UHD_ASSERT_THROW(ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6);
+ UHD_ASSERT_THROW(m and ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6);
UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) and (pfd_freq <= dbsrx_pfd_freq_range.stop()));
UHD_ASSERT_THROW((N >= 256) and (N <= 32768));
@@ -332,7 +332,7 @@ double dbsrx::set_lo_freq(double target_freq){
_max2118_write_regs.r_divider = (max2118_write_regs_t::r_divider_t) r;
_max2118_write_regs.set_n_divider(N);
_max2118_write_regs.ade_vco_ade_read = max2118_write_regs_t::ADE_VCO_ADE_READ_ENABLED;
-
+
//compute prescaler variables
int scaler = actual_freq > 1125e6 ? 2 : 4;
_max2118_write_regs.div2 = scaler == 4 ? max2118_write_regs_t::DIV2_DIV4 : max2118_write_regs_t::DIV2_DIV2;
@@ -377,7 +377,7 @@ double dbsrx::set_lo_freq(double target_freq){
if (_max2118_read_regs.adc == 0){
if (_max2118_write_regs.osc_band == 0){
UHD_MSG(warning) << boost::format(
- "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n"
+ "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n"
) % int(_max2118_write_regs.osc_band);
UHD_ASSERT_THROW(_max2118_read_regs.adc != 0); //just to cause a throw
}
@@ -389,7 +389,7 @@ double dbsrx::set_lo_freq(double target_freq){
if (_max2118_read_regs.adc == 7){
if (_max2118_write_regs.osc_band == 7){
UHD_MSG(warning) << boost::format(
- "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n"
+ "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n"
) % int(_max2118_write_regs.osc_band);
UHD_ASSERT_THROW(_max2118_read_regs.adc != 7); //just to cause a throw
}
@@ -408,7 +408,7 @@ double dbsrx::set_lo_freq(double target_freq){
//allow for setup time before checking condition again
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
}
-
+
UHD_LOGV(often) << boost::format(
"DBSRX: final vco %d, vtune adc %d"
) % int(_max2118_write_regs.osc_band) % int(_max2118_read_regs.adc) << std::endl;
@@ -417,7 +417,7 @@ double dbsrx::set_lo_freq(double target_freq){
if (_max2118_read_regs.adc <= 2) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_100UA;
else if (_max2118_read_regs.adc >= 5) _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_400UA;
else _max2118_write_regs.cp_current = max2118_write_regs_t::CP_CURRENT_I_CP_200UA;
-
+
//update charge pump bias current setting
send_reg(0x2, 0x2);
@@ -524,7 +524,7 @@ double dbsrx::set_bandwidth(double bandwidth){
bandwidth = dbsrx_bandwidth_range.clip(bandwidth);
double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX);
-
+
//NOTE: _max2118_write_regs.m_divider set in set_lo_freq
//compute f_dac setting
diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp
index edee46cd5..e9f60f765 100644
--- a/host/lib/usrp/dboard/db_tvrx.cpp
+++ b/host/lib/usrp/dboard/db_tvrx.cpp
@@ -267,7 +267,7 @@ static std::string get_band(double freq) {
* \return a voltage to feed the TVRX analog gain
*/
-static double gain_interp(double gain, boost::array<double, 17> db_vector, boost::array<double, 17> volts_vector) {
+static double gain_interp(double gain, const boost::array<double, 17>& db_vector, const boost::array<double, 17>& volts_vector) {
double volts;
gain = uhd::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here
diff --git a/host/lib/usrp/dboard/db_wbx_common.hpp b/host/lib/usrp/dboard/db_wbx_common.hpp
index 9e984dce7..d1beb160e 100644
--- a/host/lib/usrp/dboard/db_wbx_common.hpp
+++ b/host/lib/usrp/dboard/db_wbx_common.hpp
@@ -118,7 +118,7 @@ protected:
*/
class wbx_versionx {
public:
- wbx_versionx() {}
+ wbx_versionx():self_base(NULL) {}
~wbx_versionx(void) {}
virtual double set_tx_gain(double gain, const std::string &name) = 0;
diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp
index c3af75faa..105a52b30 100644
--- a/host/lib/usrp/gps_ctrl.cpp
+++ b/host/lib/usrp/gps_ctrl.cpp
@@ -223,7 +223,6 @@ private:
boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
}
throw uhd::value_error(str(boost::format("get_nmea(): no %s message found") % msgtype));
- return std::string();
}
//helper function to retrieve a field from an NMEA sentence
@@ -322,7 +321,6 @@ private:
boost::this_thread::sleep(milliseconds(GPS_TIMEOUT_DELAY_MS));
}
throw uhd::value_error("get_stat(): no servo message found");
- return std::string();
}
uart_iface::sptr _uart;
diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp
index d384eb13f..e1f17e5a6 100644
--- a/host/lib/usrp/usrp1/io_impl.cpp
+++ b/host/lib/usrp/usrp1/io_impl.cpp
@@ -63,7 +63,7 @@ static const size_t alignment_padding = 512;
* Helper struct to associate an offset with a buffer
**********************************************************************/
struct offset_send_buffer{
- offset_send_buffer(void){
+ offset_send_buffer(void):offset(0){
/* NOP */
}
diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp
index 9301721aa..6eff9d3ad 100644
--- a/host/lib/usrp/usrp1/usrp1_iface.cpp
+++ b/host/lib/usrp/usrp1/usrp1_iface.cpp
@@ -91,11 +91,11 @@ public:
return uhd::ntohx(value_out);
}
-
+
void poke16(boost::uint32_t, boost::uint16_t) {
throw uhd::not_implemented_error("Unhandled command poke16()");
}
-
+
boost::uint16_t peek16(boost::uint32_t) {
throw uhd::not_implemented_error("Unhandled command peek16()");
return 0;
@@ -141,8 +141,10 @@ public:
if (readback) {
unsigned char buff[4] = {
- (bits >> 0) & 0xff, (bits >> 8) & 0xff,
- (bits >> 16) & 0xff, (bits >> 24) & 0xff
+ (unsigned char)(bits & 0xff),
+ (unsigned char)((bits >> 8) & 0xff),
+ (unsigned char)((bits >> 16) & 0xff),
+ (unsigned char)((bits >> 24) & 0xff)
};
//conditions where there are two header bytes
if (num_bytes >= 3 and buff[num_bytes-1] != 0 and buff[num_bytes-2] != 0 and buff[num_bytes-3] == 0){
@@ -168,7 +170,7 @@ public:
(((boost::uint32_t)buff[1]) << 8) |
(((boost::uint32_t)buff[2]) << 16) |
(((boost::uint32_t)buff[3]) << 24);
- return val;
+ return val;
}
else {
// Byteswap on num_bytes
diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp
index 8b185eac0..d5e506d8d 100644
--- a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp
+++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp
@@ -22,8 +22,18 @@
class usrp2_clk_regs_t {
public:
- usrp2_clk_regs_t(void) { ; }
+ usrp2_clk_regs_t(void):
+ test(0),
+ fpga(0),
+ adc(0),
+ dac(0),
+ serdes(0),
+ exp(0),
+ tx_db(0),
+ rx_db(0) {}
+
usrp2_clk_regs_t(usrp2_iface::rev_type rev) {
+ fpga = adc = serdes = exp = tx_db = 0;
test = 0;
fpga = 1;
dac = 3;
@@ -54,7 +64,7 @@ public:
//dont throw, it may be unitialized
break;
}
-
+
rx_db = 7;
}
diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp
index 3b230ca69..5f97045e1 100644
--- a/host/lib/usrp/usrp2/usrp2_iface.cpp
+++ b/host/lib/usrp/usrp2/usrp2_iface.cpp
@@ -271,7 +271,7 @@ public:
//send and recv
usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data, MIN_PROTO_COMPAT_I2C);
UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_HERES_THE_I2C_DATA_DUDE);
- UHD_ASSERT_THROW(in_data.data.i2c_args.addr = num_bytes);
+ UHD_ASSERT_THROW(in_data.data.i2c_args.bytes == num_bytes);
//copy out the data
byte_vector_t result(num_bytes);
diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp
index 25cade693..3e2bea1c6 100644
--- a/host/lib/utils/paths.cpp
+++ b/host/lib/utils/paths.cpp
@@ -115,8 +115,8 @@ std::string uhd::get_tmp_path(void){
//try the stdio define if available
#ifdef P_tmpdir
- if (P_tmpdir != NULL) return P_tmpdir;
- #endif
+ return P_tmpdir;
+ #else
//try unix environment variables
tmp_path = std::getenv("TMPDIR");
@@ -124,6 +124,7 @@ std::string uhd::get_tmp_path(void){
//give up and use the unix default
return "/tmp";
+ #endif
}
std::string uhd::get_app_path(void){
diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp
index 9339a9739..316e24779 100644
--- a/host/tests/sph_recv_test.cpp
+++ b/host/tests/sph_recv_test.cpp
@@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){
//check the received packets
size_t num_accum_samps = 0;
- std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS];
std::vector<std::complex<float> *> buffs(NCHANNELS);
for (size_t ch = 0; ch < NCHANNELS; ch++){
buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
@@ -481,7 +481,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){
//check the received packets
size_t num_accum_samps = 0;
- std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS];
std::vector<std::complex<float> *> buffs(NCHANNELS);
for (size_t ch = 0; ch < NCHANNELS; ch++){
buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
@@ -574,7 +574,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){
//check the received packets
size_t num_accum_samps = 0;
- std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS];
std::vector<std::complex<float> *> buffs(NCHANNELS);
for (size_t ch = 0; ch < NCHANNELS; ch++){
buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
@@ -659,7 +659,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){
//check the received packets
size_t num_accum_samps = 0;
- std::vector<std::complex<float> > mem(NUM_SAMPS_PER_BUFF*NCHANNELS);
+ std::complex<float> mem[NUM_SAMPS_PER_BUFF*NCHANNELS];
std::vector<std::complex<float> *> buffs(NCHANNELS);
for (size_t ch = 0; ch < NCHANNELS; ch++){
buffs[ch] = &mem[ch*NUM_SAMPS_PER_BUFF];
diff --git a/host/tests/time_spec_test.cpp b/host/tests/time_spec_test.cpp
index 37a039cc5..c9b9652f9 100644
--- a/host/tests/time_spec_test.cpp
+++ b/host/tests/time_spec_test.cpp
@@ -117,6 +117,7 @@ BOOST_AUTO_TEST_CASE(test_time_error_irrational_rate)
const uhd::time_spec_t ts = uhd::time_spec_t::from_ticks(tick_in, rate);
const long long tick_out = ts.to_ticks(rate);
const long long err = tick_in - tick_out;
+ std::streamsize precision = std::cout.precision();
std::cout << std::setprecision(18);
std::cout << "time ............ " << ts.get_real_secs() << std::endl;
@@ -124,6 +125,7 @@ BOOST_AUTO_TEST_CASE(test_time_error_irrational_rate)
std::cout << "tick out ........ " << tick_out << std::endl;
std::cout << "tick error ...... " << err << std::endl;
std::cout << std::endl;
+ std::cout.precision(precision);
BOOST_CHECK_EQUAL(err, (long long)(0));
}
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 c182548b7..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,13 +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);
- if (vm.count("help")){
+ 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;
- } else if (vm.count("reset-usb")) {
+ }
+
+ if (vm.count("help")){
+ try {
+ std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl;
+ } catch(...) {}
+ return ~0;
+ }
+
+ if (vm.count("reset-usb")) {
return reset_usb();
}
@@ -220,13 +337,20 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
vid = B200_VENDOR_ID; // Default
pid = B200_PRODUCT_ID; // Default
- if (vm.count("vid"))
- vid = atoh(vid_str);
- if (vm.count("pid"))
- pid = atoh(pid_str);
+ if (vm.count("vid") && vm.count("pid"))
+ {
+ try {
+ vid = atoh(vid_str);
+ pid = atoh(pid_str);
+ } 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;
@@ -242,8 +366,19 @@ 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
- b200->reset_fx3();
+ try {
+ b200->reset_fx3();
+ } catch (std::exception &e) {
+ std::cerr << "Exception while reseting FX3: " << e.what() << std::endl;
+ }
// re-open device
b200.reset();
@@ -264,19 +399,24 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
if (fw_file.empty())
fw_file = uhd::find_image_path(B200_FW_FILE_NAME);
-
+
if(fw_file.empty()) {
std::cerr << "Firmware image not found!" << std::endl;
return -1;
}
-
+
if(!(fs::exists(fw_file))) {
std::cerr << "Invalid filepath: " << fw_file << std::endl;
return -1;
}
// load firmware
- b200->load_firmware(fw_file);
+ try {
+ b200->load_firmware(fw_file);
+ } catch (std::exception &e) {
+ std::cerr << "Exception while loading firmware: " << e.what() << std::endl;
+ return ~0;
+ }
// re-open device
b200.reset();
@@ -287,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
@@ -294,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;
@@ -309,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;
- 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;
+ if (erase_eeprom(b200))
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;
@@ -346,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;
@@ -379,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;
@@ -403,7 +494,7 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
try {
b200->reset_fx3();
} catch (const std::exception &e) {
- std::cerr << "Exceptions while resetting device: " << e.what() << std::endl;
+ std::cerr << "Exception while resetting device: " << e.what() << std::endl;
return -1;
}
@@ -423,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;
@@ -438,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;
@@ -452,17 +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 {
- std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl;
- return ~0;
}
std::cout << "Operation complete! I did it! I did it!" << std::endl;
diff --git a/host/utils/uhd_images_downloader.py.in b/host/utils/uhd_images_downloader.py.in
index bb082190c..697bd4e16 100644
--- a/host/utils/uhd_images_downloader.py.in
+++ b/host/utils/uhd_images_downloader.py.in
@@ -16,144 +16,341 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import atexit
-import hashlib
+import sys, os, string, tempfile, math
+import traceback
+import shutil, hashlib, urllib2, zipfile
+
from optparse import OptionParser
-import os
-import os.path
-import shutil
-import string
-import sys
-import tempfile
-import urllib2
-import zipfile
+
+_DEFAULT_BUFFER_SIZE = 8192
+_BASE_DIR_STRUCTURE_PARTS = ["share", "uhd", "images"]
+_BASE_DIR_STRUCTURE = os.path.join(_BASE_DIR_STRUCTURE_PARTS)
+_DEFAULT_INSTALL_PATH = os.path.join("@CMAKE_INSTALL_PREFIX@", *_BASE_DIR_STRUCTURE)
+_AUTOGEN_IMAGES_SOURCE = "@UHD_IMAGES_DOWNLOAD_SRC@"
+_AUTOGEN_IMAGES_CHECKSUM = "@UHD_IMAGES_MD5SUM@"
+_IMAGES_CHECKSUM_TYPE = "md5"
+_CONTACT = "support@ettus.com"
def md5Checksum(filePath):
- with open(filePath, 'rb') as fh:
- m = hashlib.md5()
- while True:
- data = fh.read(8192)
- if not data:
- break
- m.update(data)
- return m.hexdigest()
+ try:
+ with open(filePath, 'rb') as fh:
+ m = hashlib.md5()
+ while True:
+ data = fh.read(_DEFAULT_BUFFER_SIZE)
+ if not data:
+ break
+ m.update(data)
+ return m.hexdigest()
+ except Exception, e:
+ print "Failed to calculated MD5 sum of: %s (%s)" % (filePath, e)
+ raise e
-class temp_dir():
+_checksum_fns = {
+ 'md5': md5Checksum
+}
+class temporary_directory():
def __enter__(self):
- self.name = tempfile.mkdtemp()
- return self.name
+ try:
+ self.name = tempfile.mkdtemp()
+ return self.name
+ except Exception, e:
+ print "Failed to create a temporary directory (%s)" % (e)
+ raise e
+
+ # Can return 'True' to suppress incoming exception
def __exit__(self, type, value, traceback):
try:
shutil.rmtree(self.name)
- except OSError,e:
- #Utility should have already detected this, but this is for safety
- print str(e)
- raise Exception("Could not install images! Make sure you have write permissions.")
-
-if __name__ == "__main__":
-
- print
- if os.environ.get("UHD_IMAGES_DIR") != None and os.environ.get("UHD_IMAGES_DIR") != "":
- default_images_dir = os.environ.get("UHD_IMAGES_DIR")
- print "UHD_IMAGES_DIR environment variable is set. Default install location: %s" % default_images_dir
- else:
- default_images_dir = "@CMAKE_INSTALL_PREFIX@/share/uhd/images"
+ except Exception, e:
+ print "Could not delete temporary directory: %s (%s)" % (self.name, e)
- #Command line options
- parser = OptionParser()
- parser.add_option("--install-location", type="string", default=default_images_dir, help="Set custom install location for images")
- parser.add_option("--buffer-size", type="int", default=8192, help="Set download buffer size, [default=%default]",)
- (options, args) = parser.parse_args()
+class uhd_images_downloader():
+ def __init__(self):
+ pass
- #Configuring image download info
- images_src = "@UHD_IMAGES_DOWNLOAD_SRC@"
- images_zip_md5sum = "@UHD_IMAGES_MD5SUM@"
- filename = images_src.split("/")[-1]
-
- #Use this directory with relative paths
- current_directory = os.getcwd()
-
- with temp_dir() as dirname:
- os.chdir(dirname)
-
- if os.path.isabs(options.install_location):
- #Custom absolute path given
- images_dir = options.install_location
- else:
- #Custom relative path given, so construct absolute path
- images_dir = os.path.abspath(os.path.join(current_directory, options.install_location))
-
- #Before doing anything, check for write permissions in parent directory
- parent_directory = os.path.dirname(images_dir)
- if os.access(parent_directory, os.W_OK):
- print "Downloading images to: %s" % images_dir
- else:
- print "You do not have write permissions at the install location!"
- sys.exit(1)
-
+ def download(self, images_url, filename, buffer_size=_DEFAULT_BUFFER_SIZE, print_progress=False):
opener = urllib2.build_opener()
opener.add_headers = [('User-Agent', 'UHD Images Downloader')]
- u = opener.open(images_src)
- f = open(filename, "wb")
+ u = opener.open(images_url)
meta = u.info()
filesize = float(meta.getheaders("Content-Length")[0])
- print "Downloading images from: %s" % images_src
+ filesize_dl = 0
- filesize_dl = 0.0
-
- #Downloading file
- while True:
- buffer = u.read(options.buffer_size)
- if not buffer:
- break
-
- filesize_dl -= len(buffer)
- f.write(buffer)
+ with open(filename, "wb") as f:
+ while True:
+ buffer = u.read(buffer_size)
+ if not buffer:
+ break
+
+ f.write(buffer)
- status = r"%2.2f MB/%2.2f MB (%3.2f" % (-filesize_dl/1e6, filesize/1e6, (-filesize_dl*100.)/filesize) + r"%)"
- status += chr(8)*(len(status)+1)
- print status,
+ filesize_dl += len(buffer)
+
+ if print_progress:
+ status = r"%05d kB / %05d kB (%03d%%)" % (int(math.ceil(filesize_dl/1000.)), int(math.ceil(filesize/1000.)), int(math.ceil(filesize_dl*100.)/filesize))
+ status += chr(8)*(len(status)+1)
+ print status,
- f.close()
-
- #Checking md5sum of zip file
- downloaded_zip_md5sum = md5Checksum(filename)
- if images_zip_md5sum != downloaded_zip_md5sum:
- print "\nMD5 checksum does not match!"
- print "Expected %s, got %s" % (images_zip_md5sum, downloaded_zip_md5sum)
- print "Images did not install. If problem persists, please contact support@ettus.com."
- os.remove(filename)
- os.chdir("/".join(images_dir.split("/")[:-1]))
- sys.exit(1)
+ if print_progress:
+ print
+
+ return (filesize, filesize_dl)
+
+ def check_directories(self, dirs, print_progress=False):
+ if dirs is None or dirs == "":
+ dirs = "."
+ dirs = os.path.abspath(dirs)
+
+ def _check_part(head, tail=None):
+ if print_progress:
+ print "Checking: %s" % (head)
+ if tail is not None and tail == "":
+ return True
+ if not os.path.exists(head):
+ if print_progress:
+ print "Does not exist: %s" % (head)
+ return _check_part(*os.path.split(head))
+ if not os.path.isdir(head):
+ if print_progress:
+ print "Is not a directory: %s" % (head)
+ return (False, head)
+ if not os.access(head, os.W_OK):
+ if print_progress:
+ print "Write permission denied on: %s" % (head)
+ return (False, head)
+ if print_progress:
+ print "Write permission granted on: %s" % (head)
+ return (True, head)
+
+ return _check_part(dirs)
+
+ def validate_checksum(self, checksum_fn, file_path, expecting, print_progress=False):
+ if checksum_fn is None:
+ return (True, "")
+
+ calculated_checksum = checksum_fn(file_path)
+
+ if (expecting is not None) and (expecting != "") and calculated_checksum != expecting:
+ return (False, calculated_checksum)
+
+ return (True, calculated_checksum)
+
+ def extract_images_archive(self, archive_path, destination=None, print_progress=False):
+ if not os.path.exists(archive_path):
+ if print_progress:
+ print "Path does not exist: %s" % (archive_path)
+ raise Exception("path does not exist: %s" % (archive_path))
+
+ if print_progress:
+ print "Archive path: %s" % (archive_path)
+
+ (head, tail) = os.path.split(archive_path)
+
+ if not os.access(head, os.W_OK):
+ if print_progress:
+ print "Write access denied on: %s" % (head)
+ raise Exception("write access denied on: %s" % (head))
+
+ (root, ext) = os.path.splitext(tail)
+ temp_dir = os.path.join(head, root)
+
+ if print_progress:
+ print "Temporary extraction location: %s" % (temp_dir)
+
+ if os.path.exists(temp_dir):
+ if print_progress:
+ print "Deleting existing location: %s" % (temp_dir)
+ shutil.rmtree(temp_dir)
+
+ if print_progress:
+ print "Creating directory: %s" % (temp_dir)
+ os.mkdir(temp_dir)
+
+ if print_progress:
+ print "Extracting archive %s to %s" % (archive_path, temp_dir)
+
+ images_zip = zipfile.ZipFile(archive_path)
+ images_zip.extractall(temp_dir)
+ images_zip.close()
+
+ return temp_dir
+
+ def install_images(self, source, dest, keep=False, print_progress=False):
+ if not os.path.exists(source):
+ if print_progress:
+ print "Source path does not exist: %s" % (source)
+ return
+
+ if keep:
+ if print_progress:
+ print "Not wiping directory tree (existing files will be overwritten): %s" % (dest)
+ elif os.path.exists(dest):
+ if print_progress:
+ print "Deleting directory tree: %s" % (dest)
+ shutil.rmtree(dest)
+
+ (head, tail) = os.path.split(source)
+
+ if print_progress:
+ print "Source install path: %s" % (source)
+
+ uhd_source = os.path.join(source, tail, *_BASE_DIR_STRUCTURE_PARTS)
+
+ if print_progress:
+ print "Copying files from: %s" % (uhd_source)
+ print "Copying files to: %s" % (dest)
+
+ if keep:
+ # mgrant @ http://stackoverflow.com/questions/12683834/how-to-copy-directory-recursively-in-python-and-overwrite-all
+ def _recursive_overwrite(src, dest, ignore=None):
+ if os.path.isdir(src):
+ if not os.path.isdir(dest):
+ os.makedirs(dest)
+ files = os.listdir(src)
+ if ignore is not None:
+ ignored = ignore(src, files)
+ else:
+ ignored = set()
+ for f in files:
+ if f not in ignored:
+ _recursive_overwrite(os.path.join(src, f), os.path.join(dest, f), ignore)
+ else:
+ shutil.copyfile(src, dest)
+
+ _recursive_overwrite(uhd_source, dest)
else:
- temp_path = "tempdir"
-
- #Extracting contents of zip file
- if os.path.exists(temp_path):
- shutil.rmtree(temp_path)
- os.mkdir(temp_path)
-
- images_zip = zipfile.ZipFile(filename)
- images_zip.extractall(temp_path)
+ shutil.copytree(uhd_source, dest)
- #Removing images currently in images_dir
- if os.path.exists(images_dir):
- try:
- shutil.rmtree(images_dir)
- except OSError,e:
- print str(e)
- print "Make sure you have write permissions in the images directory."
- sys.exit(1)
-
- #Copying downloaded images into images_dir
- shutil.copytree(os.path.join(temp_path, os.path.splitext(filename)[0], 'share', 'uhd', 'images'), images_dir)
-
- #Removing tempdir and zip file
- shutil.rmtree(temp_path)
- images_zip.close()
- os.remove(filename)
+def main():
+ if os.environ.get("UHD_IMAGES_DIR") != None and os.environ.get("UHD_IMAGES_DIR") != "":
+ default_images_dir = os.environ.get("UHD_IMAGES_DIR")
+ print "UHD_IMAGES_DIR environment variable is set. Default install location: %s" % default_images_dir
+ else:
+ default_images_dir = _DEFAULT_INSTALL_PATH
+
+ parser = OptionParser()
+ parser.add_option("-i", "--install-location", type="string", default=default_images_dir,
+ help="Set custom install location for images [default=%default]")
+ parser.add_option("--buffer-size", type="int", default=_DEFAULT_BUFFER_SIZE,
+ help="Set download buffer size [default=%default]")
+ parser.add_option("-u", "--url", type="string", default=_AUTOGEN_IMAGES_SOURCE,
+ help="Set images download location [default=%default]")
+ parser.add_option("-c", "--checksum", type="string", default=_AUTOGEN_IMAGES_CHECKSUM,
+ help="Validate images archive against this checksum (blank to skip) [default=%default]")
+ parser.add_option("-t", "--checksum-type", type="string", default=_IMAGES_CHECKSUM_TYPE,
+ help=("Select checksum hash function (options: %s) [default=%%default]" % (",".join(_checksum_fns.keys()))))
+ parser.add_option("-k", "--keep", action="store_true", default=False,
+ help="Do not clear images directory before extracting new files [default=%default]")
+ parser.add_option("-v", "--verbose", action="store_true", default=False,
+ help="Enable verbose output [default=%default]")
+
+ (options, args) = parser.parse_args()
+
+ if options.buffer_size <= 0:
+ print "Invalid buffer size: %s" % (options.buffer_size)
+ return 1
+
+ checksum_fn = None
+ if options.checksum != "":
+ options.checksum_type = options.checksum_type.lower()
+ if not _checksum_fns.has_key(options.checksum_type):
+ print "Not a supported checksum function: %s" % (options.checksum_type)
+ return 1
+ checksum_fn = _checksum_fns[options.checksum_type]
+
+ url_parts = options.url.split("/")
+ if len(url_parts) <= 1 or url_parts[-1] == "":
+ print "Not a valid URL: %s" % (options.url)
+ return 1
+ images_filename = url_parts[-1]
+
+ images_dir = os.path.abspath(options.install_location) # This will use the current working directory if it's not absolute
+
+ if options.verbose:
+ print "Requested install location: %s" % (options.install_location)
+ print "Images source: %s" % (options.url)
+ print "Images filename: %s" % (images_filename)
+ print "Images checksum: %s (%s)" % (options.checksum, _IMAGES_CHECKSUM_TYPE)
+ print "Final install location: %s" % (images_dir)
+ else:
+ print "Images destination: %s" % (images_dir)
+
+ downloader = uhd_images_downloader()
+
+ try:
+ (access, last_path) = downloader.check_directories(images_dir, print_progress=options.verbose)
+ if access:
+ with temporary_directory() as temp_dir:
+ if options.verbose:
+ print "Using temporary directory: %s" % (temp_dir)
+
+ print "Downloading images from: %s" % options.url
+
+ temp_images_dest = os.path.join(temp_dir, images_filename)
+
+ print "Downloading images to: %s" % (temp_images_dest)
+
+ (reported_size, downloaded_size) = downloader.download(images_url=options.url, filename=temp_images_dest, buffer_size=options.buffer_size, print_progress=True)
+
+ if options.verbose:
+ print "Downloaded %d of %d bytes" % (downloaded_size, reported_size)
+
+ (checksum_match, calculated_checksum) = downloader.validate_checksum(checksum_fn, temp_images_dest, options.checksum, print_progress=options.verbose)
+
+ if options.verbose:
+ print "Calculated checksum: %s" % (calculated_checksum)
+
+ if checksum_match:
+ if options.verbose:
+ if options.checksum == "":
+ print "Ignoring checksum"
+ else:
+ print "Checksum OK"
+
+ try:
+ extract_path = downloader.extract_images_archive(temp_images_dest, print_progress=options.verbose)
+
+ if options.verbose:
+ print "Image archive extracted to: %s" % (extract_path)
+
+ downloader.install_images(extract_path, images_dir, options.keep, print_progress=options.verbose)
+
+ print
+ print "Images successfully installed to: %s" % (images_dir)
+ except Exception, e:
+ print "Failed to install image archive: %s" % (e)
+ print "This is usually a permissions problem."
+ print "Please check your file system access rights and try again."
+
+ if options.verbose:
+ traceback.print_exc()
+ else:
+ print "You can run this again with the '--verbose' flag to see more information"
+ print "If the problem persists, please email the output to: %s" % (_CONTACT)
+ else:
+ print "Checksum of downloaded file is not correct (not installing - see options to override)"
+ print "Expected: %s" % (options.checksum)
+ print "Calculated: %s" % (calculated_checksum)
+ print "Please try downloading again."
+ print "If the problem persists, please email the output to: %s" % (_CONTACT)
+ else:
+ print "You do not have sufficient permissions to write to: %s" % (last_path)
+ print "Are you root?"
+ except KeyboardInterrupt:
+ print
+ print "Cancelled at user request"
+ except Exception, e:
+ print "Downloader raised an unhandled exception: %s" % (e)
+ if options.verbose:
+ traceback.print_exc()
+ else:
+ print "You can run this again with the '--verbose' flag to see more information"
+ print "If the problem persists, please email the output to: %s" % (_CONTACT)
+ return 1
+
+ return 0
- os.chdir(images_dir)
- print "\n\nImages successfully installed!"
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/host/utils/usrp_n2xx_simple_net_burner.cpp b/host/utils/usrp_n2xx_simple_net_burner.cpp
index c3ccba173..1898ee9ae 100644
--- a/host/utils/usrp_n2xx_simple_net_burner.cpp
+++ b/host/utils/usrp_n2xx_simple_net_burner.cpp
@@ -468,13 +468,21 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << "Searching for specified images." << std::endl << std::endl;
if(burn_fpga){
if(!use_custom_fpga) fpga_path = find_image_path(default_fpga_filename);
- else validate_custom_fpga_file(filename_map[hw_rev], fpga_path);
+ else{
+ //Replace ~ with home directory
+ if(fpga_path.find("~/") == 0) fpga_path.replace(0,1,getenv("HOME"));
+ validate_custom_fpga_file(filename_map[hw_rev], fpga_path);
+ }
grab_fpga_image(fpga_path);
}
if(burn_fw){
if(!use_custom_fw) fw_path = find_image_path(default_fw_filename);
- else validate_custom_fw_file(filename_map[hw_rev], fw_path);
+ else{
+ //Replace ~ with home directory
+ if(fw_path.find("~/") == 0) fw_path.replace(0,1,getenv("HOME"));
+ validate_custom_fw_file(filename_map[hw_rev], fw_path);
+ }
grab_fw_image(fw_path);
}