Compare commits
4 Commits
cd8101428d
...
2a8b44d058
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a8b44d058 | |||
| a9025d0f49 | |||
| 4e8bb71f83 | |||
| 7587df7553 |
@@ -10,7 +10,6 @@ project(new_kbd)
|
|||||||
|
|
||||||
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
|
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
|
||||||
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/events)
|
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/events)
|
||||||
zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/configuration/atguigu_mini_keyboard_nrf52840)
|
|
||||||
|
|
||||||
target_compile_definitions(app PRIVATE
|
target_compile_definitions(app PRIVATE
|
||||||
APP_HID_KEYMAP_DEF_PATH=\"hid_keymap_def.h\"
|
APP_HID_KEYMAP_DEF_PATH=\"hid_keymap_def.h\"
|
||||||
@@ -22,12 +21,14 @@ target_sources(app PRIVATE
|
|||||||
src/events/config_event.c
|
src/events/config_event.c
|
||||||
src/events/hid_protocol_event.c
|
src/events/hid_protocol_event.c
|
||||||
src/events/hid_report_event.c
|
src/events/hid_report_event.c
|
||||||
|
src/events/keyboard_led_state_event.c
|
||||||
src/events/mode_event.c
|
src/events/mode_event.c
|
||||||
src/events/usb_hid_event.c
|
|
||||||
src/modules/battery_module.c
|
src/modules/battery_module.c
|
||||||
src/modules/ble_adv_ctrl_module.c
|
src/modules/ble_adv_ctrl_module.c
|
||||||
|
src/modules/ble_battery_module.c
|
||||||
src/modules/ble_bond_module.c
|
src/modules/ble_bond_module.c
|
||||||
src/modules/keyboard_module.c
|
src/modules/keyboard_module.c
|
||||||
|
src/modules/led_state_module.c
|
||||||
src/modules/mode_switch_module.c
|
src/modules/mode_switch_module.c
|
||||||
src/modules/usb_hid_module.c
|
src/modules/usb_hid_module.c
|
||||||
src/modules/ble_hid_module.c
|
src/modules/ble_hid_module.c
|
||||||
|
|||||||
@@ -53,6 +53,10 @@
|
|||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&led_1 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
/* 使能 SAADC,mode_switch_module 使用 channel 7 采样模式拨码电压。 */
|
/* 使能 SAADC,mode_switch_module 使用 channel 7 采样模式拨码电压。 */
|
||||||
&adc {
|
&adc {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
@@ -63,7 +67,6 @@
|
|||||||
|
|
||||||
ip5305: pmic@75 {
|
ip5305: pmic@75 {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
/* 试验项:调整 IP5305 KEY 保活周期,观察 I2C 失败窗口是否随周期移动。 */
|
|
||||||
keepalive-interval-ms = <10000>;
|
keepalive-interval-ms = <10000>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
29
inc/led_state.h
Normal file
29
inc/led_state.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef NEW_KBD_LED_STATE_H__
|
||||||
|
#define NEW_KBD_LED_STATE_H__
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
|
/* 模块内系统状态:只用于本项目的 LED 映射,不对外暴露协议语义。 */
|
||||||
|
enum led_ble_state {
|
||||||
|
LED_BLE_STATE_OFF = 0,
|
||||||
|
LED_BLE_STATE_WAIT_RECONNECT,
|
||||||
|
LED_BLE_STATE_PAIRING,
|
||||||
|
LED_BLE_STATE_CONNECTED,
|
||||||
|
LED_BLE_STATE_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum led_num_lock_state {
|
||||||
|
LED_NUM_LOCK_STATE_OFF = 0,
|
||||||
|
LED_NUM_LOCK_STATE_ON,
|
||||||
|
LED_NUM_LOCK_STATE_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum led_id_new_kbd {
|
||||||
|
LED_ID_NUM_LOCK = 0,
|
||||||
|
LED_ID_BLE_STATE,
|
||||||
|
LED_ID_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LED_UNAVAILABLE 0xFF
|
||||||
|
|
||||||
|
#endif /* NEW_KBD_LED_STATE_H__ */
|
||||||
39
inc/led_state_def.h
Normal file
39
inc/led_state_def.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#include "led_state.h"
|
||||||
|
#include <caf/led_effect.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 该文件仅被 led_state_module.c 包含一次,用于定义:
|
||||||
|
* 1) 逻辑 LED 到 CAF LED 实例编号映射;
|
||||||
|
* 2) 每个逻辑状态对应的 LED 效果。
|
||||||
|
*/
|
||||||
|
const struct {} led_state_def_include_once;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CAF LED 实例编号来源于 DTS 中 status=okay 的 gpio-leds 顺序:
|
||||||
|
* - led_0 -> 0(Num Lock)
|
||||||
|
* - led_1 -> 1(BLE 状态)
|
||||||
|
*/
|
||||||
|
static const uint8_t led_map[LED_ID_COUNT] = {
|
||||||
|
[LED_ID_NUM_LOCK] = 0,
|
||||||
|
[LED_ID_BLE_STATE] = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Num Lock 指示:灭=关闭,常亮=开启。 */
|
||||||
|
static const struct led_effect led_num_lock_state_effect[LED_NUM_LOCK_STATE_COUNT] = {
|
||||||
|
[LED_NUM_LOCK_STATE_OFF] = LED_EFFECT_LED_OFF(),
|
||||||
|
[LED_NUM_LOCK_STATE_ON] = LED_EFFECT_LED_ON(LED_COLOR(255, 255, 255)),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BLE 指示灯策略:
|
||||||
|
* - OFF: 熄灭(USB 连接或 BLE 非活动模式)
|
||||||
|
* - WAIT_RECONNECT: 慢闪(1s toggle)
|
||||||
|
* - PAIRING: 快闪(0.5s toggle)
|
||||||
|
* - CONNECTED: 常亮
|
||||||
|
*/
|
||||||
|
static const struct led_effect led_ble_state_effect[LED_BLE_STATE_COUNT] = {
|
||||||
|
[LED_BLE_STATE_OFF] = LED_EFFECT_LED_OFF(),
|
||||||
|
[LED_BLE_STATE_WAIT_RECONNECT] = LED_EFFECT_LED_BLINK(1000, LED_COLOR(255, 255, 255)),
|
||||||
|
[LED_BLE_STATE_PAIRING] = LED_EFFECT_LED_BLINK(500, LED_COLOR(255, 255, 255)),
|
||||||
|
[LED_BLE_STATE_CONNECTED] = LED_EFFECT_LED_ON(LED_COLOR(255, 255, 255)),
|
||||||
|
};
|
||||||
2
prj.conf
2
prj.conf
@@ -63,7 +63,7 @@ CONFIG_CAF_LEDS_GPIO=y
|
|||||||
CONFIG_CAF_LEDS_PM_EVENTS=y
|
CONFIG_CAF_LEDS_PM_EVENTS=y
|
||||||
|
|
||||||
CONFIG_CAF_POWER_MANAGER=y
|
CONFIG_CAF_POWER_MANAGER=y
|
||||||
CONFIG_CAF_POWER_MANAGER_TIMEOUT=300
|
CONFIG_CAF_POWER_MANAGER_TIMEOUT=30
|
||||||
CONFIG_CAF_POWER_MANAGER_ERROR_TIMEOUT=10
|
CONFIG_CAF_POWER_MANAGER_ERROR_TIMEOUT=10
|
||||||
CONFIG_REBOOT=y
|
CONFIG_REBOOT=y
|
||||||
CONFIG_CAF_KEEP_ALIVE_EVENTS=y
|
CONFIG_CAF_KEEP_ALIVE_EVENTS=y
|
||||||
|
|||||||
31
src/events/keyboard_led_state_event.c
Normal file
31
src/events/keyboard_led_state_event.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "keyboard_led_state_event.h"
|
||||||
|
|
||||||
|
static void log_keyboard_led_state_event(const struct app_event_header *aeh)
|
||||||
|
{
|
||||||
|
const struct keyboard_led_state_event *event =
|
||||||
|
cast_keyboard_led_state_event(aeh);
|
||||||
|
|
||||||
|
APP_EVENT_MANAGER_LOG(aeh, "mask=0x%02x num_lock=%u",
|
||||||
|
event->led_mask, event->num_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void profile_keyboard_led_state_event(struct log_event_buf *buf,
|
||||||
|
const struct app_event_header *aeh)
|
||||||
|
{
|
||||||
|
const struct keyboard_led_state_event *event =
|
||||||
|
cast_keyboard_led_state_event(aeh);
|
||||||
|
|
||||||
|
nrf_profiler_log_encode_uint8(buf, event->led_mask);
|
||||||
|
nrf_profiler_log_encode_uint8(buf, event->num_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
APP_EVENT_INFO_DEFINE(keyboard_led_state_event,
|
||||||
|
ENCODE(NRF_PROFILER_ARG_U8,
|
||||||
|
NRF_PROFILER_ARG_U8),
|
||||||
|
ENCODE("led_mask", "num_lock"),
|
||||||
|
profile_keyboard_led_state_event);
|
||||||
|
|
||||||
|
APP_EVENT_TYPE_DEFINE(keyboard_led_state_event,
|
||||||
|
log_keyboard_led_state_event,
|
||||||
|
&keyboard_led_state_event_info,
|
||||||
|
APP_EVENT_FLAGS_CREATE(APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE));
|
||||||
24
src/events/keyboard_led_state_event.h
Normal file
24
src/events/keyboard_led_state_event.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef KEYBOARD_LED_STATE_EVENT_H__
|
||||||
|
#define KEYBOARD_LED_STATE_EVENT_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <app_event_manager.h>
|
||||||
|
#include <app_event_manager_profiler_tracer.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 键盘 LED 状态事件:
|
||||||
|
* - 由 USB/BLE HID 接收主机输出报告后上报;
|
||||||
|
* - 当前仅消费 Num Lock 位,保留 led_mask 便于后续扩展 Caps/Scroll。
|
||||||
|
*/
|
||||||
|
struct keyboard_led_state_event {
|
||||||
|
struct app_event_header header;
|
||||||
|
|
||||||
|
uint8_t led_mask;
|
||||||
|
bool num_lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
APP_EVENT_TYPE_DECLARE(keyboard_led_state_event);
|
||||||
|
|
||||||
|
#endif /* KEYBOARD_LED_STATE_EVENT_H__ */
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
#include "usb_hid_event.h"
|
|
||||||
|
|
||||||
static const char *const usb_hid_evt_type_name[] = {
|
|
||||||
[USB_HID_EVT_STATE_REPORT] = "STATE_REPORT",
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *const usb_hid_usbd_state_name[] = {
|
|
||||||
[USB_HID_USBD_DISCONNECTED] = "DISCONNECTED",
|
|
||||||
[USB_HID_USBD_CONNECTED] = "CONNECTED",
|
|
||||||
[USB_HID_USBD_SUSPENDED] = "SUSPENDED",
|
|
||||||
};
|
|
||||||
|
|
||||||
static void log_usb_hid_event(const struct app_event_header *aeh)
|
|
||||||
{
|
|
||||||
const struct usb_hid_event *event = cast_usb_hid_event(aeh);
|
|
||||||
|
|
||||||
__ASSERT_NO_MSG(event->evt_type < ARRAY_SIZE(usb_hid_evt_type_name));
|
|
||||||
__ASSERT_NO_MSG(event->usbd_state < ARRAY_SIZE(usb_hid_usbd_state_name));
|
|
||||||
|
|
||||||
APP_EVENT_MANAGER_LOG(aeh, "type=%s en=%u usbd=%s",
|
|
||||||
usb_hid_evt_type_name[event->evt_type],
|
|
||||||
event->enable,
|
|
||||||
usb_hid_usbd_state_name[event->usbd_state]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void profile_usb_hid_event(struct log_event_buf *buf,
|
|
||||||
const struct app_event_header *aeh)
|
|
||||||
{
|
|
||||||
const struct usb_hid_event *event = cast_usb_hid_event(aeh);
|
|
||||||
|
|
||||||
nrf_profiler_log_encode_uint8(buf, (uint8_t)event->evt_type);
|
|
||||||
nrf_profiler_log_encode_uint8(buf, (uint8_t)event->enable);
|
|
||||||
nrf_profiler_log_encode_uint8(buf, (uint8_t)event->usbd_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
APP_EVENT_INFO_DEFINE(usb_hid_event,
|
|
||||||
ENCODE(NRF_PROFILER_ARG_U8,
|
|
||||||
NRF_PROFILER_ARG_U8,
|
|
||||||
NRF_PROFILER_ARG_U8),
|
|
||||||
ENCODE("evt_type", "enable", "usbd"),
|
|
||||||
profile_usb_hid_event);
|
|
||||||
|
|
||||||
APP_EVENT_TYPE_DEFINE(usb_hid_event,
|
|
||||||
log_usb_hid_event,
|
|
||||||
&usb_hid_event_info,
|
|
||||||
APP_EVENT_FLAGS_CREATE(APP_EVENT_TYPE_FLAGS_INIT_LOG_ENABLE));
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#ifndef USB_HID_EVENT_H__
|
|
||||||
#define USB_HID_EVENT_H__
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <app_event_manager.h>
|
|
||||||
#include <app_event_manager_profiler_tracer.h>
|
|
||||||
|
|
||||||
enum usb_hid_event_type {
|
|
||||||
USB_HID_EVT_STATE_REPORT = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* USB 连接层状态(偏“链路可用性”) */
|
|
||||||
enum usb_hid_usbd_state {
|
|
||||||
USB_HID_USBD_DISCONNECTED = 0,
|
|
||||||
USB_HID_USBD_CONNECTED,
|
|
||||||
USB_HID_USBD_SUSPENDED,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usb_hid_event {
|
|
||||||
struct app_event_header header;
|
|
||||||
|
|
||||||
enum usb_hid_event_type evt_type;
|
|
||||||
bool enable;
|
|
||||||
enum usb_hid_usbd_state usbd_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
APP_EVENT_TYPE_DECLARE(usb_hid_event);
|
|
||||||
|
|
||||||
#endif /* USB_HID_EVENT_H__ */
|
|
||||||
@@ -63,6 +63,7 @@ static int32_t battery_mv_window[BATTERY_MV_WINDOW_SIZE];
|
|||||||
static int64_t battery_mv_sum;
|
static int64_t battery_mv_sum;
|
||||||
static size_t battery_mv_count;
|
static size_t battery_mv_count;
|
||||||
static size_t battery_mv_index;
|
static size_t battery_mv_index;
|
||||||
|
static enum power_manager_level pm_restrict_level = POWER_MANAGER_LEVEL_MAX;
|
||||||
|
|
||||||
static void battery_module_resume(void);
|
static void battery_module_resume(void);
|
||||||
|
|
||||||
@@ -191,6 +192,23 @@ static void publish_battery_status_event(const struct battery_status *status)
|
|||||||
APP_EVENT_SUBMIT(event);
|
APP_EVENT_SUBMIT(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 电源限制策略:
|
||||||
|
* - 充电线插入(charging=true)时限制到 ALIVE,禁止自动休眠;
|
||||||
|
* - 非充电时恢复到 SUSPENDED,允许系统进入挂起但不进入 OFF。
|
||||||
|
*/
|
||||||
|
static void update_power_restrict_by_charging(bool charging)
|
||||||
|
{
|
||||||
|
enum power_manager_level target = charging ?
|
||||||
|
POWER_MANAGER_LEVEL_ALIVE : POWER_MANAGER_LEVEL_SUSPENDED;
|
||||||
|
|
||||||
|
if (pm_restrict_level == target)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pm_restrict_level = target;
|
||||||
|
power_manager_restrict(MODULE_IDX(MODULE), target);
|
||||||
|
}
|
||||||
|
|
||||||
static void battery_sample_fn(struct k_work *work)
|
static void battery_sample_fn(struct k_work *work)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(work);
|
ARG_UNUSED(work);
|
||||||
@@ -208,6 +226,8 @@ static void battery_sample_fn(struct k_work *work)
|
|||||||
goto out_reschedule;
|
goto out_reschedule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_power_restrict_by_charging(sampled.charging);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 仅在状态发生变化时上报,避免重复事件淹没总线。
|
* 仅在状态发生变化时上报,避免重复事件淹没总线。
|
||||||
* 变化条件:充电标志、满电标志、SOC 任意一个变化。
|
* 变化条件:充电标志、满电标志、SOC 任意一个变化。
|
||||||
@@ -260,11 +280,8 @@ static int battery_module_init(void)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* 默认非充电态允许进入 SUSPENDED,但禁止进入 OFF。 */
|
||||||
* 按需求将最深电源级别限制在 SUSPENDED,禁止进入 OFF。
|
update_power_restrict_by_charging(false);
|
||||||
* 这样即使 CPU 进入挂起,IP5305 的硬件保活后端仍可持续输出保活脉冲。
|
|
||||||
*/
|
|
||||||
power_manager_restrict(MODULE_IDX(MODULE), POWER_MANAGER_LEVEL_SUSPENDED);
|
|
||||||
|
|
||||||
k_work_init_delayable(&battery_sample_work, battery_sample_fn);
|
k_work_init_delayable(&battery_sample_work, battery_sample_fn);
|
||||||
has_last_status = false;
|
has_last_status = false;
|
||||||
|
|||||||
91
src/modules/ble_battery_module.c
Normal file
91
src/modules/ble_battery_module.c
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/bluetooth/gatt.h>
|
||||||
|
|
||||||
|
#include <app_event_manager.h>
|
||||||
|
|
||||||
|
#define MODULE ble_battery
|
||||||
|
#include <caf/events/module_state_event.h>
|
||||||
|
|
||||||
|
#include "battery_status_event.h"
|
||||||
|
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
||||||
|
|
||||||
|
static bool notify_enabled;
|
||||||
|
static uint8_t battery_level = 100U;
|
||||||
|
|
||||||
|
static void bas_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(attr);
|
||||||
|
notify_enabled = (value == BT_GATT_CCC_NOTIFY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t read_battery_level(struct bt_conn *conn,
|
||||||
|
const struct bt_gatt_attr *attr,
|
||||||
|
void *buf,
|
||||||
|
uint16_t len,
|
||||||
|
uint16_t offset)
|
||||||
|
{
|
||||||
|
const uint8_t *value = attr->user_data;
|
||||||
|
|
||||||
|
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));
|
||||||
|
}
|
||||||
|
|
||||||
|
BT_GATT_SERVICE_DEFINE(ble_battery_svc,
|
||||||
|
BT_GATT_PRIMARY_SERVICE(BT_UUID_BAS),
|
||||||
|
BT_GATT_CHARACTERISTIC(BT_UUID_BAS_BATTERY_LEVEL,
|
||||||
|
BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,
|
||||||
|
BT_GATT_PERM_READ_ENCRYPT,
|
||||||
|
read_battery_level, NULL, &battery_level),
|
||||||
|
BT_GATT_CCC(bas_ccc_cfg_changed,
|
||||||
|
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT),
|
||||||
|
);
|
||||||
|
|
||||||
|
static bool handle_battery_status_event(const struct battery_status_event *event)
|
||||||
|
{
|
||||||
|
battery_level = event->soc;
|
||||||
|
|
||||||
|
if (!notify_enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = bt_gatt_notify(NULL, &ble_battery_svc.attrs[1], &battery_level, sizeof(battery_level));
|
||||||
|
|
||||||
|
if (err == -ENOTCONN) {
|
||||||
|
LOG_WRN("BAS notify skipped: peer disconnecting");
|
||||||
|
} else if (err) {
|
||||||
|
LOG_ERR("BAS notify failed: %d", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_module_state_event(const struct module_state_event *event)
|
||||||
|
{
|
||||||
|
if (!check_state(event, MODULE_ID(ble_state), MODULE_STATE_READY)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_set_state(MODULE_STATE_READY);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool app_event_handler(const struct app_event_header *aeh)
|
||||||
|
{
|
||||||
|
if (is_battery_status_event(aeh)) {
|
||||||
|
return handle_battery_status_event(cast_battery_status_event(aeh));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_module_state_event(aeh)) {
|
||||||
|
return handle_module_state_event(cast_module_state_event(aeh));
|
||||||
|
}
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, battery_status_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "hid_protocol_event.h"
|
#include "hid_protocol_event.h"
|
||||||
#include "hid_report_event.h"
|
#include "hid_report_event.h"
|
||||||
#include "hid_report_descriptor.h"
|
#include "hid_report_descriptor.h"
|
||||||
|
#include "keyboard_led_state_event.h"
|
||||||
#include "mode_event.h"
|
#include "mode_event.h"
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
@@ -27,6 +28,8 @@ BT_HIDS_DEF(hids_obj, INPUT_REPORT_COUNT, OUTPUT_REPORT_COUNT, 0);
|
|||||||
static struct bt_conn *active_conn;
|
static struct bt_conn *active_conn;
|
||||||
static enum bt_hids_pm current_pm = BT_HIDS_PM_REPORT;
|
static enum bt_hids_pm current_pm = BT_HIDS_PM_REPORT;
|
||||||
static bool ble_mode_selected;
|
static bool ble_mode_selected;
|
||||||
|
static bool num_lock_known;
|
||||||
|
static bool num_lock_on;
|
||||||
|
|
||||||
static enum hid_protocol_type pm_to_protocol(enum bt_hids_pm pm)
|
static enum hid_protocol_type pm_to_protocol(enum bt_hids_pm pm)
|
||||||
{
|
{
|
||||||
@@ -42,6 +45,25 @@ static void publish_hid_protocol_event(enum hid_protocol_type protocol)
|
|||||||
APP_EVENT_SUBMIT(event);
|
APP_EVENT_SUBMIT(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* BLE 输出报告的 bit0 对应 Num Lock。仅在状态变化时上报,避免重复通知。 */
|
||||||
|
static void publish_num_lock_state_from_led_mask(uint8_t led_mask)
|
||||||
|
{
|
||||||
|
bool new_num_lock = (led_mask & BIT(0)) != 0U;
|
||||||
|
|
||||||
|
if (num_lock_known && (num_lock_on == new_num_lock)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_lock_known = true;
|
||||||
|
num_lock_on = new_num_lock;
|
||||||
|
|
||||||
|
struct keyboard_led_state_event *event = new_keyboard_led_state_event();
|
||||||
|
|
||||||
|
event->led_mask = led_mask;
|
||||||
|
event->num_lock = new_num_lock;
|
||||||
|
APP_EVENT_SUBMIT(event);
|
||||||
|
}
|
||||||
|
|
||||||
static void pm_evt_handler(enum bt_hids_pm_evt evt, struct bt_conn *conn)
|
static void pm_evt_handler(enum bt_hids_pm_evt evt, struct bt_conn *conn)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(conn);
|
ARG_UNUSED(conn);
|
||||||
@@ -86,6 +108,7 @@ static void boot_keyboard_output_report_handler(struct bt_hids_rep *rep,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
publish_num_lock_state_from_led_mask(rep->data[0]);
|
||||||
LOG_DBG("Boot KB out report 0x%02x", rep->data[0]);
|
LOG_DBG("Boot KB out report 0x%02x", rep->data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +122,7 @@ static void keyboard_output_report_handler(struct bt_hids_rep *rep,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
publish_num_lock_state_from_led_mask(rep->data[0]);
|
||||||
LOG_DBG("Report KB out report 0x%02x", rep->data[0]);
|
LOG_DBG("Report KB out report 0x%02x", rep->data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
180
src/modules/led_state_module.c
Normal file
180
src/modules/led_state_module.c
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
#include <zephyr/kernel.h>
|
||||||
|
|
||||||
|
#include <app_event_manager.h>
|
||||||
|
|
||||||
|
#define MODULE led_state
|
||||||
|
#include <caf/events/module_state_event.h>
|
||||||
|
#include <caf/events/ble_common_event.h>
|
||||||
|
#include <caf/events/led_event.h>
|
||||||
|
|
||||||
|
#include "keyboard_led_state_event.h"
|
||||||
|
#include "led_state.h"
|
||||||
|
#include "mode_event.h"
|
||||||
|
#include "led_state_def.h"
|
||||||
|
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
||||||
|
|
||||||
|
static uint8_t connected_peer_count;
|
||||||
|
static bool ble_mode_selected;
|
||||||
|
static bool peer_search_active;
|
||||||
|
static enum peer_operation peer_op = PEER_OPERATION_CANCEL;
|
||||||
|
static bool num_lock_on;
|
||||||
|
|
||||||
|
/* 根据当前聚合上下文决定 BLE 状态灯的逻辑状态。 */
|
||||||
|
static enum led_ble_state resolve_ble_led_state(void)
|
||||||
|
{
|
||||||
|
if (!ble_mode_selected)
|
||||||
|
return LED_BLE_STATE_OFF;
|
||||||
|
|
||||||
|
switch (peer_op) {
|
||||||
|
case PEER_OPERATION_SELECT:
|
||||||
|
case PEER_OPERATION_ERASE:
|
||||||
|
case PEER_OPERATION_ERASE_ADV:
|
||||||
|
return LED_BLE_STATE_PAIRING;
|
||||||
|
|
||||||
|
case PEER_OPERATION_SELECTED:
|
||||||
|
case PEER_OPERATION_ERASE_ADV_CANCEL:
|
||||||
|
case PEER_OPERATION_ERASED:
|
||||||
|
case PEER_OPERATION_CANCEL:
|
||||||
|
case PEER_OPERATION_SCAN_REQUEST:
|
||||||
|
if (peer_search_active)
|
||||||
|
return LED_BLE_STATE_PAIRING;
|
||||||
|
|
||||||
|
if (connected_peer_count > 0U)
|
||||||
|
return LED_BLE_STATE_CONNECTED;
|
||||||
|
|
||||||
|
return LED_BLE_STATE_WAIT_RECONNECT;
|
||||||
|
|
||||||
|
default:
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
return LED_BLE_STATE_OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 发布 Num Lock 灯效。 */
|
||||||
|
static void submit_num_lock_led(void)
|
||||||
|
{
|
||||||
|
if (led_map[LED_ID_NUM_LOCK] == LED_UNAVAILABLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
enum led_num_lock_state state =
|
||||||
|
num_lock_on ? LED_NUM_LOCK_STATE_ON : LED_NUM_LOCK_STATE_OFF;
|
||||||
|
struct led_event *event = new_led_event();
|
||||||
|
|
||||||
|
event->led_id = led_map[LED_ID_NUM_LOCK];
|
||||||
|
event->led_effect = &led_num_lock_state_effect[state];
|
||||||
|
APP_EVENT_SUBMIT(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 发布 BLE 状态灯效。 */
|
||||||
|
static void submit_ble_led(void)
|
||||||
|
{
|
||||||
|
if (led_map[LED_ID_BLE_STATE] == LED_UNAVAILABLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
enum led_ble_state state = resolve_ble_led_state();
|
||||||
|
struct led_event *event = new_led_event();
|
||||||
|
|
||||||
|
event->led_id = led_map[LED_ID_BLE_STATE];
|
||||||
|
event->led_effect = &led_ble_state_effect[state];
|
||||||
|
APP_EVENT_SUBMIT(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_mode_event(const struct mode_event *event)
|
||||||
|
{
|
||||||
|
ble_mode_selected = (event->mode_type == MODE_TYPE_BLE);
|
||||||
|
submit_ble_led();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_ble_peer_event(const struct ble_peer_event *event)
|
||||||
|
{
|
||||||
|
switch (event->state) {
|
||||||
|
case PEER_STATE_CONNECTED:
|
||||||
|
__ASSERT_NO_MSG(connected_peer_count < UINT8_MAX);
|
||||||
|
connected_peer_count++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PEER_STATE_DISCONNECTED:
|
||||||
|
__ASSERT_NO_MSG(connected_peer_count > 0U);
|
||||||
|
connected_peer_count--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PEER_STATE_SECURED:
|
||||||
|
case PEER_STATE_CONN_FAILED:
|
||||||
|
case PEER_STATE_DISCONNECTING:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
submit_ble_led();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_ble_peer_search_event(const struct ble_peer_search_event *event)
|
||||||
|
{
|
||||||
|
peer_search_active = event->active;
|
||||||
|
submit_ble_led();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_ble_peer_operation_event(const struct ble_peer_operation_event *event)
|
||||||
|
{
|
||||||
|
peer_op = event->op;
|
||||||
|
submit_ble_led();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handle_keyboard_led_state_event(const struct keyboard_led_state_event *event)
|
||||||
|
{
|
||||||
|
num_lock_on = event->num_lock;
|
||||||
|
submit_num_lock_led();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool app_event_handler(const struct app_event_header *aeh)
|
||||||
|
{
|
||||||
|
if (is_module_state_event(aeh)) {
|
||||||
|
const struct module_state_event *event = cast_module_state_event(aeh);
|
||||||
|
|
||||||
|
if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) {
|
||||||
|
submit_num_lock_led();
|
||||||
|
submit_ble_led();
|
||||||
|
module_set_state(MODULE_STATE_READY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_mode_event(aeh))
|
||||||
|
return handle_mode_event(cast_mode_event(aeh));
|
||||||
|
|
||||||
|
if (is_keyboard_led_state_event(aeh))
|
||||||
|
return handle_keyboard_led_state_event(cast_keyboard_led_state_event(aeh));
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_CAF_BLE_COMMON_EVENTS) && is_ble_peer_event(aeh))
|
||||||
|
return handle_ble_peer_event(cast_ble_peer_event(aeh));
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_CAF_BLE_COMMON_EVENTS) && is_ble_peer_search_event(aeh))
|
||||||
|
return handle_ble_peer_search_event(cast_ble_peer_search_event(aeh));
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_CAF_BLE_COMMON_EVENTS) && is_ble_peer_operation_event(aeh))
|
||||||
|
return handle_ble_peer_operation_event(cast_ble_peer_operation_event(aeh));
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, mode_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, keyboard_led_state_event);
|
||||||
|
#ifdef CONFIG_CAF_BLE_COMMON_EVENTS
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, ble_peer_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, ble_peer_search_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, ble_peer_operation_event);
|
||||||
|
#endif
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
#include "hid_report_descriptor.h"
|
#include "hid_report_descriptor.h"
|
||||||
#include "hid_protocol_event.h"
|
#include "hid_protocol_event.h"
|
||||||
#include "hid_report_event.h"
|
#include "hid_report_event.h"
|
||||||
|
#include "keyboard_led_state_event.h"
|
||||||
#include "mode_event.h"
|
#include "mode_event.h"
|
||||||
#include "usb_hid_event.h"
|
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
||||||
@@ -26,8 +26,8 @@ LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 模块目标:
|
* 模块目标:
|
||||||
* 1) 模块内聚控制 USB HID 栈生命周期(初始化/启用/禁用),不依赖外部 usb_hid_event 控制。
|
* 1) 模块内聚控制 USB HID 栈生命周期(初始化/启用/禁用)。
|
||||||
* 2) 对外统一上报 usb_hid_event,供 LED/上层状态机消费。
|
* 2) 对外发布 HID 协议事件和 NumLock 指示事件。
|
||||||
* 3) 仅响应 mode_event(USB/BLE/2.4G)和 power_event(休眠/唤醒)。
|
* 3) 仅响应 mode_event(USB/BLE/2.4G)和 power_event(休眠/唤醒)。
|
||||||
*
|
*
|
||||||
* 约束:
|
* 约束:
|
||||||
@@ -53,12 +53,10 @@ struct usb_hid_ctx {
|
|||||||
bool boot_in_flight;
|
bool boot_in_flight;
|
||||||
bool nkro_in_flight;
|
bool nkro_in_flight;
|
||||||
|
|
||||||
enum usb_hid_usbd_state usbd_state;
|
|
||||||
enum hid_protocol_type current_protocol;
|
enum hid_protocol_type current_protocol;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_hid_ctx g_usb_hid = {
|
static struct usb_hid_ctx g_usb_hid = {
|
||||||
.usbd_state = USB_HID_USBD_DISCONNECTED,
|
|
||||||
.current_protocol = HID_PROTO_REPORT,
|
.current_protocol = HID_PROTO_REPORT,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,28 +73,50 @@ static const uint8_t boot_report_desc[] = HID_KEYBOARD_REPORT_DESC();
|
|||||||
static const uint8_t nkro_report_desc[] = HID_DESC_KEYBOARD_NKRO_CONSUMER();
|
static const uint8_t nkro_report_desc[] = HID_DESC_KEYBOARD_NKRO_CONSUMER();
|
||||||
static const uint8_t raw_report_desc[] = HID_DESC_RAW_64();
|
static const uint8_t raw_report_desc[] = HID_DESC_RAW_64();
|
||||||
|
|
||||||
static void publish_usb_hid_state(void)
|
/* 统一入口仅处理单字节 LED 报告并发布事件。 */
|
||||||
|
static void process_usb_led_input_report(uint8_t led_report)
|
||||||
{
|
{
|
||||||
struct usb_hid_event *event = new_usb_hid_event();
|
struct keyboard_led_state_event *event = new_keyboard_led_state_event();
|
||||||
|
|
||||||
event->evt_type = USB_HID_EVT_STATE_REPORT;
|
event->led_mask = led_report;
|
||||||
event->enable = g_usb_hid.stack_enabled;
|
event->num_lock = (led_report & BIT(0)) != 0U;
|
||||||
event->usbd_state = g_usb_hid.usbd_state;
|
|
||||||
APP_EVENT_SUBMIT(event);
|
APP_EVENT_SUBMIT(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void recompute_hid_state(void)
|
static bool should_handle_led_input_from_dev(const struct device *dev)
|
||||||
{
|
{
|
||||||
/* 兼容现有调用点:对外仅发布 enable + usbd 状态。 */
|
if (g_usb_hid.current_protocol == HID_PROTO_BOOT)
|
||||||
publish_usb_hid_state();
|
return (dev == g_usb_hid.boot_dev);
|
||||||
|
|
||||||
|
return (dev == g_usb_hid.nkro_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_usbd_state(enum usb_hid_usbd_state state)
|
static bool try_extract_led_mask(const struct device *dev,
|
||||||
|
uint16_t len,
|
||||||
|
const uint8_t *buf,
|
||||||
|
uint8_t *led_mask)
|
||||||
{
|
{
|
||||||
if (g_usb_hid.usbd_state != state) {
|
if ((buf == NULL) || (len == 0U))
|
||||||
g_usb_hid.usbd_state = state;
|
return false;
|
||||||
publish_usb_hid_state();
|
|
||||||
|
if (dev == g_usb_hid.boot_dev) {
|
||||||
|
*led_mask = buf[0];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev != g_usb_hid.nkro_dev)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (len >= 2U) {
|
||||||
|
if (buf[0] != REPORT_ID_KEYBOARD)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*led_mask = buf[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*led_mask = buf[0];
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hid_stub_get_report(const struct device *dev,
|
static int hid_stub_get_report(const struct device *dev,
|
||||||
@@ -115,11 +135,22 @@ static int hid_stub_set_report(const struct device *dev,
|
|||||||
uint8_t type, uint8_t id,
|
uint8_t type, uint8_t id,
|
||||||
uint16_t len, const uint8_t *buf)
|
uint16_t len, const uint8_t *buf)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
|
||||||
ARG_UNUSED(type);
|
ARG_UNUSED(type);
|
||||||
ARG_UNUSED(id);
|
ARG_UNUSED(id);
|
||||||
ARG_UNUSED(len);
|
|
||||||
ARG_UNUSED(buf);
|
if (!should_handle_led_input_from_dev(dev)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t led_mask;
|
||||||
|
|
||||||
|
if (!try_extract_led_mask(dev, len, buf, &led_mask)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INF("hid_stub_set_report led_mask=0x%02x", led_mask);
|
||||||
|
process_usb_led_input_report(led_mask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,9 +218,18 @@ static void hid_stub_input_done(const struct device *dev, const uint8_t *report)
|
|||||||
|
|
||||||
static void hid_stub_output_report(const struct device *dev, uint16_t len, const uint8_t *buf)
|
static void hid_stub_output_report(const struct device *dev, uint16_t len, const uint8_t *buf)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
if (!should_handle_led_input_from_dev(dev)) {
|
||||||
ARG_UNUSED(len);
|
return;
|
||||||
ARG_UNUSED(buf);
|
}
|
||||||
|
|
||||||
|
uint8_t led_mask;
|
||||||
|
|
||||||
|
if (!try_extract_led_mask(dev, len, buf, &led_mask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INF("hid_stub_output_report led_mask=0x%02x", led_mask);
|
||||||
|
process_usb_led_input_report(led_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hid_iface_ready_cb(const struct device *dev, bool ready)
|
static void hid_iface_ready_cb(const struct device *dev, bool ready)
|
||||||
@@ -209,7 +249,6 @@ static void hid_iface_ready_cb(const struct device *dev, bool ready)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ready) {
|
if (ready) {
|
||||||
set_usbd_state(USB_HID_USBD_CONNECTED);
|
|
||||||
/* 连接可用后同步一次当前协议,让 keyboard_module 与传输侧编码一致。 */
|
/* 连接可用后同步一次当前协议,让 keyboard_module 与传输侧编码一致。 */
|
||||||
struct hid_protocol_event *event = new_hid_protocol_event();
|
struct hid_protocol_event *event = new_hid_protocol_event();
|
||||||
|
|
||||||
@@ -218,7 +257,6 @@ static void hid_iface_ready_cb(const struct device *dev, bool ready)
|
|||||||
APP_EVENT_SUBMIT(event);
|
APP_EVENT_SUBMIT(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
recompute_hid_state();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct hid_device_ops boot_hid_ops = {
|
static const struct hid_device_ops boot_hid_ops = {
|
||||||
@@ -258,7 +296,11 @@ static void usbd_msg_cb(struct usbd_context *const usbd_ctx,
|
|||||||
{
|
{
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
case USBD_MSG_VBUS_READY:
|
case USBD_MSG_VBUS_READY:
|
||||||
set_usbd_state(USB_HID_USBD_CONNECTED);
|
if (g_usb_hid.pm_suspended) {
|
||||||
|
LOG_INF("VBUS ready: submit wake_up_event");
|
||||||
|
APP_EVENT_SUBMIT(new_wake_up_event());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 只有在 USB 模式下才允许拉起 USB 栈。
|
* 只有在 USB 模式下才允许拉起 USB 栈。
|
||||||
* 这样即使插着线,只要用户切到 BLE/2.4G,也不会强制进入 USB HID。
|
* 这样即使插着线,只要用户切到 BLE/2.4G,也不会强制进入 USB HID。
|
||||||
@@ -269,26 +311,17 @@ static void usbd_msg_cb(struct usbd_context *const usbd_ctx,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case USBD_MSG_VBUS_REMOVED:
|
case USBD_MSG_VBUS_REMOVED:
|
||||||
set_usbd_state(USB_HID_USBD_DISCONNECTED);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBD_MSG_SUSPEND:
|
case USBD_MSG_SUSPEND:
|
||||||
set_usbd_state(USB_HID_USBD_SUSPENDED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case USBD_MSG_RESUME:
|
case USBD_MSG_RESUME:
|
||||||
set_usbd_state(USB_HID_USBD_CONNECTED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case USBD_MSG_CONFIGURATION:
|
case USBD_MSG_CONFIGURATION:
|
||||||
set_usbd_state(USB_HID_USBD_CONNECTED);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USBD_MSG_UDC_ERROR:
|
case USBD_MSG_UDC_ERROR:
|
||||||
case USBD_MSG_STACK_ERROR:
|
case USBD_MSG_STACK_ERROR:
|
||||||
LOG_ERR("USBD stack error message: %d", msg->type);
|
LOG_ERR("USBD stack error message: %d", msg->type);
|
||||||
g_usb_hid.stack_error = true;
|
g_usb_hid.stack_error = true;
|
||||||
recompute_hid_state();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -436,7 +469,6 @@ static int usb_hid_stack_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_usb_hid.stack_initialized = true;
|
g_usb_hid.stack_initialized = true;
|
||||||
recompute_hid_state();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,18 +498,14 @@ static int usb_hid_set_enabled(bool enable)
|
|||||||
g_usb_hid.raw_iface_ready = false;
|
g_usb_hid.raw_iface_ready = false;
|
||||||
g_usb_hid.boot_in_flight = false;
|
g_usb_hid.boot_in_flight = false;
|
||||||
g_usb_hid.nkro_in_flight = false;
|
g_usb_hid.nkro_in_flight = false;
|
||||||
set_usbd_state(USB_HID_USBD_DISCONNECTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err && (err != -EALREADY)) {
|
if (err && (err != -EALREADY)) {
|
||||||
LOG_ERR("usbd_%s failed: %d", enable ? "enable" : "disable", err);
|
LOG_ERR("usbd_%s failed: %d", enable ? "enable" : "disable", err);
|
||||||
g_usb_hid.stack_error = true;
|
g_usb_hid.stack_error = true;
|
||||||
recompute_hid_state();
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
recompute_hid_state();
|
|
||||||
publish_usb_hid_state();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,12 +535,10 @@ static bool handle_module_state_event(const struct module_state_event *event)
|
|||||||
LOG_ERR("USB HID stack init failed: %d", err);
|
LOG_ERR("USB HID stack init failed: %d", err);
|
||||||
g_usb_hid.stack_error = true;
|
g_usb_hid.stack_error = true;
|
||||||
module_set_state(MODULE_STATE_ERROR);
|
module_set_state(MODULE_STATE_ERROR);
|
||||||
recompute_hid_state();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
module_set_state(MODULE_STATE_READY);
|
module_set_state(MODULE_STATE_READY);
|
||||||
publish_usb_hid_state();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,14 +595,9 @@ static bool handle_hid_report_event(const struct hid_report_event *event)
|
|||||||
const uint8_t *payload = event->dyndata.data;
|
const uint8_t *payload = event->dyndata.data;
|
||||||
size_t payload_len = event->dyndata.size;
|
size_t payload_len = event->dyndata.size;
|
||||||
|
|
||||||
report_id = REPORT_ID_KEYBOARD;
|
|
||||||
|
|
||||||
if (!g_usb_hid.boot_iface_ready || !g_usb_hid.boot_dev) {
|
if (!g_usb_hid.boot_iface_ready || !g_usb_hid.boot_dev) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (report_id != REPORT_ID_KEYBOARD) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (g_usb_hid.boot_in_flight) {
|
if (g_usb_hid.boot_in_flight) {
|
||||||
LOG_WRN("Drop boot report: previous report not sent");
|
LOG_WRN("Drop boot report: previous report not sent");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user