diff --git a/Bootloaders/HID/HostLoaderApp/Makefile b/Bootloaders/HID/HostLoaderApp/Makefile index d7d6458a5..3c47ac4ae 100644 --- a/Bootloaders/HID/HostLoaderApp/Makefile +++ b/Bootloaders/HID/HostLoaderApp/Makefile @@ -7,7 +7,8 @@ ifeq ($(OS), LINUX) # also works on FreeBSD CC ?= gcc CFLAGS ?= -O2 -Wall hid_bootloader_cli: hid_bootloader_cli.c - $(CC) $(CFLAGS) -s -DUSE_LIBUSB -o hid_bootloader_cli hid_bootloader_cli.c -lusb + #$(CC) $(CFLAGS) -s -DUSE_LIBUSB -o hid_bootloader_cli hid_bootloader_cli.c ../AES/aes.c -lusb + $(CC) $(CFLAGS) -s -DUSE_HIDAPI -o hid_bootloader_cli hid_bootloader_cli.c ../AES/aes.c -I/usr/include/hidapi/ -lhidapi-libusb else ifeq ($(OS), WINDOWS) diff --git a/Bootloaders/HID/HostLoaderApp/hid_bootloader_cli.c b/Bootloaders/HID/HostLoaderApp/hid_bootloader_cli.c index b54f943b1..d81abd653 100644 --- a/Bootloaders/HID/HostLoaderApp/hid_bootloader_cli.c +++ b/Bootloaders/HID/HostLoaderApp/hid_bootloader_cli.c @@ -41,19 +41,19 @@ void usage(void) { - fprintf(stderr, "Usage: hid_bootloader_cli -mmcu= [-w] [-h] [-n] [-v] \n"); - fprintf(stderr, "\t-w : Wait for device to appear\n"); - fprintf(stderr, "\t-r : Use hard reboot if device not online\n"); - fprintf(stderr, "\t-n : No reboot after programming\n"); - fprintf(stderr, "\t-v : Verbose output\n"); - fprintf(stderr, "\n = atmegaXXuY or at90usbXXXY"); - - fprintf(stderr, "\nFor support and more information, please visit:\n"); - fprintf(stderr, "http://www.lufa-lib.org\n"); - - fprintf(stderr, "\nBased on the TeensyHID command line programmer software:\n"); - fprintf(stderr, "http://www.pjrc.com/teensy/loader_cli.html\n"); - exit(1); + fprintf(stderr, "Usage: hid_bootloader_cli -mmcu= [-w] [-h] [-n] [-v] \n"); + fprintf(stderr, "\t-w : Wait for device to appear\n"); + fprintf(stderr, "\t-r : Use hard reboot if device not online\n"); + fprintf(stderr, "\t-n : No reboot after programming\n"); + fprintf(stderr, "\t-v : Verbose output\n"); + fprintf(stderr, "\n = atmegaXXuY or at90usbXXXY"); + + fprintf(stderr, "\nFor support and more information, please visit:\n"); + fprintf(stderr, "http://www.lufa-lib.org\n"); + + fprintf(stderr, "\nBased on the TeensyHID command line programmer software:\n"); + fprintf(stderr, "http://www.pjrc.com/teensy/loader_cli.html\n"); + exit(1); } // USB Access Functions @@ -90,90 +90,90 @@ const char *filename=NULL; int main(int argc, char **argv) { - unsigned char buf[260]; - int num, addr, r, first_block=1, waited=0; - - // parse command line arguments - parse_options(argc, argv); - if (!filename) { - fprintf(stderr, "Filename must be specified\n\n"); - usage(); - } - if (!code_size) { - fprintf(stderr, "MCU type must be specified\n\n"); - usage(); - } - printf_verbose("Teensy Loader, Command Line, Version 2.0\n"); - - // read the intel hex file - // this is done first so any error is reported before using USB - num = read_intel_hex(filename); - if (num < 0) die("error reading intel hex file \"%s\"", filename); - printf_verbose("Read \"%s\": %d bytes, %.1f%% usage\n", - filename, num, (double)num / (double)code_size * 100.0); - - // open the USB device - while (1) { - if (teensy_open()) break; - if (hard_reboot_device) { - if (!hard_reboot()) die("Unable to find rebootor\n"); - printf_verbose("Hard Reboot performed\n"); - hard_reboot_device = 0; // only hard reboot once - wait_for_device_to_appear = 1; - } - if (!wait_for_device_to_appear) die("Unable to open device\n"); - if (!waited) { - printf_verbose("Waiting for Teensy device...\n"); - printf_verbose(" (hint: press the reset button)\n"); - waited = 1; - } - delay(0.25); - } - printf_verbose("Found HalfKay Bootloader\n"); - - // if we waited for the device, read the hex file again - // perhaps it changed while we were waiting? - if (waited) { - num = read_intel_hex(filename); - if (num < 0) die("error reading intel hex file \"%s\"", filename); - printf_verbose("Read \"%s\": %d bytes, %.1f%% usage\n", - filename, num, (double)num / (double)code_size * 100.0); - } - - // program the data - printf_verbose("Programming"); - fflush(stdout); - for (addr = 0; addr < code_size; addr += block_size) { - if (addr > 0 && !ihex_bytes_within_range(addr, addr + block_size - 1)) { - // don't waste time on blocks that are unused, - // but always do the first one to erase the chip - continue; - } - printf_verbose("."); - if (code_size < 0x10000) { - buf[0] = addr & 255; - buf[1] = (addr >> 8) & 255; - } else { - buf[0] = (addr >> 8) & 255; - buf[1] = (addr >> 16) & 255; - } - ihex_get_data(addr, block_size, buf + 2); - r = teensy_write(buf, block_size + 2, first_block ? 3.0 : 0.25); - if (!r) die("error writing to Teensy\n"); - first_block = 0; - } - printf_verbose("\n"); - - // reboot to the user's new code - if (reboot_after_programming) { - printf_verbose("Booting\n"); - buf[0] = 0xFF; - buf[1] = 0xFF; - memset(buf + 2, 0, sizeof(buf) - 2); - teensy_write(buf, block_size + 2, 0.25); - } - teensy_close(); - return 0; + unsigned char buf[260]; + int num, addr, r, first_block=1, waited=0; + + // parse command line arguments + parse_options(argc, argv); + if (!filename) { + fprintf(stderr, "Filename must be specified\n\n"); + usage(); + } + if (!code_size) { + fprintf(stderr, "MCU type must be specified\n\n"); + usage(); + } + printf_verbose("Teensy Loader, Command Line, Version 2.0\n"); + + // read the intel hex file + // this is done first so any error is reported before using USB + num = read_intel_hex(filename); + if (num < 0) die("error reading intel hex file \"%s\"", filename); + printf_verbose("Read \"%s\": %d bytes, %.1f%% usage\n", + filename, num, (double)num / (double)code_size * 100.0); + + // open the USB device + while (1) { + if (teensy_open()) break; + if (hard_reboot_device) { + if (!hard_reboot()) die("Unable to find rebootor\n"); + printf_verbose("Hard Reboot performed\n"); + hard_reboot_device = 0; // only hard reboot once + wait_for_device_to_appear = 1; + } + if (!wait_for_device_to_appear) die("Unable to open device\n"); + if (!waited) { + printf_verbose("Waiting for Teensy device...\n"); + printf_verbose(" (hint: press the reset button)\n"); + waited = 1; + } + delay(0.25); + } + printf_verbose("Found HalfKay Bootloader\n"); + + // if we waited for the device, read the hex file again + // perhaps it changed while we were waiting? + if (waited) { + num = read_intel_hex(filename); + if (num < 0) die("error reading intel hex file \"%s\"", filename); + printf_verbose("Read \"%s\": %d bytes, %.1f%% usage\n", + filename, num, (double)num / (double)code_size * 100.0); + } + + // program the data + printf_verbose("Programming"); + fflush(stdout); + for (addr = 0; addr < code_size; addr += block_size) { + if (addr > 0 && !ihex_bytes_within_range(addr, addr + block_size - 1)) { + // don't waste time on blocks that are unused, + // but always do the first one to erase the chip + continue; + } + printf_verbose("."); + if (code_size < 0x10000) { + buf[0] = addr & 255; + buf[1] = (addr >> 8) & 255; + } else { + buf[0] = (addr >> 8) & 255; + buf[1] = (addr >> 16) & 255; + } + ihex_get_data(addr, block_size, buf + 2); + r = teensy_write(buf, block_size + 2, first_block ? 3.0 : 0.25); + if (!r) die("error writing to Teensy\n"); + first_block = 0; + } + printf_verbose("\n"); + + // reboot to the user's new code + if (reboot_after_programming) { + printf_verbose("Booting\n"); + buf[0] = 0xFF; + buf[1] = 0xFF; + memset(buf + 2, 0, sizeof(buf) - 2); + teensy_write(buf, block_size + 2, 0.25); + } + teensy_close(); + return 0; } @@ -192,107 +192,178 @@ int main(int argc, char **argv) usb_dev_handle * open_usb_device(int vid, int pid) { - struct usb_bus *bus; - struct usb_device *dev; - usb_dev_handle *h; - #ifdef LIBUSB_HAS_GET_DRIVER_NP - char buf[128]; - #endif - int r; - - usb_init(); - usb_find_busses(); - usb_find_devices(); - //printf_verbose("\nSearching for USB device:\n"); - for (bus = usb_get_busses(); bus; bus = bus->next) { - for (dev = bus->devices; dev; dev = dev->next) { - //printf_verbose("bus \"%s\", device \"%s\" vid=%04X, pid=%04X\n", - // bus->dirname, dev->filename, - // dev->descriptor.idVendor, - // dev->descriptor.idProduct - //); - if (dev->descriptor.idVendor != vid) continue; - if (dev->descriptor.idProduct != pid) continue; - h = usb_open(dev); - if (!h) { - printf_verbose("Found device but unable to open"); - continue; - } - #ifdef LIBUSB_HAS_GET_DRIVER_NP - r = usb_get_driver_np(h, 0, buf, sizeof(buf)); - if (r >= 0) { - r = usb_detach_kernel_driver_np(h, 0); - if (r < 0) { - usb_close(h); - printf_verbose("Device is in use by \"%s\" driver", buf); - continue; - } - } - #endif - // Mac OS-X - removing this call to usb_claim_interface() might allow - // this to work, even though it is a clear misuse of the libusb API. - // normally Apple's IOKit should be used on Mac OS-X - r = usb_claim_interface(h, 0); - if (r < 0) { - usb_close(h); - printf_verbose("Unable to claim interface, check USB permissions"); - continue; - } - return h; - } - } - return NULL; + struct usb_bus *bus; + struct usb_device *dev; + usb_dev_handle *h; + #ifdef LIBUSB_HAS_GET_DRIVER_NP + char buf[128]; + #endif + int r; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + //printf_verbose("\nSearching for USB device:\n"); + for (bus = usb_get_busses(); bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + //printf_verbose("bus \"%s\", device \"%s\" vid=%04X, pid=%04X\n", + // bus->dirname, dev->filename, + // dev->descriptor.idVendor, + // dev->descriptor.idProduct + //); + if (dev->descriptor.idVendor != vid) continue; + if (dev->descriptor.idProduct != pid) continue; + h = usb_open(dev); + if (!h) { + printf_verbose("Found device but unable to open"); + continue; + } + #ifdef LIBUSB_HAS_GET_DRIVER_NP + r = usb_get_driver_np(h, 0, buf, sizeof(buf)); + if (r >= 0) { + r = usb_detach_kernel_driver_np(h, 0); + if (r < 0) { + usb_close(h); + printf_verbose("Device is in use by \"%s\" driver", buf); + continue; + } + } + #endif + // Mac OS-X - removing this call to usb_claim_interface() might allow + // this to work, even though it is a clear misuse of the libusb API. + // normally Apple's IOKit should be used on Mac OS-X + r = usb_claim_interface(h, 0); + if (r < 0) { + usb_close(h); + printf_verbose("Unable to claim interface, check USB permissions"); + continue; + } + return h; + } + } + return NULL; } static usb_dev_handle *libusb_teensy_handle = NULL; int teensy_open(void) { - teensy_close(); - libusb_teensy_handle = open_usb_device(0x16C0, 0x0478); + teensy_close(); + libusb_teensy_handle = open_usb_device(0x16C0, 0x0478); - if (!libusb_teensy_handle) - libusb_teensy_handle = open_usb_device(0x03eb, 0x2067); + if (!libusb_teensy_handle) + libusb_teensy_handle = open_usb_device(0x03eb, 0x2067); - if (!libusb_teensy_handle) return 0; - return 1; + if (!libusb_teensy_handle) return 0; + return 1; } int teensy_write(void *buf, int len, double timeout) { - int r; + int r; - if (!libusb_teensy_handle) return 0; - r = usb_control_msg(libusb_teensy_handle, 0x21, 9, 0x0200, 0, (char *)buf, - len, (int)(timeout * 1000.0)); - if (r < 0) return 0; - return 1; + if (!libusb_teensy_handle) return 0; + r = usb_control_msg(libusb_teensy_handle, 0x21, 9, 0x0200, 0, (char *)buf, + len, (int)(timeout * 1000.0)); + if (r < 0) return 0; + return 1; } void teensy_close(void) { - if (!libusb_teensy_handle) return; - usb_release_interface(libusb_teensy_handle, 0); - usb_close(libusb_teensy_handle); - libusb_teensy_handle = NULL; + if (!libusb_teensy_handle) return; + usb_release_interface(libusb_teensy_handle, 0); + usb_close(libusb_teensy_handle); + libusb_teensy_handle = NULL; } int hard_reboot(void) { - usb_dev_handle *rebootor; - int r; + usb_dev_handle *rebootor; + int r; - rebootor = open_usb_device(0x16C0, 0x0477); + rebootor = open_usb_device(0x16C0, 0x0477); - if (!rebootor) - rebootor = open_usb_device(0x03eb, 0x2067); + if (!rebootor) + rebootor = open_usb_device(0x03eb, 0x2067); - if (!rebootor) return 0; - r = usb_control_msg(rebootor, 0x21, 9, 0x0200, 0, "reboot", 6, 100); - usb_release_interface(rebootor, 0); - usb_close(rebootor); - if (r < 0) return 0; - return 1; + if (!rebootor) return 0; + r = usb_control_msg(rebootor, 0x21, 9, 0x0200, 0, "reboot", 6, 100); + usb_release_interface(rebootor, 0); + usb_close(rebootor); + if (r < 0) return 0; + return 1; +} + +#endif + + +#if defined(USE_HIDAPI) + +// http://www.signal11.us/oss/hidapi/ +#include + +static hid_device* hidapi_device = NULL; + +int teensy_open(void) +{ + hid_init(); + hidapi_device = hid_open(0x16C0, 0x0478, NULL); + + if(!hidapi_device){ + hidapi_device = hid_open(0x03eb, 0x2067, NULL); + } + + if (!hidapi_device) return 0; + return 1; +} + +int teensy_write(void *buf, int len, double timeout) +{ + if (!hidapi_device) return 0; + + // Add report ID (0) + uint8_t newbuf[len + 1]; + newbuf[0] = 0x00; + memcpy(newbuf + 1, buf, len); + + int r = hid_write(hidapi_device, newbuf, len + 1); + //int r = hid_send_feature_report(hidapi_device, newbuf, len + 1); + + if (r < 0) return 0; + return 1; +} + +int teensy_read(void *buf, int len) +{ + if (!hidapi_device) return 0; + + // Add report ID (0) + uint8_t newbuf[len + 1]; + newbuf[0] = 0x00; + + int r = hid_get_feature_report(hidapi_device, newbuf, len + 1); + memcpy(buf, newbuf + 1, len); + + if (r < 0) return 0; + return 1; +} + +void teensy_close(void) +{ + if (!hidapi_device) return; + hid_close (hidapi_device); + hidapi_device = NULL; + hid_exit(); +} + +int hard_reboot(void) +{ + if (!teensy_open()) return 0; + int r = teensy_write("reboot", 6, 1); + teensy_close(); + if (r < 0) return 0; + return 1; } #endif @@ -314,130 +385,130 @@ int hard_reboot(void) HANDLE open_usb_device(int vid, int pid) { - GUID guid; - HDEVINFO info; - DWORD index, required_size; - SP_DEVICE_INTERFACE_DATA iface; - SP_DEVICE_INTERFACE_DETAIL_DATA *details; - HIDD_ATTRIBUTES attrib; - HANDLE h; - BOOL ret; - - HidD_GetHidGuid(&guid); - info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - if (info == INVALID_HANDLE_VALUE) return NULL; - for (index=0; 1 ;index++) { - iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface); - if (!ret) { - SetupDiDestroyDeviceInfoList(info); - break; - } - SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &required_size, NULL); - details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(required_size); - if (details == NULL) continue; - memset(details, 0, required_size); - details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details, - required_size, NULL, NULL); - if (!ret) { - free(details); - continue; - } - h = CreateFile(details->DevicePath, GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, NULL); - free(details); - if (h == INVALID_HANDLE_VALUE) continue; - attrib.Size = sizeof(HIDD_ATTRIBUTES); - ret = HidD_GetAttributes(h, &attrib); - if (!ret) { - CloseHandle(h); - continue; - } - if (attrib.VendorID != vid || attrib.ProductID != pid) { - CloseHandle(h); - continue; - } - SetupDiDestroyDeviceInfoList(info); - return h; - } - return NULL; + GUID guid; + HDEVINFO info; + DWORD index, required_size; + SP_DEVICE_INTERFACE_DATA iface; + SP_DEVICE_INTERFACE_DETAIL_DATA *details; + HIDD_ATTRIBUTES attrib; + HANDLE h; + BOOL ret; + + HidD_GetHidGuid(&guid); + info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (info == INVALID_HANDLE_VALUE) return NULL; + for (index=0; 1 ;index++) { + iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface); + if (!ret) { + SetupDiDestroyDeviceInfoList(info); + break; + } + SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &required_size, NULL); + details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(required_size); + if (details == NULL) continue; + memset(details, 0, required_size); + details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details, + required_size, NULL, NULL); + if (!ret) { + free(details); + continue; + } + h = CreateFile(details->DevicePath, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); + free(details); + if (h == INVALID_HANDLE_VALUE) continue; + attrib.Size = sizeof(HIDD_ATTRIBUTES); + ret = HidD_GetAttributes(h, &attrib); + if (!ret) { + CloseHandle(h); + continue; + } + if (attrib.VendorID != vid || attrib.ProductID != pid) { + CloseHandle(h); + continue; + } + SetupDiDestroyDeviceInfoList(info); + return h; + } + return NULL; } int write_usb_device(HANDLE h, void *buf, int len, int timeout) { - static HANDLE event = NULL; - unsigned char tmpbuf[1040]; - OVERLAPPED ov; - DWORD n, r; - - if (len > sizeof(tmpbuf) - 1) return 0; - if (event == NULL) { - event = CreateEvent(NULL, TRUE, TRUE, NULL); - if (!event) return 0; - } - ResetEvent(&event); - memset(&ov, 0, sizeof(ov)); - ov.hEvent = event; - tmpbuf[0] = 0; - memcpy(tmpbuf + 1, buf, len); - if (!WriteFile(h, tmpbuf, len + 1, NULL, &ov)) { - if (GetLastError() != ERROR_IO_PENDING) return 0; - r = WaitForSingleObject(event, timeout); - if (r == WAIT_TIMEOUT) { - CancelIo(h); - return 0; - } - if (r != WAIT_OBJECT_0) return 0; - } - if (!GetOverlappedResult(h, &ov, &n, FALSE)) return 0; - return 1; + static HANDLE event = NULL; + unsigned char tmpbuf[1040]; + OVERLAPPED ov; + DWORD n, r; + + if (len > sizeof(tmpbuf) - 1) return 0; + if (event == NULL) { + event = CreateEvent(NULL, TRUE, TRUE, NULL); + if (!event) return 0; + } + ResetEvent(&event); + memset(&ov, 0, sizeof(ov)); + ov.hEvent = event; + tmpbuf[0] = 0; + memcpy(tmpbuf + 1, buf, len); + if (!WriteFile(h, tmpbuf, len + 1, NULL, &ov)) { + if (GetLastError() != ERROR_IO_PENDING) return 0; + r = WaitForSingleObject(event, timeout); + if (r == WAIT_TIMEOUT) { + CancelIo(h); + return 0; + } + if (r != WAIT_OBJECT_0) return 0; + } + if (!GetOverlappedResult(h, &ov, &n, FALSE)) return 0; + return 1; } static HANDLE win32_teensy_handle = NULL; int teensy_open(void) { - teensy_close(); - win32_teensy_handle = open_usb_device(0x16C0, 0x0478); + teensy_close(); + win32_teensy_handle = open_usb_device(0x16C0, 0x0478); - if (!win32_teensy_handle) - win32_teensy_handle = open_usb_device(0x03eb, 0x2067); + if (!win32_teensy_handle) + win32_teensy_handle = open_usb_device(0x03eb, 0x2067); - if (!win32_teensy_handle) return 0; - return 1; + if (!win32_teensy_handle) return 0; + return 1; } int teensy_write(void *buf, int len, double timeout) { - int r; - if (!win32_teensy_handle) return 0; - r = write_usb_device(win32_teensy_handle, buf, len, (int)(timeout * 1000.0)); - return r; + int r; + if (!win32_teensy_handle) return 0; + r = write_usb_device(win32_teensy_handle, buf, len, (int)(timeout * 1000.0)); + return r; } void teensy_close(void) { - if (!win32_teensy_handle) return; - CloseHandle(win32_teensy_handle); - win32_teensy_handle = NULL; + if (!win32_teensy_handle) return; + CloseHandle(win32_teensy_handle); + win32_teensy_handle = NULL; } int hard_reboot(void) { - HANDLE rebootor; - int r; + HANDLE rebootor; + int r; - rebootor = open_usb_device(0x16C0, 0x0477); + rebootor = open_usb_device(0x16C0, 0x0477); - if (!rebootor) - rebootor = open_usb_device(0x03eb, 0x2067); + if (!rebootor) + rebootor = open_usb_device(0x03eb, 0x2067); - if (!rebootor) return 0; - r = write_usb_device(rebootor, "reboot", 6, 100); - CloseHandle(rebootor); - return r; + if (!rebootor) return 0; + r = write_usb_device(rebootor, "reboot", 6, 100); + CloseHandle(rebootor); + return r; } #endif @@ -458,10 +529,10 @@ int hard_reboot(void) #include struct usb_list_struct { - IOHIDDeviceRef ref; - int pid; - int vid; - struct usb_list_struct *next; + IOHIDDeviceRef ref; + int pid; + int vid; + struct usb_list_struct *next; }; static struct usb_list_struct *usb_list=NULL; @@ -469,169 +540,169 @@ static IOHIDManagerRef hid_manager=NULL; void attach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDeviceRef dev) { - CFTypeRef type; - struct usb_list_struct *n, *p; - int32_t pid, vid; - - if (!dev) return; - type = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVendorIDKey)); - if (!type || CFGetTypeID(type) != CFNumberGetTypeID()) return; - if (!CFNumberGetValue((CFNumberRef)type, kCFNumberSInt32Type, &vid)) return; - type = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductIDKey)); - if (!type || CFGetTypeID(type) != CFNumberGetTypeID()) return; - if (!CFNumberGetValue((CFNumberRef)type, kCFNumberSInt32Type, &pid)) return; - n = (struct usb_list_struct *)malloc(sizeof(struct usb_list_struct)); - if (!n) return; - //printf("attach callback: vid=%04X, pid=%04X\n", vid, pid); - n->ref = dev; - n->vid = vid; - n->pid = pid; - n->next = NULL; - if (usb_list == NULL) { - usb_list = n; - } else { - for (p = usb_list; p->next; p = p->next) ; - p->next = n; - } + CFTypeRef type; + struct usb_list_struct *n, *p; + int32_t pid, vid; + + if (!dev) return; + type = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVendorIDKey)); + if (!type || CFGetTypeID(type) != CFNumberGetTypeID()) return; + if (!CFNumberGetValue((CFNumberRef)type, kCFNumberSInt32Type, &vid)) return; + type = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductIDKey)); + if (!type || CFGetTypeID(type) != CFNumberGetTypeID()) return; + if (!CFNumberGetValue((CFNumberRef)type, kCFNumberSInt32Type, &pid)) return; + n = (struct usb_list_struct *)malloc(sizeof(struct usb_list_struct)); + if (!n) return; + //printf("attach callback: vid=%04X, pid=%04X\n", vid, pid); + n->ref = dev; + n->vid = vid; + n->pid = pid; + n->next = NULL; + if (usb_list == NULL) { + usb_list = n; + } else { + for (p = usb_list; p->next; p = p->next) ; + p->next = n; + } } void detach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDeviceRef dev) { - struct usb_list_struct *p, *tmp, *prev=NULL; - - p = usb_list; - while (p) { - if (p->ref == dev) { - if (prev) { - prev->next = p->next; - } else { - usb_list = p->next; - } - tmp = p; - p = p->next; - free(tmp); - } else { - prev = p; - p = p->next; - } - } + struct usb_list_struct *p, *tmp, *prev=NULL; + + p = usb_list; + while (p) { + if (p->ref == dev) { + if (prev) { + prev->next = p->next; + } else { + usb_list = p->next; + } + tmp = p; + p = p->next; + free(tmp); + } else { + prev = p; + p = p->next; + } + } } void init_hid_manager(void) { - CFMutableDictionaryRef dict; - IOReturn ret; - - if (hid_manager) return; - hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { - if (hid_manager) CFRelease(hid_manager); - printf_verbose("no HID Manager - maybe this is a pre-Leopard (10.5) system?\n"); - return; - } - dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (!dict) return; - IOHIDManagerSetDeviceMatching(hid_manager, dict); - CFRelease(dict); - IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL); - IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL); - ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); - if (ret != kIOReturnSuccess) { - IOHIDManagerUnscheduleFromRunLoop(hid_manager, - CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - CFRelease(hid_manager); - printf_verbose("Error opening HID Manager"); - } + CFMutableDictionaryRef dict; + IOReturn ret; + + if (hid_manager) return; + hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); + if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { + if (hid_manager) CFRelease(hid_manager); + printf_verbose("no HID Manager - maybe this is a pre-Leopard (10.5) system?\n"); + return; + } + dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (!dict) return; + IOHIDManagerSetDeviceMatching(hid_manager, dict); + CFRelease(dict); + IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL); + IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL); + ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); + if (ret != kIOReturnSuccess) { + IOHIDManagerUnscheduleFromRunLoop(hid_manager, + CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); + CFRelease(hid_manager); + printf_verbose("Error opening HID Manager"); + } } static void do_run_loop(void) { - while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ; + while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ; } IOHIDDeviceRef open_usb_device(int vid, int pid) { - struct usb_list_struct *p; - IOReturn ret; - - init_hid_manager(); - do_run_loop(); - for (p = usb_list; p; p = p->next) { - if (p->vid == vid && p->pid == pid) { - ret = IOHIDDeviceOpen(p->ref, kIOHIDOptionsTypeNone); - if (ret == kIOReturnSuccess) return p->ref; - } - } - return NULL; + struct usb_list_struct *p; + IOReturn ret; + + init_hid_manager(); + do_run_loop(); + for (p = usb_list; p; p = p->next) { + if (p->vid == vid && p->pid == pid) { + ret = IOHIDDeviceOpen(p->ref, kIOHIDOptionsTypeNone); + if (ret == kIOReturnSuccess) return p->ref; + } + } + return NULL; } void close_usb_device(IOHIDDeviceRef dev) { - struct usb_list_struct *p; + struct usb_list_struct *p; - do_run_loop(); - for (p = usb_list; p; p = p->next) { - if (p->ref == dev) { - IOHIDDeviceClose(dev, kIOHIDOptionsTypeNone); - return; - } - } + do_run_loop(); + for (p = usb_list; p; p = p->next) { + if (p->ref == dev) { + IOHIDDeviceClose(dev, kIOHIDOptionsTypeNone); + return; + } + } } static IOHIDDeviceRef iokit_teensy_reference = NULL; int teensy_open(void) { - teensy_close(); - iokit_teensy_reference = open_usb_device(0x16C0, 0x0478); + teensy_close(); + iokit_teensy_reference = open_usb_device(0x16C0, 0x0478); - if (!iokit_teensy_reference) - iokit_teensy_reference = open_usb_device(0x03eb, 0x2067); + if (!iokit_teensy_reference) + iokit_teensy_reference = open_usb_device(0x03eb, 0x2067); - if (!iokit_teensy_reference) return 0; - return 1; + if (!iokit_teensy_reference) return 0; + return 1; } int teensy_write(void *buf, int len, double timeout) { - IOReturn ret; - - // timeouts do not work on OS-X - // IOHIDDeviceSetReportWithCallback is not implemented - // even though Apple documents it with a code example! - // submitted to Apple on 22-sep-2009, problem ID 7245050 - if (!iokit_teensy_reference) return 0; - ret = IOHIDDeviceSetReport(iokit_teensy_reference, - kIOHIDReportTypeOutput, 0, buf, len); - if (ret == kIOReturnSuccess) return 1; - return 0; + IOReturn ret; + + // timeouts do not work on OS-X + // IOHIDDeviceSetReportWithCallback is not implemented + // even though Apple documents it with a code example! + // submitted to Apple on 22-sep-2009, problem ID 7245050 + if (!iokit_teensy_reference) return 0; + ret = IOHIDDeviceSetReport(iokit_teensy_reference, + kIOHIDReportTypeOutput, 0, buf, len); + if (ret == kIOReturnSuccess) return 1; + return 0; } void teensy_close(void) { - if (!iokit_teensy_reference) return; - close_usb_device(iokit_teensy_reference); - iokit_teensy_reference = NULL; + if (!iokit_teensy_reference) return; + close_usb_device(iokit_teensy_reference); + iokit_teensy_reference = NULL; } int hard_reboot(void) { - IOHIDDeviceRef rebootor; - IOReturn ret; + IOHIDDeviceRef rebootor; + IOReturn ret; - rebootor = open_usb_device(0x16C0, 0x0477); + rebootor = open_usb_device(0x16C0, 0x0477); - if (!rebootor) - rebootor = open_usb_device(0x03eb, 0x2067); + if (!rebootor) + rebootor = open_usb_device(0x03eb, 0x2067); - if (!rebootor) return 0; - ret = IOHIDDeviceSetReport(rebootor, - kIOHIDReportTypeOutput, 0, (uint8_t *)("reboot"), 6); - close_usb_device(rebootor); - if (ret == kIOReturnSuccess) return 1; - return 0; + if (!rebootor) return 0; + ret = IOHIDDeviceSetReport(rebootor, + kIOHIDReportTypeOutput, 0, (uint8_t *)("reboot"), 6); + close_usb_device(rebootor); + if (ret == kIOReturnSuccess) return 1; + return 0; } #endif @@ -664,88 +735,88 @@ int hard_reboot(void) int open_usb_device(int vid, int pid) { - int r, fd; - DIR *dir; - struct dirent *d; - struct usb_device_info info; - char buf[256]; - - dir = opendir("/dev"); - if (!dir) return -1; - while ((d = readdir(dir)) != NULL) { - if (strncmp(d->d_name, "uhid", 4) != 0) continue; - snprintf(buf, sizeof(buf), "/dev/%s", d->d_name); - fd = open(buf, O_RDWR); - if (fd < 0) continue; - r = ioctl(fd, USB_GET_DEVICEINFO, &info); - if (r < 0) { - // NetBSD: added in 2004 - // OpenBSD: added November 23, 2009 - // FreeBSD: missing (FreeBSD 8.0) - USE_LIBUSB works! - die("Error: your uhid driver does not support" - " USB_GET_DEVICEINFO, please upgrade!\n"); - close(fd); - closedir(dir); - exit(1); - } - //printf("%s: v=%d, p=%d\n", buf, info.udi_vendorNo, info.udi_productNo); - if (info.udi_vendorNo == vid && info.udi_productNo == pid) { - closedir(dir); - return fd; - } - close(fd); - } - closedir(dir); - return -1; + int r, fd; + DIR *dir; + struct dirent *d; + struct usb_device_info info; + char buf[256]; + + dir = opendir("/dev"); + if (!dir) return -1; + while ((d = readdir(dir)) != NULL) { + if (strncmp(d->d_name, "uhid", 4) != 0) continue; + snprintf(buf, sizeof(buf), "/dev/%s", d->d_name); + fd = open(buf, O_RDWR); + if (fd < 0) continue; + r = ioctl(fd, USB_GET_DEVICEINFO, &info); + if (r < 0) { + // NetBSD: added in 2004 + // OpenBSD: added November 23, 2009 + // FreeBSD: missing (FreeBSD 8.0) - USE_LIBUSB works! + die("Error: your uhid driver does not support" + " USB_GET_DEVICEINFO, please upgrade!\n"); + close(fd); + closedir(dir); + exit(1); + } + //printf("%s: v=%d, p=%d\n", buf, info.udi_vendorNo, info.udi_productNo); + if (info.udi_vendorNo == vid && info.udi_productNo == pid) { + closedir(dir); + return fd; + } + close(fd); + } + closedir(dir); + return -1; } static int uhid_teensy_fd = -1; int teensy_open(void) { - teensy_close(); - uhid_teensy_fd = open_usb_device(0x16C0, 0x0478); + teensy_close(); + uhid_teensy_fd = open_usb_device(0x16C0, 0x0478); - if (uhid_teensy_fd < 0) - uhid_teensy_fd = open_usb_device(0x03eb, 0x2067); + if (uhid_teensy_fd < 0) + uhid_teensy_fd = open_usb_device(0x03eb, 0x2067); - if (uhid_teensy_fd < 0) return 0; - return 1; + if (uhid_teensy_fd < 0) return 0; + return 1; } int teensy_write(void *buf, int len, double timeout) { - int r; + int r; - // TODO: implement timeout... how?? - r = write(uhid_teensy_fd, buf, len); - if (r == len) return 1; - return 0; + // TODO: implement timeout... how?? + r = write(uhid_teensy_fd, buf, len); + if (r == len) return 1; + return 0; } void teensy_close(void) { - if (uhid_teensy_fd >= 0) { - close(uhid_teensy_fd); - uhid_teensy_fd = -1; - } + if (uhid_teensy_fd >= 0) { + close(uhid_teensy_fd); + uhid_teensy_fd = -1; + } } int hard_reboot(void) { - int r, rebootor_fd; + int r, rebootor_fd; - rebootor_fd = open_usb_device(0x16C0, 0x0477); + rebootor_fd = open_usb_device(0x16C0, 0x0477); - if (rebootor_fd < 0) - rebootor_fd = open_usb_device(0x03eb, 0x2067); + if (rebootor_fd < 0) + rebootor_fd = open_usb_device(0x03eb, 0x2067); - if (rebootor_fd < 0) return 0; - r = write(rebootor_fd, "reboot", 6); - delay(0.1); - close(rebootor_fd); - if (r == 6) return 1; - return 0; + if (rebootor_fd < 0) return 0; + r = write(rebootor_fd, "reboot", 6); + delay(0.1); + close(rebootor_fd); + if (r == 6) return 1; + return 0; } #endif @@ -772,39 +843,39 @@ static int parse_hex_line(char *line); int read_intel_hex(const char *filename) { - FILE *fp; - int i, lineno=0; - char buf[1024]; - - byte_count = 0; - end_record_seen = 0; - for (i=0; i= MAX_MEMORY_SIZE) return 0; + if (addr + extended_addr + len >= MAX_MEMORY_SIZE) return 0; ptr += 2; sum = (len & 255) + ((addr >> 8) & 255) + (addr & 255) + (code & 255); - if (code != 0) { - if (code == 1) { - end_record_seen = 1; - return 1; - } - if (code == 2 && len == 2) { - if (!sscanf(ptr, "%04x", &i)) return 1; - ptr += 4; - sum += ((i >> 8) & 255) + (i & 255); - if (!sscanf(ptr, "%02x", &cksum)) return 1; - if (((sum & 255) + (cksum & 255)) & 255) return 1; - extended_addr = i << 4; - //printf("ext addr = %05X\n", extended_addr); - } - if (code == 4 && len == 2) { - if (!sscanf(ptr, "%04x", &i)) return 1; - ptr += 4; - sum += ((i >> 8) & 255) + (i & 255); - if (!sscanf(ptr, "%02x", &cksum)) return 1; - if (((sum & 255) + (cksum & 255)) & 255) return 1; - extended_addr = i << 16; - //printf("ext addr = %08X\n", extended_addr); - } - return 1; // non-data line - } - byte_count += len; + if (code != 0) { + if (code == 1) { + end_record_seen = 1; + return 1; + } + if (code == 2 && len == 2) { + if (!sscanf(ptr, "%04x", &i)) return 1; + ptr += 4; + sum += ((i >> 8) & 255) + (i & 255); + if (!sscanf(ptr, "%02x", &cksum)) return 1; + if (((sum & 255) + (cksum & 255)) & 255) return 1; + extended_addr = i << 4; + //printf("ext addr = %05X\n", extended_addr); + } + if (code == 4 && len == 2) { + if (!sscanf(ptr, "%04x", &i)) return 1; + ptr += 4; + sum += ((i >> 8) & 255) + (i & 255); + if (!sscanf(ptr, "%02x", &cksum)) return 1; + if (((sum & 255) + (cksum & 255)) & 255) return 1; + extended_addr = i << 16; + //printf("ext addr = %08X\n", extended_addr); + } + return 1; // non-data line + } + byte_count += len; while (num != len) { if (sscanf(ptr, "%02x", &i) != 1) return 0; - i &= 255; - firmware_image[addr + extended_addr + num] = i; - firmware_mask[addr + extended_addr + num] = 1; + i &= 255; + firmware_image[addr + extended_addr + num] = i; + firmware_mask[addr + extended_addr + num] = 1; ptr += 2; sum += i; (num)++; @@ -880,36 +951,36 @@ parse_hex_line(char *line) int ihex_bytes_within_range(int begin, int end) { - int i; - - if (begin < 0 || begin >= MAX_MEMORY_SIZE || - end < 0 || end >= MAX_MEMORY_SIZE) { - return 0; - } - for (i=begin; i<=end; i++) { - if (firmware_mask[i]) return 1; - } - return 0; + int i; + + if (begin < 0 || begin >= MAX_MEMORY_SIZE || + end < 0 || end >= MAX_MEMORY_SIZE) { + return 0; + } + for (i=begin; i<=end; i++) { + if (firmware_mask[i]) return 1; + } + return 0; } void ihex_get_data(int addr, int len, unsigned char *bytes) { - int i; + int i; - if (addr < 0 || len < 0 || addr + len >= MAX_MEMORY_SIZE) { - for (i=0; i= MAX_MEMORY_SIZE) { + for (i=0; i