STM32F4 High Speed USB with LIBUSB
Hey everyone,
I have been using the STM32F4 for quite some time now and have used the STM32F429 Eval1 board for developing a firmware that uses the external USB3300 PHY over ULPI to achieve high speed USB transfers in device mode with the CDC (virtual com port) profile.
While this works to some extent, the aim is to improve the bandwidth of the data transfers from device to the host to approximately 160Mbit/second. Since CDC emulates the old, but reliable, serial port I don't think it is meant to do these kinds of speedy transfers.
If anyone has been able to get these kinds of transfer speeds out of an STM32F4 high speed USB CDC device, I would love to hear how that would be achievable since my tests show that this interface chokes after about 14KB of transferred data.
When looking around I stumbled upon a video from STM with the topic: STM32 USB training - 09.3 USB CDC libusb device lab. In which they adjust a standard device CDC firmware for full-speed USB that enumerates as a virtual com port to a libusb device which would benefit from higher transfer speeds.
Following the adjustments from the video, the project compiles and can be flashed to the STM32F4. Both a windows 10 and ubuntu 22.04 machine find a new USB device and after installing the libusb drivers they are recognized but with some errors on both Windows (This device cannot start. (Code 10) STATUS_DEVICE_DATA_ERROR) and Ubuntu (usb 1-1: can't set config #1, error -32).
Does anyone have any idea what I would be doing wrong or is there a better resource for figuring out how to adjust the FW to work with a high speed libusb interface?
Or does anyone have experience using other, better USB libraries that work with STM32F4 and its high speed interface that would be able to get the 160Mbit/s bandwidth?
Any help, pointers or tips would be helpful!
In order to provide some more information, I adjusted the following in a standard high speed USB device with CDC profile:
- In usbd_desc.c
#define USBD_VID 1155
#define USBD_LANGID_STRING 1033
#define USBD_MANUFACTURER_STRING "STM"
#define USBD_PID_HS 0xC1B0
#define USBD_PRODUCT_STRING_HS "LIBUSB interface"
#define USBD_CONFIGURATION_STRING_HS "CDC Config"
#define USBD_INTERFACE_STRING_HS "CDC Interface"/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_HS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
#if (USBD_LPM_ENABLED == 1)
0x01, /*bcdUSB */ /* changed to USB version 2.01
in order to support LPM L1 suspend
resume test of USBCV3.0*/
#else
0x00, /*bcdUSB */
#endif /* (USBD_LPM_ENABLED == 1) */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_HS), /*idProduct*/
HIBYTE(USBD_PID_HS), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};- In usbd_cdc.h
/* 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 USB_CDC_CONFIG_DESC_SIZ 32U
#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
#define CDC_REQ_MAX_DATA_SIZE 0x7U- In usbd_cdc.c, I removed all references to the CMD endpoint but the file is too long to be inserted here but I attached the file to this post.
Best regards!
