diff --git a/cores/esp32/esp32-hal-tinyusb.c b/cores/esp32/esp32-hal-tinyusb.c index 8bf9932d2e4..5f8ec77308d 100644 --- a/cores/esp32/esp32-hal-tinyusb.c +++ b/cores/esp32/esp32-hal-tinyusb.c @@ -651,7 +651,11 @@ static void usb_device_task(void *param) { #endif static bool tinyusb_is_initialized = false; -esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb) +esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb){ + return tinyusb_enable_interface2(interface, descriptor_len, cb, false); +} + +esp_err_t tinyusb_enable_interface2(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb, bool reserve_endpoints) { if(tinyusb_is_initialized){ log_e("TinyUSB has already started! Interface %s not enabled", (interface >= USB_INTERFACE_MAX)?"":tinyusb_interface_names[interface]); @@ -661,6 +665,13 @@ esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descr log_e("Interface %s invalid or already enabled", (interface >= USB_INTERFACE_MAX)?"":tinyusb_interface_names[interface]); return ESP_FAIL; } + if(interface == USB_INTERFACE_HID && reserve_endpoints){ + // Some simple PC BIOS requires specific endpoint addresses for keyboard at boot + if(!tinyusb_reserve_out_endpoint(1) ||!tinyusb_reserve_in_endpoint(1)){ + log_e("HID Reserve Endpoints Failed"); + return ESP_FAIL; + } + } if(interface == USB_INTERFACE_CDC){ if(!tinyusb_reserve_out_endpoint(3) ||!tinyusb_reserve_in_endpoint(4) || !tinyusb_reserve_in_endpoint(5)){ log_e("CDC Reserve Endpoints Failed"); diff --git a/cores/esp32/esp32-hal-tinyusb.h b/cores/esp32/esp32-hal-tinyusb.h index 84e156e874d..2ed1feb8a7f 100644 --- a/cores/esp32/esp32-hal-tinyusb.h +++ b/cores/esp32/esp32-hal-tinyusb.h @@ -94,6 +94,7 @@ typedef enum { typedef uint16_t (*tinyusb_descriptor_cb_t)(uint8_t * dst, uint8_t * itf); esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb); +esp_err_t tinyusb_enable_interface2(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb, bool reserve_endpoints); uint8_t tinyusb_add_string_descriptor(const char * str); uint8_t tinyusb_get_free_duplex_endpoint(void); uint8_t tinyusb_get_free_in_endpoint(void); diff --git a/libraries/USB/src/USBHID.cpp b/libraries/USB/src/USBHID.cpp index a5bdb2d6739..46b2e3876a8 100644 --- a/libraries/USB/src/USBHID.cpp +++ b/libraries/USB/src/USBHID.cpp @@ -39,6 +39,7 @@ static xSemaphoreHandle tinyusb_hid_device_input_sem = NULL; static xSemaphoreHandle tinyusb_hid_device_input_mutex = NULL; static bool tinyusb_hid_is_initialized = false; +static hid_interface_protocol_enum_t tinyusb_interface_protocol = HID_ITF_PROTOCOL_NONE; static uint8_t tinyusb_loaded_hid_devices_num = 0; static uint16_t tinyusb_hid_device_descriptor_len = 0; static uint8_t * tinyusb_hid_device_descriptor = NULL; @@ -173,7 +174,7 @@ static bool tinyusb_load_enabled_hid_devices(){ esp_hid_report_map_t *hid_report_map = esp_hid_parse_report_map(tinyusb_hid_device_descriptor, tinyusb_hid_device_descriptor_len); if(hid_report_map){ - log_d("Loaded HID Desriptor with the following reports:"); + log_d("Loaded HID Descriptor with the following reports:"); for(uint8_t i=0; ireports_len; i++){ if(hid_report_map->reports[i].protocol_mode == ESP_HID_PROTOCOL_MODE_REPORT){ log_d(" ID: %3u, Type: %7s, Size: %2u, Usage: %8s", @@ -201,14 +202,15 @@ extern "C" uint16_t tusb_hid_load_descriptor(uint8_t * dst, uint8_t * itf) tinyusb_hid_is_initialized = true; uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB HID"); - uint8_t ep_in = tinyusb_get_free_in_endpoint(); + // For keyboard boot protocol, we've already called tinyusb_enable_interface2(reserve_endpoints=true) + uint8_t ep_in = tinyusb_interface_protocol == HID_ITF_PROTOCOL_KEYBOARD ? 1 : tinyusb_get_free_in_endpoint(); TU_VERIFY (ep_in != 0); - uint8_t ep_out = tinyusb_get_free_out_endpoint(); + uint8_t ep_out = tinyusb_interface_protocol == HID_ITF_PROTOCOL_KEYBOARD ? 1 : tinyusb_get_free_out_endpoint(); TU_VERIFY (ep_out != 0); uint8_t descriptor[TUD_HID_INOUT_DESC_LEN] = { // HID Input & Output descriptor // Interface number, string index, protocol, report descriptor len, EP OUT & IN address, size & polling interval - TUD_HID_INOUT_DESCRIPTOR(*itf, str_index, HID_ITF_PROTOCOL_NONE, tinyusb_hid_device_descriptor_len, ep_out, (uint8_t)(0x80 | ep_in), 64, 1) + TUD_HID_INOUT_DESCRIPTOR(*itf, str_index, tinyusb_interface_protocol, tinyusb_hid_device_descriptor_len, ep_out, (uint8_t)(0x80 | ep_in), 64, 1) }; *itf+=1; memcpy(dst, descriptor, TUD_HID_INOUT_DESC_LEN); @@ -275,14 +277,15 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_ } } -USBHID::USBHID(){ +USBHID::USBHID(hid_interface_protocol_enum_t itf_protocol){ if(!tinyusb_hid_devices_is_initialized){ tinyusb_hid_devices_is_initialized = true; for(uint8_t i=0; i