esp32-usb-host-demos icon indicating copy to clipboard operation
esp32-usb-host-demos copied to clipboard

No keyboard_transfer_cb HID report on usbhhidboot

Open luftaquila opened this issue 2 years ago • 3 comments

Thank you for your code. It is very helpful to understanding the USB Host structure.

I'm trying to make ESP32 read data from my USB keyboard. The usbhhidboot example works well and reports device descriptors when keyboard is connected.

BTW, I can't receive any keyboard_transfer_cb reports. I'm wondering if this is the problem you mentioned on README that some keyboards require SetProtocol that are not implemented. My keyboard is a custom keyboard with QMK firmware uploaded.

Below is the output of my usbhhidboot. Nothing happens when I press some keys on keyboard.

Thank you.

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:0x3fcd0108,len:0x43c
load:0x403b6000,len:0xbd0
load:0x403ba000,len:0x29c8
entry 0x403b61d8
[    84][I][usbhhelp.hpp:75] usbh_setup(): [] startup.
[   114][I][usbhhelp.hpp:80] usbh_setup(): [] usb_host_install: 0
[   114][I][usbhhelp.hpp:91] usbh_setup(): [] usb_host_client_register: 0
[   530][I][usbhhelp.hpp:40] _client_event_callback(): [] New device address: 1
[   531][I][usbhhelp.hpp:49] _client_event_callback(): [] speed: 1 dev_addr 1 vMaxPacketSize0 8 bConfigurationValue 1
[   537][I][show_desc.hpp:44] show_dev_desc(): [] bLength: 18
[   542][I][show_desc.hpp:45] show_dev_desc(): [] bDescriptorType(device): 1
[   549][I][show_desc.hpp:46] show_dev_desc(): [] bcdUSB: 0x110
[   554][I][show_desc.hpp:47] show_dev_desc(): [] bDeviceClass: 0x00
[   561][I][show_desc.hpp:48] show_dev_desc(): [] bDeviceSubClass: 0x00
[   567][I][show_desc.hpp:49] show_dev_desc(): [] bDeviceProtocol: 0x00
[   573][I][show_desc.hpp:50] show_dev_desc(): [] bMaxPacketSize0: 8
[   579][I][show_desc.hpp:51] show_dev_desc(): [] idVendor: 0x1209
[   585][I][show_desc.hpp:52] show_dev_desc(): [] idProduct: 0x2328
[   591][I][show_desc.hpp:53] show_dev_desc(): [] bcdDevice: 0x500
[   597][I][show_desc.hpp:54] show_dev_desc(): [] iManufacturer: 1
[   603][I][show_desc.hpp:55] show_dev_desc(): [] iProduct: 2
[   608][I][show_desc.hpp:56] show_dev_desc(): [] iSerialNumber: 0
[   614][I][show_desc.hpp:57] show_dev_desc(): [] bNumConfigurations: 1
[   621][I][show_desc.hpp:64] show_config_desc(): [] bLength: 9
[   626][I][show_desc.hpp:65] show_config_desc(): [] bDescriptorType(config): 2
[   633][I][show_desc.hpp:66] show_config_desc(): [] wTotalLength: 109
[   640][I][show_desc.hpp:67] show_config_desc(): [] bNumInterfaces: 4
[   646][I][show_desc.hpp:68] show_config_desc(): [] bConfigurationValue: 1
[   653][I][show_desc.hpp:69] show_config_desc(): [] iConfiguration: 0
[   659][I][show_desc.hpp:74] show_config_desc(): [] bmAttributes(, Remote Wakeup): 0xa0
[   667][I][show_desc.hpp:75] show_config_desc(): [] bMaxPower: 250 = 500 mA
[   673][I][show_desc.hpp:82] show_interface_desc(): [] bLength: 9
[   679][I][show_desc.hpp:83] show_interface_desc(): [] bDescriptorType (interface): 4
[   687][I][show_desc.hpp:84] show_interface_desc(): [] bInterfaceNumber: 0
[   694][I][show_desc.hpp:85] show_interface_desc(): [] bAlternateSetting: 0
[   700][I][show_desc.hpp:86] show_interface_desc(): [] bNumEndpoints: 1
[   707][I][show_desc.hpp:87] show_interface_desc(): [] bInterfaceClass: 0x03
[   714][I][show_desc.hpp:88] show_interface_desc(): [] bInterfaceSubClass: 0x01
[   721][I][show_desc.hpp:89] show_interface_desc(): [] bInterfaceProtocol: 0x01
[   728][I][show_desc.hpp:90] show_interface_desc(): [] iInterface: 0
[   734][I][sketch_jul04a.ino:66] check_interface_desc_boot_keyboard(): [] Claiming a boot keyboard!
[   743][I][show_desc.hpp:115] show_hid_desc(): [] bLength: 9
[   748][I][show_desc.hpp:116] show_hid_desc(): [] bDescriptorType (HID): 33
[   755][I][show_desc.hpp:117] show_hid_desc(): [] bcdHID: 0x0111
[   761][I][show_desc.hpp:118] show_hid_desc(): [] bCountryCode: 0
[   767][I][show_desc.hpp:119] show_hid_desc(): [] bNumDescriptor: 1
[   773][I][show_desc.hpp:120] show_hid_desc(): [] bDescriptorType: 34
[   779][I][show_desc.hpp:121] show_hid_desc(): [] wDescriptorLength: 64
[   786][I][show_desc.hpp:100] show_endpoint_desc(): [] bLength: 7
[   791][I][show_desc.hpp:101] show_endpoint_desc(): [] bDescriptorType (endpoint): 5
[   799][I][show_desc.hpp:104] show_endpoint_desc(): [] bEndpointAddress(In): 0x81
[   806][I][show_desc.hpp:107] show_endpoint_desc(): [] bmAttributes(Interrupt): 0x03
[   814][I][show_desc.hpp:108] show_endpoint_desc(): [] wMaxPacketSize: 8
[   820][I][show_desc.hpp:109] show_endpoint_desc(): [] bInterval: 1
[   827][I][sketch_jul04a.ino:96] prepare_endpoint(): [] USB boot keyboard ready
[   834][I][show_desc.hpp:82] show_interface_desc(): [] bLength: 9
[   839][I][show_desc.hpp:83] show_interface_desc(): [] bDescriptorType (interface): 4
[   847][I][show_desc.hpp:84] show_interface_desc(): [] bInterfaceNumber: 1
[   854][I][show_desc.hpp:85] show_interface_desc(): [] bAlternateSetting: 0
[   861][I][show_desc.hpp:86] show_interface_desc(): [] bNumEndpoints: 1
[   867][I][show_desc.hpp:87] show_interface_desc(): [] bInterfaceClass: 0x03
[   874][I][show_desc.hpp:88] show_interface_desc(): [] bInterfaceSubClass: 0x01
[   881][I][show_desc.hpp:89] show_interface_desc(): [] bInterfaceProtocol: 0x02
[   888][I][show_desc.hpp:90] show_interface_desc(): [] iInterface: 0
[   894][I][show_desc.hpp:115] show_hid_desc(): [] bLength: 9
[   900][I][show_desc.hpp:116] show_hid_desc(): [] bDescriptorType (HID): 33
[   907][I][show_desc.hpp:117] show_hid_desc(): [] bcdHID: 0x0111
[   912][I][show_desc.hpp:118] show_hid_desc(): [] bCountryCode: 0
[   918][I][show_desc.hpp:119] show_hid_desc(): [] bNumDescriptor: 1
[   924][I][show_desc.hpp:120] show_hid_desc(): [] bDescriptorType: 34
[   931][I][show_desc.hpp:121] show_hid_desc(): [] wDescriptorLength: 77
[   937][I][show_desc.hpp:100] show_endpoint_desc(): [] bLength: 7
[   943][I][show_desc.hpp:101] show_endpoint_desc(): [] bDescriptorType (endpoint): 5
[   950][I][show_desc.hpp:104] show_endpoint_desc(): [] bEndpointAddress(In): 0x82
[   958][I][show_desc.hpp:107] show_endpoint_desc(): [] bmAttributes(Interrupt): 0x03
[   965][I][show_desc.hpp:108] show_endpoint_desc(): [] wMaxPacketSize: 8
[   972][I][show_desc.hpp:109] show_endpoint_desc(): [] bInterval: 10
[   978][I][show_desc.hpp:82] show_interface_desc(): [] bLength: 9
[   984][I][show_desc.hpp:83] show_interface_desc(): [] bDescriptorType (interface): 4
[   991][I][show_desc.hpp:84] show_interface_desc(): [] bInterfaceNumber: 2
[   998][I][show_desc.hpp:85] show_interface_desc(): [] bAlternateSetting: 0
[  1005][I][show_desc.hpp:86] show_interface_desc(): [] bNumEndpoints: 1
[  1011][I][show_desc.hpp:87] show_interface_desc(): [] bInterfaceClass: 0x03
[  1018][I][show_desc.hpp:88] show_interface_desc(): [] bInterfaceSubClass: 0x00
[  1025][I][show_desc.hpp:89] show_interface_desc(): [] bInterfaceProtocol: 0x00
[  1032][I][show_desc.hpp:90] show_interface_desc(): [] iInterface: 0
[  1039][I][show_desc.hpp:115] show_hid_desc(): [] bLength: 9
[  1044][I][show_desc.hpp:116] show_hid_desc(): [] bDescriptorType (HID): 33
[  1051][I][show_desc.hpp:117] show_hid_desc(): [] bcdHID: 0x0111
[  1057][I][show_desc.hpp:118] show_hid_desc(): [] bCountryCode: 0
[  1063][I][show_desc.hpp:119] show_hid_desc(): [] bNumDescriptor: 1
[  1069][I][show_desc.hpp:120] show_hid_desc(): [] bDescriptorType: 34
[  1075][I][show_desc.hpp:121] show_hid_desc(): [] wDescriptorLength: 54
[  1081][I][show_desc.hpp:100] show_endpoint_desc(): [] bLength: 7
[  1087][I][show_desc.hpp:101] show_endpoint_desc(): [] bDescriptorType (endpoint): 5
[  1095][I][show_desc.hpp:104] show_endpoint_desc(): [] bEndpointAddress(In): 0x83
[  1102][I][show_desc.hpp:107] show_endpoint_desc(): [] bmAttributes(Interrupt): 0x03
[  1110][I][show_desc.hpp:108] show_endpoint_desc(): [] wMaxPacketSize: 8
[  1116][I][show_desc.hpp:109] show_endpoint_desc(): [] bInterval: 10
[  1122][I][show_desc.hpp:82] show_interface_desc(): [] bLength: 9
[  1128][I][show_desc.hpp:83] show_interface_desc(): [] bDescriptorType (interface): 4
[  1136][I][show_desc.hpp:84] show_interface_desc(): [] bInterfaceNumber: 3
[  1143][I][show_desc.hpp:85] show_interface_desc(): [] bAlternateSetting: 0
[  1149][I][show_desc.hpp:86] show_interface_desc(): [] bNumEndpoints: 1
[  1156][I][show_desc.hpp:87] show_interface_desc(): [] bInterfaceClass: 0x03
[  1163][I][show_desc.hpp:88] show_interface_desc(): [] bInterfaceSubClass: 0x00
[  1170][I][show_desc.hpp:89] show_interface_desc(): [] bInterfaceProtocol: 0x00
[  1177][I][show_desc.hpp:90] show_interface_desc(): [] iInterface: 0
[  1183][I][show_desc.hpp:115] show_hid_desc(): [] bLength: 9
[  1188][I][show_desc.hpp:116] show_hid_desc(): [] bDescriptorType (HID): 33
[  1195][I][show_desc.hpp:117] show_hid_desc(): [] bcdHID: 0x0111
[  1201][I][show_desc.hpp:118] show_hid_desc(): [] bCountryCode: 0
[  1207][I][show_desc.hpp:119] show_hid_desc(): [] bNumDescriptor: 1
[  1213][I][show_desc.hpp:120] show_hid_desc(): [] bDescriptorType: 34
[  1219][I][show_desc.hpp:121] show_hid_desc(): [] wDescriptorLength: 57
[  1226][I][show_desc.hpp:100] show_endpoint_desc(): [] bLength: 7
[  1232][I][show_desc.hpp:101] show_endpoint_desc(): [] bDescriptorType (endpoint): 5
[  1239][I][show_desc.hpp:104] show_endpoint_desc(): [] bEndpointAddress(In): 0x84
[  1246][I][show_desc.hpp:107] show_endpoint_desc(): [] bmAttributes(Interrupt): 0x03
[  1254][I][show_desc.hpp:108] show_endpoint_desc(): [] wMaxPacketSize: 32
[  1261][I][show_desc.hpp:109] show_endpoint_desc(): [] bInterval: 1

luftaquila avatar Jul 05 '22 06:07 luftaquila

I tried a QMK keyboard and the 8 byte HID report shows up. However, QMK has so many options it is possible some combinations work and some do not.

I have a N-Key rollover keyboard that does not work. I suspect it needs the set_protocol to force it into HID Boot mode.

The demo code examples do not follow the recommendations in

https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/usb_host.html

so the demos are at a development dead end. I have no plans to add more features.

In keyboard_transfer_cb print out the value of transfer->actual_num_bytes. It might be greater than 8 so it is ignored. If USBH_HID_DEBUG is on, there should be message "Keyboard boot HID transfer too short or long".

If it is much longer, you can try to reverse engineer the format. For N-Key rollover, I have seen two variations. The HID boot format is 8 bytes with space for 6 key codes. In variation #1, the report is 63 bytes long instead of 8. The first two bytes are the same (modifier bit map and reserved=0) but the remaining 61 are for key codes. So as a many as 61 keys can be held down instead of 6.

The second variation, I think the report is about 14 bytes long. The report is a bit map with 1 bit per USB keycode.

touchgadget avatar Jul 05 '22 19:07 touchgadget

@touchgadget I found that keyboard_transfer_cb is not even called in any case. Maybe the set_protocol you mentioned will be needed. Thank you for your help.

luftaquila avatar Jul 09 '22 13:07 luftaquila

@touchgadget May I ask you which part of your code is an implementation of get_protocol?

luftaquila avatar Jul 12 '22 04:07 luftaquila