-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ZLP not sent in USB device #15384
Comments
cc @ARMmbed/team-st-mcd |
Hi @daniel-starke |
The easiest solution is to disallow any write with a size equal to the endpoint buffer size. However, this solution may not be desired. |
@daniel-starke , some USB device may have the capability to detcect packet size & auto send ZLP. |
I also encountered this, and put together a reproduction (#15451) |
Fix issue ARMmbed#15384 by sending a zero-length packet if the packet sent had the same size as the endpoint buffer size. This is needed to comply with the USB protocol which assumes an ongoing multi-packet USB transaction otherwise. STM32 HAL PCD handle parameters are used to avoid data duplication in RAM. Signed-off-by: Daniel Starke <[email protected]>
Hi @cyliangtw @agausmann Could you have a look on #15465 ? Thx |
About usbd control packet, https://github.com/ARMmbed/mbed-os/blob/72f27cee92a4bdafa30513f732e007ba635dc93f/drivers/usb/source/USBDevice.cpp#L262C4-L262C4 could handle & send ZLP. About usbd non-control packet, it's possible to wait ZLP. |
Pull request #15473 has been merged. Therefore, this issue can be closed. |
Description of defect
Sending out a 64 byte buffer on USB CDC does not show up on the receiving side until more data with a length != 64 bytes is sent.
The USB protocol is a physical 1:1 half-duplex bus protocol with multiple channels (a.k.a. endpoints). That means only one side can send at a time. The device defines a buffer size for each endpoint. Any data larger than this needs to be split into multiple packets. To form a transaction and block the bus until end of the data transmission pakets with the maximum size for the endpoint are sent. The end of the transaction is signalled by sending a packet with less than the maximum size. A zero-length packet (ZLP) can be sent in case no more data is available but the complete data size was a multiple of the maximum endpoint buffer size.
STM32 does not automatically sends out ZLPs at the end of a trancaction as it has no knowledge about it. This needs to be done in the USB device driver. The user can not do so as the driver prevents transmissions of zero length. See line 402
mbed-os/drivers/usb/source/USBCDC.cpp
Lines 398 to 407 in 17dc3dc
As this appears to be a USB protocol issue instead of a STM32 HAL specific one I would suggest solving it in
mbed-os/drivers/usb/source/USBDevice.cpp
Lines 990 to 1006 in 17dc3dc
However, I am not aware of how other device platforms handle this. It may be necessary to send a ZLP if the last packet was a multiple of the maximum endpoint buffer size and track its transmission state in
mbed-os/targets/TARGET_STM/USBPhy_STM32.cpp
Lines 108 to 119 in 17dc3dc
Target(s) affected by this defect ?
STM32
Toolchain(s) (name and version) displaying this defect ?
PlatformIO latest version
What version of Mbed-os are you using (tag or sha) ?
mbed-os-6.15.0
What version(s) of tools are you using. List all that apply (E.g. mbed-cli)
PlatformIO latest version
How is this defect reproduced ?
Send out 64 bytes after a client connects to a USB CDC port. Read from it on the client side (e.g. by opening the serial device with PuTTY). The 64 bytes of data should show up but don't.
The text was updated successfully, but these errors were encountered: