Open buzhaodi opened 3 weeks ago
Hi, @buzhaodi,
There are only 8 channels available on ESP32S3. There is an error in the log about that:
E (1164) HCD DWC: No more HCD channels available
Each Hub occupies 2 channels, so the are only 5 left. Every HID device requires 1 channel for CTRL endpoint and 1 channel per interface. If HID device has 3 interfaces (Mouse, Keyboard and for example unspecified protocol «None»), for two such devices you already need 8 channels in total (So, with Hub it will be 2+(1+3)*2) > 8
).
Currently, the HID Host Driver allocates a channel for each interface, even if the last one is not used. Which is also a limitation factor.
Can you try to use simple usb_host_lib
example from esp-idf
with all attached devices you want and attach its output log here?
Connect multiple HID devices (such as a keyboard and mouse) using a USB hub or directly.
Do you have the same problem, when you connect HID devices directly (without external Hub)?
The limitation in the HID Host Driver could be removed (but we don’t have it planned yet), meanwhile you could try any other HID devices, which have less interfaces to fit into 8 channels on S3.
Hi, @roma-jam Thank you for the previous information! I’ve done some additional testing and wanted to share my results and thoughts, as well as inquire about potential solutions for my project needs. Test Results I’ve tested the ESP32-S3 with the following two examples: HID Host Example: When I connect multiple HID devices (such as a keyboard and mouse) via a USB hub, I encounter an issue where the system runs out of HCD channels and returns the ESP_ERR_NOT_SUPPORTED error. However, if I either connect without a hub or connect only one device through the hub, everything works fine, with no errors related to channel allocation. USB Host Library Example: With the usb_host_lib example, I successfully connected multiple HID devices via a USB hub. The system correctly identified all devices, and it displayed device descriptors without running into channel allocation issues. This suggests that the ESP32-S3’s USB Host mode can handle multiple devices, at least under certain conditions. Background and Goals I’m working towards implementing a solution similar to a KVM device, without HDMI, where I can connect both a keyboard and mouse simultaneously. However, I’m facing limitations due to the restricted number of channels available for HID devices on the ESP32-S3, particularly when using a hub, which consumes additional channels. Any guidance on these points would be greatly appreciated, as well as suggestions on how best to implement multi-device HID support for this KVM-like solution. Thank you again for your help! this is my usb_host_lib log: D:\esp32\hid\usbhostlib\usb_host_lib> & 'd:\esp32\python_env\idf5.4_py3.11_env\Scripts\python.exe' 'd:\esp32\esp-idf\tools\idf_monitor.py' -p COM21 -b 115200 --toolchain-prefix xtensa-esp32s3-elf- --target esp32s3 'd:\esp32\hid\usbhostlib\usb_host_lib\build\usb_host_lib_example.elf' --- Warning: GDB cannot open serial ports accessed as COMx --- Using \.\COM21 instead... --- esp-idf-monitor 1.5.0 on \.\COM21 115200 --- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0x1 (POWERON),boot:0x28 (SPI_FAST_FLASH_BOOT) SPIWP:0xee mode:DIO, clock div:1 load:0x3fce2810,len:0x15a0 load:0x403c8700,len:0x4 load:0x403c8704,len:0xd20 load:0x403cb700,len:0x2edc entry 0x403c8928 I (27) boot: ESP-IDF v5.4-dev-3951-g9106c43acc-dirty 2nd stage bootloader I (27) boot: compile time Nov 6 2024 23:29:06 I (27) boot: Multicore bootloader I (29) boot: chip revision: v0.2 I (32) boot: efuse block revision: v1.3 I (36) boot.esp32s3: Boot SPI Speed : 80MHz I (40) boot.esp32s3: SPI Mode : DIO I (43) boot.esp32s3: SPI Flash Size : 2MB I (47) boot: Enabling RNG early entropy source... I (52) boot: Partition Table: I (54) boot: ## Label Usage Type ST Offset Length I (60) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (67) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (73) boot: 2 factory factory app 00 00 00010000 00100000 I (80) boot: End of partition table I (83) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=0cde0h ( 52704) map I (100) esp_image: segment 1: paddr=0001ce08 vaddr=3fc92500 size=028b0h ( 10416) load I (102) esp_image: segment 2: paddr=0001f6c0 vaddr=40374000 size=00958h ( 2392) load I (106) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=20ccch (134348) map I (137) esp_image: segment 4: paddr=00040cf4 vaddr=40374958 size=0db88h ( 56200) load I (149) esp_image: segment 5: paddr=0004e884 vaddr=600fe100 size=0001ch ( 28) load I (155) boot: Loaded app from partition at offset 0x10000 I (155) boot: Disabling RNG early entropy source... I (167) cpu_start: Multicore app I (176) cpu_start: Pro cpu start user code I (176) cpu_start: cpu freq: 160000000 Hz I (176) app_init: Application information: I (176) app_init: Project name: usb_host_lib_example I (181) app_init: App version: 1 I (185) app_init: Compile time: Nov 6 2024 23:28:02 I (190) app_init: ELF file SHA256: 58bc8c81e... I (194) app_init: ESP-IDF: v5.4-dev-3951-g9106c43acc-dirty I (200) efuse_init: Min chip rev: v0.0 I (204) efuse_init: Max chip rev: v0.99 I (208) efuse_init: Chip rev: v0.2 I (212) heap_init: Initializing. RAM available for dynamic allocation: I (218) heap_init: At 3FC95610 len 00054100 (336 KiB): RAM I (223) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM I (228) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM I (234) heap_init: At 600FE11C len 00001ECC (7 KiB): RTCRAM I (240) spi_flash: detected chip: generic I (243) spi_flash: flash io: dio W (246) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. I (258) sleep_gpio: Configure to isolate all GPIO pins in sleep state I (264) sleep_gpio: Enable automatic switching of GPIO sleep configuration I (271) main_task: Started on CPU0 I (281) main_task: Calling app_main() I (281) USB host lib: USB host library example I (281) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2 I (291) USB host lib: Installing USB Host Library I (321) CLASS: Registering Client I (701) CLASS: Opening device at address 1 I (701) CLASS: Getting device information I (701) CLASS: Full speed I (701) CLASS: Parent info: I (701) CLASS: Port: ROOT I (701) CLASS: bConfigurationValue 1 I (701) CLASS: Getting device descriptor Device descriptor bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0x9 bDeviceSubClass 0x0 bDeviceProtocol 0x0 bMaxPacketSize0 64 idVendor 0x214b idProduct 0x7250 bcdDevice 1.00 iManufacturer 0 iProduct 1 iSerialNumber 0 bNumConfigurations 1 I (731) CLASS: Getting config descriptor Configuration descriptor bLength 9 bDescriptorType 2 wTotalLength 25 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xe0 bMaxPower 100mA Interface descriptor bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 0x9 bInterfaceSubClass 0x0 bInterfaceProtocol 0x0 iInterface 0 Endpoint descriptor bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 0x3 INT wMaxPacketSize 1 bInterval 255 I (781) CLASS: Getting Product string descriptor USB2.0 HUB I (7031) CLASS: Opening device at address 2 I (7031) CLASS: Getting device information I (7031) CLASS: Full speed I (7031) CLASS: Parent info: I (7031) CLASS: Bus addr: 1 I (7031) CLASS: Port: 2 I (7041) CLASS: bConfigurationValue 1 I (7041) CLASS: Getting device descriptor Device descriptor bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0x0 bDeviceSubClass 0x0 bDeviceProtocol 0x0 bMaxPacketSize0 32 idVendor 0x46d idProduct 0xc53f bcdDevice 4.00 iManufacturer 1 iProduct 2 iSerialNumber 0 bNumConfigurations 1 I (7071) CLASS: Getting config descriptor Configuration descriptor bLength 9 bDescriptorType 2 wTotalLength 84 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 4 bmAttributes 0xa0 bMaxPower 98mA Interface descriptor bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 0x3 bInterfaceSubClass 0x1 bInterfaceProtocol 0x1 iInterface 0 Endpoint descriptor bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 0x3 INT wMaxPacketSize 12 bInterval 1 Interface descriptor bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 0x3 bInterfaceSubClass 0x1 bInterfaceProtocol 0x2 iInterface 0 Endpoint descriptor bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 0x3 INT wMaxPacketSize 32 bInterval 1 Interface descriptor bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 0x3 bInterfaceSubClass 0x0 bInterfaceProtocol 0x0 iInterface 0 Endpoint descriptor bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 0x3 INT wMaxPacketSize 32 bInterval 1 I (7171) CLASS: Getting Manufacturer string descriptor Logitech I (7181) CLASS: Getting Product string descriptor USB Receiver I (16601) CLASS: Opening device at address 3 I (16601) CLASS: Getting device information I (16601) CLASS: Full speed I (16601) CLASS: Parent info: I (16601) CLASS: Bus addr: 1 I (16601) CLASS: Port: 1 I (16601) CLASS: bConfigurationValue 1 I (16611) CLASS: Getting device descriptor Device descriptor bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0x0 bDeviceSubClass 0x0 bDeviceProtocol 0x0 bMaxPacketSize0 64 idVendor 0x46a idProduct 0xcb bcdDevice 1.00 iManufacturer 1 iProduct 2 iSerialNumber 0 bNumConfigurations 1 I (16631) CLASS: Getting config descriptor Configuration descriptor bLength 9 bDescriptorType 2 wTotalLength 66 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xa0 bMaxPower 500mA Interface descriptor bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 0x3 bInterfaceSubClass 0x1 bInterfaceProtocol 0x1 iInterface 0 Endpoint descriptor bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 0x3 INT wMaxPacketSize 8 bInterval 1 Interface descriptor bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 0x3 bInterfaceSubClass 0x1 bInterfaceProtocol 0x2 iInterface 0 Endpoint descriptor bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 0x3 INT wMaxPacketSize 64 bInterval 1 Endpoint descriptor bLength 7 bDescriptorType 5 bEndpointAddress 0x3 EP 3 OUT bmAttributes 0x3 INT wMaxPacketSize 64 bInterval 1 I (16731) CLASS: Getting Manufacturer string descriptor CHERRY I (16731) CLASS: Getting Product string descriptor Mechanical Keyboard
Hi @buzhaodi ,
thanks for the additional log.
Yes, the usb_host_lib
example doesn't use the device features, so it doesn't allocate any channel, except the channel for CTRL endpoint. Thus, with an external hub and S2/S3 you are able to attach 6 devices through the hub ((2ch (hub) + 1ch (ep0) * 6) <= 8
).
The HID Host class driver example opens every interface on connection: hid_host_example.c, line 437
But you can change any way you need for your device and open only interfaces you need, based on the dev_params.proto
value.
Something like this:
if (dev_params.proto == HID_PROTOCOL_KEYBOARD || dev_params.proto == HID_PROTOCOL_MOUSE) {
ESP_ERROR_CHECK(hid_host_device_open(hid_device_handle, &dev_config));
}
This omit the channel allocation for other interfaces, which not specify the protocol.
Also, you can open the HID device via hid_host_device_open
, only if there was no one before. Basically, register only one hid_host_interface_callback
per one Mouse and do not open the device again, if the Mouse feature is already present.
This could also help to decrease the channel usage.
@buzhaodi, FWIW I just went through this with my KVM project to add hub support. I was able to get it working by excluding any non-kb/mouse devices as suggested by @roma-jam.
Answers checklist.
General issue report
When using the USB host mode on the ESP32-S3 to connect multiple HID devices (keyboard and mouse), I encountered the following errors:
Steps to Reproduce Power on the ESP32-S3 development board. Connect multiple HID devices (such as a keyboard and mouse) using a USB hub or directly. Run the application and observe the output logs. Expected Behavior I expect to be able to connect and recognize multiple HID devices simultaneously without encountering errors.
Actual Behavior When connecting multiple devices, the system is unable to allocate enough HCD channels and returns the ESP_ERR_NOT_SUPPORTED error. This leads to the failure to successfully claim the interface, preventing the HID devices from functioning properly.
Additional Information ESP-IDF Version: v5.4-dev-3951-g9106c43acc Relevant Code: The issue occurs in the hid_host_example.c example, specifically at line 437 during the call to hid_host_device_open. Hardware Information: ESP32-S3 development board, connected HID devices include a brand-name USB keyboard and USB mouse.
不好意思 英语有点难受 回归中文,我想知道是ESP32-S3的host模式不能用hub吗?还是需要改代码?我看报错位置是usb_dwc_hal_chan_alloc这个函数,貌似是要alloc个东西。。我看OTG_NUM_HOST_CHAN这个的定义是16 是不是也就是只有一个?
Rebooting... ESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0xc (RTC_SW_CPU_RST),boot:0x28 (SPI_FAST_FLASH_BOOT) Saved PC:0x40375a18 --- 0x40375a18: esp_restart_noos at D:/esp32/esp-idf/components/esp_system/port/soc/esp32s3/system_internal.c:160
SPIWP:0xee mode:DIO, clock div:1 load:0x3fce2810,len:0x15a0 load:0x403c8700,len:0x4 load:0x403c8704,len:0xd20 load:0x403cb700,len:0x2edc entry 0x403c8928 I (31) boot: ESP-IDF v5.4-dev-3951-g9106c43acc 2nd stage bootloader I (31) boot: compile time Nov 3 2024 14:09:17 I (31) boot: Multicore bootloader I (33) boot: chip revision: v0.2 I (36) boot: efuse block revision: v1.3 I (40) boot.esp32s3: Boot SPI Speed : 80MHz I (43) boot.esp32s3: SPI Mode : DIO I (47) boot.esp32s3: SPI Flash Size : 2MB I (51) boot: Enabling RNG early entropy source... I (55) boot: Partition Table: I (58) boot: ## Label Usage Type ST Offset Length I (64) boot: 0 nvs WiFi data 01 02 00009000 00006000 I (71) boot: 1 phy_init RF data 01 01 0000f000 00001000 I (77) boot: 2 factory factory app 00 00 00010000 00100000 I (84) boot: End of partition table I (87) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=0d5f0h ( 54768) map I (104) esp_image: segment 1: paddr=0001d618 vaddr=3fc92400 size=028c0h ( 10432) load I (107) esp_image: segment 2: paddr=0001fee0 vaddr=40374000 size=00138h ( 312) load I (110) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=22560h (140640) map I (142) esp_image: segment 4: paddr=00042588 vaddr=40374138 size=0e27ch ( 57980) load I (155) esp_image: segment 5: paddr=0005080c vaddr=600fe100 size=0001ch ( 28) load I (161) boot: Loaded app from partition at offset 0x10000 I (161) boot: Disabling RNG early entropy source... I (172) cpu_start: Multicore app I (182) cpu_start: Pro cpu start user code I (182) cpu_start: cpu freq: 160000000 Hz I (182) app_init: Application information: I (182) app_init: Project name: hid I (185) app_init: App version: 1 I (189) app_init: Compile time: Nov 3 2024 14:08:17 I (194) app_init: ELF file SHA256: 05856467c... I (198) app_init: ESP-IDF: v5.4-dev-3951-g9106c43acc I (203) efuse_init: Min chip rev: v0.0 I (207) efuse_init: Max chip rev: v0.99 I (211) efuse_init: Chip rev: v0.2 I (215) heap_init: Initializing. RAM available for dynamic allocation: I (221) heap_init: At 3FC95530 len 000541E0 (336 KiB): RAM I (227) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM I (232) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM I (237) heap_init: At 600FE11C len 00001ECC (7 KiB): RTCRAM I (243) spi_flash: detected chip: generic I (246) spi_flash: flash io: dio W (249) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header. I (261) sleep_gpio: Configure to isolate all GPIO pins in sleep state I (268) sleep_gpio: Enable automatic switching of GPIO sleep configuration I (274) main_task: Started on CPU0 I (284) main_task: Calling app_main() I (284) example: HID Host example I (284) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2 I (324) example: Waiting for HID Device to be connected W (704) hid-host: No HID device at USB port 1 I (884) example: HID Device, protocol 'KEYBOARD' CONNECTED I (984) example: HID Device, protocol 'MOUSE' CONNECTED I (1064) example: HID Device, protocol 'KEYBOARD' CONNECTED I (1164) example: HID Device, protocol 'MOUSE' CONNECTED E (1164) HCD DWC: No more HCD channels available E (1164) USBH: EP Alloc error: ESP_ERR_NOT_SUPPORTED E (1164) USB HOST: EP allocation error ESP_ERR_NOT_SUPPORTED E (1164) USB HOST: Claiming interface error: ESP_ERR_NOT_SUPPORTED E (1174) hid-host: hid_host_interface_claim_and_prepare_transfer(576): Unable to claim Interface E (1184) hid-host: hid_host_device_open(1186): Unable to claim interface ESP_ERROR_CHECK failed: esp_err_t 0x106 (ESP_ERR_NOT_SUPPORTED) at 0x4200775a --- 0x4200775a: hid_host_device_event at D:/esp32/hid/hid/main/hid_host_example.c:437 (discriminator 1)
file: "./main/hid_host_example.c" line 437 func: hid_host_device_event expression: hid_host_device_open(hid_device_handle, &dev_config)
abort() was called at PC 0x40379c5b on core 0 --- 0x40379c5b: _esp_error_check_failed at D:/esp32/esp-idf/components/esp_system/esp_err.c:49
Backtrace: 0x40375ad9:0x3fc97810 0x40379c65:0x3fc97830 0x403802f5:0x3fc97850 0x40379c5b:0x3fc978c0
0x4200775a:0x3fc978f0 0x42007965:0x3fc97920 0x42021efb:0x3fc979a0 0x4037a645:0x3fc979d0 --- 0x40375ad9: panic_abort at D:/esp32/esp-idf/components/esp_system/panic.c:454 0x40379c65: esp_system_abort at D:/esp32/esp-idf/components/esp_system/port/esp_system_chip.c:92 0x403802f5: abort at D:/esp32/esp-idf/components/newlib/abort.c:38 0x40379c5b: _esp_error_check_failed at D:/esp32/esp-idf/components/esp_system/esp_err.c:49 0x4200775a: hid_host_device_event at D:/esp32/hid/hid/main/hid_host_example.c:437 (discriminator 1) 0x42007965: app_main at D:/esp32/hid/hid/main/hid_host_example.c:604 0x42021efb: main_task at D:/esp32/esp-idf/components/freertos/app_startup.c:208 0x4037a645: vPortTaskWrapper at D:/esp32/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139
ELF file SHA256: 05856467c