feat: 添加HID传输管理和旋转编码器支持
添加了hid_tx_event和hid_tx_done_event事件类型,用于统一管理HID 数据传输,并在ble_hid_module和usb_hid_module中实现相应的处理逻辑。 新增qdec_module模块来处理旋转编码器输入,将旋转事件转换为步进事件, 并在keyboard_module中集成音量控制功能。 更新CMakeLists.txt以包含新的事件和模块文件,在app.overlay中启 用qdec设备,并在prj.conf中添加SENSOR配置。 BREAKING CHANGE: 将原有的hid_boot_event和hid_report_event替换 为统一的hid_tx_event事件系统。
This commit is contained in:
@@ -15,7 +15,8 @@
|
||||
#include "hid_report_descriptor.h"
|
||||
#include "hid_boot_event.h"
|
||||
#include "hid_protocol_event.h"
|
||||
#include "hid_report_event.h"
|
||||
#include "hid_tx_done_event.h"
|
||||
#include "hid_tx_event.h"
|
||||
#include "keyboard_led_event.h"
|
||||
#include "mode_event.h"
|
||||
|
||||
@@ -67,6 +68,11 @@ static struct usb_hid_ctx g_usb_hid = {
|
||||
.current_protocol = HID_PROTO_REPORT,
|
||||
};
|
||||
|
||||
static void submit_usb_tx_done(enum hid_tx_kind kind, bool success)
|
||||
{
|
||||
hid_tx_done_event_submit(kind, success);
|
||||
}
|
||||
|
||||
USBD_DEVICE_DEFINE(new_kbd_usbd,
|
||||
DEVICE_DT_GET(DT_NODELABEL(usbd)),
|
||||
APP_USB_VID, APP_USB_PID);
|
||||
@@ -242,6 +248,9 @@ static void hid_stub_input_done(const struct device *dev, const uint8_t *report)
|
||||
|
||||
if (iface) {
|
||||
iface->in_flight = false;
|
||||
submit_usb_tx_done((dev == g_usb_hid.boot.dev) ?
|
||||
HID_TX_KIND_BOOT : HID_TX_KIND_REPORT,
|
||||
true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -596,73 +605,76 @@ static bool handle_wake_up_event(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool handle_hid_boot_event(const struct hid_boot_event *event)
|
||||
static bool handle_hid_tx_event(const struct hid_tx_event *event)
|
||||
{
|
||||
if (!g_usb_hid.policy.usb_mode_selected || !usb_hid_stack_is_active()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usb_hid.current_protocol != HID_PROTO_BOOT) {
|
||||
if (event->kind == HID_TX_KIND_BOOT) {
|
||||
const uint8_t *payload = hid_tx_event_get_data(event);
|
||||
size_t payload_len = hid_tx_event_get_size(event);
|
||||
int err;
|
||||
|
||||
if (g_usb_hid.current_protocol != HID_PROTO_BOOT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!g_usb_hid.boot.iface_ready || !g_usb_hid.boot.dev) {
|
||||
submit_usb_tx_done(HID_TX_KIND_BOOT, false);
|
||||
return false;
|
||||
}
|
||||
if (g_usb_hid.boot.in_flight) {
|
||||
LOG_WRN("Drop boot tx: previous report not sent");
|
||||
submit_usb_tx_done(HID_TX_KIND_BOOT, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = hid_device_submit_report(g_usb_hid.boot.dev,
|
||||
payload_len,
|
||||
payload);
|
||||
if (err) {
|
||||
LOG_WRN("USB boot report send failed err=%d", err);
|
||||
submit_usb_tx_done(HID_TX_KIND_BOOT, false);
|
||||
} else {
|
||||
g_usb_hid.boot.in_flight = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *payload = hid_boot_event_get_data(event);
|
||||
size_t payload_len = hid_boot_event_get_size(event);
|
||||
|
||||
if (!g_usb_hid.boot.iface_ready || !g_usb_hid.boot.dev) {
|
||||
return false;
|
||||
}
|
||||
if (g_usb_hid.boot.in_flight) {
|
||||
LOG_WRN("Drop boot report: previous report not sent");
|
||||
return false;
|
||||
}
|
||||
|
||||
int err = hid_device_submit_report(g_usb_hid.boot.dev,
|
||||
payload_len,
|
||||
payload);
|
||||
if (err) {
|
||||
LOG_WRN("USB boot report send failed err=%d", err);
|
||||
} else {
|
||||
g_usb_hid.boot.in_flight = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool handle_hid_report_event(const struct hid_report_event *event)
|
||||
{
|
||||
/*
|
||||
* USB 侧仅在 active 条件满足时发送:
|
||||
* - 当前 mode 为 USB;
|
||||
* - USB HID 栈已启用且对应接口 ready。
|
||||
*/
|
||||
if (!g_usb_hid.policy.usb_mode_selected || !usb_hid_stack_is_active()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_usb_hid.current_protocol != HID_PROTO_REPORT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *data = hid_report_event_get_data(event);
|
||||
size_t data_len = hid_report_event_get_size(event);
|
||||
const uint8_t *data = hid_tx_event_get_data(event);
|
||||
size_t data_len = hid_tx_event_get_size(event);
|
||||
uint8_t report_id;
|
||||
|
||||
if (data_len < 1U) {
|
||||
submit_usb_tx_done(HID_TX_KIND_REPORT, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
report_id = data[0];
|
||||
|
||||
if (!g_usb_hid.nkro.iface_ready || !g_usb_hid.nkro.dev) {
|
||||
submit_usb_tx_done(HID_TX_KIND_REPORT, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((report_id != REPORT_ID_KEYBOARD) && (report_id != REPORT_ID_CONSUMER)) {
|
||||
submit_usb_tx_done(HID_TX_KIND_REPORT, false);
|
||||
return false;
|
||||
}
|
||||
if (g_usb_hid.nkro.in_flight) {
|
||||
LOG_WRN("Drop report id=0x%02x: previous report not sent", report_id);
|
||||
LOG_WRN("Drop tx report id=0x%02x: previous report not sent", report_id);
|
||||
submit_usb_tx_done(HID_TX_KIND_REPORT, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -670,6 +682,7 @@ static bool handle_hid_report_event(const struct hid_report_event *event)
|
||||
int err = hid_device_submit_report(g_usb_hid.nkro.dev, data_len, data);
|
||||
if (err) {
|
||||
LOG_WRN("USB report send failed id=0x%02x err=%d", report_id, err);
|
||||
submit_usb_tx_done(HID_TX_KIND_REPORT, false);
|
||||
} else {
|
||||
g_usb_hid.nkro.in_flight = true;
|
||||
}
|
||||
@@ -695,12 +708,8 @@ static bool app_event_handler(const struct app_event_header *aeh)
|
||||
return handle_wake_up_event();
|
||||
}
|
||||
|
||||
if (is_hid_report_event(aeh)) {
|
||||
return handle_hid_report_event(cast_hid_report_event(aeh));
|
||||
}
|
||||
|
||||
if (is_hid_boot_event(aeh)) {
|
||||
return handle_hid_boot_event(cast_hid_boot_event(aeh));
|
||||
if (is_hid_tx_event(aeh)) {
|
||||
return handle_hid_tx_event(cast_hid_tx_event(aeh));
|
||||
}
|
||||
|
||||
__ASSERT_NO_MSG(false);
|
||||
@@ -712,5 +721,4 @@ APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, mode_event);
|
||||
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);
|
||||
APP_EVENT_SUBSCRIBE_EARLY(MODULE, hid_boot_event);
|
||||
APP_EVENT_SUBSCRIBE_EARLY(MODULE, hid_report_event);
|
||||
APP_EVENT_SUBSCRIBE_EARLY(MODULE, hid_tx_event);
|
||||
|
||||
Reference in New Issue
Block a user