Files
JoyD/ESP32/my_usb_project/main/my_usb_project.c
2026-04-09 13:10:24 +08:00

212 lines
5.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "tinyusb.h"
#include "tusb.h"
#include "rust_app_wrapper.h"
static const char *TAG = "USB";
#define REPORT_ID_KEYBOARD 1
#define REPORT_ID_MOUSE 2
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + 2 * TUD_HID_DESC_LEN)
#define USB_VID 0x30D8
#define USB_PID 0x50A6
#define USB_BCD 0x0200
enum {
ITF_NUM_KEYBOARD, // 0
ITF_NUM_MOUSE, // 1
ITF_NUM_TOTAL
};
static tusb_desc_device_t const desc_device =
{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_VID,
.idProduct = USB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
// 独立键盘描述符
uint8_t const desc_hid_report_kb[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD))
};
// 独立鼠标描述符
uint8_t const desc_hid_report_mouse[] = {
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE))
};
// 按接口返回正确描述符
uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance)
{
if (instance == ITF_NUM_KEYBOARD) {
return desc_hid_report_kb;
}
if (instance == ITF_NUM_MOUSE) {
return desc_hid_report_mouse;
}
return NULL;
}
static char const *hid_string_descriptor[] = {
(char[]){0x09, 0x04}, // 0: 语言ID
"久鼎智控", // 1: 厂商
"智控键鼠套装", // 2: 产品
"1", // 3: 序列号
"HID 智控键盘", // 4: 键盘接口
"HID 智控鼠标", // 5: 鼠标接口
};
#define EPNUM_KEYBOARD 0x81
#define EPNUM_MOUSE 0x82
// ==============================
// 🔥 这里是修复重点!!!
// ==============================
static uint8_t const hid_configuration_descriptor[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// 键盘 HID 接口
TUD_HID_DESCRIPTOR(
ITF_NUM_KEYBOARD, // 接口号
4, // 字符串索引
0, // 协议 = 0必须
sizeof(desc_hid_report_kb),
EPNUM_KEYBOARD,
CFG_TUD_HID_EP_BUFSIZE,
10
),
// 鼠标 HID 接口
TUD_HID_DESCRIPTOR(
ITF_NUM_MOUSE, // 接口号
5, // 字符串索引
0, // 协议 = 0必须不能用 MOUSE 协议)
sizeof(desc_hid_report_mouse),
EPNUM_MOUSE,
CFG_TUD_HID_EP_BUFSIZE,
10
)
};
uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
{
(void) instance;
(void) report_id;
(void) report_type;
(void) buffer;
(void) reqlen;
return 0;
}
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
(void) instance;
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
}
// 暴露给 Rust 的函数
bool rust_is_usb_mounted() {
bool mounted = tud_mounted();
ESP_LOGD(TAG, "USB mounted state: %d", mounted);
return mounted;
}
//====================================================================
// 键盘函数(不动)
//====================================================================
void rust_send_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t const* keycode) {
tud_hid_keyboard_report(report_id, modifier, keycode);
}
//====================================================================
// 鼠标函数(正确 6 参数版)
//====================================================================
void rust_send_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t wheel, int8_t pan) {
tud_hid_mouse_report(report_id, buttons, x, y, wheel, pan);
}
// 暴露 FreeRTOS 函数给 Rust
void rust_vTaskDelay(uint32_t xTicksToDelay) {
vTaskDelay(xTicksToDelay);
}
// 暴露日志函数给 Rust
void rust_esp_log_i(const char* tag, const char* message) {
ESP_LOGI(tag, "%s", message);
}
void app_main(void)
{
ESP_LOGI(TAG, "USB 初始化");
const tinyusb_config_t tusb_cfg = {
.port = TINYUSB_PORT_FULL_SPEED_0,
.phy = {
.skip_setup = false,
.self_powered = false,
.vbus_monitor_io = 0,
},
.task = {
.size = 3500,
.priority = 14,
.xCoreID = 0,
},
.descriptor = {
.device = &desc_device,
.qualifier = NULL,
.string = hid_string_descriptor,
.string_count = sizeof(hid_string_descriptor)/sizeof(hid_string_descriptor[0]),
.full_speed_config = hid_configuration_descriptor,
.high_speed_config = NULL,
},
.event_cb = NULL,
.event_arg = NULL,
};
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
ESP_LOGI(TAG, "✅ USB HID 设备启动成功");
ESP_LOGI(TAG, "请连接 USB OTG 线到电脑");
rust_app_wrapper_init();
int count = 0;
bool last_mounted = false;
while (1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
bool mounted = tud_mounted();
if (mounted != last_mounted) {
if (mounted) {
ESP_LOGI(TAG, "🔌 USB 已连接到主机");
} else {
ESP_LOGI(TAG, "🔌 USB 已断开");
}
last_mounted = mounted;
}
if (count % 10 == 0) {
ESP_LOGI(TAG, "USB 设备运行中... 挂载状态: %s", mounted ? "已连接" : "未连接");
}
count++;
}
}