src/libusb_ll: libusb wrapper (currently limited to scan device), src/main: add scan-usb option
This commit is contained in:
parent
2311f2c6ec
commit
228f71d9b5
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_
|
||||
15
src/main.cpp
15
src/main.cpp
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue