USB - multiple Qs

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
KUn_4718781
Level 1
Level 1

Hi, I have multiple questions:

1) How do I set every field in a HID descriptor to a different size.  For example, let's say I want one field to be 1 bit, and a second field to be 7 bits?

2) The 64kB/s, is that per pipe, each way, total?  Lets say that I have 2 pipes, 2 sets of endpoints, just like AN 82072.  Does each endpoint go up to 64kB/s?  Could I have (is it 16 endpoints or 16 pipes?) each with 64kB/s? So in theory I could make 16(?) pipes, each moving 64kB/s???  How would I set up multiple IN or OUT pipes, from the PC side?

That leads me to my next question:

3) As I understand it, each IN endpoint, again looking back at AN82072, is polled from the PC at whatever timer interval you have set, up to 1000 times per second.  Ok, so then the maximum data rate for that endpoint is 64bytes per poll, and that is where we get the 64kB/s.  But the OUT endpoint, and I've been having trouble with one in my own code, do I need to put that on a timer? 

I guess this comes to the report descriptor, is the whole AN82072 pg. 16 fig. 20, passed back and forth every time, or are the two (IN and OUT) sent/received separately? 

PC -> OUT -> uC

PC -> prompt -> uC

     <-  IN        <-

or

PC -> IN/OUT -> uC

then

PC <- IN/OUT <- uC

I think I'm missing some piece of what's going on here.  I thought that the report was like a sheet of paper, a form, getting passed back and forth.  The values in the fields getting changed.  But is it two pieces of paper, one IN, one OUT, being passed independently?

4) That leads me to my more immediate question.  I'm having problems with a project, in which I pass a string from a keypad to the PC, and a string from the PC to the uC.  I'm having problems with the PC->uC.  The uC receives up to 5 bytes, so "hello".  But if I send to it "1234567890" it receives "1234500000".  I've tried a 1 byte OUT report, and that didn't work, so I went back to the AN82072 examples 8 bytes, just in case I made a mistake in my HID descriptor, but that doesn't seem to be the problem.  Again, in both cases I'm sending 1 byte at a time(only using the first field).  I've then used the second field in the OUT descriptor to add packet numbers, and the numbers do the same thing as the letters.  My first thought is that, because I am sending the bytes, on the PC side, one at a time in a foreach loop,  that it is outpacing the uC, and that I should be using a timer - mimicking the IN timer?  The once per millisecond applies to the IN and OUT pipes?  update: It seems to work when I slow down the rate I am sending to the uC, am I correct in understanding why?

Why would it receive the last byte multiple times?  Even if it is a rate thing, it should miss bytes entirely, yes?  Not get the same byte multiple times???

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
Aashita_R
Moderator
Moderator
Moderator
50 likes received 100 solutions authored 250 replies posted

Hi KUn_4718781​,

I have been through your queries and tried to find the solution. Here are the responses as follows-

1. Different fields in the HID descriptor have their size defined according to the USB- spec, which you can find here : https://www.usb.org/sites/default/files/documents/hid1_11.pdf . You need to set the fields in accordance with USB- HID spec as mentioned.

2. Pipes are a connection pathway from the host controller to an addressable buffer called an endpoint.  A USB device can have multiple endpoints and each endpoint has a pipe associated with it.

Since HID devices make use of interrupt endpoints due to the periodic checks for the status of transactions. Full-Speed capable devices support a maximum transfer size for an interrupt endpoint is 64 bytes. Interrupt transfers have a guaranteed bandwidth of 90 percent on Low- and Full-Speed devices, so the maximum transfer speed for an endpoint is 1.216 MB/s.

The USB specification sets a limit on the number of endpoints to 16 for each direction (16 IN/16 OUT – 32 Total) for High-Speed and Full-Speed devices, which does not include the control endpoints 0 IN and 0 OUT. You can set up multiple IN and OUT endpoints by adding endpoints to the device descriptor.   A bit is set in bEndpoint Address attribute in the Endpoint descriptor to tell if it is an OUT or IN endpoint. Please go through the section 'Endpoint Descriptor' in the App-note here : https://www.cypress.com/documentation/application-notes/an57294-usb-101-introduction-universal-seria...  .

3. Interrupt transfers are regularly scheduled IN and OUT transactions that occur at an interval. It can be defined in bInterval attribute, which is the Polling interval in milliseconds for interrupt endpoints in the the Endpoint Descriptor for a particular endpoint. I have attached images to show the IN and OUT Interrupt transactions respectively.

pastedImage_13.png

pastedImage_14.png

In short, your first inference of the flow of transaction is correct for IN and OUT transaction. The detailed image is given above. You can also go through this App-note : https://www.cypress.com/documentation/application-notes/an56377-psoc-3-and-psoc-5lp-introduction-imp...  to get a more clear understanding on this.

And, Input and Output reports are also passed independently. You can read about this in the HID spec in the link already mentioned.

Also, Can you please explain elaborate your issue with the OUT endpoint that you are facing?

4. We have a similar code example. I have attached it here. The USBFS component is configured as a Virtual COM port and basically sends received data backward to COM-port terminal. I will check through your procedure for your project and update here. Please go though the attached code example and let us know in case of further queries.

Best Regards,

Aashita

View solution in original post

0 Likes
3 Replies
lock attach
Attachments are accessible only for community members.
Aashita_R
Moderator
Moderator
Moderator
50 likes received 100 solutions authored 250 replies posted

Hi KUn_4718781​,

I have been through your queries and tried to find the solution. Here are the responses as follows-

1. Different fields in the HID descriptor have their size defined according to the USB- spec, which you can find here : https://www.usb.org/sites/default/files/documents/hid1_11.pdf . You need to set the fields in accordance with USB- HID spec as mentioned.

2. Pipes are a connection pathway from the host controller to an addressable buffer called an endpoint.  A USB device can have multiple endpoints and each endpoint has a pipe associated with it.

Since HID devices make use of interrupt endpoints due to the periodic checks for the status of transactions. Full-Speed capable devices support a maximum transfer size for an interrupt endpoint is 64 bytes. Interrupt transfers have a guaranteed bandwidth of 90 percent on Low- and Full-Speed devices, so the maximum transfer speed for an endpoint is 1.216 MB/s.

The USB specification sets a limit on the number of endpoints to 16 for each direction (16 IN/16 OUT – 32 Total) for High-Speed and Full-Speed devices, which does not include the control endpoints 0 IN and 0 OUT. You can set up multiple IN and OUT endpoints by adding endpoints to the device descriptor.   A bit is set in bEndpoint Address attribute in the Endpoint descriptor to tell if it is an OUT or IN endpoint. Please go through the section 'Endpoint Descriptor' in the App-note here : https://www.cypress.com/documentation/application-notes/an57294-usb-101-introduction-universal-seria...  .

3. Interrupt transfers are regularly scheduled IN and OUT transactions that occur at an interval. It can be defined in bInterval attribute, which is the Polling interval in milliseconds for interrupt endpoints in the the Endpoint Descriptor for a particular endpoint. I have attached images to show the IN and OUT Interrupt transactions respectively.

pastedImage_13.png

pastedImage_14.png

In short, your first inference of the flow of transaction is correct for IN and OUT transaction. The detailed image is given above. You can also go through this App-note : https://www.cypress.com/documentation/application-notes/an56377-psoc-3-and-psoc-5lp-introduction-imp...  to get a more clear understanding on this.

And, Input and Output reports are also passed independently. You can read about this in the HID spec in the link already mentioned.

Also, Can you please explain elaborate your issue with the OUT endpoint that you are facing?

4. We have a similar code example. I have attached it here. The USBFS component is configured as a Virtual COM port and basically sends received data backward to COM-port terminal. I will check through your procedure for your project and update here. Please go though the attached code example and let us know in case of further queries.

Best Regards,

Aashita

0 Likes

Hi, thanks for the response. 

With regards to my first question, I would like some instruction as to how to make my own generic HID descriptor with the aforementioned variability(1 bit, 7 bits, etc...).  I follow AN82072 for setting up coarser fields, like the 8 byte report in the example, sure.  But I don't know how to make a complex report myself, in the PSOC Creator component editor window.

For my second point, I think I understand your response, thank you.  Just to be clear: the USB standard specifies an upper limit of 16 pipes each way (IN and OUT), ok, the devices themselves (in this case a 4200L, but also for curiosities sake 3&5) also support the full 16/16? 

For my third point, I understand completely now, again thank you.

4'th point: Based on my prior misunderstanding, I had an error with my OUT code.  I read AN82072 PC side sample code, and didn't see the OUT data attached to a timer.  I then foolishly duplicated this for streaming chars.  I didn't realize that the reason that the author didn't bother with an OUT timer was because the timer was unnecessary in that particular circumstance - a human occasionally clicking a button. 

Now my code has the IN and OUT both attached to a timer, and it does work for more than 5 bytes.  My goal was to have a keypad send data to the PC, and a textbox on the PC send data to a microcontroller -> LCD.  Right now I have the PC sending a large, fixed string of text to the uC, which echoes it back.  One byte at a time.  It is interesting to observe the delay.  Unfortunately I still have problems with it occasionally messing up a character, and I don't know why.  Ex: 0123455789.  I don't know why it would receive the 5 twice. 

As I understand it, and correct me if I'm wrong here, is that USB interrupt will drop packets and they are just lost.  But, there is some error correction if a defective packet is received.  So why would it receive double characters?  Also, sometimes it just drops characters, but at least that I can chalk up to noise in the line or something.  I would appreciate some outside clarity here.  I'm thinking that I need to have a mechanism in my code that checks for missed packets, and ask for a resend.

0 Likes

I have a theory about the duplicate bytes.  I am wondering if the device is receiving a bad byte, and the bad byte is being discarded.  As I understand it, the device requests a resend from the host when this happens, yes(AN 56377 pg. 8)?  I am wondering if the device is still thinking it received a byte -> OUT_BUFFER_FULL, and reading the contents.  Except the contents are whatever was leftover from before.

Is this what's happening?

Is there a way of eliminating the problem short of wasting report space on packet numbers?

Maybe a register I can check for ACK or NACK or something? 

Some API function that checks for new packets only?

Ultimately, how do I fix this?

0 Likes