tags:

views:

177

answers:

3

I'm having an issue with a USB project using LIB-USB. The USB device is based on a PIC18F4550 and has a single control endpoint. The PC front-end is written in MSVC and uses Lib-Usb 1.12.

On the PC end, the program begins by setting the configuration, claiming the interface, then sending (and receiving) control messages (vendor specific), all successfully. After what seems like a random # of bytes have been transferred (anywhere between 100 and 2000) the transfer halts with an error rc=-5 returned from the usb_control_msg call.

On the PC-end, the calls look like this:
ret=usb_set_configuration(udev, 1);
ret=usb_claim_interface(udev, 0);
ret = usb_control_msg(udev, USB_TYPE_VENDOR|USB_RECIP_DEVICE, CMD_RESET, 0, 0, buffer, 0, 100);
ret = usb_control_msg(udev, 0xC0, GET_FIFO_DATA, 0, 0, buffer, 8, 100);

The last call, which actually acquires data from the USB device, runs many times in sucession but always dies after a random number of bytes (100 to 2000 in total) are transferred in this way. Changing the pipe to EP1 does the same thing with the same error eventually appearing.

On the USB device (PIC) end the descriptor is very simple, having only the EP0 pipe, and looks like this: Device db 0x12, DEVICE ; bLength, bDescriptorType
db 0x10, 0x01 ; bcdUSB (low byte), bcdUSB (high byte)
db 0x00, 0x00 ; bDeviceClass, bDeviceSubClass
db 0x00, MAX_PACKET_SIZE ; bDeviceProtocol, bMaxPacketSize
db 0xD8, 0x04 ; idVendor (low byte), idVendor (high byte)
db 0x01, 0x00 ; idProduct (low byte), idProduct (high byte)
db 0x00, 0x00 ; bcdDevice (low byte), bcdDevice (high byte)
db 0x01, 0x02 ; iManufacturer, iProduct
db 0x00, NUM_CONFIGURATIONS ; iSerialNumber (none), bNumConfigurations
Configuration1
db 0x09, CONFIGURATION ; bLength, bDescriptorType
db 0x12, 0x00 ; wTotalLength (low byte), wTotalLength (high byte)
db NUM_INTERFACES, 0x01 ; bNumInterfaces, bConfigurationValue
db 0x00, 0xA0 ; iConfiguration (none), bmAttributes
db 0x32, 0x09 ; bMaxPower (100 mA), bLength (Interface1 descriptor starts here)
db INTERFACE, 0x00 ; bDescriptorType, bInterfaceNumber
db 0x00, 0x00 ; bAlternateSetting, bNumEndpoints (excluding EP0)
db 0xFF, 0x00 ; bInterfaceClass (vendor specific class code), bInterfaceSubClass
db 0xFF, 0x00 ; bInterfaceProtocol (vendor specific protocol used), iInterface (none)

The actual framework is that of Bradley Minch's in assembly language.

If anyone has encountered this type of problem before I'd love to hear about it as I've tried just about everything to solve it including using a different pipe (EP1, with the same results), checking the UOWN bit on the PIC before writing to the pipe, handshaking with the PC host (where the PC must send a vendor-specific command first before the datsa is written) but to no avail.

Thanks! Mark

A: 

It's very advisable to have USB bus analyzer Lecroy and Ellisys are high end and a little bit expensive. Total Phase is an example of low end one.
Using bus analyzers will help you great deal writing both your firmware and pc side software if you can afford one. Using the analyzer you can determine if the problem in your pc side (data you read is on the bus, but you can't see it in you software) or problem in your firmware implementation (you don't see data on the bus).

From your description is hard to understand what is the problem and i don't know what is error -5 mean, if you can post the define name for this i might be more helpful.
In general it's a good practice to transfer data from/to device in multiplies of max packet size. I also suggest you to read carefully relevant sections 5.5.3 (for control transfers) and 5.8.3 for bulk transfers in USB Spec

Additional comment based on the second log provided:

The real error returned by the usb stack is in your log and its:
vendor_class_request(): request failed: status: 0xc0000001, urb-status: 0xc000000c

URB (usb request block) status defined in Windows Driver kit usb.h as :
usb.h:#define USBD_STATUS_BUFFER_OVERRUN ((USBD_STATUS)0xC000000CL)

I found a good explanation about this error here.
Please ignore the fact that this is WinDriver defined error it's just redefined error from Windows and the explanation about what it's usually mean is correct.

Here is an example why it's can happened, but there is more potential reasons for this behavior.

Ilya
A: 

I do not have an analyzer ("yet", at least) but I did install DebugView to see what the driver is doing, with the following output trace. The first transfer shown (a vendor-specific one) is successful while the second one dies. A return code of "-5" which means "I/O error" (not particularly useful) is returned from the call.

00002674 315.26220703 LIBUSB-DRIVER - vendor_class_request(): type: vendor 00002675 315.26223755 LIBUSB-DRIVER - vendor_class_request(): recipient: device 00002676 315.26223755 LIBUSB-DRIVER - vendor_class_request(): request: 0x04 00002677 315.26223755 LIBUSB-DRIVER - vendor_class_request(): value: 0x0000 00002678 315.26223755 LIBUSB-DRIVER - vendor_class_request(): index: 0x0000 00002679 315.26223755 LIBUSB-DRIVER - vendor_class_request(): size: 8 00002680 315.26226807 LIBUSB-DRIVER - vendor_class_request(): direction: in 00002681 315.26226807 LIBUSB-DRIVER - vendor_class_request(): timeout: 100 00002682 315.26617432 LIBUSB-DRIVER - vendor_class_request(): 8 bytes transmitted 00002683 315.26721191 00002684 315.26721191 00002685 315.26721191 LIBUSB-DRIVER - vendor_class_request(): type: vendor 00002686 315.26721191 LIBUSB-DRIVER - vendor_class_request(): recipient: device 00002687 315.26724243 LIBUSB-DRIVER - vendor_class_request(): request: 0x04 00002688 315.26724243 LIBUSB-DRIVER - vendor_class_request(): value: 0x0000 00002689 315.26724243 LIBUSB-DRIVER - vendor_class_request(): index: 0x0000 00002690 315.26724243 LIBUSB-DRIVER - vendor_class_request(): size: 8 00002691 315.26724243 LIBUSB-DRIVER - vendor_class_request(): direction: in 00002692 315.26727295 LIBUSB-DRIVER - vendor_class_request(): timeout: 100 00002693 315.27017212 LIBUSB-DRIVER - vendor_class_request(): request failed: status: 0xc0000001, urb-status: 0xc000000c 00002694 315.27407837 [3684] LIBUSB_DLL: error: usb_control_msg: sending control message failed, win error: A device attached to the system is not functioning. 00002695 315.27407837 [3684] 00002696 315.27511597 00002697 315.27514648 LIBUSB-DRIVER - release_interface(): interface 0

A: 

It Now Works!!

Of course, I now feel "smart like a bag of hammers" Had I read section 18 thoroughly I would have noticed the line about adding a 220nF capacitor between Vusb and ground. Added a 470nF cap between pin18 and ground and that was all it took .... reliable transfers now.

Just another case of "I forgot to read the fine print"

Cheers!