eclipse-threadx / usbx

Eclipse ThreadX - USBX is a high-performance USB host, device, and on-the-go (OTG) embedded stack, that is fully integrated with Eclipse ThreadX RTOS
https://github.com/eclipse-threadx/rtos-docs/blob/main/rtos-docs/usbx/index.md
MIT License
154 stars 89 forks source link

HID IN data transmission frequency is only about 10 times per second #39

Open arilink-tech opened 2 years ago

arilink-tech commented 2 years ago

I used ThreadX and USBX STM32 in the project as USB HID devices to connect to the computer. My program collects sensor data every millisecond and calls the ux_device_class_hid_event_set() function to send to the host computer, but the host computer can only receive about 10 per second The data, why is there such a situation, ux_device_class_hid_event_set is also set to 1ms in the endpoint descriptor

arilink-tech commented 2 years ago

@xiaocq2001

xiaocq2001 commented 2 years ago

Firstly please confirm that the host generates token every 1ms, if host generates token every 100ms (10 frame/s), you should check your descriptor (FS/LS interval should be 1, HS interval should be 4) or check host driver.

If you are using tx_thread_sleep() as time reference, please adjust ThreadX tick setting to generate 1ms tick (by default we are using 10ms tick).

arilink-tech commented 2 years ago

1.I #define TX_TIMER_TICKS_PER_SECOND 1000 in the tx_user.h file 2.The delay of the descriptor is set to 1ms endpoint

arilink-tech commented 2 years ago

I used an oscilloscope to confirm that the time reference of tx_thread_sleep() is normal. Another project of mine uses TinyUSB. The descriptors of the two projects are the same. But when using USBX, the amount of token packet data observed through BUS hound is very low. I don’t understand why.

xiaocq2001 commented 2 years ago
  1. Please confirm the ThreadX tick is 1ms (check ThreadX clocks settings), if that's not really 1ms changing the macro will cause problem.
  2. The descriptor seems OK if you are using full speed.
arilink-tech commented 2 years ago

I measured it with an oscilloscope to determine that the ThreadX tick is 1ms, and the same descriptor can be used normally on STM32H7. It can transmit data 1000 times per second, but it does not work on STM32F1.

arilink-tech commented 2 years ago

I can basically determine that the USB transmission problem is caused by FIFO allocation. When I only use HID and allocate the USB FIFO as shown below, HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80); HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40); HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); the transmission rate can reach 1000 times per second. But my project needs to use HID and CDC at the same time. When I set the FIFO according to the following allocation, the transmission speed will be reduced. I want to know how to deal with the FIFO allocation to ensure that HID and CDC can work normally HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80);

/ Set Tx FIFO 0 / HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x10);

/ Set Tx FIFO 2 / HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, 0x80);

/ Set Tx FIFO 3 / HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x30);

arilink-tech commented 2 years ago

@xiaocq2001 Is there any solution? This is really confusing

xiaocq2001 commented 2 years ago

Not so familiar with ST FIFO setting. But here are some suggestion I think worth to try:

  1. Since you are not focused on reading from host, suggest to decrease RxFIFO, e.g., to 0x20.
  2. Since you are not focused on CDC communication speed, you can decrease bulk FIFO, guessing FIFO 2, e.g., to 0x40.
  3. Now you have enough space for interrupt FIFO, which can set to 0x80.
arilink-tech commented 2 years ago

Is the interrupt FIFO FIFO 0? When I only use HID, it can work normally even if the HID FIFO is set very small. HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x40); HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x10); HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x10); Once I join CDC and use USB as a composite device, the transmission frequency of HID will drop. I tried to adjust the FIFO size many times, but I couldn’t solve

xiaocq2001 commented 2 years ago

OK. From your descriptor, your endpoint is 0x81, then TxFIFO 1 is used for interrupt endpoint ... Also your bulk IN FIFO should be configured. All OUT endpoints share RxFIFO.

arilink-tech commented 2 years ago

My HID IN endpoint is 0x83 CDC IN is 0x82 If TX FIFO1 is an interrupt endpoint, what is the purpose of configuring TX FIFO0?

xiaocq2001 commented 2 years ago

TX FIFO 0 is for control endpoint 0 IN.

arilink-tech commented 2 years ago

So no matter what device type is used, RX FIFO and TX FIFO 0 are necessary. My current CDC IN uses 0x82 endpoint and HID IN uses 0x83 endpoint. Therefore, I have configured TX FIFO 2 and TXFIFO 3 for this operation should be correct?

xiaocq2001 commented 2 years ago

Yes.

arilink-tech commented 2 years ago

This is very strange. Could it be that USBX does not support the STM32F1 series?

xiaocq2001 commented 2 years ago

That's related to the hardware peripheral usage and ST HAL implement (which is used by USBX to operate hardware).

Since the total FIFO is limited, user should control the FIFO for his purpose. E.g., normally bulk endpoints require large FIFO (at least two full packet to ping-pong) for speed optimization but can be reduced (to just one packet) in composite device to support more endpoints.

arilink-tech commented 2 years ago

The total FIFO of STM32F105RBT6 is 1.25K. My allocation is based on the needs. I allocate the same size of FIFO to STM32H750 and it can work normally.

xiaocq2001 commented 2 years ago

If same hardware configuration generates different results, please check with ST to see if there is hardware difference between two chips.

arilink-tech commented 2 years ago

I tried to report my current problems to the ST community, but I didn’t get any useful information. Can you contact the ST official?

liydu commented 2 years ago

@arilink , we will pass over the information to ST and get back to you on this.

arilink-tech commented 2 years ago

@liydu I am looking forward to your reply