tinyusb
tinyusb copied to clipboard
Don't receive packets immediately when usb packet equals CFG_TUD_ENDPOINT0_SIZE
Operating System
Linux
Board
STM32U575
Firmware
938cae818
What happened ?
I dont receive USB packets when they are the maximum packet size CFG_TUD_ENDPOINT0_SIZE immediately. I do receive when the host sends more bytes. (The host is a linux PC). So it's seem that the incoming ZLP isn't processed.
If I trigger handle_epout_irq manually, the packet is still not processed. So the packet is for some reason not provided yet by the hardware.
How to reproduce ?
USB device with dualport CDC. Send exactly 64 bytes on FS connection
Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2)
Will add later
Screenshots
No response
I have checked existing issues, dicussion and documentation
- [X] I confirm I have checked existing issues, dicussion and documentation.
Are you sure a zlp was sent ? Normally it has to be done explicitly.
Well,
- If I use the the official STM32 USB library (yikes), it works fine and I get 3 usb interrupts when receiving a 64 bytes from my linux host
- If I use tinyusb I only get one usb interrupt, which handles the 64 bytes packet. But no second interrupt to complete the transfer
-> So it's seems that the the stm32u575 is not correctly initialised by tinyusb? Still need to take a deeper look
The issue appears when CFG_TUD_CDC_RX_BUFSIZE CFG_TUD_CDC_TX_BUFSIZE and CFG_TUD_CDC_EP_BUFSIZE have a different definition than CFG_TUD_ENDPOINT0_SIZE.
It's still a mystery to me why that is the case
Please enable debug print which gives you much more information.
USB 2.0 specification:
A bulk transfer is complete when the endpoint does one of the following:
• Has transferred exactly the amount of data expected
• Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet
When a bulk transfer is complete, the Host Controller retires the current IRP and advances to the next IRP.
If a data payload is received that is larger than expected, all pending bulk IRPs for that endpoint will be
aborted/retired.
So it's a intended behavior.
If you need to receive packet immediately:
- Set CFG_TUD_CDC_EP_BUFSIZE to endpoint size, which is 64 for FS or 512 for HS
- Send ZLP explicitly, you need low level control of the port, something like
serial.write(b"")
in Python won't work
ST's lib works as it queue data length equal to EP size:
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */
#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE