Split function keys from HID path
This commit is contained in:
@@ -36,3 +36,26 @@ Design notes:
|
|||||||
- CDC transport module
|
- CDC transport module
|
||||||
- GATT transport module
|
- GATT transport module
|
||||||
- nanopb integration and generated protocol code
|
- 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`
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
#include "hid_protocol_event.h"
|
#include "hid_protocol_event.h"
|
||||||
#include "hid_report_event.h"
|
#include "hid_report_event.h"
|
||||||
#include "hid_vendor_mask_event.h"
|
#include "hid_vendor_mask_event.h"
|
||||||
|
#include "function_bitmap_event.h"
|
||||||
|
#include "function_key_event.h"
|
||||||
#include "qdec_step_event.h"
|
#include "qdec_step_event.h"
|
||||||
|
|
||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
@@ -100,6 +102,7 @@ struct keyboard_state {
|
|||||||
uint8_t physical_usage_bm[KEYBOARD_BITMAP_SIZE];
|
uint8_t physical_usage_bm[KEYBOARD_BITMAP_SIZE];
|
||||||
uint8_t mask_modifier_bm;
|
uint8_t mask_modifier_bm;
|
||||||
uint8_t mask_bm[KEYBOARD_BITMAP_SIZE];
|
uint8_t mask_bm[KEYBOARD_BITMAP_SIZE];
|
||||||
|
uint8_t function_bm[KEYBOARD_BITMAP_SIZE];
|
||||||
enum hid_protocol_type current_protocol;
|
enum hid_protocol_type current_protocol;
|
||||||
uint16_t consumer_usage;
|
uint16_t consumer_usage;
|
||||||
};
|
};
|
||||||
@@ -124,6 +127,16 @@ static void keyboard_mask_init(void)
|
|||||||
{
|
{
|
||||||
ks.mask_modifier_bm = 0xFF;
|
ks.mask_modifier_bm = 0xFF;
|
||||||
memset(ks.mask_bm, 0xFF, sizeof(ks.mask_bm));
|
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 位在当前键盘位图里是否处于按下状态。 */
|
/* 查询某 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)
|
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))
|
if (!keyboard_usage_update(map->usage_id, pressed))
|
||||||
return false;
|
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)
|
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)
|
if (active_protocol_get() == HID_PROTO_BOOT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -381,6 +404,21 @@ static bool handle_hid_vendor_mask_event(const struct hid_vendor_mask_event *eve
|
|||||||
return false;
|
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)
|
static bool handle_qdec_step_event(const struct qdec_step_event *event)
|
||||||
{
|
{
|
||||||
int8_t step = qdec_step_event_get_step(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));
|
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)) {
|
if (is_module_state_event(aeh)) {
|
||||||
const struct module_state_event *event = cast_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, button_event);
|
||||||
APP_EVENT_SUBSCRIBE(MODULE, hid_protocol_event);
|
APP_EVENT_SUBSCRIBE(MODULE, hid_protocol_event);
|
||||||
APP_EVENT_SUBSCRIBE(MODULE, hid_vendor_mask_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, qdec_step_event);
|
||||||
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||||
|
|||||||
Reference in New Issue
Block a user