5
votes

I'm implementing USB on a PIC 18F2550 using a generic HID interface. I've set up the HID profile configuation to have a single 64 byte message for both inputs and outputs.

Now it's basically working. The device registers OK with windows. I can find it in my program on the PC and can send and receive data to it. The problem is this though - messages from the PC to the PIC are truncated to the size of the EP0 endpoint buffer.

Before I go debugging too much further I want to try to clarify my understanding of the USB protocols here and check I got it right.

Assume that the EP0 input buffer is 8 bytes. It's my understanding that the PC end will send a control packet which is 8 bytes. In there is the length in bytes of the data to follow. And then it will send a sequence of 8 byte data packets and the PIC end has to acknowledge each one.

It's my understanding that the PC end knows how big each packet may be by looking in the maximum packet size field in the device descriptor and will divide up the message accordingly into multiple data packets.

Before I go looking for more hours at the code, can anyone confirm that this is basically correct? That if the EP0 buffer size is 8 bytes then the PC should know this because of the configuration field I mentioned above and send multiple data packets?

If I make my receive buffer on the PIC 64 bytes then I get 64 bytes of the message which is sufficient for my needs, but I don't like not understanding why it doesn't work with small buffers, and one day I'll probably need them anyway.

Any advice or information would be welcome.

1

1 Answers

4
votes

There is something called Endpoint Descriptor, which, among other things, defines the wMaxPacketSize - which is what the Host Controller Interface drivers use to subdivide a large USB transfer into smaller packets.

This is entirely different from the EP0 buffer size - which however, is always required to be larger than the wMaxPacketSize. My guess is (try posting your usb_config.h and usb_descriptors.c, if you use Microchip USB stack), that you're either trying to use 8-byte long EP0 with 64-byte long wMaxPacketSize, which is truncating the transfer.

Also, be aware that in USB 1.1 Low Speed, the wMaxPacketSize cannot exceed 8, and in USB 1.1 Full Speed it cannot exceed 64.

0x07,/*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
HID_EP | _EP_IN,            //EndpointAddress
_INTERRUPT,                       //Attributes
DESC_CONFIG_WORD(9),        //size
0x01,                        //Interval

/* Endpoint Descriptor */
0x07,/*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
HID_EP | _EP_OUT,            //EndpointAddress
_INTERRUPT,                       //Attributes
DESC_CONFIG_WORD(9),        //size
0x01                        //Interval