feat: 添加HID流控制模块和相关事件处理
- 添加hid_flowctrl_module.c实现HID报告流控制功能,包括FIFO队列管理和 报告发送控制 - 新增hid_report_sent_event、hid_transport_state_event和 hid_tx_report_event事件类型及其对应的头文件和实现 - 在CMakeLists.txt中注册新模块和事件源文件 - 修改keyboard_core_module.c以支持队列策略,并添加编码器事件处理逻辑 - 更新usb_hid_module.c将直接的键盘HID报告事件改为通过 hid_tx_report_event进行传输,并添加状态报告事件 - 在keyboard_hid_report_event中增加queue_policy字段以支持不同 队列策略
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
#include "encoder_event.h"
|
||||
#include "keyboard_core.h"
|
||||
#include "keyboard_hid_report_event.h"
|
||||
#include "mode_switch_event.h"
|
||||
@@ -228,6 +229,7 @@ static void build_consumer_report(uint8_t report[KEYBOARD_CONSUMER_REPORT_SIZE])
|
||||
}
|
||||
|
||||
static void submit_keyboard_report_event(enum keyboard_report_type report_type,
|
||||
enum hid_queue_policy queue_policy,
|
||||
const uint8_t *data, size_t size)
|
||||
{
|
||||
struct keyboard_hid_report_event *event =
|
||||
@@ -236,11 +238,49 @@ static void submit_keyboard_report_event(enum keyboard_report_type report_type,
|
||||
event->mode = current_mode;
|
||||
event->report_type = report_type;
|
||||
event->protocol_mode = protocol_mode;
|
||||
event->queue_policy = queue_policy;
|
||||
memcpy(event->dyndata.data, data, size);
|
||||
|
||||
APP_EVENT_SUBMIT(event);
|
||||
}
|
||||
|
||||
static void submit_consumer_fifo_frame(uint16_t usage_id)
|
||||
{
|
||||
uint8_t report_buf[KEYBOARD_CONSUMER_REPORT_SIZE];
|
||||
|
||||
if (!running || !mode_valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
sys_put_le16(usage_id, report_buf);
|
||||
submit_keyboard_report_event(KEYBOARD_REPORT_TYPE_CONSUMER,
|
||||
HID_QUEUE_POLICY_FIFO,
|
||||
report_buf,
|
||||
KEYBOARD_CONSUMER_REPORT_SIZE);
|
||||
}
|
||||
|
||||
static void submit_consumer_pulse_frames(enum keyboard_consumer_control control_id,
|
||||
uint8_t pulse_count)
|
||||
{
|
||||
uint16_t usage_id;
|
||||
|
||||
if (control_id >= KEYBOARD_CONSUMER_CTRL_COUNT) {
|
||||
LOG_WRN("Unsupported consumer control id %u", control_id);
|
||||
return;
|
||||
}
|
||||
|
||||
usage_id = consumer_usage_map[control_id];
|
||||
if (usage_id == 0U) {
|
||||
LOG_WRN("Unmapped consumer control id %u", control_id);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < pulse_count; i++) {
|
||||
submit_consumer_fifo_frame(usage_id);
|
||||
submit_consumer_fifo_frame(0U);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_keys_report(bool force)
|
||||
{
|
||||
uint8_t report_buf[KEYBOARD_NKRO_REPORT_SIZE];
|
||||
@@ -271,7 +311,10 @@ static void emit_keys_report(bool force)
|
||||
memcpy(cache_buf, report_buf, report_size);
|
||||
*cache_valid = true;
|
||||
|
||||
submit_keyboard_report_event(KEYBOARD_REPORT_TYPE_KEYS, report_buf, report_size);
|
||||
submit_keyboard_report_event(KEYBOARD_REPORT_TYPE_KEYS,
|
||||
HID_QUEUE_POLICY_LATEST,
|
||||
report_buf,
|
||||
report_size);
|
||||
}
|
||||
|
||||
static void emit_consumer_report(bool force)
|
||||
@@ -293,6 +336,7 @@ static void emit_consumer_report(bool force)
|
||||
reports_cache.consumer_valid = true;
|
||||
|
||||
submit_keyboard_report_event(KEYBOARD_REPORT_TYPE_CONSUMER,
|
||||
HID_QUEUE_POLICY_LATEST,
|
||||
report_buf,
|
||||
KEYBOARD_CONSUMER_REPORT_SIZE);
|
||||
}
|
||||
@@ -416,12 +460,33 @@ static bool handle_mode_switch_event(const struct mode_switch_event *event)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool handle_encoder_event(const struct encoder_event *event)
|
||||
{
|
||||
if (!running || !mode_valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event->detents > 0) {
|
||||
submit_consumer_pulse_frames(KEYBOARD_CONSUMER_CTRL_VOLUME_UP,
|
||||
(uint8_t)event->detents);
|
||||
} else if (event->detents < 0) {
|
||||
submit_consumer_pulse_frames(KEYBOARD_CONSUMER_CTRL_VOLUME_DOWN,
|
||||
(uint8_t)(-event->detents));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool app_event_handler(const struct app_event_header *aeh)
|
||||
{
|
||||
if (is_button_event(aeh)) {
|
||||
return handle_button_event(cast_button_event(aeh));
|
||||
}
|
||||
|
||||
if (is_encoder_event(aeh)) {
|
||||
return handle_encoder_event(cast_encoder_event(aeh));
|
||||
}
|
||||
|
||||
if (is_set_protocol_event(aeh)) {
|
||||
const struct set_protocol_event *event = cast_set_protocol_event(aeh);
|
||||
|
||||
@@ -496,6 +561,7 @@ static bool app_event_handler(const struct app_event_header *aeh)
|
||||
|
||||
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, button_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, encoder_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, set_protocol_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, mode_switch_event);
|
||||
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||
|
||||
Reference in New Issue
Block a user