aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2014-12-18 15:37:20 -0800
committerBen Hilburn <ben.hilburn@ettus.com>2014-12-18 15:37:20 -0800
commit3c5fe0a201d78a8732aad31a71bf806e00c89db1 (patch)
treeb5460e28d3f0d727f8eeb83ed5fb82dd95a80ef8
parent8c87a524668355eee2c911b512c91be843624806 (diff)
downloaduhd-3c5fe0a201d78a8732aad31a71bf806e00c89db1.tar.gz
uhd-3c5fe0a201d78a8732aad31a71bf806e00c89db1.tar.bz2
uhd-3c5fe0a201d78a8732aad31a71bf806e00c89db1.zip
Adding support for NI VID + PIDs for USRP B2xx devices.
-rw-r--r--host/include/uhd/transport/usb_device_handle.hpp3
-rw-r--r--host/lib/transport/libusb1_base.cpp20
-rw-r--r--host/lib/usrp/b200/b200_iface.hpp3
-rw-r--r--host/lib/usrp/b200/b200_impl.cpp72
-rw-r--r--host/utils/b2xx_fx3_utils.cpp80
5 files changed, 134 insertions, 44 deletions
diff --git a/host/include/uhd/transport/usb_device_handle.hpp b/host/include/uhd/transport/usb_device_handle.hpp
index fdea9e2be..bf122f549 100644
--- a/host/include/uhd/transport/usb_device_handle.hpp
+++ b/host/include/uhd/transport/usb_device_handle.hpp
@@ -41,6 +41,7 @@ namespace uhd { namespace transport {
class UHD_API usb_device_handle : boost::noncopyable {
public:
typedef boost::shared_ptr<usb_device_handle> sptr;
+ typedef std::pair<boost::uint16_t, boost::uint16_t> vid_pid_pair_t;
/*!
* Return the device's serial number
@@ -83,6 +84,8 @@ public:
* \return a vector of USB device handles that match vid and pid
*/
static std::vector<usb_device_handle::sptr> get_device_list(boost::uint16_t vid, boost::uint16_t pid);
+ static std::vector<usb_device_handle::sptr> get_device_list(const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list);
+
}; //namespace usb
diff --git a/host/lib/transport/libusb1_base.cpp b/host/lib/transport/libusb1_base.cpp
index ee4e20adb..18acb1fdc 100644
--- a/host/lib/transport/libusb1_base.cpp
+++ b/host/lib/transport/libusb1_base.cpp
@@ -343,15 +343,21 @@ libusb::special_handle::sptr libusb::special_handle::make(device::sptr dev){
std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(
boost::uint16_t vid, boost::uint16_t pid
){
- std::vector<usb_device_handle::sptr> handles;
+ return usb_device_handle::get_device_list(std::vector<usb_device_handle::vid_pid_pair_t>(1,usb_device_handle::vid_pid_pair_t(vid,pid)));
+}
+std::vector<usb_device_handle::sptr> usb_device_handle::get_device_list(const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list)
+{
+ std::vector<usb_device_handle::sptr> handles;
libusb::device_list::sptr dev_list = libusb::device_list::make();
- for (size_t i = 0; i < dev_list->size(); i++){
- usb_device_handle::sptr handle = libusb::special_handle::make(dev_list->at(i));
- if (handle->get_vendor_id() == vid and handle->get_product_id() == pid){
- handles.push_back(handle);
- }
+ for(size_t iter = 0; iter < vid_pid_pair_list.size(); ++iter)
+ {
+ for (size_t i = 0; i < dev_list->size(); i++){
+ usb_device_handle::sptr handle = libusb::special_handle::make(dev_list->at(i));
+ if (handle->get_vendor_id() == vid_pid_pair_list[iter].first and handle->get_product_id() == vid_pid_pair_list[iter].second){
+ handles.push_back(handle);
+ }
+ }
}
-
return handles;
}
diff --git a/host/lib/usrp/b200/b200_iface.hpp b/host/lib/usrp/b200/b200_iface.hpp
index 83adfdd64..1821865d3 100644
--- a/host/lib/usrp/b200/b200_iface.hpp
+++ b/host/lib/usrp/b200/b200_iface.hpp
@@ -26,7 +26,10 @@
#include "ad9361_ctrl.hpp"
const static boost::uint16_t B200_VENDOR_ID = 0x2500;
+const static boost::uint16_t B200_VENDOR_NI_ID = 0x3923;
const static boost::uint16_t B200_PRODUCT_ID = 0x0020;
+const static boost::uint16_t B200_PRODUCT_NI_ID = 0x7813;
+const static boost::uint16_t B210_PRODUCT_NI_ID = 0x7814;
const static boost::uint16_t FX3_VID = 0x04b4;
const static boost::uint16_t FX3_DEFAULT_PID = 0x00f3;
const static boost::uint16_t FX3_REENUM_PID = 0x00f0;
diff --git a/host/lib/usrp/b200/b200_impl.cpp b/host/lib/usrp/b200/b200_impl.cpp
index b2f0d8d3e..9b323cb13 100644
--- a/host/lib/usrp/b200/b200_impl.cpp
+++ b/host/lib/usrp/b200/b200_impl.cpp
@@ -87,14 +87,16 @@ static device_addrs_t b200_find(const device_addr_t &hint)
//since an address and resource is intended for a different, non-USB, device.
if (hint.has_key("addr") || hint.has_key("resource")) return b200_addrs;
- boost::uint16_t vid, pid;
+ size_t found = 0;
+ std::vector<usb_device_handle::vid_pid_pair_t> vid_pid_pair_list;//vid pid pair search list for devices.
if(hint.has_key("vid") && hint.has_key("pid") && hint.has_key("type") && hint["type"] == "b200") {
- vid = uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("vid"));
- pid = uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("pid"));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("vid")),
+ uhd::cast::hexstr_cast<boost::uint16_t>(hint.get("pid"))));
} else {
- vid = B200_VENDOR_ID;
- pid = B200_PRODUCT_ID;
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID, B200_PRODUCT_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B200_PRODUCT_NI_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID, B210_PRODUCT_NI_ID));
}
// Important note:
@@ -104,8 +106,9 @@ static device_addrs_t b200_find(const device_addr_t &hint)
// This requirement is a courtesy of libusb1.0 on windows.
//find the usrps and load firmware
- size_t found = 0;
- BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
+ std::vector<usb_device_handle::sptr> uhd_usb_device_vector = usb_device_handle::get_device_list(vid_pid_pair_list);
+
+ BOOST_FOREACH(usb_device_handle::sptr handle, uhd_usb_device_vector) {
//extract the firmware path for the b200
std::string b200_fw_image;
try{
@@ -138,7 +141,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, usb_device_handle::get_device_list(vid, pid))
+ BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid_pid_pair_list))
{
usb_control::sptr control;
try{control = usb_control::make(handle, 0);}
@@ -155,12 +158,16 @@ static device_addrs_t b200_find(const device_addr_t &hint)
{
switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]))
{
+ //0x0001 and 0x7737 are Ettus B200 product Ids.
case 0x0001:
case 0x7737:
+ case B200_PRODUCT_NI_ID:
new_addr["product"] = "B200";
break;
- case 0x7738:
+ //0x0002 and 0x7738 are Ettus B210 product Ids.
case 0x0002:
+ case 0x7738:
+ case B210_PRODUCT_NI_ID:
new_addr["product"] = "B210";
break;
default: UHD_MSG(error) << "B200 unknown product code: " << mb_eeprom["product"] << std::endl;
@@ -204,13 +211,50 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
//try to match the given device address with something on the USB bus
boost::uint16_t vid = B200_VENDOR_ID;
boost::uint16_t pid = B200_PRODUCT_ID;
+ bool specified_vid = false;
+ bool specified_pid = false;
+
if (device_addr.has_key("vid"))
+ {
vid = uhd::cast::hexstr_cast<boost::uint16_t>(device_addr.get("vid"));
+ specified_vid = true;
+ }
+
if (device_addr.has_key("pid"))
+ {
pid = uhd::cast::hexstr_cast<boost::uint16_t>(device_addr.get("pid"));
+ specified_pid = true;
+ }
+
+ std::vector<usb_device_handle::vid_pid_pair_t> vid_pid_pair_list;//search list for devices.
- std::vector<usb_device_handle::sptr> device_list =
- usb_device_handle::get_device_list(vid, pid);
+ // Search only for specified VID and PID if both specified
+ if (specified_vid && specified_pid)
+ {
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid,pid));
+ }
+ // Search for all supported PIDs limited to specified VID if only VID specified
+ else if (specified_vid)
+ {
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid,B200_PRODUCT_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid,B200_PRODUCT_NI_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(vid,B210_PRODUCT_NI_ID));
+ }
+ // Search for all supported VIDs limited to specified PID if only PID specified
+ else if (specified_pid)
+ {
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID,pid));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID,pid));
+ }
+ // Search for all supported devices if neither VID nor PID specified
+ else
+ {
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_ID,B200_PRODUCT_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID,B200_PRODUCT_NI_ID));
+ vid_pid_pair_list.push_back(usb_device_handle::vid_pid_pair_t(B200_VENDOR_NI_ID,B210_PRODUCT_NI_ID));
+ }
+
+ 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;
@@ -244,13 +288,17 @@ b200_impl::b200_impl(const device_addr_t &device_addr)
{
switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["product"]))
{
+ //0x0001 and 0x7737 are Ettus B200 product Ids.
case 0x0001:
case 0x7737:
+ case B200_PRODUCT_NI_ID:
product_name = "B200";
default_file_name = B200_FPGA_FILE_NAME;
break;
- case 0x7738:
+ //0x0002 and 0x7738 are Ettus B210 product Ids.
case 0x0002:
+ case 0x7738:
+ case B210_PRODUCT_NI_ID:
product_name = "B210";
default_file_name = B210_FPGA_FILE_NAME;
break;
diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp
index 8b64be63e..78449a8a4 100644
--- a/host/utils/b2xx_fx3_utils.cpp
+++ b/host/utils/b2xx_fx3_utils.cpp
@@ -54,17 +54,21 @@ const static vid_pid_t known_vid_pids[] = {
{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])));
+
+static const size_t EEPROM_INIT_VALUE_VECTOR_SIZE = 8;
+static uhd::byte_vector_t construct_eeprom_init_value_vector(boost::uint16_t vid, boost::uint16_t pid)
+{
+ uhd::byte_vector_t init_values(EEPROM_INIT_VALUE_VECTOR_SIZE);
+ init_values.push_back(0x43);
+ init_values.push_back(0x59);
+ init_values.push_back(0x14);
+ init_values.push_back(0xB2);
+ init_values.push_back(static_cast<boost::uint8_t>(pid & 0xff));
+ init_values.push_back(static_cast<boost::uint8_t>(pid >> 8));
+ init_values.push_back(static_cast<boost::uint8_t>(vid & 0xff));
+ init_values.push_back(static_cast<boost::uint8_t>(vid >> 8));
+ return init_values;
+}
//!used with lexical cast to parse a hex string
template <class T> struct to_hex{
@@ -153,15 +157,22 @@ uhd::transport::usb_device_handle::sptr open_device(const boost::uint16_t vid, c
try {
// 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++)
+ std::vector<uhd::transport::usb_device_handle::vid_pid_pair_t> vid_pid_pair_list(1,uhd::transport::usb_device_handle::vid_pid_pair_t(vid,pid));
+ handles = uhd::transport::usb_device_handle::get_device_list(vid_pid_pair_list);
+ if (handles.size() == 0)
{
- vp = known_vid_pid_vector[i];
- handles = uhd::transport::usb_device_handle::get_device_list(vp.vid,vp.pid);
+ if (user_supplied)
+ {
+ 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)
@@ -281,7 +292,7 @@ int erase_eeprom(b200_iface::sptr& b200)
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;
+ std::string pid_str, vid_str, fw_file, fpga_file, writevid_str, writepid_str;
bool user_supplied_vid_pid = false;
po::options_description visible("Allowed options");
@@ -295,7 +306,6 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
("reset-device,D", "Reset the B2xx Device.")
("reset-fpga,F", "Reset the FPGA (does not require re-programming.")
("reset-usb,U", "Reset the USB subsystem on your host computer.")
- ("init-device,I", "Initialize a B2xx device.")
("load-fw,W", po::value<std::string>(&fw_file),
"Load a firmware (hex) file into the FX3.")
("load-fpga,L", po::value<std::string>(&fpga_file),
@@ -305,9 +315,14 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
// Hidden options provided for testing - use at your own risk!
po::options_description hidden("Hidden options");
hidden.add_options()
- ("uninit-device,U", "Uninitialize a B2xx device.")
+ ("init-device,I", "Initialize a B2xx device.")
+ ("uninit-device", "Uninitialize a B2xx device.")
("read-eeprom,R", "Read first 8 bytes of EEPROM")
- ("erase-eeprom,E", "Erase first 8 bytes of EEPROM");
+ ("erase-eeprom,E", "Erase first 8 bytes of EEPROM")
+ ("write-vid", po::value<std::string>(&writevid_str),
+ "Write VID field of EEPROM")
+ ("write-pid", po::value<std::string>(&writepid_str),
+ "Write PID field of EEPROM");
po::options_description desc;
desc.add(visible);
@@ -486,9 +501,24 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
* Cypress VID/PID for the initial FW load, but we can initialize from any state. */
if (vm.count("init-device"))
{
+ uint16_t writevid = B200_VENDOR_ID;
+ uint16_t writepid = B200_PRODUCT_ID;
+
/* Now, initialize the device. */
- if (write_and_verify_eeprom(b200, eeprom_init_value_vector))
- return -1;
+ // Added for testing purposes - not exposed
+ if (vm.count("write-vid") && vm.count("write-pid"))
+ {
+ try {
+ writevid = atoh(writevid_str);
+ writepid = atoh(writepid_str);
+ } catch (std::exception &e) {
+ std::cerr << "Exception while parsing write VID and PID: " << e.what() << std:: endl;
+ return ~0;
+ }
+ }
+
+ std::cout << "Writing VID and PID to EEPROM..." << std::endl << std::endl;
+ if (write_and_verify_eeprom(b200, construct_eeprom_init_value_vector(writevid, writepid))) return -1;
std::cout << "EEPROM initialized, resetting device..."
<< std::endl << std::endl;