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
148 stars 88 forks source link

ux_device_class_hid_event_set corrupts GET_REPORT request on STM32L5 #76

Open oliinykb opened 1 year ago

oliinykb commented 1 year ago

Hello, STM32 is an HID Device, Host - Win PC. Data are transferred correctly when the host sets GET_REPORT or SET_REPORT. Callbacks are called and data are correct on both sides of the USB line. However, when I set an event with ux_device_class_hid_event_set the GET_REPORT set by the host is received correctly, the callback is correctly called, and data are set to a _hidevent, but the host receives random numbers instead of data loaded into the buffer. Although, data sent by ux_device_class_hid_event_set are correctly transferred and received by the host. Data corruption occurs on the device side since the USB flow monitor shows the same "random" data as my host application receives. It looks like there is some buffer overwriting by the ux_device_class_hid_event_set or so. My HID descriptor, if needed. `

0x05, 0x0c,                    // USAGE_PAGE (Consumer Devices)
0x09, 0x00,                    // USAGE (Unassigned)
0xa1, 0x01,                    // COLLECTION (Application)
0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
0x75, 0x08,                    //   REPORT_SIZE (8)
0x85, 0x01,                    //   REPORT_ID (1)
0x09, 0x30,                    //   USAGE (Power)
0x95, 0x32,                    //   REPORT_COUNT (50)
0x81, 0x82,                    //   INPUT (Data,Var,Abs,Vol)
0x85, 0x02,                    //   REPORT_ID (2)
0x09, 0xe0,                    //   USAGE (Volume)
0x95, 0x14,                    //   REPORT_COUNT (20)
0x81, 0x02,                    //   INPUT (Data,Var,Abs)
0x85, 0x03,                    //   REPORT_ID (3)
0x09, 0x35,                    //   USAGE (Illumination)
0x95, 0x37,                    //   REPORT_COUNT (55)
0x81, 0x82,                    //   INPUT (Data,Var,Abs,Vol)
0x85, 0x11,                    //   REPORT_ID (17)
0x09, 0x01,                    //   USAGE (Consumer Control)
0x95, 0x0c,                    //   REPORT_COUNT (12)
0x91, 0x82,                    //   OUTPUT (Data,Var,Abs,Vol)
0x85, 0x12,                    //   REPORT_ID (18)
0x0a, 0x00, 0x01,              //   USAGE (Fan Enable)
0x95, 0x01,                    //   REPORT_COUNT (1)
0x81, 0x02,                    //   INPUT (Data,Var,Abs)
0x85, 0x13,                    //   REPORT_ID (19)
0x09, 0x40,                    //   USAGE (Menu)
0x95, 0x37,                    //   REPORT_COUNT (55)
0x91, 0x80,                    //   OUTPUT (Data,Ary,Abs,Vol)
0xc0                           // END_COLLECTION

`

xiaocq2001 commented 1 year ago

Hi,

It seems your event length is over the default buffer setting (32 bytes). Maybe you can check following:

  1. if UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH can fit your max report length (with report ID).
  2. if endpoint size in USB framework can cover the max report length.
  3. if the TX FIFO for the physical endpoint is enough for the transfer size.
oliinykb commented 1 year ago

Hello, I also tried with the smaller event length (less than 32 bytes). Also, I tried to switch default buffer setting to 64. Neither helped. But I found why data are corrupted. Despite I configured PMA buffers at a certain location (using HAL_PCDEx_PMAConfig), when I run the program the content of the BTABLE (when HAL_PCD_EP_Transmit is called) is different, for the first endpoint, from the value specified in HAL_PCDEx_PMAConfig. For example, if I set PMA addresses: HAL_PCDEx_PMAConfig(&hpcd_USB_FS, 0x00, PCD_SNG_BUF, 0x40); HAL_PCDEx_PMAConfig(&hpcd_USB_FS, 0x80, PCD_SNG_BUF, 0x80); HAL_PCDEx_PMAConfig(&hpcd_USB_FS, 0x81, PCD_SNG_BUF, 0x100); When I look at BTABLE[0] the first time HAL_PCD_EP_Transmit is called the value is 0x800080. As it must be, and data sent via USB are correct. But second time it is called I see 0x2120212 in BTABLE[0]. The data sent are not correct. If I manually, in debug mode, modify this value to 0x800080 the data I receive on PC side are correct, for several cycles (I send reports periodically), but it returns to 0x2120212 after some random number of cycles and the data are corrupted again.

Another solution is to set PMA address to this "magic" value of 0x2120212. In this case data sent are correct also. But(!) if I use two different events - there are separate "magic" number for each.

If I add : // correct PMA BTABLE uint32_t *btable = (uint32_t *) USB_PMAADDR_NS; btable[ep->num*4] = ep->pmaadress; to HAL_PCD_EP_Transmit() in stm32l5xx_hal_pcd.c it fixes everything. Now it works. But it is not a real solution. First, because it is removed every time Cube regenerates project. I am not sure in the stability of this solution. This workaround I found here: https://stackoverflow.com/a/59951272

Can you figure out why BTABLE is overwritten? Why it is changing always and how to fix it properly?

xiaocq2001 commented 1 year ago

From stackoverflow link it's some issue in STMCube generated HAL, so I think the better way to have this solved is to ask help on ST side or check if that's fixed in latest STMCube generated code.