2025-07-09 3:16 AM
Hello ST Community,
I'm working with the STM32N6570-DK board and using the ST-provided UVC video streaming example.
By default, the example uses MJPEG format, but I modified the UVC descriptors to stream in UNCOMPRESSED format (YUY2).
Where as i am sending static image data
-->> When using a lower resolution configuration 320*236 and HS_MPS is 512 , Then the static image displays correctly on Windows Camera, and Wireshark shows proper isochronous packets.
However, when I change the configuration to a higher resolution like 800×480 and increase HS_MPS:
#define USBD_VIDEO_EPIN_HS_MPS 1024 // Also tried 2044, 3036, 3072
#define UVC_FRAME_WIDTH 800U
#define UVC_FRAME_HEIGHT 480U
#define USBX_DEVICE_MEMORY_STACK_SIZE (32*1024)
#define UX_DEVICE_APP_THREAD_STACK_SIZE 2048
#define TX_APP_MEM_POOL_SIZE (16*1024)
#define UX_DEVICE_APP_MEM_POOL_SIZE (48*1024)
#define USBPD_DEVICE_APP_MEM_POOL_SIZE (5*1024)
.LD file in STM32CubeIDE :
.usbx_data 0x341D8000 (NOLOAD) : { *(.UsbHpcdSection) } >RAM
.usbx_bss 0x341E0000 (NOLOAD) :{ *(.UsbxPoolSection) } >RAM
-->> The enumeration completes, the UVC device appears in Device Manager, and Windows Camera detects it, but no image is displayed. In Wireshark, I observe only 1575-byte isochronous packets (despite setting HS_MPS to higher values), and no data is visible.
-->>Moreover, when I increase HS_MPS above 1024, the device fails to enumerate or get recognized by the host.
For comparison, I tested the ST-provided binary from the following link:
https://github.com/STMicroelectronics/x-cube-n6-camera-capture/tree/main/Binary
This works fine with the default IMX335 camera, streams live data via UVC, and Wireshark shows HS_MPS = 3072, with high frame rates and smooth display on Windows Camera.
Questions:
What is the proper way to increase USBD_VIDEO_EPIN_HS_MPS upto 3072 safely?
Are there any special pool sizes or USB stack configurations required for high MPS and large resolution support?
Could ST kindly share the source code for the example binary provided in the GitHub repo above? It would help to resolve this issue and understand the correct setup for high-resolution UVC.
Thanks in advance for your support.
Solved! Go to Solution.
2025-07-15 8:06 AM
Hi @saib
First, according to the USB 2.0 specification, the maximum packet size for high-speed isochronous endpoints is 1024 bytes per microframe (125 µs). So, to achieve higher bandwidth, increase the number of packets per frame rather than increasing packet size.
Ensure the video frame buffer size matches the resolution and format:
Frame Size=Width×Height×Bytes per pixel.
Adjust the UVC payload header size and ensure proper framing of video data across multiple USB packets.
You can find here the source code for the binaries.
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-07-15 8:06 AM
Hi @saib
First, according to the USB 2.0 specification, the maximum packet size for high-speed isochronous endpoints is 1024 bytes per microframe (125 µs). So, to achieve higher bandwidth, increase the number of packets per frame rather than increasing packet size.
Ensure the video frame buffer size matches the resolution and format:
Frame Size=Width×Height×Bytes per pixel.
Adjust the UVC payload header size and ensure proper framing of video data across multiple USB packets.
You can find here the source code for the binaries.
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-08-28 11:06 AM
Have you figured out how to increase the packet size? I'm in the exact same boat as you. Got 320x240 video streaming from a camera, but in order to increase the frame rate I need to bump the packet size, and packets per microframe, up from 512/1 to 1024/3. I've combed through the examples, but couldn't decipher what was being done differently.
2025-09-02 2:50 AM - edited 2025-09-03 7:17 AM
Hi @chornbeck
Regarding your question on increasing throughput for higher frame rates and resolutions with STM32 USBX UVC streaming:
The maximum packet size must remain at 1024 bytes.
To achieve higher bandwidth, you correctly increase the number of packets per microframe (up to 3), which multiplies the effective throughput without violating the USB standard.
It is important to increase the USBX memory pool sizes specifically UX_DEVICE_APP_MEM_POOL_SIZE and TX_APP_MEM_POOL_SIZE to accommodate the larger buffers required for handling multiple packets per frame.
Additionally, you should increase the USB peripheral’s Transmit FIFO size for isochronous transfer and adjust it to achieve higher bandwidth. For example, in your USB peripheral initialization, you can configure the FIFO sizes as follows:
HAL_PCDEx_SetRxFiFo(&hpcd_USB1_OTG_HS, 0x30); // 48 words
HAL_PCDEx_SetTxFiFo(&hpcd_USB1_OTG_HS, 0, 0x10); // 16 words
HAL_PCDEx_SetTxFiFo(&hpcd_USB1_OTG_HS, 1, 0x300); // 768 words (ISO )
This setup helps maintain maximum allowed streaming by the USB peripheral (max 4KB) and ensure smooth multiple packets efficiently.
If still having issues, and to better assist you, could you please share a minimal project or code snippet that reproduces the behavior.
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-09-02 5:58 AM - edited 2025-09-02 5:59 AM
Thank you @FBL , I have worked through our code having deduced some of this information. I maintain my packet size at 1024, but from what I can see, the code generated from the Cube MX doesn't properly generate for multiple microframes? In the Cube, I can set the value for the Maximum Packet Size up to 3072. This should be 3, 1024 byte transactions. However, the way it enumerates in the endpoint is actually as 2 1024 byte transactions. I believe there is an issue in the way the cube mx code isolates the "number of transactions" bits in the packet size field of the USB enumeration.
For example, when the value of 3072 (the max accepted) is entered into the Cube MX as the maximum packet size, indicating 3*1024 transactions, this number is passed straight through to the USB endpoint. So, the endpoint advertises it's max packet size as 3072. But 3072, in hex, is only 0x0C00, which, when related to the USB expected bitfields, actually advertises only 2*1024 packets. The correct advertisement for 3*1024 is 5120, or 0x1400. Similarly, attempting to enter 2048 as the packet size, for 2*1024, creates an error on the endpoint, because the first 11 bits (which USB looks at for the actual packet size) is all 0's, but bits 13-11 (which USB looks at for number of transactions) displays 0x01, for two packets per transaction. It seems to be only a fluke that 3072 is still a correct advertisement, though it's the incorrect sizing.
This is what I am seeing directly after testing auto-generated code from the Cube MX. I can change this manually to properly advertise the correct 3*1024 packet sizing, but I'm concerned about the generated code's interaction with the changed number, and the actual size of buffers it creates, since there is so much generated code behind it that I haven't parsed through.
I am using Cube MX v6.15.0 on Linux
2025-09-05 6:15 AM
HI @chornbeck
Would you attach your ioc file to facilitate bug report?
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.