mirror of
https://github.com/avrdudes/avrdude.git
synced 2026-09-22 09:06:23 +03:00
Merge pull request #1588 from MikeRaffa/main
Issue #973: Differentiate multiple USB programmers of the same VID/PI…
This commit is contained in:
@@ -739,8 +739,11 @@ and Mac OS but not on Windows. For more information about AVR-Doper see
|
||||
For the USBtinyISP, which is a simplistic device not implementing
|
||||
serial numbers, multiple devices can be distinguished by their
|
||||
location in the USB hierarchy.
|
||||
See the respective
|
||||
@xref{Troubleshooting} entry for examples.
|
||||
See the respective @ref{Troubleshooting} entry for examples.
|
||||
|
||||
For USBasp, multiple devices can be distinguished by either USB connection
|
||||
or serial number.
|
||||
See the respective @ref{Troubleshooting} entry for examples.
|
||||
|
||||
For the XBee programmer the target MCU is to be programmed wirelessly
|
||||
over a ZigBee mesh using the XBeeBoot bootloader. The ZigBee 64-bit
|
||||
@@ -4233,6 +4236,14 @@ avrdude -c usbtiny -p atmega8 \
|
||||
-P usb:bus-0:\\.\libusb0-0001--0x1781-0x0c9f (Windows)
|
||||
@end example
|
||||
|
||||
For USBasp, the same format for @var{-P usb} can be used to match usb bus/device. Alternatively,
|
||||
device serial number can be specified as follows (for serial number '1234').
|
||||
|
||||
@example
|
||||
avrdude -c USBasp -p atmega8 -P usb:1234
|
||||
@end example
|
||||
|
||||
|
||||
@item
|
||||
Problem: I cannot do @dots{} when the target is in debugWire mode.
|
||||
|
||||
|
||||
59
src/usbasp.c
59
src/usbasp.c
@@ -162,9 +162,9 @@ static int usbasp_transmit(const PROGRAMMER *pgm, unsigned char receive,
|
||||
unsigned char functionid, const unsigned char *send,
|
||||
unsigned char *buffer, int buffersize);
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName);
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName, const char *port);
|
||||
#else
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName);
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName, const char *port);
|
||||
#endif
|
||||
// interface - prog.
|
||||
static int usbasp_open(PROGRAMMER *pgm, const char *port);
|
||||
@@ -399,6 +399,26 @@ static int usbasp_transmit(const PROGRAMMER *pgm,
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int check_for_port_argument_match(const char *port, char *bus, char *device, char *serial_num) {
|
||||
|
||||
pmsg_notice("usbOpenDevice(): found USBasp, bus:device: %s:%s, serial_number: %s\n", bus, device, serial_num);
|
||||
const size_t usb_len = strlen("usb");
|
||||
if(str_starts(port, "usb") && ':' == port[usb_len]) {
|
||||
port += usb_len + 1;
|
||||
char *colon_pointer = strchr(port, ':');
|
||||
if (colon_pointer) {
|
||||
// Value contains ':' character. Compare with bus/device.
|
||||
if (strncmp(port, bus, colon_pointer - port))
|
||||
return 0;
|
||||
port = colon_pointer + 1;
|
||||
return str_eq(port, device);
|
||||
}
|
||||
// serial number case
|
||||
return *port && str_ends(serial_num, port);
|
||||
}
|
||||
// Invalid -P option.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to open USB device with given VID, PID, vendor and product name
|
||||
@@ -407,8 +427,8 @@ static int usbasp_transmit(const PROGRAMMER *pgm,
|
||||
* shared VID/PID
|
||||
*/
|
||||
#ifdef USE_LIBUSB_1_0
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
||||
const char *vendorName, int product, const char *productName)
|
||||
static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName,
|
||||
int product, const char *productName, const char *port)
|
||||
{
|
||||
libusb_device_handle *handle = NULL;
|
||||
int errorCode = USB_ERROR_NOTFOUND;
|
||||
@@ -463,6 +483,18 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
||||
if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName))
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
}
|
||||
if (errorCode == 0) {
|
||||
if(!str_eq(port, "usb")) {
|
||||
// -P option given
|
||||
libusb_get_string_descriptor_ascii(handle, descriptor.iSerialNumber, (unsigned char*)string, sizeof(string));
|
||||
char bus_num[21];
|
||||
sprintf(bus_num, "%d", libusb_get_bus_number(dev));
|
||||
char dev_addr[21];
|
||||
sprintf(dev_addr, "%d", libusb_get_device_address(dev));
|
||||
if (!check_for_port_argument_match(port, bus_num, dev_addr, string))
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
}
|
||||
}
|
||||
if (errorCode == 0)
|
||||
break;
|
||||
libusb_close(handle);
|
||||
@@ -477,8 +509,8 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor,
|
||||
return errorCode;
|
||||
}
|
||||
#else
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor,
|
||||
const char *vendorName, int product, const char *productName)
|
||||
static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName,
|
||||
int product, const char *productName, const char *port)
|
||||
{
|
||||
struct usb_bus *bus;
|
||||
struct usb_device *dev;
|
||||
@@ -533,6 +565,15 @@ static int didUsbInit = 0;
|
||||
if((productName != NULL) && (productName[0] != 0) && !str_eq(string, productName))
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
}
|
||||
if (errorCode == 0) {
|
||||
if(!str_eq(port, "usb")) {
|
||||
// -P option given
|
||||
usb_get_string_simple(handle, dev->descriptor.iSerialNumber,
|
||||
string, sizeof(string));
|
||||
if (!check_for_port_argument_match(port, bus->dirname, dev->filename, string))
|
||||
errorCode = USB_ERROR_NOTFOUND;
|
||||
}
|
||||
}
|
||||
if (errorCode == 0)
|
||||
break;
|
||||
usb_close(handle);
|
||||
@@ -566,14 +607,14 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) {
|
||||
pid = USBASP_SHARED_PID;
|
||||
}
|
||||
vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID;
|
||||
if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct) != 0) {
|
||||
if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct, port) != 0) {
|
||||
/* try alternatives */
|
||||
if(str_eq(pgmid, "usbasp")) {
|
||||
/* for id usbasp autodetect some variants */
|
||||
if(str_caseeq(port, "nibobee")) {
|
||||
pmsg_error("using -C usbasp -P nibobee is deprecated, use -C nibobee instead\n");
|
||||
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_NIBOBEE_VID, "www.nicai-systems.com",
|
||||
USBASP_NIBOBEE_PID, "NIBObee") != 0) {
|
||||
USBASP_NIBOBEE_PID, "NIBObee", port) != 0) {
|
||||
pmsg_error("cannot find USB device NIBObee with vid=0x%x pid=0x%x\n",
|
||||
USBASP_NIBOBEE_VID, USBASP_NIBOBEE_PID);
|
||||
return -1;
|
||||
@@ -582,7 +623,7 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) {
|
||||
}
|
||||
/* check if device with old VID/PID is available */
|
||||
if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de",
|
||||
USBASP_OLD_PID, "USBasp") == 0) {
|
||||
USBASP_OLD_PID, "USBasp", port) == 0) {
|
||||
/* found USBasp with old IDs */
|
||||
pmsg_error("found USB device USBasp with old VID/PID; please update firmware of USBasp\n");
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user