feat: 添加第三屏幕及其音量控制功能
- 在 CMakeLists.txt 中添加 ui_Screen3.c 源文件以支持新屏幕 - 新增 ui_events.c 和 ui_events.h,定义音量控制按钮的点击事件处理函数 - 实现 ui_Screen3.c,构建第三屏幕的 UI 组件和事件回调 - 更新 ui.c 以初始化和加载第三屏幕 - 修改 ble_hid.c 和 ble_hid.h,添加消费者控制功能以支持音量调节 - 更新相关头文件,确保新屏幕与现有结构兼容
This commit is contained in:
@@ -13,6 +13,7 @@ idf_component_register(SRCS
|
|||||||
"ui/ui_helpers.c"
|
"ui/ui_helpers.c"
|
||||||
"ui/screens/ui_Screen1.c"
|
"ui/screens/ui_Screen1.c"
|
||||||
"ui/screens/ui_Screen2.c"
|
"ui/screens/ui_Screen2.c"
|
||||||
|
"ui/screens/ui_Screen3.c"
|
||||||
"ui/widgets/ui_comp_hook.c"
|
"ui/widgets/ui_comp_hook.c"
|
||||||
PRIV_REQUIRES
|
PRIV_REQUIRES
|
||||||
bt
|
bt
|
||||||
|
|||||||
@@ -18,6 +18,15 @@ static void send_hid_combo_or_warn(uint8_t modifier, uint8_t keycode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void send_consumer_or_warn(uint16_t usage)
|
||||||
|
{
|
||||||
|
if (ble_hid_ready()) {
|
||||||
|
ble_hid_send_consumer(usage);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "HID not ready");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void on_boot_press(void)
|
static void on_boot_press(void)
|
||||||
{
|
{
|
||||||
send_hid_combo_or_warn(0, HID_KEY_C);
|
send_hid_combo_or_warn(0, HID_KEY_C);
|
||||||
@@ -50,3 +59,39 @@ void click_button_one(lv_event_t * e)
|
|||||||
(void)e;
|
(void)e;
|
||||||
send_hid_combo_or_warn(HID_MOD_LCTRL, HID_KEY_X);
|
send_hid_combo_or_warn(HID_MOD_LCTRL, HID_KEY_X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void click_consumer_vol_up(lv_event_t * e)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
send_consumer_or_warn(HID_CONSUMER_VOLUME_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_vol_down(lv_event_t * e)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
send_consumer_or_warn(HID_CONSUMER_VOLUME_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_mute(lv_event_t * e)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
send_consumer_or_warn(HID_CONSUMER_MUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_play_pause(lv_event_t * e)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
send_consumer_or_warn(HID_CONSUMER_PLAY_PAUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_prev(lv_event_t * e)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
send_consumer_or_warn(HID_CONSUMER_SCAN_PREVIOUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_next(lv_event_t * e)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
send_consumer_or_warn(HID_CONSUMER_SCAN_NEXT);
|
||||||
|
}
|
||||||
|
|||||||
+240
-31
@@ -17,21 +17,125 @@
|
|||||||
static const char *TAG = "ble_hid";
|
static const char *TAG = "ble_hid";
|
||||||
|
|
||||||
#define HID_KEYBOARD_REPORT_ID 1
|
#define HID_KEYBOARD_REPORT_ID 1
|
||||||
#define HID_KEYBOARD_REPORT_LEN 7
|
#define HID_CONSUMER_REPORT_ID 2
|
||||||
|
#define HID_KEYBOARD_REPORT_LEN 8
|
||||||
|
#define HID_CONSUMER_REPORT_LEN 2
|
||||||
|
|
||||||
static const unsigned char s_keyboard_report_map[] = {
|
/* Bit positions for ESP-IDF mediaReportMap2 (Windows-compatible). */
|
||||||
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x85, 0x01, 0x05, 0x07, 0x19, 0xE0,
|
#define HID_CC_RPT_VOLUME_BITS 0x3F
|
||||||
0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02,
|
#define HID_CC_RPT_BUTTON_BITS 0xF0
|
||||||
0x95, 0x01, 0x75, 0x08, 0x81, 0x03, 0x95, 0x05, 0x75, 0x01, 0x05, 0x08,
|
#define HID_CC_RPT_VOLUME_UP 0x40
|
||||||
0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, 0x91, 0x03,
|
#define HID_CC_RPT_VOLUME_DOWN 0x80
|
||||||
0x95, 0x05, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, 0x00,
|
#define HID_CC_RPT_MUTE 1
|
||||||
0x29, 0x65, 0x81, 0x00, 0xC0,
|
#define HID_CC_RPT_PLAY 5
|
||||||
|
#define HID_CC_RPT_SCAN_NEXT_TRK 10
|
||||||
|
#define HID_CC_RPT_SCAN_PREV_TRK 11
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Keyboard (Report ID 1) + Consumer Control (Report ID 2, mediaReportMap2).
|
||||||
|
* Windows 11 expects the bit-packed consumer report from ESP-IDF examples,
|
||||||
|
* not a raw 16-bit HID usage in the input report.
|
||||||
|
*/
|
||||||
|
static const unsigned char s_hid_report_map[] = {
|
||||||
|
/* Keyboard - Report ID 1 */
|
||||||
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
|
0x09, 0x06, // Usage (Keyboard)
|
||||||
|
0xA1, 0x01, // Collection (Application)
|
||||||
|
0x85, HID_KEYBOARD_REPORT_ID,
|
||||||
|
0x05, 0x07, // Usage Page (Keyboard/Keypad)
|
||||||
|
0x19, 0xE0, // Usage Minimum (0xE0)
|
||||||
|
0x29, 0xE7, // Usage Maximum (0xE7)
|
||||||
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
|
0x25, 0x01, // Logical Maximum (1)
|
||||||
|
0x75, 0x01, // Report Size (1)
|
||||||
|
0x95, 0x08, // Report Count (8)
|
||||||
|
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||||
|
0x95, 0x01, // Report Count (1)
|
||||||
|
0x75, 0x08, // Report Size (8)
|
||||||
|
0x81, 0x03, // Input (Constant, Variable, Absolute)
|
||||||
|
0x95, 0x05, // Report Count (5)
|
||||||
|
0x75, 0x01, // Report Size (1)
|
||||||
|
0x05, 0x08, // Usage Page (LEDs)
|
||||||
|
0x19, 0x01, // Usage Minimum (0x01)
|
||||||
|
0x29, 0x05, // Usage Maximum (0x05)
|
||||||
|
0x91, 0x02, // Output (Data, Variable, Absolute)
|
||||||
|
0x95, 0x01, // Report Count (1)
|
||||||
|
0x75, 0x03, // Report Size (3)
|
||||||
|
0x91, 0x03, // Output (Constant, Variable, Absolute)
|
||||||
|
0x95, 0x05, // Report Count (5)
|
||||||
|
0x75, 0x08, // Report Size (8)
|
||||||
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
|
0x25, 0x65, // Logical Maximum (101)
|
||||||
|
0x05, 0x07, // Usage Page (Keyboard/Keypad)
|
||||||
|
0x19, 0x00, // Usage Minimum (0x00)
|
||||||
|
0x29, 0x65, // Usage Maximum (0x65)
|
||||||
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
|
0xC0, // End Collection
|
||||||
|
|
||||||
|
/* Consumer Control - Report ID 2 (mediaReportMap2 from ESP-IDF) */
|
||||||
|
0x05, 0x0C, // Usage Page (Consumer)
|
||||||
|
0x09, 0x01, // Usage (Consumer Control)
|
||||||
|
0xA1, 0x01, // Collection (Application)
|
||||||
|
0x85, HID_CONSUMER_REPORT_ID,
|
||||||
|
0x09, 0x02, // Usage (Numeric Key Pad)
|
||||||
|
0xA1, 0x02, // Collection (Logical)
|
||||||
|
0x05, 0x09, // Usage Page (Button)
|
||||||
|
0x19, 0x01, // Usage Minimum (0x01)
|
||||||
|
0x29, 0x0A, // Usage Maximum (0x0A)
|
||||||
|
0x15, 0x01, // Logical Minimum (1)
|
||||||
|
0x25, 0x0A, // Logical Maximum (10)
|
||||||
|
0x75, 0x04, // Report Size (4)
|
||||||
|
0x95, 0x01, // Report Count (1)
|
||||||
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
|
0xC0, // End Collection
|
||||||
|
0x05, 0x0C, // Usage Page (Consumer)
|
||||||
|
0x09, 0x86, // Usage (Channel)
|
||||||
|
0x15, 0xFF, // Logical Minimum (-1)
|
||||||
|
0x25, 0x01, // Logical Maximum (1)
|
||||||
|
0x75, 0x02, // Report Size (2)
|
||||||
|
0x95, 0x01, // Report Count (1)
|
||||||
|
0x81, 0x46, // Input (Data, Variable, Relative)
|
||||||
|
0x09, 0xE9, // Usage (Volume Increment)
|
||||||
|
0x09, 0xEA, // Usage (Volume Decrement)
|
||||||
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
|
0x75, 0x01, // Report Size (1)
|
||||||
|
0x95, 0x02, // Report Count (2)
|
||||||
|
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||||
|
0x09, 0xE2, // Usage (Mute)
|
||||||
|
0x09, 0x30, // Usage (Power)
|
||||||
|
0x09, 0x83, // Usage (Recall Last)
|
||||||
|
0x09, 0x81, // Usage (Assign Selection)
|
||||||
|
0x09, 0xB0, // Usage (Play)
|
||||||
|
0x09, 0xB1, // Usage (Pause)
|
||||||
|
0x09, 0xB2, // Usage (Record)
|
||||||
|
0x09, 0xB3, // Usage (Fast Forward)
|
||||||
|
0x09, 0xB4, // Usage (Rewind)
|
||||||
|
0x09, 0xB5, // Usage (Scan Next Track)
|
||||||
|
0x09, 0xB6, // Usage (Scan Previous Track)
|
||||||
|
0x09, 0xB7, // Usage (Stop)
|
||||||
|
0x15, 0x01, // Logical Minimum (1)
|
||||||
|
0x25, 0x0C, // Logical Maximum (12)
|
||||||
|
0x75, 0x04, // Report Size (4)
|
||||||
|
0x95, 0x01, // Report Count (1)
|
||||||
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
|
0x09, 0x80, // Usage (Selection)
|
||||||
|
0xA1, 0x02, // Collection (Logical)
|
||||||
|
0x05, 0x09, // Usage Page (Button)
|
||||||
|
0x19, 0x01, // Usage Minimum (0x01)
|
||||||
|
0x29, 0x03, // Usage Maximum (0x03)
|
||||||
|
0x15, 0x01, // Logical Minimum (1)
|
||||||
|
0x25, 0x03, // Logical Maximum (3)
|
||||||
|
0x75, 0x02, // Report Size (2)
|
||||||
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
|
0xC0, // End Collection
|
||||||
|
0x81, 0x03, // Input (Constant, Variable, Absolute)
|
||||||
|
0xC0, // End Collection
|
||||||
};
|
};
|
||||||
|
|
||||||
static esp_hid_raw_report_map_t s_report_maps[] = {
|
static esp_hid_raw_report_map_t s_report_maps[] = {
|
||||||
{
|
{
|
||||||
.data = s_keyboard_report_map,
|
.data = s_hid_report_map,
|
||||||
.len = sizeof(s_keyboard_report_map),
|
.len = sizeof(s_hid_report_map),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,9 +154,56 @@ static esp_hidd_dev_t *s_hid_dev;
|
|||||||
static ble_hid_status_cb_t s_status_cb;
|
static ble_hid_status_cb_t s_status_cb;
|
||||||
static bool s_connected;
|
static bool s_connected;
|
||||||
|
|
||||||
|
static void ble_hid_cc_set_volume_up(uint8_t *buffer)
|
||||||
|
{
|
||||||
|
buffer[0] &= HID_CC_RPT_VOLUME_BITS;
|
||||||
|
buffer[0] |= HID_CC_RPT_VOLUME_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ble_hid_cc_set_volume_down(uint8_t *buffer)
|
||||||
|
{
|
||||||
|
buffer[0] &= HID_CC_RPT_VOLUME_BITS;
|
||||||
|
buffer[0] |= HID_CC_RPT_VOLUME_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ble_hid_cc_set_button(uint8_t *buffer, uint8_t button)
|
||||||
|
{
|
||||||
|
buffer[1] &= HID_CC_RPT_BUTTON_BITS;
|
||||||
|
buffer[1] |= button;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ble_hid_encode_consumer_report(uint16_t usage, uint8_t buffer[HID_CONSUMER_REPORT_LEN])
|
||||||
|
{
|
||||||
|
memset(buffer, 0, HID_CONSUMER_REPORT_LEN);
|
||||||
|
|
||||||
|
switch (usage) {
|
||||||
|
case HID_CONSUMER_VOLUME_UP:
|
||||||
|
ble_hid_cc_set_volume_up(buffer);
|
||||||
|
return true;
|
||||||
|
case HID_CONSUMER_VOLUME_DOWN:
|
||||||
|
ble_hid_cc_set_volume_down(buffer);
|
||||||
|
return true;
|
||||||
|
case HID_CONSUMER_MUTE:
|
||||||
|
ble_hid_cc_set_button(buffer, HID_CC_RPT_MUTE);
|
||||||
|
return true;
|
||||||
|
case HID_CONSUMER_PLAY_PAUSE:
|
||||||
|
ble_hid_cc_set_button(buffer, HID_CC_RPT_PLAY);
|
||||||
|
return true;
|
||||||
|
case HID_CONSUMER_SCAN_NEXT:
|
||||||
|
ble_hid_cc_set_button(buffer, HID_CC_RPT_SCAN_NEXT_TRK);
|
||||||
|
return true;
|
||||||
|
case HID_CONSUMER_SCAN_PREVIOUS:
|
||||||
|
ble_hid_cc_set_button(buffer, HID_CC_RPT_SCAN_PREV_TRK);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
ESP_LOGW(TAG, "unsupported consumer usage 0x%04X", usage);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ble_hid_log_buffer(const char *label, const uint8_t *data, size_t len)
|
static void ble_hid_log_buffer(const char *label, const uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
char hex[32];
|
char hex[40];
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < len && pos + 3 < sizeof(hex); i++) {
|
for (size_t i = 0; i < len && pos + 3 < sizeof(hex); i++) {
|
||||||
@@ -62,17 +213,33 @@ static void ble_hid_log_buffer(const char *label, const uint8_t *data, size_t le
|
|||||||
ESP_LOGI(TAG, "%s len=%u: %s", label, (unsigned)len, hex);
|
ESP_LOGI(TAG, "%s len=%u: %s", label, (unsigned)len, hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ble_hid_send_idle_report(void)
|
static int ble_hid_send_input_report(uint8_t report_id, const uint8_t *buffer, size_t len,
|
||||||
|
const char *label)
|
||||||
{
|
{
|
||||||
uint8_t buffer[HID_KEYBOARD_REPORT_LEN] = {0};
|
esp_err_t ret;
|
||||||
|
|
||||||
|
if (!ble_hid_ready()) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_hid_log_buffer(label, buffer, len);
|
||||||
|
ret = esp_hidd_dev_input_set(s_hid_dev, 0, report_id, (uint8_t *)buffer, len);
|
||||||
|
return (ret == ESP_OK) ? 0 : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ble_hid_send_idle_reports(void)
|
||||||
|
{
|
||||||
|
uint8_t keyboard[HID_KEYBOARD_REPORT_LEN] = {0};
|
||||||
|
uint8_t consumer[HID_CONSUMER_REPORT_LEN] = {0};
|
||||||
|
|
||||||
if (!ble_hid_ready()) {
|
if (!ble_hid_ready()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ble_hid_log_buffer("idle", buffer, sizeof(buffer));
|
(void)ble_hid_send_input_report(HID_KEYBOARD_REPORT_ID, keyboard, sizeof(keyboard),
|
||||||
(void)esp_hidd_dev_input_set(s_hid_dev, 0, HID_KEYBOARD_REPORT_ID, buffer,
|
"keyboard idle");
|
||||||
sizeof(buffer));
|
(void)ble_hid_send_input_report(HID_CONSUMER_REPORT_ID, consumer, sizeof(consumer),
|
||||||
|
"consumer idle");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ble_hid_idle_task(void *arg)
|
static void ble_hid_idle_task(void *arg)
|
||||||
@@ -80,7 +247,7 @@ static void ble_hid_idle_task(void *arg)
|
|||||||
(void)arg;
|
(void)arg;
|
||||||
/* Windows often enables notify a few seconds after connect. */
|
/* Windows often enables notify a few seconds after connect. */
|
||||||
vTaskDelay(pdMS_TO_TICKS(3500));
|
vTaskDelay(pdMS_TO_TICKS(3500));
|
||||||
ble_hid_send_idle_report();
|
ble_hid_send_idle_reports();
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,15 +324,15 @@ int ble_hid_init(ble_hid_status_cb_t status_cb)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(TAG, "esp_hidd keyboard ready (report payload=%u bytes)",
|
ESP_LOGI(TAG, "esp_hidd ready (keyboard=%u bytes, consumer=%u bytes)",
|
||||||
(unsigned)HID_KEYBOARD_REPORT_LEN);
|
(unsigned)HID_KEYBOARD_REPORT_LEN, (unsigned)HID_CONSUMER_REPORT_LEN);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ble_hid_on_input_notify(bool enabled)
|
void ble_hid_on_input_notify(bool enabled)
|
||||||
{
|
{
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
ble_hid_send_idle_report();
|
ble_hid_send_idle_reports();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +344,6 @@ bool ble_hid_ready(void)
|
|||||||
int ble_hid_key_press(uint8_t modifier, uint8_t keycode)
|
int ble_hid_key_press(uint8_t modifier, uint8_t keycode)
|
||||||
{
|
{
|
||||||
uint8_t buffer[HID_KEYBOARD_REPORT_LEN] = {0};
|
uint8_t buffer[HID_KEYBOARD_REPORT_LEN] = {0};
|
||||||
esp_err_t ret;
|
|
||||||
|
|
||||||
if (!ble_hid_ready()) {
|
if (!ble_hid_ready()) {
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
@@ -185,26 +351,18 @@ int ble_hid_key_press(uint8_t modifier, uint8_t keycode)
|
|||||||
|
|
||||||
buffer[0] = modifier;
|
buffer[0] = modifier;
|
||||||
buffer[2] = keycode;
|
buffer[2] = keycode;
|
||||||
ble_hid_log_buffer("press", buffer, sizeof(buffer));
|
return ble_hid_send_input_report(HID_KEYBOARD_REPORT_ID, buffer, sizeof(buffer), "press");
|
||||||
|
|
||||||
ret = esp_hidd_dev_input_set(s_hid_dev, 0, HID_KEYBOARD_REPORT_ID, buffer,
|
|
||||||
sizeof(buffer));
|
|
||||||
return (ret == ESP_OK) ? 0 : ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ble_hid_key_release(void)
|
int ble_hid_key_release(void)
|
||||||
{
|
{
|
||||||
uint8_t buffer[HID_KEYBOARD_REPORT_LEN] = {0};
|
uint8_t buffer[HID_KEYBOARD_REPORT_LEN] = {0};
|
||||||
esp_err_t ret;
|
|
||||||
|
|
||||||
if (!ble_hid_ready()) {
|
if (!ble_hid_ready()) {
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ble_hid_log_buffer("release", buffer, sizeof(buffer));
|
return ble_hid_send_input_report(HID_KEYBOARD_REPORT_ID, buffer, sizeof(buffer), "release");
|
||||||
ret = esp_hidd_dev_input_set(s_hid_dev, 0, HID_KEYBOARD_REPORT_ID, buffer,
|
|
||||||
sizeof(buffer));
|
|
||||||
return (ret == ESP_OK) ? 0 : ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ble_hid_send_combo(uint8_t modifier, uint8_t keycode)
|
int ble_hid_send_combo(uint8_t modifier, uint8_t keycode)
|
||||||
@@ -220,6 +378,51 @@ int ble_hid_send_combo(uint8_t modifier, uint8_t keycode)
|
|||||||
return ble_hid_key_release();
|
return ble_hid_key_release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ble_hid_consumer_press(uint16_t usage)
|
||||||
|
{
|
||||||
|
uint8_t buffer[HID_CONSUMER_REPORT_LEN] = {0};
|
||||||
|
|
||||||
|
if (!ble_hid_ready()) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usage == 0) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ble_hid_encode_consumer_report(usage, buffer)) {
|
||||||
|
return ESP_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ble_hid_send_input_report(HID_CONSUMER_REPORT_ID, buffer, sizeof(buffer),
|
||||||
|
"consumer press");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ble_hid_consumer_release(void)
|
||||||
|
{
|
||||||
|
uint8_t buffer[HID_CONSUMER_REPORT_LEN] = {0};
|
||||||
|
|
||||||
|
if (!ble_hid_ready()) {
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ble_hid_send_input_report(HID_CONSUMER_REPORT_ID, buffer, sizeof(buffer),
|
||||||
|
"consumer release");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ble_hid_send_consumer(uint16_t usage)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ble_hid_consumer_press(usage);
|
||||||
|
if (rc != 0) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
|
return ble_hid_consumer_release();
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int ble_hid_init(ble_hid_status_cb_t status_cb)
|
int ble_hid_init(ble_hid_status_cb_t status_cb)
|
||||||
@@ -252,4 +455,10 @@ int ble_hid_send_combo(uint8_t modifier, uint8_t keycode)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ble_hid_send_consumer(uint16_t usage)
|
||||||
|
{
|
||||||
|
(void)usage;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* BOARD_BLE_ENABLED */
|
#endif /* BOARD_BLE_ENABLED */
|
||||||
|
|||||||
@@ -13,6 +13,13 @@
|
|||||||
#define HID_KEY_X 0x1B
|
#define HID_KEY_X 0x1B
|
||||||
#define HID_KEY_F5 0x3E
|
#define HID_KEY_F5 0x3E
|
||||||
|
|
||||||
|
#define HID_CONSUMER_VOLUME_UP 0x00E9
|
||||||
|
#define HID_CONSUMER_VOLUME_DOWN 0x00EA
|
||||||
|
#define HID_CONSUMER_MUTE 0x00E2
|
||||||
|
#define HID_CONSUMER_PLAY_PAUSE 0x00CD
|
||||||
|
#define HID_CONSUMER_SCAN_NEXT 0x00B5
|
||||||
|
#define HID_CONSUMER_SCAN_PREVIOUS 0x00B6
|
||||||
|
|
||||||
typedef void (*ble_hid_status_cb_t)(bool connected);
|
typedef void (*ble_hid_status_cb_t)(bool connected);
|
||||||
|
|
||||||
int ble_hid_init(ble_hid_status_cb_t status_cb);
|
int ble_hid_init(ble_hid_status_cb_t status_cb);
|
||||||
@@ -21,6 +28,7 @@ bool ble_hid_ready(void);
|
|||||||
int ble_hid_key_press(uint8_t modifier, uint8_t keycode);
|
int ble_hid_key_press(uint8_t modifier, uint8_t keycode);
|
||||||
int ble_hid_key_release(void);
|
int ble_hid_key_release(void);
|
||||||
int ble_hid_send_combo(uint8_t modifier, uint8_t keycode);
|
int ble_hid_send_combo(uint8_t modifier, uint8_t keycode);
|
||||||
|
int ble_hid_send_consumer(uint16_t usage);
|
||||||
|
|
||||||
#if defined(BOARD_BLE_ENABLED) && BOARD_BLE_ENABLED
|
#if defined(BOARD_BLE_ENABLED) && BOARD_BLE_ENABLED
|
||||||
void ble_hid_on_input_notify(bool enabled);
|
void ble_hid_on_input_notify(bool enabled);
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
// This file was generated by SquareLine Studio
|
||||||
|
// SquareLine Studio version: SquareLine Studio 1.6.1
|
||||||
|
// LVGL version: 9.2.2
|
||||||
|
// Project name: HeavenlyHeroStar
|
||||||
|
|
||||||
|
#include "../ui.h"
|
||||||
|
|
||||||
|
lv_obj_t * ui_Screen3 = NULL;
|
||||||
|
lv_obj_t * ui_BtnVolDown = NULL;
|
||||||
|
lv_obj_t * ui_BtnVolUp = NULL;
|
||||||
|
lv_obj_t * ui_BtnMute = NULL;
|
||||||
|
lv_obj_t * ui_BtnPlayPause = NULL;
|
||||||
|
lv_obj_t * ui_BtnPrev = NULL;
|
||||||
|
lv_obj_t * ui_BtnNext = NULL;
|
||||||
|
lv_obj_t * ui_LabelVolDown = NULL;
|
||||||
|
lv_obj_t * ui_LabelVolUp = NULL;
|
||||||
|
lv_obj_t * ui_LabelMute = NULL;
|
||||||
|
lv_obj_t * ui_LabelPlayPause = NULL;
|
||||||
|
lv_obj_t * ui_LabelPrev = NULL;
|
||||||
|
lv_obj_t * ui_LabelNext = NULL;
|
||||||
|
|
||||||
|
static void ui_screen3_create_button(lv_obj_t **btn, lv_obj_t **label, int32_t x, int32_t y,
|
||||||
|
const char *text)
|
||||||
|
{
|
||||||
|
*btn = lv_button_create(ui_Screen3);
|
||||||
|
lv_obj_set_width(*btn, 75);
|
||||||
|
lv_obj_set_height(*btn, 90);
|
||||||
|
lv_obj_set_x(*btn, x);
|
||||||
|
lv_obj_set_y(*btn, y);
|
||||||
|
lv_obj_set_align(*btn, LV_ALIGN_CENTER);
|
||||||
|
lv_obj_add_flag(*btn, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
|
||||||
|
lv_obj_remove_flag(*btn, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
*label = lv_label_create(ui_Screen3);
|
||||||
|
lv_obj_set_width(*label, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_height(*label, LV_SIZE_CONTENT);
|
||||||
|
lv_obj_set_x(*label, x);
|
||||||
|
lv_obj_set_y(*label, y);
|
||||||
|
lv_obj_set_align(*label, LV_ALIGN_CENTER);
|
||||||
|
lv_label_set_text(*label, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// event funtions
|
||||||
|
void ui_event_BtnVolDown(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
click_consumer_vol_down(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_event_BtnVolUp(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
click_consumer_vol_up(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_event_BtnMute(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
click_consumer_mute(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_event_BtnPlayPause(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
click_consumer_play_pause(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_event_BtnPrev(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
click_consumer_prev(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_event_BtnNext(lv_event_t * e)
|
||||||
|
{
|
||||||
|
lv_event_code_t event_code = lv_event_get_code(e);
|
||||||
|
|
||||||
|
if(event_code == LV_EVENT_CLICKED) {
|
||||||
|
click_consumer_next(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build funtions
|
||||||
|
|
||||||
|
void ui_Screen3_screen_init(void)
|
||||||
|
{
|
||||||
|
ui_Screen3 = lv_obj_create(NULL);
|
||||||
|
lv_obj_remove_flag(ui_Screen3, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
|
ui_screen3_create_button(&ui_BtnVolDown, &ui_LabelVolDown, -42, -107, "Vol-");
|
||||||
|
ui_screen3_create_button(&ui_BtnVolUp, &ui_LabelVolUp, 42, -107, "Vol+");
|
||||||
|
ui_screen3_create_button(&ui_BtnMute, &ui_LabelMute, -42, 0, "Mute");
|
||||||
|
ui_screen3_create_button(&ui_BtnPlayPause, &ui_LabelPlayPause, 42, 0, "Play");
|
||||||
|
ui_screen3_create_button(&ui_BtnPrev, &ui_LabelPrev, -42, 107, "Prev");
|
||||||
|
ui_screen3_create_button(&ui_BtnNext, &ui_LabelNext, 42, 107, "Next");
|
||||||
|
|
||||||
|
lv_obj_add_event_cb(ui_BtnVolDown, ui_event_BtnVolDown, LV_EVENT_ALL, NULL);
|
||||||
|
lv_obj_add_event_cb(ui_BtnVolUp, ui_event_BtnVolUp, LV_EVENT_ALL, NULL);
|
||||||
|
lv_obj_add_event_cb(ui_BtnMute, ui_event_BtnMute, LV_EVENT_ALL, NULL);
|
||||||
|
lv_obj_add_event_cb(ui_BtnPlayPause, ui_event_BtnPlayPause, LV_EVENT_ALL, NULL);
|
||||||
|
lv_obj_add_event_cb(ui_BtnPrev, ui_event_BtnPrev, LV_EVENT_ALL, NULL);
|
||||||
|
lv_obj_add_event_cb(ui_BtnNext, ui_event_BtnNext, LV_EVENT_ALL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_Screen3_screen_destroy(void)
|
||||||
|
{
|
||||||
|
if(ui_Screen3) lv_obj_del(ui_Screen3);
|
||||||
|
|
||||||
|
ui_Screen3 = NULL;
|
||||||
|
ui_BtnVolDown = NULL;
|
||||||
|
ui_BtnVolUp = NULL;
|
||||||
|
ui_BtnMute = NULL;
|
||||||
|
ui_BtnPlayPause = NULL;
|
||||||
|
ui_BtnPrev = NULL;
|
||||||
|
ui_BtnNext = NULL;
|
||||||
|
ui_LabelVolDown = NULL;
|
||||||
|
ui_LabelVolUp = NULL;
|
||||||
|
ui_LabelMute = NULL;
|
||||||
|
ui_LabelPlayPause = NULL;
|
||||||
|
ui_LabelPrev = NULL;
|
||||||
|
ui_LabelNext = NULL;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// This file was generated by SquareLine Studio
|
||||||
|
// SquareLine Studio version: SquareLine Studio 1.6.1
|
||||||
|
// LVGL version: 9.2.2
|
||||||
|
// Project name: HeavenlyHeroStar
|
||||||
|
|
||||||
|
#ifndef UI_SCREEN3_H
|
||||||
|
#define UI_SCREEN3_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// SCREEN: ui_Screen3
|
||||||
|
extern void ui_Screen3_screen_init(void);
|
||||||
|
extern void ui_Screen3_screen_destroy(void);
|
||||||
|
extern lv_obj_t * ui_Screen3;
|
||||||
|
extern void ui_event_BtnVolDown(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_BtnVolDown;
|
||||||
|
extern void ui_event_BtnVolUp(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_BtnVolUp;
|
||||||
|
extern void ui_event_BtnMute(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_BtnMute;
|
||||||
|
extern void ui_event_BtnPlayPause(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_BtnPlayPause;
|
||||||
|
extern void ui_event_BtnPrev(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_BtnPrev;
|
||||||
|
extern void ui_event_BtnNext(lv_event_t * e);
|
||||||
|
extern lv_obj_t * ui_BtnNext;
|
||||||
|
extern lv_obj_t * ui_LabelVolDown;
|
||||||
|
extern lv_obj_t * ui_LabelVolUp;
|
||||||
|
extern lv_obj_t * ui_LabelMute;
|
||||||
|
extern lv_obj_t * ui_LabelPlayPause;
|
||||||
|
extern lv_obj_t * ui_LabelPrev;
|
||||||
|
extern lv_obj_t * ui_LabelNext;
|
||||||
|
// CUSTOM VARIABLES
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /*extern "C"*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
+3
-1
@@ -32,12 +32,14 @@ void ui_init(void)
|
|||||||
lv_disp_set_theme(dispp, theme);
|
lv_disp_set_theme(dispp, theme);
|
||||||
ui_Screen1_screen_init();
|
ui_Screen1_screen_init();
|
||||||
ui_Screen2_screen_init();
|
ui_Screen2_screen_init();
|
||||||
|
ui_Screen3_screen_init();
|
||||||
ui____initial_actions0 = lv_obj_create(NULL);
|
ui____initial_actions0 = lv_obj_create(NULL);
|
||||||
lv_disp_load_scr(ui_Screen2);
|
lv_disp_load_scr(ui_Screen3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_destroy(void)
|
void ui_destroy(void)
|
||||||
{
|
{
|
||||||
ui_Screen1_screen_destroy();
|
ui_Screen1_screen_destroy();
|
||||||
ui_Screen2_screen_destroy();
|
ui_Screen2_screen_destroy();
|
||||||
|
ui_Screen3_screen_destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "screens/ui_Screen1.h"
|
#include "screens/ui_Screen1.h"
|
||||||
#include "screens/ui_Screen2.h"
|
#include "screens/ui_Screen2.h"
|
||||||
|
#include "screens/ui_Screen3.h"
|
||||||
|
|
||||||
///////////////////// VARIABLES ////////////////////
|
///////////////////// VARIABLES ////////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -24,3 +24,33 @@ void click_button_one(lv_event_t * e)
|
|||||||
{
|
{
|
||||||
// Your code here
|
// Your code here
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void click_consumer_vol_up(lv_event_t * e)
|
||||||
|
{
|
||||||
|
// Your code here
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_vol_down(lv_event_t * e)
|
||||||
|
{
|
||||||
|
// Your code here
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_mute(lv_event_t * e)
|
||||||
|
{
|
||||||
|
// Your code here
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_play_pause(lv_event_t * e)
|
||||||
|
{
|
||||||
|
// Your code here
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_prev(lv_event_t * e)
|
||||||
|
{
|
||||||
|
// Your code here
|
||||||
|
}
|
||||||
|
|
||||||
|
void click_consumer_next(lv_event_t * e)
|
||||||
|
{
|
||||||
|
// Your code here
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ void update_year_action(lv_event_t * e);
|
|||||||
void click_button_two(lv_event_t * e);
|
void click_button_two(lv_event_t * e);
|
||||||
void click_button_three(lv_event_t * e);
|
void click_button_three(lv_event_t * e);
|
||||||
void click_button_one(lv_event_t * e);
|
void click_button_one(lv_event_t * e);
|
||||||
|
void click_consumer_vol_up(lv_event_t * e);
|
||||||
|
void click_consumer_vol_down(lv_event_t * e);
|
||||||
|
void click_consumer_mute(lv_event_t * e);
|
||||||
|
void click_consumer_play_pause(lv_event_t * e);
|
||||||
|
void click_consumer_prev(lv_event_t * e);
|
||||||
|
void click_consumer_next(lv_event_t * e);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /*extern "C"*/
|
} /*extern "C"*/
|
||||||
|
|||||||
Reference in New Issue
Block a user