本帖最后由 hztwb 于 2022-8-23 07:53 编辑
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode: DIO, clock div:1
load:0x3ffe6100,len:0x524
load:0x4004c000,len:0xa50
load:0x40050000,len:0x28cc
entry 0x4004c18c
E (9899) USBH: Device 1 gone
键盘插着的时候,按任意一键都没反应,拨下键盘USB口的时候串口输出“E (9899) USBH: Device 1 gone”
我烧录的是下面这个示例代码:
/*
* MIT License
*
* Copyright (c) 2021 touchgadgetdev@gmail.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <elapsedMillis.h>
#include <usb/usb_host.h>
#include "show_desc.hpp"
#include "usbhhelp.hpp"
bool isKeyboard = false;
bool isKeyboardReady = false;
uint8_t KeyboardInterval;
bool isKeyboardPolling = false;
elapsedMillis KeyboardTimer;
const size_t KEYBOARD_IN_BUFFER_SIZE = 8;
usb_transfer_t *KeyboardIn = NULL;
void keyboard_transfer_cb(usb_transfer_t *transfer)
{
if (Device_Handle == transfer->device_handle) {
isKeyboardPolling = false;
if (transfer->status == 0) {
if (transfer->actual_num_bytes == 8) {
uint8_t *const p = transfer->data_buffer;
ESP_LOGI("", "HID report: %02x %02x %02x %02x %02x %02x %02x %02x",
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
}
else {
ESP_LOGI("", "Keyboard boot hid transfer too short or long");
}
}
else {
ESP_LOGI("", "transfer->status %d", transfer->status);
}
}
}
void check_interface_desc_boot_keyboard(const void *p)
{
const usb_intf_desc_t *intf = (const usb_intf_desc_t *)p;
if ((intf->bInterfaceClass == USB_CLASS_HID) &&
(intf->bInterfaceSubClass == 1) &&
(intf->bInterfaceProtocol == 1)) {
isKeyboard = true;
ESP_LOGI("", "Claiming a boot keyboard!");
esp_err_t err = usb_host_interface_claim(Client_Handle, Device_Handle,
intf->bInterfaceNumber, intf->bAlternateSetting);
if (err != ESP_OK) ESP_LOGI("", "usb_host_interface_claim failed: %x", err);
}
}
void prepare_endpoint(const void *p)
{
const usb_ep_desc_t *endpoint = (const usb_ep_desc_t *)p;
esp_err_t err;
// must be interrupt for HID
if ((endpoint->bmAttributes & USB_BM_ATTRIBUTES_XFERTYPE_MASK) != USB_BM_ATTRIBUTES_XFER_INT) {
ESP_LOGI("", "Not interrupt endpoint: 0x%02x", endpoint->bmAttributes);
return;
}
if (endpoint->bEndpointAddress & USB_B_ENDPOINT_ADDRESS_EP_DIR_MASK) {
err = usb_host_transfer_alloc(KEYBOARD_IN_BUFFER_SIZE, 0, &KeyboardIn);
if (err != ESP_OK) {
KeyboardIn = NULL;
ESP_LOGI("", "usb_host_transfer_alloc In fail: %x", err);
return;
}
KeyboardIn->device_handle = Device_Handle;
KeyboardIn->bEndpointAddress = endpoint->bEndpointAddress;
KeyboardIn->callback = keyboard_transfer_cb;
KeyboardIn->context = NULL;
isKeyboardReady = true;
KeyboardInterval = endpoint->bInterval;
ESP_LOGI("", "USB boot keyboard ready");
}
else {
ESP_LOGI("", "Ignoring interrupt Out endpoint");
}
}
void show_config_desc_full(const usb_config_desc_t *config_desc)
{
// Full decode of config desc.
const uint8_t *p = &config_desc->val[0];
static uint8_t USB_Class = 0;
uint8_t bLength;
for (int i = 0; i < config_desc->wTotalLength; i+=bLength, p+=bLength) {
bLength = *p;
if ((i + bLength) <= config_desc->wTotalLength) {
const uint8_t bDescriptorType = *(p + 1);
switch (bDescriptorType) {
case USB_B_DESCRIPTOR_TYPE_DEVICE:
ESP_LOGI("", "USB Device Descriptor should not appear in config");
break;
case USB_B_DESCRIPTOR_TYPE_CONFIGURATION:
show_config_desc(p);
break;
case USB_B_DESCRIPTOR_TYPE_STRING:
ESP_LOGI("", "USB string desc TBD");
break;
case USB_B_DESCRIPTOR_TYPE_INTERFACE:
USB_Class = show_interface_desc(p);
check_interface_desc_boot_keyboard(p);
break;
case USB_B_DESCRIPTOR_TYPE_ENDPOINT:
show_endpoint_desc(p);
if (isKeyboard && KeyboardIn == NULL) prepare_endpoint(p);
break;
case USB_B_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
// Should not be config config?
ESP_LOGI("", "USB device qual desc TBD");
break;
case USB_B_DESCRIPTOR_TYPE_OTHER_SPEED_CONFIGURATION:
// Should not be config config?
ESP_LOGI("", "USB Other Speed TBD");
break;
case USB_B_DESCRIPTOR_TYPE_INTERFACE_POWER:
// Should not be config config?
ESP_LOGI("", "USB Interface Power TBD");
break;
case 0x21:
if (USB_Class == USB_CLASS_HID) {
show_hid_desc(p);
}
break;
default:
ESP_LOGI("", "Unknown USB Descriptor Type: 0x%x", bDescriptorType);
break;
}
}
else {
ESP_LOGI("", "USB Descriptor invalid");
return;
}
}
}
void setup()
{
usbh_setup(show_config_desc_full);
}
void loop()
{
usbh_task();
if (isKeyboardReady && !isKeyboardPolling && (KeyboardTimer > KeyboardInterval)) {
KeyboardIn->num_bytes = 8;
esp_err_t err = usb_host_transfer_submit(KeyboardIn);
if (err != ESP_OK) {
ESP_LOGI("", "usb_host_transfer_submit In fail: %x", err);
}
isKeyboardPolling = true;
KeyboardTimer = 0;
}
}
|