diff --git a/docs/firmware_proto_transport.md b/docs/firmware_proto_transport.md index 49e880b..8fd7b6f 100644 --- a/docs/firmware_proto_transport.md +++ b/docs/firmware_proto_transport.md @@ -36,3 +36,26 @@ Design notes: - CDC transport module - GATT transport module - nanopb integration and generated protocol code + +### Node 2: keyboard split point + +Files updated in this step: + +- `src/modules/keyboard_module.c` + +Design notes: + +- reuse the existing keymap and HID path +- add one explicit split point before HID submission +- keep normal keys on HID +- send configured function keys to private transport only + +Implemented behavior: + +- store the 29-byte function bitmap +- for keyboard usages marked as function keys: + - stop normal HID reporting + - emit `function_key_event` +- for consumer usages marked as function keys: + - stop normal HID reporting + - emit `function_key_event` diff --git a/src/modules/keyboard_module.c b/src/modules/keyboard_module.c index 0fef737..35c3c4d 100644 --- a/src/modules/keyboard_module.c +++ b/src/modules/keyboard_module.c @@ -14,6 +14,8 @@ #include "hid_protocol_event.h" #include "hid_report_event.h" #include "hid_vendor_mask_event.h" +#include "function_bitmap_event.h" +#include "function_key_event.h" #include "qdec_step_event.h" #include @@ -100,6 +102,7 @@ struct keyboard_state { uint8_t physical_usage_bm[KEYBOARD_BITMAP_SIZE]; uint8_t mask_modifier_bm; uint8_t mask_bm[KEYBOARD_BITMAP_SIZE]; + uint8_t function_bm[KEYBOARD_BITMAP_SIZE]; enum hid_protocol_type current_protocol; uint16_t consumer_usage; }; @@ -124,6 +127,16 @@ static void keyboard_mask_init(void) { ks.mask_modifier_bm = 0xFF; memset(ks.mask_bm, 0xFF, sizeof(ks.mask_bm)); + memset(ks.function_bm, 0, sizeof(ks.function_bm)); +} + +static bool function_usage_active(uint16_t usage_id) +{ + if (usage_id > KEYBOARD_USAGE_MAX) { + return false; + } + + return (ks.function_bm[usage_id / 8] & BIT(usage_id % 8)) != 0U; } /* 查询某 usage 位在当前键盘位图里是否处于按下状态。 */ @@ -298,6 +311,11 @@ static void submit_consumer_click_usage(uint16_t usage_id) */ static bool handle_keyboard_usage_event(const struct hid_keymap *map, bool pressed) { + if (function_usage_active(map->usage_id)) { + function_key_event_submit(map->usage_id, pressed); + return false; + } + if (!keyboard_usage_update(map->usage_id, pressed)) return false; @@ -313,6 +331,11 @@ static bool handle_keyboard_usage_event(const struct hid_keymap *map, bool press */ static bool handle_consumer_usage_event(const struct hid_keymap *map, bool pressed) { + if (function_usage_active(map->usage_id)) { + function_key_event_submit(map->usage_id, pressed); + return false; + } + if (active_protocol_get() == HID_PROTO_BOOT) return false; @@ -381,6 +404,21 @@ static bool handle_hid_vendor_mask_event(const struct hid_vendor_mask_event *eve return false; } +static bool handle_function_bitmap_event(const struct function_bitmap_event *event) +{ + const uint8_t *data = function_bitmap_event_get_data(event); + size_t size = function_bitmap_event_get_size(event); + + if (size != sizeof(ks.function_bm)) { + LOG_WRN("Ignore function bitmap len=%u expect=%u", + size, sizeof(ks.function_bm)); + return false; + } + + memcpy(ks.function_bm, data, sizeof(ks.function_bm)); + return false; +} + static bool handle_qdec_step_event(const struct qdec_step_event *event) { int8_t step = qdec_step_event_get_step(event); @@ -415,6 +453,10 @@ static bool app_event_handler(const struct app_event_header *aeh) return handle_hid_vendor_mask_event(cast_hid_vendor_mask_event(aeh)); } + if (is_function_bitmap_event(aeh)) { + return handle_function_bitmap_event(cast_function_bitmap_event(aeh)); + } + if (is_module_state_event(aeh)) { const struct module_state_event *event = cast_module_state_event(aeh); @@ -436,5 +478,6 @@ APP_EVENT_LISTENER(MODULE, app_event_handler); APP_EVENT_SUBSCRIBE(MODULE, button_event); APP_EVENT_SUBSCRIBE(MODULE, hid_protocol_event); APP_EVENT_SUBSCRIBE(MODULE, hid_vendor_mask_event); +APP_EVENT_SUBSCRIBE(MODULE, function_bitmap_event); APP_EVENT_SUBSCRIBE(MODULE, qdec_step_event); APP_EVENT_SUBSCRIBE(MODULE, module_state_event);