src/libusb_ll: libusb wrapper (currently limited to scan device), src/main: add scan-usb option

This commit is contained in:
Gwenhael Goavec-Merou 2022-10-15 22:28:06 +02:00
parent 2311f2c6ec
commit 228f71d9b5
5 changed files with 166 additions and 3 deletions

View File

@ -105,6 +105,7 @@ set(OPENFPGALOADER_SOURCE
src/ftdipp_mpsse.cpp
src/main.cpp
src/latticeBitParser.cpp
src/libusb_ll.cpp
src/gowin.cpp
src/device.cpp
src/jlink.cpp
@ -145,6 +146,7 @@ set(OPENFPGALOADER_HEADERS
src/jlink.hpp
src/jtag.hpp
src/jtagInterface.hpp
src/libusb_ll.hpp
src/fsparser.hpp
src/part.hpp
src/board.hpp

View File

@ -92,6 +92,7 @@ openFPGALoader -- a program to flash FPGA
--protect-flash arg protect SPI flash area
--quiet Produce quiet output (no progress bar)
-r, --reset reset FPGA after operations
--scan-usb scan USB to display connected probes
--skip-load-bridge skip writing bridge to SRAM when in write-flash
mode
--skip-reset skip resetting the device when in write-flash

128
src/libusb_ll.cpp Normal file
View File

@ -0,0 +1,128 @@
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (c) 2022 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#include <libusb.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "cable.hpp"
#include "display.hpp"
#include "libusb_ll.hpp"
using namespace std;
libusb_ll::libusb_ll(int vid, int pid):_verbose(true)
{
(void)vid;
(void)pid;
if (libusb_init(&_usb_ctx) < 0)
throw std::runtime_error("libusb_init_failed");
}
libusb_ll::~libusb_ll()
{
libusb_exit(_usb_ctx);
}
bool libusb_ll::scan()
{
int i = 0;
libusb_device **dev_list;
libusb_device *usb_dev;
libusb_device_handle *handle;
/* iteration */
ssize_t list_size = libusb_get_device_list(_usb_ctx, &dev_list);
if (_verbose)
printInfo("found " + std::to_string(list_size) + " USB device");
char *mess = (char *)malloc(1024);
snprintf(mess, 1024, "%3s %3s %-13s %-15s %-12s %-20s %s",
"Bus", "device", "vid:pid", "probe type", "manufacturer",
"serial", "product");
printSuccess(mess);
while ((usb_dev = dev_list[i++]) != NULL) {
bool found = false;
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(usb_dev, &desc) != 0) {
printError("Unable to get device descriptor");
return false;
}
char probe_type[256];
/* Linux host controller */
if (desc.idVendor == 0x1d6b)
continue;
/* ftdi devices */
// FIXME: missing iProduct in cable_list
if (desc.idVendor == 0x403) {
if (desc.idProduct == 0x6010)
snprintf(probe_type, 256, "FTDI2232");
else if (desc.idProduct == 0x6011)
snprintf(probe_type, 256, "ft4232");
else if (desc.idProduct == 0x6001)
snprintf(probe_type, 256, "ft2232RL");
else if (desc.idProduct == 0x6014)
snprintf(probe_type, 256, "ft232H");
else if (desc.idProduct == 0x6015)
snprintf(probe_type, 256, "ft231X");
else
snprintf(probe_type, 256, "unknown FTDI");
found = true;
} else {
// FIXME: DFU device can't be detected here
for (auto b = cable_list.begin(); b != cable_list.end(); b++) {
cable_t *c = &(*b).second;
if (c->vid == desc.idVendor && c->vid == desc.idProduct) {
snprintf(probe_type, 256, "%s", (*b).first.c_str());
found = true;
}
}
}
if (!found)
continue;
int ret = libusb_open(usb_dev, &handle);
uint8_t iproduct[200];
uint8_t iserial[200];
uint8_t imanufacturer[200];
ret = libusb_get_string_descriptor_ascii(handle,
desc.iProduct, iproduct, 200);
if (ret < 0)
snprintf((char*)iproduct, 200, "none");
ret = libusb_get_string_descriptor_ascii(handle,
desc.iManufacturer, imanufacturer, 200);
if (ret < 0)
snprintf((char*)imanufacturer, 200, "none");
ret = libusb_get_string_descriptor_ascii(handle,
desc.iSerialNumber, iserial, 200);
if (ret < 0)
snprintf((char*)iserial, 200, "none");
uint8_t bus_addr = libusb_get_bus_number(usb_dev);
uint8_t dev_addr = libusb_get_device_address(usb_dev);
snprintf(mess, 1024, "%03d %03d 0x%04x:0x%04x %-15s %-12s %-20s %s",
bus_addr, dev_addr,
desc.idVendor, desc.idProduct,
probe_type, imanufacturer, iserial, iproduct);
printInfo(mess);
libusb_close(handle);
}
libusb_free_device_list(dev_list, 1);
free(mess);
return true;
}

23
src/libusb_ll.hpp Normal file
View File

@ -0,0 +1,23 @@
// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (c) 2022 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
*/
#ifndef SRC_LIBUSB_LL_HPP_
#define SRC_LIBUSB_LL_HPP_
#include <libusb.h>
class libusb_ll {
public:
explicit libusb_ll(int vid = -1, int pid = -1);
~libusb_ll();
bool scan();
private:
struct libusb_context *_usb_ctx;
bool _verbose;
};
#endif // SRC_LIBUSB_LL_HPP_

View File

@ -25,6 +25,7 @@
#include "gowin.hpp"
#include "ice40.hpp"
#include "lattice.hpp"
#include "libusb_ll.hpp"
#include "jtag.hpp"
#include "part.hpp"
#include "spiFlash.hpp"
@ -40,7 +41,7 @@ using namespace std;
struct arguments {
int8_t verbose;
bool reset, detect, verify;
bool reset, detect, verify, scan_usb;
unsigned int offset;
string bit_file;
string device;
@ -98,7 +99,7 @@ int main(int argc, char **argv)
jtag_pins_conf_t pins_config = {0, 0, 0, 0};
/* command line args. */
struct arguments args = {0, false, false, false, 0, "", "", "-", "", -1,
struct arguments args = {0, false, false, false, false, 0, "", "", "-", "", -1,
0, false, "-", false, false, false, false, Device::PRG_NONE, false,
false, false, "", "", "", -1, 0, false, -1,
/* vid, pid, index bus_addr, device_addr */
@ -708,6 +709,8 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
cxxopts::value<bool>(quiet))
("r,reset", "reset FPGA after operations",
cxxopts::value<bool>(args->reset))
("scan-usb", "scan USB to display connected probes",
cxxopts::value<bool>(args->scan_usb))
("skip-load-bridge", "skip writing bridge to SRAM when in write-flash mode",
cxxopts::value<bool>(args->skip_load_bridge))
("skip-reset", "skip resetting the device when in write-flash mode",
@ -860,7 +863,8 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p
args->pin_config = true;
}
if (args->list_cables || args->list_boards || args->list_fpga)
if (args->list_cables || args->list_boards || args->list_fpga ||
args->scan_usb)
args->is_list_command = true;
if (args->bit_file.empty() &&
@ -931,5 +935,10 @@ void displaySupported(const struct arguments &args)
}
cout << endl;
}
if (args.scan_usb) {
libusb_ll usb(0,0);
usb.scan();
}
}