diff --git a/ChangeLog b/ChangeLog index e4e27ef5..16efc7bc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-09-17 Joerg Wunsch + + Submitted by Thomas Fischl: + * usbasp.c: Check for USBasp with new as well as old VID/PID + pair, warn the user about upgrading the firmware in case an + old one has been found. + * usbasp.h: Add new VID/PID. + 2006-09-15 Joerg Wunsch * avrdude.conf.in: Fix some mistakes for the ATtinyX61 family: diff --git a/usbasp.c b/usbasp.c index 013ff6b0..f931c1c2 100644 --- a/usbasp.c +++ b/usbasp.c @@ -40,6 +40,7 @@ #ifdef HAVE_LIBUSB #include +extern int verbose; extern char * progname; extern int do_cycles; @@ -67,33 +68,121 @@ static int usbasp_transmit(unsigned char receive, unsigned char functionid, return nbytes; } + +/* + * Try to open USB device with given VID, PID, vendor and product name + * Parts of this function were taken from an example code by OBJECTIVE + * DEVELOPMENT Software GmbH (www.obdev.at) to meet conditions for + * shared VID/PID + */ +static int usbOpenDevice(usb_dev_handle **device, int vendor, + char *vendorName, int product, char *productName) +{ +struct usb_bus *bus; +struct usb_device *dev; +usb_dev_handle *handle = NULL; +int errorCode = USB_ERROR_NOTFOUND; +static int didUsbInit = 0; + + if(!didUsbInit){ + didUsbInit = 1; + usb_init(); + } + usb_find_busses(); + usb_find_devices(); + for(bus=usb_get_busses(); bus; bus=bus->next){ + for(dev=bus->devices; dev; dev=dev->next){ + if(dev->descriptor.idVendor == vendor && + dev->descriptor.idProduct == product){ + char string[256]; + int len; + /* we need to open the device in order to query strings */ + handle = usb_open(dev); + if(!handle){ + errorCode = USB_ERROR_ACCESS; + fprintf(stderr, + "%s: Warning: cannot open USB device: %s\n", + progname, usb_strerror()); + continue; + } + if(vendorName == NULL && productName == NULL){ + /* name does not matter */ + break; + } + /* now check whether the names match: */ + len = usb_get_string_simple(handle, dev->descriptor.iManufacturer, + string, sizeof(string)); + if(len < 0){ + errorCode = USB_ERROR_IO; + fprintf(stderr, + "%s: Warning: cannot query manufacturer for device: %s\n", + progname, usb_strerror()); + }else{ + errorCode = USB_ERROR_NOTFOUND; + if (verbose > 1) + fprintf(stderr, + "%s: seen device from vendor ->%s<-\n", + progname, string); + if(strcmp(string, vendorName) == 0){ + len = usb_get_string_simple(handle, dev->descriptor.iProduct, + string, sizeof(string)); + if(len < 0){ + errorCode = USB_ERROR_IO; + fprintf(stderr, + "%s: Warning: cannot query product for device: %s\n", + progname, usb_strerror()); + }else{ + errorCode = USB_ERROR_NOTFOUND; + if (verbose > 1) + fprintf(stderr, + "%s: seen product ->%s<-\n", + progname, string); + if(strcmp(string, productName) == 0) + break; + } + } + } + usb_close(handle); + handle = NULL; + } + } + if(handle) + break; + } + if(handle != NULL){ + errorCode = 0; + *device = handle; + } + return errorCode; +} + + static int usbasp_open(PROGRAMMER * pgm, char * port) { - struct usb_bus *bus; - struct usb_device *dev = 0; - usb_init(); - usb_find_busses(); - usb_find_devices(); - for(bus=usb_busses; bus; bus=bus->next){ - for(dev=bus->devices; dev; dev=dev->next){ - if(dev->descriptor.idVendor == USBDEV_VENDOR && dev->descriptor.idProduct == USBDEV_PRODUCT) - break; - } - if(dev) - break; - } - if(!dev){ - fprintf(stderr, "%s: error: could not find USB device vendor=0x%x product=0x%x\n", - progname, USBDEV_VENDOR, USBDEV_PRODUCT); - exit(1); - } - usbhandle = usb_open(dev); - if(!usbhandle){ - fprintf(stderr, "%s: error: opening usb device: %s\n", - progname, usb_strerror()); - exit(1); + if (usbOpenDevice(&usbhandle, USBASP_SHARED_VID, "www.fischl.de", + USBASP_SHARED_PID, "USBasp") != 0) { + + /* check if device with old VID/PID is available */ + if (usbOpenDevice(&usbhandle, USBASP_OLD_VID, "www.fischl.de", + USBASP_OLD_PID, "USBasp") != 0) { + + /* no USBasp found */ + fprintf(stderr, + "%s: error: could not find USB device " + "\"USBasp\" with vid=0x%x pid=0x%x\n", + progname, USBASP_SHARED_VID, USBASP_SHARED_PID); + exit(1); + + } else { + + /* found USBasp with old IDs */ + fprintf(stderr, + "%s: Warning: Found USB device \"USBasp\" with " + "old VID/PID! Please update firmware of USBasp!\n", + progname); + } } return 0; diff --git a/usbasp.h b/usbasp.h index 9a2d37be..f2959628 100644 --- a/usbasp.h +++ b/usbasp.h @@ -25,8 +25,11 @@ #include "avrpart.h" -#define USBDEV_VENDOR 0x03eb /* ATMEL */ -#define USBDEV_PRODUCT 0xc7B4 /* USBasp */ +#define USBASP_SHARED_VID 0x16C0 /* VOTI */ +#define USBASP_SHARED_PID 0x05DC /* Obdev's free shared PID */ + +#define USBASP_OLD_VID 0x03EB /* ATMEL */ +#define USBASP_OLD_PID 0xC7B4 /* (unoffical) USBasp */ #define USBASP_FUNC_CONNECT 1 #define USBASP_FUNC_DISCONNECT 2 @@ -43,6 +46,9 @@ #define USBASP_READBLOCKSIZE 200 #define USBASP_WRITEBLOCKSIZE 200 +#define USB_ERROR_NOTFOUND 1 +#define USB_ERROR_ACCESS 2 +#define USB_ERROR_IO 3 void usbasp_initpgm (PROGRAMMER * pgm);