Merge pull request #665 from r4d10n/esp_usb_jtag
esp_usb_jtag: support multiple boards (--busdev-num, --usb-serial-num)
This commit is contained in:
commit
79aa75dd8e
|
|
@ -70,7 +70,9 @@ openFPGALoader -- a program to flash FPGA
|
|||
--cable-index arg probe index (FTDI and cmsisDAP)
|
||||
--busdev-num arg select a probe by it bus and device number
|
||||
(bus_num:device_addr)
|
||||
--ftdi-serial arg FTDI chip serial number
|
||||
--usb-serial-num arg USB iSerial (FTDI chip serial number or ESP32
|
||||
iSerialNumber substring)
|
||||
--ftdi-serial arg FTDI chip serial number (Deprecated)
|
||||
--ftdi-channel arg FTDI chip channel number (channels 0-3 map to
|
||||
A-D)
|
||||
-d, --device arg device to use (/dev/ttyUSBx)
|
||||
|
|
|
|||
|
|
@ -245,13 +245,17 @@ static uint16_t esp_usb_target_chip_id = 0; /* not applicable for FPGA, they hav
|
|||
|
||||
/* end copy from openocd */
|
||||
|
||||
esp_usb_jtag::esp_usb_jtag(uint32_t clkHZ, int8_t verbose, int vid = ESPUSBJTAG_VID, int pid = ESPUSBJTAG_PID):
|
||||
esp_usb_jtag::esp_usb_jtag(uint32_t clkHZ, int8_t verbose,
|
||||
int vid = ESPUSBJTAG_VID, int pid = ESPUSBJTAG_PID,
|
||||
uint8_t bus_addr = 0, uint8_t dev_addr = 0,
|
||||
const std::string &serial = ""):
|
||||
_verbose(verbose > 1),
|
||||
dev_handle(NULL), usb_ctx(NULL), _tdi(0), _tms(0),
|
||||
/* Default for emard firmware. */
|
||||
_esp_usb_jtag_caps(0x2000), _write_ep(0x02),
|
||||
_vid(ESPUSBJTAG_VID), _pid(ESPUSBJTAG_PID)
|
||||
{
|
||||
libusb_device **devs = NULL;
|
||||
int ret;
|
||||
char mess[256];
|
||||
|
||||
|
|
@ -260,18 +264,61 @@ esp_usb_jtag::esp_usb_jtag(uint32_t clkHZ, int8_t verbose, int vid = ESPUSBJTAG_
|
|||
throw std::exception();
|
||||
}
|
||||
|
||||
dev_handle = libusb_open_device_with_vid_pid(usb_ctx,
|
||||
_vid, _pid);
|
||||
if (!dev_handle) {
|
||||
_esp_usb_jtag_caps = 0x030A;
|
||||
_write_ep = 0x03;
|
||||
_pid = 0x1002;
|
||||
dev_handle = libusb_open_device_with_vid_pid(usb_ctx,
|
||||
_vid, _pid);
|
||||
ssize_t cnt = libusb_get_device_list(usb_ctx, &devs);
|
||||
if (cnt < 0) {
|
||||
std::cerr << "esp_usb_jtag: libusb_get_device_list failed: "
|
||||
<< libusb_error_name(static_cast<int>(cnt)) << std::endl;
|
||||
libusb_exit(usb_ctx);
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
for (ssize_t i = 0; i < cnt; i++) {
|
||||
libusb_device *dev = devs[i];
|
||||
struct libusb_device_descriptor desc;
|
||||
if (libusb_get_device_descriptor(dev, &desc) < 0)
|
||||
continue;
|
||||
if (desc.idVendor != vid || desc.idProduct != pid)
|
||||
continue;
|
||||
/* bus/device filter (only when both are user-supplied) */
|
||||
if (bus_addr != 0 && dev_addr != 0 &&
|
||||
(libusb_get_bus_number(dev) != bus_addr ||
|
||||
libusb_get_device_address(dev) != dev_addr))
|
||||
continue;
|
||||
|
||||
/* serial filter */
|
||||
if (!serial.empty()) {
|
||||
libusb_device_handle *probe = NULL;
|
||||
if (libusb_open(dev, &probe) < 0)
|
||||
continue;
|
||||
unsigned char raw[256] = {0};
|
||||
int n = 0;
|
||||
if (desc.iSerialNumber)
|
||||
n = libusb_get_string_descriptor_ascii(probe,
|
||||
desc.iSerialNumber, raw, sizeof(raw));
|
||||
libusb_close(probe);
|
||||
if (n <= 0)
|
||||
continue;
|
||||
const std::string found(reinterpret_cast<char *>(raw), n);
|
||||
|
||||
if (found.find(serial) == std::string::npos)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (libusb_open(dev, &dev_handle) == 0)
|
||||
break;
|
||||
dev_handle = NULL;
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
|
||||
if (!dev_handle) {
|
||||
snprintf(mess, 256, "fails to open esp_usb_jtag device");
|
||||
printError(mess);
|
||||
std::cerr << "fails to open esp_usb_jtag device vid:pid 0x"
|
||||
<< std::hex << vid << ":0x" << pid;
|
||||
if (bus_addr || dev_addr)
|
||||
std::cerr << " bus:dev " << std::dec << static_cast<int>(bus_addr)
|
||||
<< ":" << static_cast<int>(dev_addr);
|
||||
if (!serial.empty())
|
||||
std::cerr << " serial '" << serial << "'";
|
||||
std::cerr << std::endl;
|
||||
libusb_exit(usb_ctx);
|
||||
throw std::exception();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include <libusb.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "jtagInterface.hpp"
|
||||
|
||||
/*!
|
||||
|
|
@ -23,7 +25,9 @@
|
|||
|
||||
class esp_usb_jtag : public JtagInterface {
|
||||
public:
|
||||
esp_usb_jtag(uint32_t clkHZ, int8_t verbose, int vid, int pid);
|
||||
esp_usb_jtag(uint32_t clkHZ, int8_t verbose, int vid, int pid,
|
||||
uint8_t bus_addr, uint8_t dev_addr,
|
||||
const std::string &serial);
|
||||
virtual ~esp_usb_jtag();
|
||||
|
||||
int setClkFreq(uint32_t clkHZ) override;
|
||||
|
|
|
|||
|
|
@ -165,7 +165,8 @@ Jtag::Jtag(const cable_t &cable, const jtag_pins_conf_t *pin_conf,
|
|||
break;
|
||||
case MODE_ESP:
|
||||
#ifdef ENABLE_ESP_USB
|
||||
_jtag = new esp_usb_jtag(clkHZ, verbose, 0x303a, 0x1001);
|
||||
_jtag = new esp_usb_jtag(clkHZ, verbose, 0x303a, 0x1001,
|
||||
cable.bus_addr, cable.device_addr, serial);
|
||||
#else
|
||||
std::cerr << "Jtag: support for esp32s3 cable was not enabled at compile time" << std::endl;
|
||||
throw std::exception();
|
||||
|
|
|
|||
36
src/main.cpp
36
src/main.cpp
|
|
@ -79,7 +79,7 @@ struct arguments {
|
|||
std::string secondary_bit_file;
|
||||
std::string device;
|
||||
std::string cable;
|
||||
std::string ftdi_serial;
|
||||
std::string usb_serial_num;
|
||||
int ftdi_channel;
|
||||
int status_pin;
|
||||
uint32_t freq;
|
||||
|
|
@ -264,13 +264,6 @@ int main(int argc, char **argv)
|
|||
cable.config.interface = mapping[args.ftdi_channel];
|
||||
}
|
||||
|
||||
if (!args.ftdi_serial.empty()) {
|
||||
if (cable.type != MODE_FTDI_SERIAL && cable.type != MODE_FTDI_BITBANG){
|
||||
printError("Error: FTDI serial param is for FTDI cables.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.status_pin != -1) {
|
||||
if (cable.type != MODE_FTDI_SERIAL){
|
||||
printError("Error: FTDI status pin is for FTDI MPSSE cables.");
|
||||
|
|
@ -279,6 +272,14 @@ int main(int argc, char **argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!args.usb_serial_num.empty()) {
|
||||
if (cable.type != MODE_FTDI_SERIAL && cable.type != MODE_FTDI_BITBANG &&
|
||||
cable.type != MODE_ESP){
|
||||
printError("Error: usb-serial-num param is for FTDI and esp32s3 cables.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.vid != 0) {
|
||||
printInfo("Cable VID overridden");
|
||||
cable.vid = args.vid;
|
||||
|
|
@ -389,7 +390,7 @@ int main(int argc, char **argv)
|
|||
|
||||
Jtag *jtag;
|
||||
try {
|
||||
jtag = new Jtag(cable, &pins_config, args.device, args.ftdi_serial,
|
||||
jtag = new Jtag(cable, &pins_config, args.device, args.usb_serial_num,
|
||||
args.freq, args.verbose, args.ip_adr, args.port,
|
||||
args.invert_read_edge, args.probe_firmware,
|
||||
args.user_misc_devs);
|
||||
|
|
@ -667,7 +668,7 @@ int run_xvc_server(const struct arguments &args, const cable_t &cable,
|
|||
try {
|
||||
XVC_server *xvc = NULL;
|
||||
xvc = new XVC_server(args.port, cable, pins_config, args.device,
|
||||
args.ftdi_serial, args.freq, args.verbose, args.ip_adr,
|
||||
args.usb_serial_num, args.freq, args.verbose, args.ip_adr,
|
||||
args.invert_read_edge, args.probe_firmware);
|
||||
/* create connection */
|
||||
xvc->open_connection();
|
||||
|
|
@ -889,6 +890,7 @@ int parse_opt(int argc, char **argv, struct arguments *args,
|
|||
jtag_pins_conf_t *pins_config)
|
||||
{
|
||||
std::string freqo;
|
||||
std::string ftdi_serial;
|
||||
std::vector<std::string> pins, bus_dev_num;
|
||||
bool verbose = false, quiet = false;
|
||||
int8_t verbose_level = -2;
|
||||
|
|
@ -927,8 +929,10 @@ int parse_opt(int argc, char **argv, struct arguments *args,
|
|||
("busdev-num",
|
||||
"select a probe by it bus and device number (bus_num:device_addr)",
|
||||
cxxopts::value<std::vector<std::string>>(bus_dev_num))
|
||||
("ftdi-serial", "FTDI chip serial number",
|
||||
cxxopts::value<std::string>(args->ftdi_serial))
|
||||
("usb-serial-num", "USB iSerial (FTDI chip serial number or ESP32 iSerialNumber substring)",
|
||||
cxxopts::value<std::string>(args->usb_serial_num))
|
||||
("ftdi-serial", "FTDI chip serial number (Deprecated)",
|
||||
cxxopts::value<std::string>(ftdi_serial))
|
||||
("ftdi-channel",
|
||||
"FTDI chip channel number (channels 0-3 map to A-D)",
|
||||
cxxopts::value<int>(args->ftdi_channel))
|
||||
|
|
@ -1134,6 +1138,14 @@ int parse_opt(int argc, char **argv, struct arguments *args,
|
|||
}
|
||||
}
|
||||
|
||||
if (result.count("ftdi-serial")) {
|
||||
if (result.count("usb-serial-num")) {
|
||||
printError("Error: ftdi-serial and usb-serial-num can't be used at the same time.");
|
||||
return -1;
|
||||
}
|
||||
args->usb_serial_num = ftdi_serial;
|
||||
}
|
||||
|
||||
if (result.count("busdev-num")) {
|
||||
if (bus_dev_num.size() != 2) {
|
||||
printError("Error: busdev-num must be xx:yy");
|
||||
|
|
|
|||
Loading…
Reference in New Issue