Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No keyboard_transfer_cb HID report on usbhhidboot #5

Open
luftaquila opened this issue Jul 5, 2022 · 3 comments
Open

No keyboard_transfer_cb HID report on usbhhidboot #5

luftaquila opened this issue Jul 5, 2022 · 3 comments

Comments

@luftaquila
Copy link

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
@touchgadget
Copy link
Owner

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.

@luftaquila
Copy link
Author

@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
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants