From c999083b8f7a0312451ea9ed58cbb8bb76f4926d Mon Sep 17 00:00:00 2001 From: MCUdude Date: Thu, 20 Oct 2022 00:12:17 +0200 Subject: [PATCH 1/6] Change message type from error to warning and add additional USB info --- src/usb_hidapi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/usb_hidapi.c b/src/usb_hidapi.c index b6dc3d33..4ad372b1 100644 --- a/src/usb_hidapi.c +++ b/src/usb_hidapi.c @@ -133,8 +133,9 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor dev = hid_open(pinfo.usbinfo.vid, pinfo.usbinfo.pid, NULL); if (dev == NULL) { - pmsg_error("no device found\n"); - return -1; + pmsg_warning("USB device with VID: 0x%04x and PID: 0x%04x not found\n", + pinfo.usbinfo.vid, pinfo.usbinfo.pid); + return -1; } } From 13817459e1010e37752a15cf45937335100ca705 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Thu, 20 Oct 2022 00:12:44 +0200 Subject: [PATCH 2/6] Add missing USB VID/PIDs --- src/usbdevs.h | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/usbdevs.h b/src/usbdevs.h index 0dbdb482..f801e01b 100644 --- a/src/usbdevs.h +++ b/src/usbdevs.h @@ -25,19 +25,28 @@ #ifndef usbdevs_h #define usbdevs_h -#define USB_VENDOR_ATMEL 1003 -#define USB_DEVICE_JTAGICEMKII 0x2103 -#define USB_DEVICE_AVRISPMKII 0x2104 -#define USB_DEVICE_STK600 0x2106 -#define USB_DEVICE_AVRDRAGON 0x2107 -#define USB_DEVICE_JTAGICE3 0x2110 -#define USB_DEVICE_XPLAINEDPRO 0x2111 -#define USB_DEVICE_JTAG3_EDBG 0x2140 -#define USB_DEVICE_ATMEL_ICE 0x2141 +#define USB_VENDOR_ATMEL 0x03EB +#define USB_VENDOR_MICROCHIP 0x04D8 -#define USB_VENDOR_FTDI 0x0403 -#define USB_DEVICE_FT2232 0x6010 -#define USB_DEVICE_FT245 0x6001 +#define USB_DEVICE_JTAGICEMKII 0x2103 +#define USB_DEVICE_AVRISPMKII 0x2104 +#define USB_DEVICE_STK600 0x2106 +#define USB_DEVICE_AVRDRAGON 0x2107 +#define USB_DEVICE_JTAGICE3 0x2110 +#define USB_DEVICE_XPLAINEDPRO 0x2111 +#define USB_DEVICE_JTAG3_EDBG 0x2140 +#define USB_DEVICE_ATMEL_ICE 0x2141 +#define USB_DEVICE_POWERDEBUGGER 0x2144 +#define USB_DEVICE_XPLAINEDMINI 0x2145 +#define USB_DEVICE_PKOBN 0x2175 +#define USB_DEVICE_PICKIT4_AVR_MODE 0x2177 +#define USB_DEVICE_PICKIT4_PIC_MODE 0x9012 +#define USB_DEVICE_SNAP_AVR_MODE 0x2180 +#define USB_DEVICE_SNAP_PIC_MODE 0x9018 + +#define USB_VENDOR_FTDI 0x0403 +#define USB_DEVICE_FT2232 0x6010 +#define USB_DEVICE_FT245 0x6001 #define USBASP_SHARED_VID 0x16C0 /* VOTI */ #define USBASP_SHARED_PID 0x05DC /* Obdev's free shared PID */ From b083416e3b335d1ccc94a7a7fd1625d918dd8523 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Thu, 20 Oct 2022 00:13:15 +0200 Subject: [PATCH 3/6] Let Avrdude use the valid SNAP USB PID first --- src/avrdude.conf.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in index 706b915a..6e3ea3cd 100644 --- a/src/avrdude.conf.in +++ b/src/avrdude.conf.in @@ -2280,7 +2280,7 @@ programmer type = "jtagice3_updi"; prog_modes = PM_UPDI; connection_type = usb; - usbpid = 0x217f, 0x2180, 0x2181; + usbpid = 0x2180, 0x217f, 0x2181; hvupdi_support = 1; ; @@ -2294,7 +2294,7 @@ programmer type = "jtagice3_pdi"; prog_modes = PM_PDI; connection_type = usb; - usbpid = 0x217f, 0x2180, 0x2181; + usbpid = 0x2180, 0x217f, 0x2181; ; #------------------------------------------------------------ @@ -2307,7 +2307,7 @@ programmer type = "jtagice3_isp"; prog_modes = PM_ISP; connection_type = usb; - usbpid = 0x217f, 0x2180, 0x2181; + usbpid = 0x2180, 0x217f, 0x2181; ; #------------------------------------------------------------ From 14446950dfdef305c4e40512434640f6188a2535 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Thu, 20 Oct 2022 00:13:37 +0200 Subject: [PATCH 4/6] Check for PICkit4 or SNAP in PIC mode --- src/jtag3.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/jtag3.c b/src/jtag3.c index e3e39fbe..3ca5f4e3 100644 --- a/src/jtag3.c +++ b/src/jtag3.c @@ -1504,6 +1504,30 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port) { } #endif if (rv < 0) { + // Check if SNAP or PICkit4 is in PIC mode + for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) { + if (matches(ldata(ln), "snap")) { + pinfo.usbinfo.vid = USB_VENDOR_MICROCHIP; + pinfo.usbinfo.pid = USB_DEVICE_SNAP_PIC_MODE; + int pic_mode = serial_open(port, pinfo, &pgm->fd); + if(pic_mode >= 0) { + msg_error("\n"); + pmsg_error("MPLAB SNAP in PIC mode detected!\n"); + imsg_error("Use MPLAB X or Microchip Studio to switch to AVR mode\n\n"); + return -1; + } + } else if(matches(ldata(ln), "pickit4")) { + pinfo.usbinfo.vid = USB_VENDOR_MICROCHIP; + pinfo.usbinfo.pid = USB_DEVICE_PICKIT4_PIC_MODE; + int pic_mode = serial_open(port, pinfo, &pgm->fd); + if(pic_mode >= 0) { + msg_error("\n"); + pmsg_error("PICkit4 in PIC mode detected!\n"); + imsg_error("Use MPLAB X or Microchip Studio to switch to AVR mode\n\n"); + return -1; + } + } + } pmsg_error("did not find any device matching VID 0x%04x and PID list: ", (unsigned) pinfo.usbinfo.vid); int notfirst = 0; From 867d83c21536ed7e13f32f2a3a152302e784b742 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Thu, 20 Oct 2022 12:27:59 +0200 Subject: [PATCH 5/6] Print error message if no HID device is connected when using hidapi --- src/usb_hidapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/usb_hidapi.c b/src/usb_hidapi.c index 4ad372b1..4ddb80e3 100644 --- a/src/usb_hidapi.c +++ b/src/usb_hidapi.c @@ -93,8 +93,10 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor */ struct hid_device_info *list, *walk; list = hid_enumerate(pinfo.usbinfo.vid, pinfo.usbinfo.pid); - if (list == NULL) - return -1; + if (list == NULL) { + pmsg_error("No USB HID devices found\n"); + return -1; + } walk = list; while (walk) From 72da5c73db639c0b79cdd9a52954bf26ccb7c521 Mon Sep 17 00:00:00 2001 From: MCUdude Date: Thu, 20 Oct 2022 12:39:11 +0200 Subject: [PATCH 6/6] Fix formatting and replace tabs with spaces --- src/usb_hidapi.c | 253 +++++++++++++++++++++-------------------------- 1 file changed, 114 insertions(+), 139 deletions(-) diff --git a/src/usb_hidapi.c b/src/usb_hidapi.c index 4ddb80e3..c9fa258e 100644 --- a/src/usb_hidapi.c +++ b/src/usb_hidapi.c @@ -65,81 +65,70 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor * right-to-left, so only the least significant nibbles need to be * specified. */ - if ((serno = strchr(port, ':')) != NULL) - { - /* first, drop all colons there if any */ - cp2 = ++serno; + if ((serno = strchr(port, ':')) != NULL) { + /* First, drop all colons there if any */ + cp2 = ++serno; - while ((cp2 = strchr(cp2, ':')) != NULL) - { - x = strlen(cp2) - 1; - memmove(cp2, cp2 + 1, x); - cp2[x] = '\0'; - } + while ((cp2 = strchr(cp2, ':')) != NULL) { + x = strlen(cp2) - 1; + memmove(cp2, cp2 + 1, x); + cp2[x] = '\0'; + } - if (strlen(serno) > 12) - { - pmsg_error("invalid serial number %s\n", serno); - return -1; - } + if (strlen(serno) > 12) { + pmsg_error("invalid serial number %s\n", serno); + return -1; + } - wchar_t wserno[15]; - mbstowcs(wserno, serno, 15); - size_t serlen = strlen(serno); + wchar_t wserno[15]; + mbstowcs(wserno, serno, 15); + size_t serlen = strlen(serno); - /* - * Now, try finding all devices matching VID:PID, and compare - * their serial numbers against the requested one. - */ - struct hid_device_info *list, *walk; - list = hid_enumerate(pinfo.usbinfo.vid, pinfo.usbinfo.pid); - if (list == NULL) { - pmsg_error("No USB HID devices found\n"); - return -1; - } + /* + * Now, try finding all devices matching VID:PID, and compare + * their serial numbers against the requested one. + */ + struct hid_device_info *list, *walk; + list = hid_enumerate(pinfo.usbinfo.vid, pinfo.usbinfo.pid); + if (list == NULL) { + pmsg_error("No USB HID devices found\n"); + return -1; + } - walk = list; - while (walk) + walk = list; + while (walk) { + pmsg_notice("usbhid_open(): found %ls, serno: %ls\n", walk->product_string, walk->serial_number); + size_t slen = wcslen(walk->serial_number); + if (slen >= serlen && wcscmp(walk->serial_number + slen - serlen, wserno) == 0) { - pmsg_notice("usbhid_open(): found %ls, serno: %ls\n", walk->product_string, walk->serial_number); - size_t slen = wcslen(walk->serial_number); - if (slen >= serlen && - wcscmp(walk->serial_number + slen - serlen, wserno) == 0) - { - /* found matching serial number */ - break; - } - pmsg_debug("usbhid_open(): serial number does not match\n"); - walk = walk->next; + /* Found matching serial number */ + break; } - if (walk == NULL) - { - pmsg_error("no matching device found\n"); - hid_free_enumeration(list); - return -1; - } - pmsg_debug("usbhid_open(): opening path %s\n", walk->path); - dev = hid_open_path(walk->path); + pmsg_debug("usbhid_open(): serial number does not match\n"); + walk = walk->next; + } + if (walk == NULL) { + pmsg_error("no matching device found\n"); hid_free_enumeration(list); - if (dev == NULL) - { - pmsg_error("found device, but hid_open_path() failed\n"); - return -1; - } + return -1; } - else + pmsg_debug("usbhid_open(): opening path %s\n", walk->path); + dev = hid_open_path(walk->path); + hid_free_enumeration(list); + if (dev == NULL) { + pmsg_error("found device, but hid_open_path() failed\n"); + return -1; + } + } else { + /* No serial number requested, pass straight to hid_open() */ + dev = hid_open(pinfo.usbinfo.vid, pinfo.usbinfo.pid, NULL); + if (dev == NULL) { - /* - * No serial number requested, pass straight to hid_open() - */ - dev = hid_open(pinfo.usbinfo.vid, pinfo.usbinfo.pid, NULL); - if (dev == NULL) - { - pmsg_warning("USB device with VID: 0x%04x and PID: 0x%04x not found\n", - pinfo.usbinfo.vid, pinfo.usbinfo.pid); - return -1; - } + pmsg_warning("USB device with VID: 0x%04x and PID: 0x%04x not found\n", + pinfo.usbinfo.vid, pinfo.usbinfo.pid); + return -1; } + } fd->usb.handle = dev; @@ -169,39 +158,38 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor * be incremented by one, as the report ID will be omitted by the * hidapi library. */ - if (pinfo.usbinfo.vid == USB_VENDOR_ATMEL) - { - pmsg_debug("usbhid_open(): probing for max packet size\n"); - memset(usbbuf, 0, sizeof usbbuf); - usbbuf[0] = 0; /* no HID reports used */ - usbbuf[1] = 0; /* DAP_Info */ - usbbuf[2] = 0xFF; /* get max. packet size */ + if (pinfo.usbinfo.vid == USB_VENDOR_ATMEL) { + pmsg_debug("usbhid_open(): probing for max packet size\n"); + memset(usbbuf, 0, sizeof usbbuf); + usbbuf[0] = 0; /* no HID reports used */ + usbbuf[1] = 0; /* DAP_Info */ + usbbuf[2] = 0xFF; /* get max. packet size */ - hid_write(dev, usbbuf, 65); - fd->usb.max_xfer = 64; /* first guess */ + hid_write(dev, usbbuf, 65); + fd->usb.max_xfer = 64; /* first guess */ - memset(usbbuf, 0, sizeof usbbuf); - int res = hid_read_timeout(dev, usbbuf, 10 /* bytes */, 50 /* milliseconds */); - if (res == 0) { - /* no timely response, assume 512 byte size */ - hid_write(dev, usbbuf, (512 - 64) + 1); - fd->usb.max_xfer = 512; - res = hid_read_timeout(dev, usbbuf, 10, 50); - } - if (res <= 0) { - pmsg_error("no response from device\n"); - hid_close(dev); - return -1; - } - if (usbbuf[0] != 0 || usbbuf[1] != 2) { - pmsg_error("unexpected reply to DAP_Info: 0x%02x 0x%02x\n", - usbbuf[0], usbbuf[1]); - } else { - fd->usb.max_xfer = usbbuf[2] + (usbbuf[3] << 8); - pmsg_debug("usbhid_open(): setting max_xfer from DAP_Info response to %d\n", - fd->usb.max_xfer); - } + memset(usbbuf, 0, sizeof usbbuf); + int res = hid_read_timeout(dev, usbbuf, 10 /* bytes */, 50 /* milliseconds */); + if (res == 0) { + /* No timely response, assume 512 byte size */ + hid_write(dev, usbbuf, (512 - 64) + 1); + fd->usb.max_xfer = 512; + res = hid_read_timeout(dev, usbbuf, 10, 50); } + if (res <= 0) { + pmsg_error("no response from device\n"); + hid_close(dev); + return -1; + } + if (usbbuf[0] != 0 || usbbuf[1] != 2) { + pmsg_error("unexpected reply to DAP_Info: 0x%02x 0x%02x\n", + usbbuf[0], usbbuf[1]); + } else { + fd->usb.max_xfer = usbbuf[2] + (usbbuf[3] << 8); + pmsg_debug("usbhid_open(): setting max_xfer from DAP_Info response to %d\n", + fd->usb.max_xfer); + } + } if (fd->usb.max_xfer > USBDEV_MAX_XFER_3) { pmsg_error("unexpected max size %d, reducing to %d\n", fd->usb.max_xfer, USBDEV_MAX_XFER_3); @@ -211,8 +199,7 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor return 0; } -static void usbhid_close(union filedescriptor *fd) -{ +static void usbhid_close(union filedescriptor *fd) { hid_device *udev = (hid_device *)fd->usb.handle; if (udev == NULL) @@ -222,22 +209,20 @@ static void usbhid_close(union filedescriptor *fd) } -static int usbhid_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen) -{ +static int usbhid_send(const union filedescriptor *fd, const unsigned char *bp, size_t mlen) { hid_device *udev = (hid_device *)fd->usb.handle; int rv; int i = mlen; const unsigned char * p = bp; unsigned char usbbuf[USBDEV_MAX_XFER_3 + 1]; - int tx_size; if (udev == NULL) return -1; tx_size = (mlen < USBDEV_MAX_XFER_3)? mlen: USBDEV_MAX_XFER_3; - usbbuf[0] = 0; /* no report ID used */ + usbbuf[0] = 0; /* No report ID used */ memcpy(usbbuf + 1, bp, tx_size); rv = hid_write(udev, usbbuf, tx_size + 1); if (rv < 0) { @@ -247,30 +232,26 @@ static int usbhid_send(const union filedescriptor *fd, const unsigned char *bp, if (rv != tx_size + 1) pmsg_error("short write to USB: %d bytes out of %d written\n", rv, tx_size + 1); - if (verbose > 4) - { - pmsg_trace2("sent: "); + if (verbose > 4) { + pmsg_trace2("sent: "); - while (i) { - unsigned char c = *p; - if (isprint(c)) { - msg_trace2("%c ", c); - } - else { - msg_trace2(". "); - } - msg_trace2("[%02x] ", c); + while (i) { + unsigned char c = *p; + if (isprint(c)) + msg_trace2("%c ", c); + else + msg_trace2(". "); + msg_trace2("[%02x] ", c); - p++; - i--; - } - msg_trace2("\n"); + p++; + i--; + } + msg_trace2("\n"); } return 0; } -static int usbhid_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) -{ +static int usbhid_recv(const union filedescriptor *fd, unsigned char *buf, size_t nbytes) { hid_device *udev = (hid_device *)fd->usb.handle; int i, rv; unsigned char * p = buf; @@ -282,31 +263,26 @@ static int usbhid_recv(const union filedescriptor *fd, unsigned char *buf, size_ if (i != nbytes) pmsg_error("short read, read only %d out of %lu bytes\n", i, (unsigned long) nbytes); - if (verbose > 4) - { - pmsg_trace2("recv: "); + if (verbose > 4) { + pmsg_trace2("recv: "); - while (i) { - unsigned char c = *p; - if (isprint(c)) { - msg_trace2("%c ", c); - } - else { - msg_trace2(". "); - } - msg_trace2("[%02x] ", c); + while (i) { + unsigned char c = *p; + if (isprint(c)) + msg_trace2("%c ", c); + else + msg_trace2(". "); + msg_trace2("[%02x] ", c); - p++; - i--; - } - msg_trace2("\n"); + p++; + i--; + } + msg_trace2("\n"); } - return rv; } -static int usbhid_drain(const union filedescriptor *fd, int display) -{ +static int usbhid_drain(const union filedescriptor *fd, int display) { /* * There is not much point in trying to flush any data * on an USB endpoint, as the endpoint is supposed to @@ -324,8 +300,7 @@ static int usbhid_drain(const union filedescriptor *fd, int display) /* * Device descriptor. */ -struct serial_device usbhid_serdev = -{ +struct serial_device usbhid_serdev = { .open = usbhid_open, .close = usbhid_close, .send = usbhid_send,