【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
前面我们开发esp32s3的usb功能时,当时就用了device功能。不过和stm32f103不同的是,esp32s3支持device,也支持host。所以,正好来看看怎么用esp32s3作为usb host,来访问其他usb设备。所有usb device当中,最有价值的其实是usb camera,当然这一点等后面再说。

题外话:
关于usb这些库的代码,类似于espressif_usb & espressif_usb_host_uvc,其实在managed_components里面都能找到,有时间的话,还是建议好好看一看。
1、准备typec转usb的模块
现在大部分esp32s3都是typec接口,但是很多usb device还是传统的usb接口,所以需要转接一下。
2、需要usb转ttl模块
之所以要这么一个模块,主要是加了typec转usb模块之后,另外一个烧录的usb口就不能用了,两个usb没有办法一起弄,毕竟typec转usb模块有点大。这种情况下就只能用usb转ttl模块代替,不仅负责烧入,还负责供电,5v供电。
3、用烙铁实现usb otg短接
短接的两个pin藏在模块下面,需要烙铁短接一下,这样板子才能给usb供电,很多朋友会忽视这一点。
4、更新idf_component.yml文件
要使用usb host,哪怕是最简单的hid,也要添加第三方库,这里注意添加一下,
## IDF Component Manager Manifest File
dependencies:
## Required IDF version
idf:
version: '>=4.1.0'
# # Put list of dependencies here
# # For components maintained by Espressif:
# component: "~1.0.0"
# # For 3rd party components:
# username/component: ">=1.0.0,<2.0.0"
# username2/component2:
# version: "~1.0.0"
# # For transient dependencies `public` flag can be set.
# # `public` flag doesn't have an effect dependencies of the `main` component.
# # All dependencies of `main` are public by default.
# public: true
lvgl/lvgl:
version: "^8.3.11"
espressif/esp_lvgl_port:
version: "^2.3.0"
espressif/w5500: ^1.0.0
usb_host_hid: "^1.0.1"
5、CMakeLists.txt文件
至于CMakeLists文件,可以复用之前的文件,
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "."
REQUIRES w5500 esp_eth esp_wifi esp_event esp_netif esp_http_server nvs_flash driver)
6、拷贝main.c代码
这里的代码不是ai生成的,而是直接从example获取的,原来的代码地址在这,
E:\software\esp32\esp\v6.0.1\esp-idf\examples\peripherals\usb\host\hid\main
大家可以根据自己的安装路径,灵活做出修改。为了方便大家,这里一并给出main.c文件,这样编译烧入之后,就可以插上鼠标测试了,
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "freertos/queue.h"
#include "esp_err.h"
#include "esp_log.h"
#include "usb/usb_host.h"
#include "errno.h"
#include "driver/gpio.h"
#include "usb/hid_host.h"
#include "usb/hid_usage_keyboard.h"
#include "usb/hid_usage_mouse.h"
/* GPIO Pin number for quit from example logic */
#define APP_QUIT_PIN GPIO_NUM_0
static const char *TAG = "example";
QueueHandle_t app_event_queue = NULL;
/**
* @brief APP event group
*
* Application logic can be different. There is a one among other ways to distinguish the
* event by application event group.
* In this example we have two event groups:
* APP_EVENT - General event, which is APP_QUIT_PIN press event (Generally, it is IO0).
* APP_EVENT_HID_HOST - HID Host Driver event, such as device connection/disconnection or input report.
*/
typedef enum {
APP_EVENT = 0,
APP_EVENT_HID_HOST
} app_event_group_t;
/**
* @brief APP event queue
*
* This event is used for delivering the HID Host event from callback to a task.
*/
typedef struct {
app_event_group_t event_group;
/* HID Host - Device related info */
struct {
hid_host_device_handle_t handle;
hid_host_driver_event_t event;
void *arg;
} hid_host_device;
} app_event_queue_t;
/**
* @brief HID Protocol string names
*/
static const char *hid_proto_name_str[] = {
"NONE",
"KEYBOARD",
"MOUSE"
};
/**
* @brief Key event
*/
typedef struct {
enum key_state {
KEY_STATE_PRESSED = 0x00,
KEY_STATE_RELEASED = 0x01
} state;
uint8_t modifier;
uint8_t key_code;
} key_event_t;
/* Main char symbol for ENTER key */
#define KEYBOARD_ENTER_MAIN_CHAR '\r'
/* When set to 1 pressing ENTER will be extending with LineFeed during serial debug output */
#define KEYBOARD_ENTER_LF_EXTEND 1
/* When set to 1, numbers entered from the numeric keypad while ALT is pressed will be escaped */
#define KEYBOARD_ENTER_ALT_ESCAPE 1
#if KEYBOARD_ENTER_ALT_ESCAPE
static bool is_ansi = false;
static unsigned int alt_code = 0;
#endif
/**
* @brief Scancode to ascii table
*/
const uint8_t keycode2ascii [57][2] = {
{0, 0}, /* HID_KEY_NO_PRESS */
{0, 0}, /* HID_KEY_ROLLOVER */
{0, 0}, /* HID_KEY_POST_FAIL */
{0, 0}, /* HID_KEY_ERROR_UNDEFINED */
{'a', 'A'}, /* HID_KEY_A */
{'b', 'B'}, /* HID_KEY_B */
{'c', 'C'}, /* HID_KEY_C */
{'d', 'D'}, /* HID_KEY_D */
{'e', 'E'}, /* HID_KEY_E */
{'f', 'F'}, /* HID_KEY_F */
{'g', 'G'}, /* HID_KEY_G */
{'h', 'H'}, /* HID_KEY_H */
{'i', 'I'}, /* HID_KEY_I */
{'j', 'J'}, /* HID_KEY_J */
{'k', 'K'}, /* HID_KEY_K */
{'l', 'L'}, /* HID_KEY_L */
{'m', 'M'}, /* HID_KEY_M */
{'n', 'N'}, /* HID_KEY_N */
{'o', 'O'}, /* HID_KEY_O */
{'p', 'P'}, /* HID_KEY_P */
{'q', 'Q'}, /* HID_KEY_Q */
{'r', 'R'}, /* HID_KEY_R */
{'s', 'S'}, /* HID_KEY_S */
{'t', 'T'}, /* HID_KEY_T */
{'u', 'U'}, /* HID_KEY_U */
{'v', 'V'}, /* HID_KEY_V */
{'w', 'W'}, /* HID_KEY_W */
{'x', 'X'}, /* HID_KEY_X */
{'y', 'Y'}, /* HID_KEY_Y */
{'z', 'Z'}, /* HID_KEY_Z */
{'1', '!'}, /* HID_KEY_1 */
{'2', '@'}, /* HID_KEY_2 */
{'3', '#'}, /* HID_KEY_3 */
{'4', '$'}, /* HID_KEY_4 */
{'5', '%'}, /* HID_KEY_5 */
{'6', '^'}, /* HID_KEY_6 */
{'7', '&'}, /* HID_KEY_7 */
{'8', '*'}, /* HID_KEY_8 */
{'9', '('}, /* HID_KEY_9 */
{'0', ')'}, /* HID_KEY_0 */
{KEYBOARD_ENTER_MAIN_CHAR, KEYBOARD_ENTER_MAIN_CHAR}, /* HID_KEY_ENTER */
{0, 0}, /* HID_KEY_ESC */
{'\b', 0}, /* HID_KEY_DEL */
{0, 0}, /* HID_KEY_TAB */
{' ', ' '}, /* HID_KEY_SPACE */
{'-', '_'}, /* HID_KEY_MINUS */
{'=', '+'}, /* HID_KEY_EQUAL */
{'[', '{'}, /* HID_KEY_OPEN_BRACKET */
{']', '}'}, /* HID_KEY_CLOSE_BRACKET */
{'\\', '|'}, /* HID_KEY_BACK_SLASH */
{'\\', '|'}, /* HID_KEY_SHARP */ // HOTFIX: for NonUS Keyboards repeat HID_KEY_BACK_SLASH
{';', ':'}, /* HID_KEY_COLON */
{'\'', '"'}, /* HID_KEY_QUOTE */
{'`', '~'}, /* HID_KEY_TILDE */
{',', '<'}, /* HID_KEY_LESS */
{'.', '>'}, /* HID_KEY_GREATER */
{'/', '?'} /* HID_KEY_SLASH */
};
/**
* @brief HID Keyboard print char symbol
*
* @param[in] key_char Keyboard char to stdout
*/
static inline void hid_keyboard_print_char(unsigned int key_char)
{
if (!!key_char) {
putchar(key_char);
#if (KEYBOARD_ENTER_LF_EXTEND)
if (KEYBOARD_ENTER_MAIN_CHAR == key_char) {
putchar('\n');
}
#endif // KEYBOARD_ENTER_LF_EXTEND
fflush(stdout);
}
}
/**
* @brief Makes new line depending on report output protocol type
*
* @param[in] proto Current protocol to output
*/
static void hid_print_new_device_report_header(hid_protocol_t proto)
{
static hid_protocol_t prev_proto_output = -1;
if (prev_proto_output != proto) {
prev_proto_output = proto;
printf("\r\n");
if (proto == HID_PROTOCOL_MOUSE) {
printf("Mouse\r\n");
} else if (proto == HID_PROTOCOL_KEYBOARD) {
printf("Keyboard\r\n");
} else {
printf("Generic\r\n");
}
fflush(stdout);
}
}
/**
* @brief HID Keyboard modifier verification for capitalization application (right or left shift)
*
* @param[in] modifier
* @return true Modifier was pressed (left or right shift)
* @return false Modifier was not pressed (left or right shift)
*
*/
static inline bool hid_keyboard_is_modifier_shift(uint8_t modifier)
{
if (((modifier & HID_LEFT_SHIFT) == HID_LEFT_SHIFT) ||
((modifier & HID_RIGHT_SHIFT) == HID_RIGHT_SHIFT)) {
return true;
}
return false;
}
#if KEYBOARD_ENTER_ALT_ESCAPE
/**
* @brief HID Keyboard modifier verification for capitalization application (right or left alt)
*
* @param[in] modifier
* @return true Modifier was pressed (left or right alt)
* @return false Modifier was not pressed (left or right alt)
*
*/
static inline bool hid_keyboard_is_modifier_alt(uint8_t modifier)
{
if (((modifier & HID_LEFT_ALT) == HID_LEFT_ALT) ||
((modifier & HID_RIGHT_ALT) == HID_RIGHT_ALT)) {
return true;
}
return false;
}
/**
* @brief HID Keyboard alt code process(Called when ALT is pressed)
*
* @param[in] key_code Entered key value
* @return true Key values that qualify for ALT escape processing
* @return false Key values that do not comply with ALT escape processing
*
*/
static inline bool hid_keyboard_alt_code_processing(uint8_t key_code)
{
if ((key_code < HID_KEY_KEYPAD_1) || (key_code > HID_KEY_KEYPAD_0)) {
return false;
}
if (key_code == HID_KEY_KEYPAD_0) {
if (alt_code == 0) {
is_ansi = true;
return true;
}
/* Note: Since the keyboard code 0 of the numeric keypad is not keyboard code 1 minus 1, the
* conversion is performed here to facilitate subsequent calculations of the input numbers.
*/
key_code = HID_KEY_KEYPAD_1 - 1;
}
alt_code = alt_code * 10 + (key_code - (HID_KEY_KEYPAD_1 - 1));
return true;
}
/**
* @brief HID Keyboard alt code process complete(Called when ALT is not pressed)
*/
static inline void hid_keyboard_alt_code_process_complete(void)
{
if (alt_code > 0) {
alt_code = alt_code & 0xff;
if (is_ansi || alt_code == 0) {
char utf8_buffer[8] = { 0 };
if (alt_code == 0) {
alt_code = 0x100;
}
//ANSI is processed as UTF8
if (alt_code <= 0x7F) {
utf8_buffer[0] = (char)alt_code;
} else {
utf8_buffer[0] = 0xC0 | ((alt_code >> 6) & 0x1F);
utf8_buffer[1] = 0x80 | (alt_code & 0x3F);
}
printf("%s", utf8_buffer);
fflush(stdout);
} else {
hid_keyboard_print_char(alt_code);
}
alt_code = 0;
}
is_ansi = false;
}
#endif
/**
* @brief HID Keyboard get char symbol from key code
*
* @param[in] modifier Keyboard modifier data
* @param[in] key_code Keyboard key code
* @param[in] key_char Pointer to key char data
*
* @return true Key scancode converted successfully
* @return false Key scancode unknown
*/
static inline bool hid_keyboard_get_char(uint8_t modifier,
uint8_t key_code,
unsigned char *key_char)
{
uint8_t mod = (hid_keyboard_is_modifier_shift(modifier)) ? 1 : 0;
#if KEYBOARD_ENTER_ALT_ESCAPE
if (hid_keyboard_is_modifier_alt(modifier)) {
// ALT modifier is still pressed
if (hid_keyboard_alt_code_processing(key_code)) {
// ALT code processed, no need to go further
return false;
}
}
#endif
if ((key_code >= HID_KEY_A) && (key_code <= HID_KEY_SLASH)) {
*key_char = keycode2ascii[key_code][mod];
} else {
// All other key pressed
return false;
}
return true;
}
/**
* @brief Key Event. Key event with the key code, state and modifier.
*
* @param[in] key_event Pointer to Key Event structure
*
*/
static void key_event_callback(key_event_t *key_event)
{
unsigned char key_char;
hid_print_new_device_report_header(HID_PROTOCOL_KEYBOARD);
if (KEY_STATE_PRESSED == key_event->state) {
if (hid_keyboard_get_char(key_event->modifier,
key_event->key_code, &key_char)) {
hid_keyboard_print_char(key_char);
}
}
}
/**
* @brief Key buffer scan code search.
*
* @param[in] src Pointer to source buffer where to search
* @param[in] key Key scancode to search
* @param[in] length Size of the source buffer
*/
static inline bool key_found(const uint8_t *const src,
uint8_t key,
unsigned int length)
{
for (unsigned int i = 0; i < length; i++) {
if (src[i] == key) {
return true;
}
}
return false;
}
/**
* @brief USB HID Host Keyboard Interface report callback handler
*
* @param[in] data Pointer to input report data buffer
* @param[in] length Length of input report data buffer
*/
static void hid_host_keyboard_report_callback(const uint8_t *const data, const int length)
{
hid_keyboard_input_report_boot_t *kb_report = (hid_keyboard_input_report_boot_t *)data;
if (length < sizeof(hid_keyboard_input_report_boot_t)) {
return;
}
static uint8_t prev_keys[HID_KEYBOARD_KEY_MAX] = { 0 };
key_event_t key_event;
#if KEYBOARD_ENTER_ALT_ESCAPE
if (!hid_keyboard_is_modifier_alt(kb_report->modifier.val)) {
hid_keyboard_alt_code_process_complete();
}
#endif
for (int i = 0; i < HID_KEYBOARD_KEY_MAX; i++) {
// key has been released verification
if (prev_keys[i] > HID_KEY_ERROR_UNDEFINED &&
!key_found(kb_report->key, prev_keys[i], HID_KEYBOARD_KEY_MAX)) {
key_event.key_code = prev_keys[i];
key_event.modifier = 0;
key_event.state = KEY_STATE_RELEASED;
key_event_callback(&key_event);
}
// key has been pressed verification
if (kb_report->key[i] > HID_KEY_ERROR_UNDEFINED &&
!key_found(prev_keys, kb_report->key[i], HID_KEYBOARD_KEY_MAX)) {
key_event.key_code = kb_report->key[i];
key_event.modifier = kb_report->modifier.val;
key_event.state = KEY_STATE_PRESSED;
key_event_callback(&key_event);
}
}
memcpy(prev_keys, &kb_report->key, HID_KEYBOARD_KEY_MAX);
}
/**
* @brief USB HID Host Mouse Interface report callback handler
*
* @param[in] data Pointer to input report data buffer
* @param[in] length Length of input report data buffer
*/
static void hid_host_mouse_report_callback(const uint8_t *const data, const int length)
{
hid_mouse_input_report_boot_t *mouse_report = (hid_mouse_input_report_boot_t *)data;
if (length < sizeof(hid_mouse_input_report_boot_t)) {
return;
}
static int x_pos = 0;
static int y_pos = 0;
// Calculate absolute position from displacement
x_pos += mouse_report->x_displacement;
y_pos += mouse_report->y_displacement;
hid_print_new_device_report_header(HID_PROTOCOL_MOUSE);
printf("X: %06d\tY: %06d\t|%c|%c|\r",
x_pos, y_pos,
(mouse_report->buttons.button1 ? 'o' : ' '),
(mouse_report->buttons.button2 ? 'o' : ' '));
fflush(stdout);
}
/**
* @brief USB HID Host Generic Interface report callback handler
*
* 'generic' means anything else than mouse or keyboard
*
* @param[in] data Pointer to input report data buffer
* @param[in] length Length of input report data buffer
*/
static void hid_host_generic_report_callback(const uint8_t *const data, const int length)
{
hid_print_new_device_report_header(HID_PROTOCOL_NONE);
for (int i = 0; i < length; i++) {
printf("%02X", data[i]);
}
putchar('\r');
}
/**
* @brief USB HID Host interface callback
*
* @param[in] hid_device_handle HID Device handle
* @param[in] event HID Host interface event
* @param[in] arg Pointer to arguments, does not used
*/
void hid_host_interface_callback(hid_host_device_handle_t hid_device_handle,
const hid_host_interface_event_t event,
void *arg)
{
uint8_t data[64] = { 0 };
size_t data_length = 0;
hid_host_dev_params_t dev_params;
ESP_ERROR_CHECK(hid_host_device_get_params(hid_device_handle, &dev_params));
switch (event) {
case HID_HOST_INTERFACE_EVENT_INPUT_REPORT:
ESP_ERROR_CHECK(hid_host_device_get_raw_input_report_data(hid_device_handle,
data,
64,
&data_length));
if (HID_SUBCLASS_BOOT_INTERFACE == dev_params.sub_class) {
if (HID_PROTOCOL_KEYBOARD == dev_params.proto) {
hid_host_keyboard_report_callback(data, data_length);
} else if (HID_PROTOCOL_MOUSE == dev_params.proto) {
hid_host_mouse_report_callback(data, data_length);
}
} else {
hid_host_generic_report_callback(data, data_length);
}
break;
case HID_HOST_INTERFACE_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HID Device, protocol '%s' DISCONNECTED",
hid_proto_name_str[dev_params.proto]);
ESP_ERROR_CHECK(hid_host_device_close(hid_device_handle));
break;
case HID_HOST_INTERFACE_EVENT_TRANSFER_ERROR:
ESP_LOGI(TAG, "HID Device, protocol '%s' TRANSFER_ERROR",
hid_proto_name_str[dev_params.proto]);
break;
default:
ESP_LOGW(TAG, "HID Device, protocol '%s' Unhandled event: %d (possibly suspend/resume)",
hid_proto_name_str[dev_params.proto],
event);
break;
}
}
/**
* @brief USB HID Host Device event
*
* @param[in] hid_device_handle HID Device handle
* @param[in] event HID Host Device event
* @param[in] arg Pointer to arguments, does not used
*/
void hid_host_device_event(hid_host_device_handle_t hid_device_handle,
const hid_host_driver_event_t event,
void *arg)
{
hid_host_dev_params_t dev_params;
ESP_ERROR_CHECK(hid_host_device_get_params(hid_device_handle, &dev_params));
switch (event) {
case HID_HOST_DRIVER_EVENT_CONNECTED:
ESP_LOGI(TAG, "HID Device, protocol '%s' CONNECTED",
hid_proto_name_str[dev_params.proto]);
const hid_host_device_config_t dev_config = {
.callback = hid_host_interface_callback,
.callback_arg = NULL
};
if (dev_params.proto != HID_PROTOCOL_NONE) {
ESP_ERROR_CHECK(hid_host_device_open(hid_device_handle, &dev_config));
if (HID_SUBCLASS_BOOT_INTERFACE == dev_params.sub_class) {
ESP_ERROR_CHECK(hid_class_request_set_protocol(hid_device_handle, HID_REPORT_PROTOCOL_BOOT));
if (HID_PROTOCOL_KEYBOARD == dev_params.proto) {
ESP_ERROR_CHECK(hid_class_request_set_idle(hid_device_handle, 0, 0));
}
}
ESP_ERROR_CHECK(hid_host_device_start(hid_device_handle));
}
break;
default:
break;
}
}
/**
* @brief Start USB Host install and handle common USB host library events while app pin not low
*
* @param[in] arg Not used
*/
static void usb_lib_task(void *arg)
{
const usb_host_config_t host_config = {
.skip_phy_setup = false,
.intr_flags = ESP_INTR_FLAG_LOWMED,
};
ESP_ERROR_CHECK(usb_host_install(&host_config));
xTaskNotifyGive(arg);
while (true) {
uint32_t event_flags;
usb_host_lib_handle_events(portMAX_DELAY, &event_flags);
// In this example, there is only one client registered
// So, once we deregister the client, this call must succeed with ESP_OK
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
ESP_ERROR_CHECK(usb_host_device_free_all());
break;
}
}
ESP_LOGI(TAG, "USB shutdown");
// Clean up USB Host
vTaskDelay(10); // Short delay to allow clients clean-up
ESP_ERROR_CHECK(usb_host_uninstall());
vTaskDelete(NULL);
}
/**
* @brief BOOT button pressed callback
*
* Signal application to exit the HID Host task
*
* @param[in] arg Unused
*/
static void gpio_isr_cb(void *arg)
{
BaseType_t xTaskWoken = pdFALSE;
const app_event_queue_t evt_queue = {
.event_group = APP_EVENT,
};
if (app_event_queue) {
xQueueSendFromISR(app_event_queue, &evt_queue, &xTaskWoken);
}
if (xTaskWoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
/**
* @brief HID Host Device callback
*
* Puts new HID Device event to the queue
*
* @param[in] hid_device_handle HID Device handle
* @param[in] event HID Device event
* @param[in] arg Not used
*/
void hid_host_device_callback(hid_host_device_handle_t hid_device_handle,
const hid_host_driver_event_t event,
void *arg)
{
const app_event_queue_t evt_queue = {
.event_group = APP_EVENT_HID_HOST,
// HID Host Device related info
.hid_host_device.handle = hid_device_handle,
.hid_host_device.event = event,
.hid_host_device.arg = arg
};
if (app_event_queue) {
xQueueSend(app_event_queue, &evt_queue, 0);
}
}
void app_main(void)
{
BaseType_t task_created;
app_event_queue_t evt_queue;
ESP_LOGI(TAG, "HID Host example");
// Init BOOT button: Pressing the button simulates app request to exit
// It will disconnect the USB device and uninstall the HID driver and USB Host Lib
const gpio_config_t input_pin = {
.pin_bit_mask = BIT64(APP_QUIT_PIN),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.intr_type = GPIO_INTR_NEGEDGE,
};
ESP_ERROR_CHECK(gpio_config(&input_pin));
ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LOWMED));
ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_isr_cb, NULL));
/*
* Create usb_lib_task to:
* - initialize USB Host library
* - Handle USB Host events while APP pin in in HIGH state
*/
task_created = xTaskCreatePinnedToCore(usb_lib_task,
"usb_events",
4096,
xTaskGetCurrentTaskHandle(),
2, NULL, 0);
assert(task_created == pdTRUE);
// Wait for notification from usb_lib_task to proceed
ulTaskNotifyTake(false, 1000);
/*
* HID host driver configuration
* - create background task for handling low level event inside the HID driver
* - provide the device callback to get new HID Device connection event
*/
const hid_host_driver_config_t hid_host_driver_config = {
.create_background_task = true,
.task_priority = 5,
.stack_size = 4096,
.core_id = 0,
.callback = hid_host_device_callback,
.callback_arg = NULL
};
ESP_ERROR_CHECK(hid_host_install(&hid_host_driver_config));
// Create queue
app_event_queue = xQueueCreate(10, sizeof(app_event_queue_t));
ESP_LOGI(TAG, "Waiting for HID Device to be connected");
while (1) {
// Wait queue
if (xQueueReceive(app_event_queue, &evt_queue, portMAX_DELAY)) {
if (APP_EVENT == evt_queue.event_group) {
// User pressed button
usb_host_lib_info_t lib_info;
ESP_ERROR_CHECK(usb_host_lib_info(&lib_info));
if (lib_info.num_devices == 0) {
// End while cycle
break;
} else {
ESP_LOGW(TAG, "To shutdown example, remove all USB devices and press button again.");
// Keep polling
}
}
if (APP_EVENT_HID_HOST == evt_queue.event_group) {
hid_host_device_event(evt_queue.hid_host_device.handle,
evt_queue.hid_host_device.event,
evt_queue.hid_host_device.arg);
}
}
}
ESP_LOGI(TAG, "HID Driver uninstall");
ESP_ERROR_CHECK(hid_host_uninstall());
gpio_isr_handler_remove(APP_QUIT_PIN);
xQueueReset(app_event_queue);
vQueueDelete(app_event_queue);
}
7、测试
测试的时候就是要注意一下怎么用usb转ttl模块进行测试,烧入后手动复位。最后,就是typec接口要插好,确认鼠标供电ok。这样复位后,就很容易看到monitor这边的打印,鼠标移动后,也会有对应的x和y输出。
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0x1 (POWERON),boot:0xb (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce2820,len:0x14f0
load:0x403c8700,len:0xda0
load:0x403cb700,len:0x2f58
entry 0x403c8908
I (24) boot: ESP-IDF v6.0.1 2nd stage bootloader
I (25) boot: compile time Jul 19 2026 08:17:49
I (25) boot: Multicore bootloader
I (25) boot: chip revision: v0.2
I (28) boot: efuse block revision: v1.3
I (31) boot.esp32s3: Boot SPI Speed : 80MHz
I (35) boot.esp32s3: SPI Mode : DIO
I (39) boot.esp32s3: SPI Flash Size : 2MB
I (43) boot: Enabling RNG early entropy source...
I (47) boot: Partition Table:
I (50) boot: ## Label Usage Type ST Offset Length
I (56) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (63) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (69) boot: 2 factory factory app 00 00 00010000 00100000
I (76) boot: End of partition table
I (79) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0ddc4h ( 56772) map
I (97) esp_image: segment 1: paddr=0001ddec vaddr=3fc90800 size=0222ch ( 8748) load
I (99) esp_image: segment 2: paddr=00020020 vaddr=42000020 size=1dc14h (121876) map
I (123) esp_image: segment 3: paddr=0003dc3c vaddr=3fc92a2c size=00ed0h ( 3792) load
I (124) esp_image: segment 4: paddr=0003eb14 vaddr=40374000 size=0c744h ( 51012) load
I (138) esp_image: segment 5: paddr=0004b260 vaddr=50000000 size=00024h ( 36) load
I (144) boot: Loaded app from partition at offset 0x10000
I (144) boot: Disabling RNG early entropy source...
I (156) cpu_start: Multicore app
I (164) cpu_start: GPIO 44 and 43 are used as console UART I/O pins
I (165) cpu_start: Pro cpu start user code
I (165) cpu_start: cpu freq: 160000000 Hz
I (167) app_init: Application information:
I (170) app_init: Project name: my_project
I (175) app_init: App version: 1
I (178) app_init: Compile time: Jul 19 2026 08:47:11
I (183) app_init: ELF file SHA256: 454273d86...
I (187) app_init: ESP-IDF: v6.0.1
I (191) efuse_init: Min chip rev: v0.0
I (195) efuse_init: Max chip rev: v0.99
I (199) efuse_init: Chip rev: v0.2
I (203) heap_init: Initializing. RAM available for dynamic allocation:
I (209) heap_init: At 3FC94470 len 000552A0 (340 KiB): RAM
I (214) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
I (219) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (225) heap_init: At 600FE000 len 00001FE8 (7 KiB): RTCRAM
I (231) spi_flash: detected chip: gd
I (233) spi_flash: flash io: dio
W (236) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
I (249) sleep_gpio: Configure to isolate all GPIO pins in sleep state
I (255) sleep_gpio: Enable automatic switching of GPIO sleep configuration
I (262) main_task: Started on CPU0
I (282) main_task: Calling app_main()
I (282) example: HID Host example
I (312) example: Waiting for HID Device to be connected
I (1932) example: HID Device, protocol 'MOUSE' CONNECTED
Mouse
X: 000335 Y: -00047 | | |

被折叠的 条评论
为什么被折叠?



