2025-03-06 7:00 AM - edited 2025-03-06 7:12 AM
Hi,
I am testing the USB HS Device CDC implemented from the CDC example (so using ST middlewares) and I notice a strange behavior while reading transfers of 512B.
Internally, the function CDC_Receive_HS file Appli/Src/usb_cdc_if.c has been adapted for a simple loopback as follows:
static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 11 */
USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceHS);
SCB_CleanDCache_by_Addr((uint32_t *)Buf, *Len);
CDC_Transmit_HS(Buf, *Len);
return (USBD_OK);
/* USER CODE END 11 */
}
So basically, my testing program, based on libusb v1.0.27.11936, consists of consecutive bulk transfers to EP #0x01 (bulk writing to STM32 CDC device) and from EP #0x81 (bulk reading from STM32 CDC device) during a time interval of 1 second.
It works fine except for bulk transfers of 512B: in this case, the test results in approx. 50% of zero length bulk reads (0 B of data) so resulting in 75% of the achievable throughput (a maximum of 12 MB/s for 511B transfers with this tests), since for any bulk transfer of size < 512B, there are no zero length reads: data written to STM32 CDC is correctly read back from it, both in therms of equal data transferred size (both W/R) and data matching.
I checked the MPSIZ and XFERSIZ fields values. The RM doesn't specify anything special regarding the programming value. I could check during debugging that 512 is being written into these fields.
So what could be the problem with exactly 512 B?
Sounds like a possible off-by-one error.
Thanks,
S.
Solved! Go to Solution.
2025-03-07 6:52 AM - edited 2025-03-07 6:53 AM
Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h
change:
#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
to
#define CDC_DATA_HS_IN_PACKET_SIZE 2*CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_HS_OUT_PACKET_SIZE 2*CDC_DATA_HS_MAX_PACKET_SIZE
it seems that the relevant size is CDC_DATA_HS_IN_PACKET_SIZE.
Actually after various test, this is not failing with 512B.
2025-03-07 1:45 AM
Hi @simo zz
You need to consider overhead and propagation time for control transfers in high-speed operations? Bulk transfers have no reserved bandwidth and are scheduled after periodic and control transfers. In my understanding,
Modify the CDC_Receive_HS function to ensure that a ZLP is sent when the transfer size is exactly 512 bytes.
static int8_t CDC_Receive_HS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 11 */
USBD_CDC_SetRxBuffer(&hUsbDeviceHS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceHS);
SCB_CleanDCache_by_Addr((uint32_t *)Buf, *Len);
if (*Len == 512) {
// Transmit 512 bytes
CDC_Transmit_HS(Buf, *Len);
// Send a zero-length packet to indicate the end of the transfer
CDC_Transmit_HS(NULL, 0);
} else {
CDC_Transmit_HS(Buf, *Len);
}
return (USBD_OK);
/* USER CODE END 11 */
}
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-03-07 3:44 AM - edited 2025-03-07 3:46 AM
Hello @FBL,
Thank you for your interest.
@FBL wrote:You need to consider overhead and propagation time for control transfers in high-speed operations?
Not at the moment, the test is just for loopback, bandwidth, correctness of the functionality.
I tested sending a ZLP as you propose but it does not solve the issue. Also, why should I do it in case of exactly 512B? With, for example, 511B and 513B, this problem does not happen, so for every bulk transfer size different than 512B.
s.
2025-03-07 6:52 AM - edited 2025-03-07 6:53 AM
Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h
change:
#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
to
#define CDC_DATA_HS_IN_PACKET_SIZE 2*CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_HS_OUT_PACKET_SIZE 2*CDC_DATA_HS_MAX_PACKET_SIZE
it seems that the relevant size is CDC_DATA_HS_IN_PACKET_SIZE.
Actually after various test, this is not failing with 512B.