USB (FS) control transfer packet size constraints - Page 1
Forum section: electronics / projects

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 02:05:17 pm
content: USB 2.0 spec writes; (for control transfers) the data stage when device is sending data to host is complete when either the exact amount of data is sent (as much as wLength I assume) or when a packet with less than the max packet size (including empty/zero length) data is sent. What I dont get is, wLength in standard requests is a must, and if the data is a multiple of max packet size, then the above conditions result different number of packets (the latter requires an extra 0 length packet). Do they both work or what is said above is correct in general for control transfers but for standard requests always the wLength should be obeyed (in other words, there is no need for 0 length data to terminate the data stage or more strongly 0 length data should not be sent).

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 04:09:18 pm
content: You always need ZLP if your data size is a multiple of the bMaxPacketSize0. Yes, you will get an extra empty packet at the end of the transfer. The host will expect it.It does not matter how that data size happened. So, let's say host requested a string descriptor and wLength was set at 123 bytes. But the string itself is shorter and results in a 64 byte packet. You need to send one data packet and a ZLP after that.ZLP or short packets are used as a stream terminator/delimiter.

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 04:14:14 pm
content: Even for the first get device descriptor request (in default state) ? Because I have an impression the host immediately sends the status OUT after the first (when max packet size is 8 and wLength is also 8 )

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 04:17:15 pm
content: For any request. The logic is universal and does not depend on where it happens or what the data is. This logic is much more low level.It is hard to tell what you are looking at without seeing the logs.Correction. I'm looking at my code, and the condition for ZLP with the SETUP packets is that you are sending less than wLength and the size is a multiple.

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 04:20:20 pm
content: I was also thinking there should not be an exception but it was not working so I thought maybe. I will post some logs later when I am back to my desk.By the way, I really want to thank you, you are answering all my USB questions.

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 04:21:19 pm
content: Look at the correction. I do remember adding that condition at some point:Code:bool need_zlp = (size < usb_setup_length) &&((size & (usb_device_descriptor.bMaxPacketSize0-1)) == 0);So, if the host requested 8 bytes and bMaxPacketSize0 is also 8 bytes, then no ZLP is needed. This is specific to SETUP transfers only, not regular transfers over the control endpoint.I remember adding that when one of my device descriptors became a multiple of 64 bytes by coincidence and things stopped working. But this is strange, because the request would have been limited to that size as well. So, I'm not entirely sure what exactly happened there. But I remember having to add that usb_setup_length variable and being annoyed by it.

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 04:28:29 pm
content: When you say setup transfers, you mean everything that happens in endpoint 0 ?

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 04:32:14 pm
content: No, only actual transfers that were initiated using a SETUP token. This is different from the regular IN/OUT tokens.

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 04:35:13 pm
content: Am I forgetting something, isnt all endpoint 0 operations start with SETUP ?

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 04:37:30 pm
content: Not at all. You can have normal application-level communication on EP0. But the standard descriptor requests happen using SETUP packets. Once device is enumerated, you are free to send arbitrary data, just like with any other endpoint.And when you do that, ZLPs will be need only if the application-level protocol requires them, so they are likely to be driven by the class documentation, or by you if this is something custom.

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 04:43:42 pm
content: OK I got it. I should have combined the two questions it seems. I didnt know if ep0 can be used by the application also.

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 06:06:13 pm
content: Quote from: metebalci on December 01, 2023, 04:35:13 pmActually on a closer reading of the standard, it does not look like you can send IN/OUT outside of the data stage of the SETUP transfer. It is not explicitly mentioned, but all the descriptions and diagrams imply that.In practice SETUP with a class/vendor transfer type is used for arbitrary data exchange. And all the OS APIs are setup for that. DFU is also using class requests and the fields of the SETUP packet are used for additional information (like the address of the data block to be programmed).

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 07:40:50 pm
content: So what that means in terms of ZLP ? Control endoints does not require it at all ? But it is kinda mentioned in control transfer section, quite confusing.

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 07:45:53 pm
content: Control endpoint needs ZLP if you are sending less than requested in wLength of the setup packet and the amount you send is a multiple of the endpoint size. Those are the only conditions where it is mandatory. If you send exactly as many bytes as requested, the host know to not wait for more. If you send less and the size is not the multiple of the endpoint size, then the host also knows that you are done. But if you send less and the size is the multiple, then the host has to wait for more data, it has no way to know that you are done. ZLP is essentially just a packet less the endpoint size containing the remaining data, which is nothing.Some specific classes may need ZLP in other cases, but this would be defined in the class specification.ZLP is used in USB all over the place for different reasons. It is just a convenient way to send a signal without sending any actual data.

author: metebalci
author_rank: Frequent Contributor
timestamp: December 01, 2023, 07:52:59 pm
content: OK this makes sense but still slightly different than regular use. Like you said, if max packet size is 8, wLength is 8, and also the data is 8 bytes (or more, but wLength matters so only wLength size will be send, so data size will be same as wLength) then ZLP should not be sent but it would be needed in normal IN/OUT transaction. So there is an exception when setup/wLength is present.

author: ataradov
author_rank: Super Contributor
timestamp: December 01, 2023, 07:56:59 pm
content: Normal IN/OUT transactions do not need ZLP ever. ZLP may be specified by the specific class, but this is a separate thing.If you are making a custom protocol, you don't have to use ZLPs. They are just a convenient signal. CDC, for example, uses them as frame separator where a frame can consist of multiple data packets. But this is only because CDC was originally designed to carry network frames, and it may need to reassemble all those fragments into a full Ethernet frame. They could have used some other way to signal end of frame, but ZLP is just such a convenient marker that it makes sense to use it.With CDC being used more for USB-to-UART adapters, that ZLP thing becomes an annoyance, since UART is a byte oriented protocol and there is no need to separate frames. But CDC drivers will be stuck waiting for more data unless you send ZLP.

author: SiliconWizard
author_rank: Super Contributor
timestamp: December 01, 2023, 09:43:23 pm
content: Quote from: ataradov on December 01, 2023, 07:56:59 pmYep. And I think there was/still is a bug with this in the CDC device class in TinyUSB, for instance.