diff options
Diffstat (limited to 'host')
| -rw-r--r-- | host/include/uhd/transport/usb_device_handle.hpp | 3 | ||||
| -rw-r--r-- | host/lib/transport/libusb1_base.cpp | 20 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_iface.hpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/b200/b200_impl.cpp | 72 | ||||
| -rw-r--r-- | host/utils/b2xx_fx3_utils.cpp | 80 | 
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;  | 
