Skip to main content
Graduate II
March 6, 2025
Solved

STM32H7RSxx OTG strange behavior with bulk transfer

  • March 6, 2025
  • 1 reply
  • 617 views

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.

    This topic has been closed for replies.
    Best answer by simo zz

    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.

    1 reply

    Technical Moderator
    March 7, 2025

    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, 

    1. For a 512-byte payload consumes 8% of the micro frame bandwidth per transfer. Maximum of 13 transfers per micro frame. Theoretical maximum useful bandwidth is 53.2 MBps. So, ensure periodic transfers should not exceed 80% of the bus bandwidth.
    2. Total overhead for bulk transfer: 55 bytes

    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 */
    }

     

    simo zzAuthor
    Graduate II
    March 7, 2025

    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.

    simo zzAuthorAnswer
    Graduate II
    March 7, 2025

    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.