aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/b200/b200_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/b200/b200_impl.cpp')
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp39
1 files changed, 29 insertions, 10 deletions
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index b45529c1a..f5129bc24 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -37,6 +37,8 @@
#include <ctime>
#include <cmath>
+#include "../../transport/libusb1_base.hpp"
+
using namespace uhd;
using namespace uhd::usrp;
using namespace uhd::transport;
@@ -125,8 +127,7 @@ static device_addrs_t b200_find(const device_addr_t &hint)
// so that re-enumeration after fw load can occur successfully.
// This requirement is a courtesy of libusb1.0 on windows.
size_t found = 0;
- std::vector<usb_device_handle::sptr> b200_device_handles = get_b200_device_handles(hint);
- BOOST_FOREACH(usb_device_handle::sptr handle, b200_device_handles) {
+ BOOST_FOREACH(usb_device_handle::sptr handle, get_b200_device_handles(hint)) {
//extract the firmware path for the b200
std::string b200_fw_image;
try{
@@ -157,7 +158,7 @@ static device_addrs_t b200_find(const device_addr_t &hint)
//search for the device until found or timeout
while (boost::get_system_time() < timeout_time and b200_addrs.empty() and found != 0)
{
- BOOST_FOREACH(usb_device_handle::sptr handle, b200_device_handles)
+ BOOST_FOREACH(usb_device_handle::sptr handle, get_b200_device_handles(hint))
{
usb_control::sptr control;
try{control = usb_control::make(handle, 0);}
@@ -195,7 +196,24 @@ static device_addrs_t b200_find(const device_addr_t &hint)
**********************************************************************/
static device::sptr b200_make(const device_addr_t &device_addr)
{
- return device::sptr(new b200_impl(device_addr));
+ uhd::transport::usb_device_handle::sptr handle;
+
+ // We try twice, because the first time, the link might be in a bad state
+ // and we might need to reset the link, but if that didn't help, trying
+ // a third time is pointless.
+ try {
+ return device::sptr(new b200_impl(device_addr, handle));
+ }
+ catch (const uhd::usb_error &e) {
+ libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle(
+ boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()
+ ));
+ dev_handle->clear_endpoints(B200_USB_CTRL_RECV_ENDPOINT, B200_USB_CTRL_SEND_ENDPOINT);
+ dev_handle->clear_endpoints(B200_USB_DATA_RECV_ENDPOINT, B200_USB_DATA_SEND_ENDPOINT);
+ dev_handle->reset_device();
+ }
+
+ return device::sptr(new b200_impl(device_addr, handle));
}
UHD_STATIC_BLOCK(register_b200_device)
@@ -206,7 +224,7 @@ UHD_STATIC_BLOCK(register_b200_device)
/***********************************************************************
* Structors
**********************************************************************/
-b200_impl::b200_impl(const device_addr_t &device_addr) :
+b200_impl::b200_impl(const uhd::device_addr_t& device_addr, usb_device_handle::sptr &handle) :
_revision(0),
_tick_rate(0.0) // Forces a clock initialization at startup
{
@@ -263,7 +281,6 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
std::vector<usb_device_handle::sptr> device_list = usb_device_handle::get_device_list(vid_pid_pair_list);
//locate the matching handle in the device list
- usb_device_handle::sptr handle;
BOOST_FOREACH(usb_device_handle::sptr dev_handle, device_list) {
if (dev_handle->get_serial() == device_addr["serial"]){
handle = dev_handle;
@@ -361,10 +378,11 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
ctrl_xport_args["send_frame_size"] = min_frame_size;
ctrl_xport_args["num_send_frames"] = "16";
+ // This may throw a uhd::usb_error, which will be caught by b200_make().
_ctrl_transport = usb_zero_copy::make(
handle,
- 4, 8, //interface, endpoint
- 3, 4, //interface, endpoint
+ B200_USB_CTRL_RECV_INTERFACE, B200_USB_CTRL_RECV_ENDPOINT, //interface, endpoint
+ B200_USB_CTRL_SEND_INTERFACE, B200_USB_CTRL_SEND_ENDPOINT, //interface, endpoint
ctrl_xport_args
);
while (_ctrl_transport->get_recv_buff(0.0)){} //flush ctrl xport
@@ -443,10 +461,11 @@ b200_impl::b200_impl(const device_addr_t &device_addr) :
data_xport_args["send_frame_size"] = device_addr.get("send_frame_size", "8192");
data_xport_args["num_send_frames"] = device_addr.get("num_send_frames", "16");
+ // This may throw a uhd::usb_error, which will be caught by b200_make().
_data_transport = usb_zero_copy::make(
handle, // identifier
- 2, 6, // IN interface, endpoint
- 1, 2, // OUT interface, endpoint
+ B200_USB_DATA_RECV_INTERFACE, B200_USB_DATA_RECV_ENDPOINT, //interface, endpoint
+ B200_USB_DATA_SEND_INTERFACE, B200_USB_DATA_SEND_ENDPOINT, //interface, endpoint
data_xport_args // param hints
);
while (_data_transport->get_recv_buff(0.0)){} //flush ctrl xport