From e56d09dee240be7e8b25fc5687ba86893dc91a27 Mon Sep 17 00:00:00 2001 From: Michael Copland Date: Wed, 22 Jun 2016 13:06:23 +0100 Subject: Changed to manually iterate through the device list --- commandline/builds/Windows/micronucleus.exe | Bin 104257 -> 104447 bytes commandline/library/micronucleus_lib.c | 137 ++++++++++++++-------------- 2 files changed, 70 insertions(+), 67 deletions(-) diff --git a/commandline/builds/Windows/micronucleus.exe b/commandline/builds/Windows/micronucleus.exe index c808e91..da02390 100644 Binary files a/commandline/builds/Windows/micronucleus.exe and b/commandline/builds/Windows/micronucleus.exe differ diff --git a/commandline/library/micronucleus_lib.c b/commandline/library/micronucleus_lib.c index 59ca62c..58ed10a 100644 --- a/commandline/library/micronucleus_lib.c +++ b/commandline/library/micronucleus_lib.c @@ -31,97 +31,100 @@ #include "littleWire_util.h" micronucleus* micronucleus_connect(int fast_mode) { - // intialise usb and find micronucleus device - if (libusb_init(NULL) < 0) return NULL; - - micronucleus *nucleus = malloc(sizeof(micronucleus)); + micronucleus *nucleus = NULL; + libusb_device **devs, **dev; - nucleus->device = libusb_open_device_with_vid_pid(NULL, MICRONUCLEUS_VENDOR_ID, MICRONUCLEUS_PRODUCT_ID); + // intialise usb and find micronucleus device + if (libusb_init(NULL) < 0 || libusb_get_device_list(NULL, &devs) < 0) return NULL; - if (nucleus->device) { - libusb_device* dev = libusb_get_device(nucleus->device); + for (dev = devs; *dev; dev++) { struct libusb_device_descriptor desc; - if (libusb_get_device_descriptor(dev, &desc) < 0) { - fprintf(stderr, "failed to get device descriptor"); - return NULL; - } + // skip device if we cannot get its descriptor + if (libusb_get_device_descriptor(*dev, &desc) < 0) continue; + + if (desc.idVendor == MICRONUCLEUS_VENDOR_ID && desc.idProduct == MICRONUCLEUS_PRODUCT_ID) { + nucleus = malloc(sizeof(micronucleus)); + nucleus->version.major = (desc.bcdDevice >> 8) & 0xFF; + nucleus->version.minor = desc.bcdDevice & 0xFF; + + if (nucleus->version.major > MICRONUCLEUS_MAX_MAJOR_VERSION) { + fprintf(stderr, + "Warning: device with unknown new version of Micronucleus detected.\n" + "This tool doesn't know how to upload to this new device. Updates may be available.\n" + "Device reports version as: %d.%d\n", + nucleus->version.major, nucleus->version.minor); + return NULL; + } - nucleus->version.major = (desc.bcdDevice >> 8) & 0xFF; - nucleus->version.minor = desc.bcdDevice & 0xFF; + if (libusb_open(*dev, &nucleus->device) < 0) return NULL; - if (nucleus->version.major > MICRONUCLEUS_MAX_MAJOR_VERSION) { - fprintf(stderr, - "Warning: device with unknown new version of Micronucleus detected.\n" - "This tool doesn't know how to upload to this new device. Updates may be available.\n" - "Device reports version as: %d.%d\n", - nucleus->version.major, nucleus->version.minor); - return NULL; - } + if (nucleus->version.major>=2) { // Version 2.x + // get nucleus info + unsigned char buffer[6]; + int res = libusb_control_transfer(nucleus->device, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|LIBUSB_RECIPIENT_DEVICE, 0, 0, 0, buffer, 6, MICRONUCLEUS_USB_TIMEOUT); - if (nucleus->version.major>=2) { // Version 2.x - // get nucleus info - unsigned char buffer[6]; - int res = libusb_control_transfer(nucleus->device, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|LIBUSB_RECIPIENT_DEVICE, 0, 0, 0, buffer, 6, MICRONUCLEUS_USB_TIMEOUT); + // Device descriptor was found, but talking to it was not succesful. This can happen when the device is being reset. + if (res<0) return NULL; - // Device descriptor was found, but talking to it was not succesful. This can happen when the device is being reset. - if (res<0) return NULL; + assert(res >= 6); - assert(res >= 6); + nucleus->flash_size = (buffer[0]<<8) + buffer[1]; + nucleus->page_size = buffer[2]; + nucleus->pages = (nucleus->flash_size / nucleus->page_size); + if (nucleus->pages * nucleus->page_size < nucleus->flash_size) nucleus->pages += 1; - nucleus->flash_size = (buffer[0]<<8) + buffer[1]; - nucleus->page_size = buffer[2]; - nucleus->pages = (nucleus->flash_size / nucleus->page_size); - if (nucleus->pages * nucleus->page_size < nucleus->flash_size) nucleus->pages += 1; + nucleus->bootloader_start = nucleus->pages*nucleus->page_size; - nucleus->bootloader_start = nucleus->pages*nucleus->page_size; + if ((nucleus->version.major>=2)&&(!fast_mode)) { + // firmware v2 reports more aggressive write times. Add 2ms if fast mode is not used. + nucleus->write_sleep = (buffer[3] & 127) + 2; + } else { + nucleus->write_sleep = (buffer[3] & 127); + } - if ((nucleus->version.major>=2)&&(!fast_mode)) { - // firmware v2 reports more aggressive write times. Add 2ms if fast mode is not used. - nucleus->write_sleep = (buffer[3] & 127) + 2; - } else { - nucleus->write_sleep = (buffer[3] & 127); - } + // if bit 7 of write sleep time is set, divide the erase time by four to + // accomodate to the 4*page erase of the ATtiny841/441 + if (buffer[3]&128) { + nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages / 4; + } else { + nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages; + } - // if bit 7 of write sleep time is set, divide the erase time by four to - // accomodate to the 4*page erase of the ATtiny841/441 - if (buffer[3]&128) { - nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages / 4; - } else { - nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages; - } + nucleus->signature1 = buffer[4]; + nucleus->signature2 = buffer[5]; - nucleus->signature1 = buffer[4]; - nucleus->signature2 = buffer[5]; + } else { // Version 1.x + // get nucleus info + unsigned char buffer[4]; + int res = libusb_control_transfer(nucleus->device, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR |LIBUSB_RECIPIENT_DEVICE, 0, 0, 0, buffer, 4, MICRONUCLEUS_USB_TIMEOUT); - } else { // Version 1.x - // get nucleus info - unsigned char buffer[4]; - int res = libusb_control_transfer(nucleus->device, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR |LIBUSB_RECIPIENT_DEVICE, 0, 0, 0, buffer, 4, MICRONUCLEUS_USB_TIMEOUT); + // Device descriptor was found, but talking to it was not succesful. This can happen when the device is being reset. + if (res<0) return NULL; - // Device descriptor was found, but talking to it was not succesful. This can happen when the device is being reset. - if (res<0) return NULL; + assert(res >= 4); - assert(res >= 4); + nucleus->flash_size = (buffer[0]<<8) + buffer[1]; + nucleus->page_size = buffer[2]; + nucleus->pages = (nucleus->flash_size / nucleus->page_size); + if (nucleus->pages * nucleus->page_size < nucleus->flash_size) nucleus->pages += 1; - nucleus->flash_size = (buffer[0]<<8) + buffer[1]; - nucleus->page_size = buffer[2]; - nucleus->pages = (nucleus->flash_size / nucleus->page_size); - if (nucleus->pages * nucleus->page_size < nucleus->flash_size) nucleus->pages += 1; + nucleus->bootloader_start = nucleus->pages*nucleus->page_size; - nucleus->bootloader_start = nucleus->pages*nucleus->page_size; + nucleus->write_sleep = (buffer[3] & 127); + nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages; - nucleus->write_sleep = (buffer[3] & 127); - nucleus->erase_sleep = nucleus->write_sleep * nucleus->pages; + nucleus->signature1 = 0; + nucleus->signature2 = 0; + } - nucleus->signature1 = 0; - nucleus->signature2 = 0; + // we've found the device; there's no sense in checking everything else + break; } - } else { - free(nucleus); - nucleus = NULL; } + libusb_free_device_list(devs, 1); + return nucleus; } -- cgit v1.2.3