feat(keyboard): 添加蓝牙HID支持和电池状态事件

- 添加BLE相关模块:ble_adv_ctrl_module、ble_adv_uuid16、ble_bas_module、
  ble_hid_module
- 新增电池状态事件(bat_state_event)用于监控电池电量、充电状态
- 在多个事件中添加HID_TRANSPORT_BLE支持,包括hid_led_event、
  set_protocol_event等
- 更新配置文件prj.conf以启用蓝牙功能、HID服务和设置系统
- 修改电池模块以计算并报告电池SOC百分比
- 集成CAF设置加载器以管理蓝牙配对信息
This commit is contained in:
2026-04-10 19:28:20 +08:00
parent b9b7d342f5
commit 39d2962258
21 changed files with 1186 additions and 60 deletions

View File

@@ -85,12 +85,42 @@ static const uint16_t consumer_usage_map[KEYBOARD_CONSUMER_CTRL_COUNT] = {
static struct keyboard_state keyboard_state;
static struct keyboard_reports_cache reports_cache;
static enum keyboard_protocol_mode protocol_mode = KEYBOARD_PROTOCOL_MODE_REPORT;
static enum keyboard_protocol_mode transport_protocol_modes[HID_TRANSPORT_COUNT] = {
[HID_TRANSPORT_USB] = KEYBOARD_PROTOCOL_MODE_REPORT,
[HID_TRANSPORT_BLE] = KEYBOARD_PROTOCOL_MODE_REPORT,
};
static enum mode_switch_mode current_mode;
static bool initialized;
static bool running;
static bool mode_valid;
static bool mode_to_transport(enum mode_switch_mode mode, enum hid_transport *transport)
{
switch (mode) {
case MODE_SWITCH_USB:
*transport = HID_TRANSPORT_USB;
return true;
case MODE_SWITCH_BLE:
*transport = HID_TRANSPORT_BLE;
return true;
default:
return false;
}
}
static enum keyboard_protocol_mode active_protocol_mode_get(void)
{
enum hid_transport transport;
if (mode_valid && mode_to_transport(current_mode, &transport)) {
return transport_protocol_modes[transport];
}
return KEYBOARD_PROTOCOL_MODE_REPORT;
}
static const struct keymap_entry *keymap_get(uint16_t key_id)
{
size_t left = 0;
@@ -234,6 +264,7 @@ static void submit_keyboard_report_event(enum keyboard_report_type report_type,
{
struct keyboard_hid_report_event *event =
new_keyboard_hid_report_event(size);
enum keyboard_protocol_mode protocol_mode = active_protocol_mode_get();
event->mode = current_mode;
event->report_type = report_type;
@@ -247,8 +278,10 @@ static void submit_keyboard_report_event(enum keyboard_report_type report_type,
static void submit_consumer_fifo_frame(uint16_t usage_id)
{
uint8_t report_buf[KEYBOARD_CONSUMER_REPORT_SIZE];
enum keyboard_protocol_mode protocol_mode = active_protocol_mode_get();
if (!running || !mode_valid) {
if (!running || !mode_valid ||
(protocol_mode == KEYBOARD_PROTOCOL_MODE_BOOT)) {
return;
}
@@ -264,6 +297,10 @@ static void submit_consumer_pulse_frames(enum keyboard_consumer_control control_
{
uint16_t usage_id;
if (active_protocol_mode_get() == KEYBOARD_PROTOCOL_MODE_BOOT) {
return;
}
if (control_id >= KEYBOARD_CONSUMER_CTRL_COUNT) {
LOG_WRN("Unsupported consumer control id %u", control_id);
return;
@@ -287,6 +324,7 @@ static void emit_keys_report(bool force)
uint8_t report_size;
uint8_t *cache_buf;
bool *cache_valid;
enum keyboard_protocol_mode protocol_mode = active_protocol_mode_get();
if (!mode_valid) {
return;
@@ -320,8 +358,9 @@ static void emit_keys_report(bool force)
static void emit_consumer_report(bool force)
{
uint8_t report_buf[KEYBOARD_CONSUMER_REPORT_SIZE];
enum keyboard_protocol_mode protocol_mode = active_protocol_mode_get();
if (!mode_valid) {
if (!mode_valid || (protocol_mode == KEYBOARD_PROTOCOL_MODE_BOOT)) {
return;
}
@@ -344,7 +383,10 @@ static void emit_consumer_report(bool force)
static void emit_all_reports(bool force)
{
emit_keys_report(force);
emit_consumer_report(force);
if (active_protocol_mode_get() != KEYBOARD_PROTOCOL_MODE_BOOT) {
emit_consumer_report(force);
}
}
static void emit_release_reports(enum mode_switch_mode mode)
@@ -352,6 +394,7 @@ static void emit_release_reports(enum mode_switch_mode mode)
struct keyboard_hid_report_event *event;
uint8_t keys_report[KEYBOARD_NKRO_REPORT_SIZE] = { 0 };
uint8_t consumer_report[KEYBOARD_CONSUMER_REPORT_SIZE] = { 0 };
enum keyboard_protocol_mode protocol_mode = active_protocol_mode_get();
size_t keys_report_size =
(protocol_mode == KEYBOARD_PROTOCOL_MODE_BOOT) ?
KEYBOARD_BOOT_REPORT_SIZE : KEYBOARD_NKRO_REPORT_SIZE;
@@ -363,12 +406,15 @@ static void emit_release_reports(enum mode_switch_mode mode)
memcpy(event->dyndata.data, keys_report, keys_report_size);
APP_EVENT_SUBMIT(event);
event = new_keyboard_hid_report_event(KEYBOARD_CONSUMER_REPORT_SIZE);
event->mode = mode;
event->report_type = KEYBOARD_REPORT_TYPE_CONSUMER;
event->protocol_mode = protocol_mode;
memcpy(event->dyndata.data, consumer_report, KEYBOARD_CONSUMER_REPORT_SIZE);
APP_EVENT_SUBMIT(event);
if (protocol_mode != KEYBOARD_PROTOCOL_MODE_BOOT) {
event = new_keyboard_hid_report_event(KEYBOARD_CONSUMER_REPORT_SIZE);
event->mode = mode;
event->report_type = KEYBOARD_REPORT_TYPE_CONSUMER;
event->protocol_mode = protocol_mode;
memcpy(event->dyndata.data, consumer_report,
KEYBOARD_CONSUMER_REPORT_SIZE);
APP_EVENT_SUBMIT(event);
}
}
static int module_init(void)
@@ -376,7 +422,10 @@ static int module_init(void)
keyboard_state_clear();
reports_cache_invalidate();
mode_valid = false;
protocol_mode = KEYBOARD_PROTOCOL_MODE_REPORT;
transport_protocol_modes[HID_TRANSPORT_USB] =
KEYBOARD_PROTOCOL_MODE_REPORT;
transport_protocol_modes[HID_TRANSPORT_BLE] =
KEYBOARD_PROTOCOL_MODE_REPORT;
return 0;
}
@@ -489,12 +538,24 @@ static bool app_event_handler(const struct app_event_header *aeh)
if (is_set_protocol_event(aeh)) {
const struct set_protocol_event *event = cast_set_protocol_event(aeh);
enum hid_transport active_transport;
if (protocol_mode != event->protocol_mode) {
protocol_mode = event->protocol_mode;
if (event->transport >= HID_TRANSPORT_COUNT) {
return false;
}
if (running && mode_valid && (current_mode == MODE_SWITCH_USB)) {
if (transport_protocol_modes[event->transport] != event->protocol_mode) {
transport_protocol_modes[event->transport] = event->protocol_mode;
if (running && mode_valid &&
mode_to_transport(current_mode, &active_transport) &&
(active_transport == event->transport)) {
reports_cache_invalidate();
emit_keys_report(true);
if (event->protocol_mode != KEYBOARD_PROTOCOL_MODE_BOOT) {
emit_consumer_report(true);
}
}
}