Xiaofan Chen wrote: > This may tend to be a firmware bug or your libusb program bug. > Which Microchip stack are your firmware based on? MCHPUSB Framework 2.5a. This seems to be the same version that's currently on MCHP's website. > One potential issue is wrong Data Toggle in the firmware. Surely the MCHP framework / SIE handles this? > usb_release_interface(devh, 0); > usb_reset_device(devh); (adding this one often helps). > usb_close(devh); > usb_exit(); Now that's quite different to what I'm doing -- I wasn't aware that you had to call all that before / after usb_close(). Also, doesn't the usb_reset_device() call cause the device to reset and re-enumerate? > You can also try to call usb_set_configuration() before > claiming the interface. I think you have it since libusb-win32 > requires it. You may also try to remove it to see if that helps > under Linux. Already done that -- it's specced that way in the libusb-win32 and libusb manuals :) > One example I tried before. > http://www.microchip.com/forums/tm.aspx?m=340892 ... Which seems to be doing what I'm doing (calling usb_close() on its own without releasing the interface). Here's the code I've been using (sans some constants and syntactic sugar): //////// struct usb_dev_handle *g_dev; int suite_init_usb(void) { struct usb_dev_handle *dh; usb_init(); usb_find_busses(); usb_find_devices(); // scan USB buses for (struct usb_bus *bus = usb_get_busses(); bus != NULL; bus = bus->next) { // scan all devices on a given bus for (struct usb_device *dev = bus->devices; dev != NULL; dev = dev->next) { // Search for our device by VID/PID if ((dev->descriptor.idVendor == DEV_VID) && (dev->descriptor.idProduct == DEV_PID)) { // VID/PID match. // Open the device dh = usb_open(dev); if (!dh) { // printf("error opening usb device\n"); return -1; } // Set the configuration and claim the interface if (usb_set_configuration(dh, DEV_CFG)) { // printf("error setting USB device configuration\n"); return -2; } if (usb_claim_interface(dh, DEV_IFC)) { // printf("claim failed, bailing out...\n"); return -3; } // Set the device handle and exit g_dev = dh; return 0; } } } // If we get here, then we didn't find a device... return -4; } int suite_cleanup_usb(void) { // Close the USB device if (usb_close(g_dev) < 0) { return -1; // failure } else { return 0; // success } } //////// int main(void) { int i, j; unsigned char buf[64]; if (i=suite_init_usb()) { printf("err: init usb = %d\n", i); return i; } i=0; buf[i++] = CMD_SELECT_DRIVE; buf[i++] = 0x11; // motor enable + DS0 printf("bulk_write: %d\n", usb_bulk_write(g_dev, DEV_EPO, (char *)&buf, i, USB_TIMEOUT)); sleep(3); printf("setup complete, initiating seek...\n"); j=0x8000 | 100; // 100 steps, seek towards track 0 i=0; buf[i++] = CMD_SEEK_SYNC; buf[i++] = (j >> 8); buf[i++] = (j & 0xff); printf("bulk_write: %d\n", usb_bulk_write(g_dev, DEV_EPO, (char *)&buf, i, USB_TIMEOUT)); printf("bulk_read: %d\n", (i=usb_bulk_read(g_dev, DEV_EPI, (char *)&buf, sizeof(buf), USB_TIMEOUT))); printf("dump: %02X\n", buf[0]); sleep(3); // deselect drive i=0; buf[i++] = CMD_SELECT_DRIVE; buf[i++] = 0x00; printf("bulk_write: %d\n", usb_bulk_write(g_dev, DEV_EPO, (char *)&buf, i, USB_TIMEOUT)); sleep(3); if (i=suite_cleanup_usb()) { printf("err: cleanup usb = %d\n", i); return i; } return 0; // ERROR_SUCCESS } /////// It's missing some #includes and #defines, but that should give you a pretty good idea what I've got. -- Phil. piclist@philpem.me.uk http://www.philpem.me.uk/ -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist