请教 尝试同时使用蓝牙HID例程的HID Media和HID 键盘 无报错错误

dpiner
Posts: 3
Joined: Sun Feb 02, 2025 3:43 am

请教 尝试同时使用蓝牙HID例程的HID Media和HID 键盘 无报错错误

Postby dpiner » Sun Feb 02, 2025 4:04 am

HID报文如下: 基于BLEHID设备的例程进行修改

Code: Untitled.c Select all

const unsigned char mediaReportMap[] = {//Media 报文

0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x00, // Report ID (0)
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,Abs,No Wrap,Linear,Preferred State,No Null Position)
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,Var,Rel,No Wrap,Linear,Preferred State,Null State)
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,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
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,Abs,No Wrap,Linear,Preferred State,No Null Position)
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,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection

0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Kbrd/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,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x05, // Usage Maximum (Kana)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x05, // Report Count (5)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x29, 0x65, // Usage Maximum (0x65)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection


0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Kbrd/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,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x05, // Usage Maximum (Kana)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x05, // Report Count (5)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x29, 0x65, // Usage Maximum (0x65)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
log无报错,警告如下,但是HID调节音量正常执行

W (2897) BT_HCI: hcif disc complete: hdl 0x1, rsn 0x3e
W (2897) BT_HCI: btu_hcif_hdl_command_status,opcode:0x2016,status:0x02

实现代码如下:

esp_hidd_send_consumer_value(HID_CONSUMER_MENU, true);
vTaskDelay(KeyPressDelay / portTICK_PERIOD_MS);
esp_hidd_send_consumer_value(HID_CONSUMER_MENU, false);
ESP_LOGI(TAG, "HID_CONSUMER_MENU");

vTaskDelay(KeyPressDelay / portTICK_PERIOD_MS);

send_keyboard('1');//可以直接调用?
vTaskDelay(KeyPressDelay / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "UP_CODE");

设置comsumer的代码正常执行,但是键盘的操作未能正确执行,感谢!

附上
Attachments
Snipaste_2025-02-02_12-03-52.jpg
HID设备树信息
Snipaste_2025-02-02_12-03-52.jpg (295.01 KiB) Viewed 2485 times
:geek: :oops: :D

dpiner
Posts: 3
Joined: Sun Feb 02, 2025 3:43 am

Re: 请教 尝试同时使用蓝牙HID例程的HID Media和HID 键盘 无报错错误

Postby dpiner » Mon Feb 03, 2025 4:05 am

单独使用键盘也有问题
E (574964) BLE_HIDD: Indicate Not Enabled: 0

Code: Untitled.c Select all


/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#define CONFIG_EXAMPLE_HID_DEVICE_ROLE 2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_bt.h"

#if CONFIG_BT_NIMBLE_ENABLED
#include "host/ble_hs.h"
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#else
#include "esp_bt_defs.h"
#if CONFIG_BT_BLE_ENABLED
#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
#include "esp_gatt_defs.h"
#endif
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#if CONFIG_BT_SDP_COMMON_ENABLED
#include "esp_sdp_api.h"
#endif /* CONFIG_BT_SDP_COMMON_ENABLED */
#endif

#include "esp_hidd.h"
#include "esp_hid_gap.h"

static const char *TAG = "HID_DEV_DEMO";

typedef struct
{
TaskHandle_t task_hdl;
esp_hidd_dev_t *hid_dev;
uint8_t protocol_mode;
uint8_t *buffer;
} local_param_t;

static local_param_t s_ble_hid_param = {0};


#define CASE(a, b, c) \
case a: \
buffer[0] = b; \
buffer[2] = c; \
break;\

// USB keyboard codes
#define USB_HID_MODIFIER_LEFT_CTRL 0x01
#define USB_HID_MODIFIER_LEFT_SHIFT 0x02
#define USB_HID_MODIFIER_LEFT_ALT 0x04
#define USB_HID_MODIFIER_RIGHT_CTRL 0x10
#define USB_HID_MODIFIER_RIGHT_SHIFT 0x20
#define USB_HID_MODIFIER_RIGHT_ALT 0x40

#define USB_HID_SPACE 0x2C
#define USB_HID_DOT 0x37
#define USB_HID_NEWLINE 0x28
#define USB_HID_FSLASH 0x38
#define USB_HID_BSLASH 0x31
#define USB_HID_COMMA 0x36
#define USB_HID_DOT 0x37

const unsigned char keyboardReportMap[] = { //7 bytes input (modifiers, resrvd, keys*5), 1 byte output

0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION

/*
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Kbrd/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,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05, // Report Count (5)
0x75, 0x01, // Report Size (1)
0x05, 0x08, // Usage Page (LEDs)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x05, // Usage Maximum (Kana)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x01, // Report Count (1)
0x75, 0x03, // Report Size (3)
0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x05, // Report Count (5)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x29, 0x65, // Usage Maximum (0x65)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
*/
// 65 bytes
};

static void char_to_code(uint8_t *buffer, char ch)
{
// Check if lower or upper case
if(ch >= 'a' && ch <= 'z')
{
buffer[0] = 0;
// convert ch to HID letter, starting at a = 4
buffer[2] = (uint8_t)(4 + (ch - 'a'));
}
else if(ch >= 'A' && ch <= 'Z')
{
// Add left shift
buffer[0] = USB_HID_MODIFIER_LEFT_SHIFT;
// convert ch to lower case
ch = ch - ('A'-'a');
// convert ch to HID letter, starting at a = 4
buffer[2] = (uint8_t)(4 + (ch - 'a'));
}
else if(ch >= '0' && ch <= '9') // Check if number
{
buffer[0] = 0;
// convert ch to HID number, starting at 1 = 30, 0 = 39
if(ch == '0')
{
buffer[2] = 39;
}
else
{
buffer[2] = (uint8_t)(30 + (ch - '1'));
}
}
else // not a letter nor a number
{
switch(ch)
{
CASE(' ', 0, USB_HID_SPACE);
CASE('.', 0,USB_HID_DOT);
CASE('\n', 0, USB_HID_NEWLINE);
CASE('?', USB_HID_MODIFIER_LEFT_SHIFT, USB_HID_FSLASH);
CASE('/', 0 ,USB_HID_FSLASH);
CASE('\\', 0, USB_HID_BSLASH);
CASE('|', USB_HID_MODIFIER_LEFT_SHIFT, USB_HID_BSLASH);
CASE(',', 0, USB_HID_COMMA);
CASE('<', USB_HID_MODIFIER_LEFT_SHIFT, USB_HID_COMMA);
CASE('>', USB_HID_MODIFIER_LEFT_SHIFT, USB_HID_COMMA);
CASE('@', USB_HID_MODIFIER_LEFT_SHIFT, 31);
CASE('!', USB_HID_MODIFIER_LEFT_SHIFT, 30);
CASE('#', USB_HID_MODIFIER_LEFT_SHIFT, 32);
CASE('$', USB_HID_MODIFIER_LEFT_SHIFT, 33);
CASE('%', USB_HID_MODIFIER_LEFT_SHIFT, 34);
CASE('^', USB_HID_MODIFIER_LEFT_SHIFT,35);
CASE('&', USB_HID_MODIFIER_LEFT_SHIFT, 36);
CASE('*', USB_HID_MODIFIER_LEFT_SHIFT, 37);
CASE('(', USB_HID_MODIFIER_LEFT_SHIFT, 38);
CASE(')', USB_HID_MODIFIER_LEFT_SHIFT, 39);
CASE('-', 0, 0x2D);
CASE('_', USB_HID_MODIFIER_LEFT_SHIFT, 0x2D);
CASE('=', 0, 0x2E);
CASE('+', USB_HID_MODIFIER_LEFT_SHIFT, 39);
CASE(8, 0, 0x2A); // backspace
CASE('\t', 0, 0x2B);
default:
buffer[0] = 0;
buffer[2] = 0;
}
}
}

#define REPORT_ID 0
void send_keyboard(char c)
{
static uint8_t buffer[8] = {0};
char_to_code(buffer, c);
esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, REPORT_ID, buffer, 8);
/* send the keyrelease event with sufficient delay */
vTaskDelay(50 / portTICK_PERIOD_MS);
memset(buffer, 0, sizeof(uint8_t) * 8);
esp_hidd_dev_input_set(s_ble_hid_param.hid_dev, 0, REPORT_ID, buffer, 8);
}

void ble_hid_demo_task_kbd(void *pvParameters)
{
char c = '1';

while (1) {

if(c != 255) {
send_keyboard(c);
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}

static esp_hid_raw_report_map_t ble_report_maps[] = {
{
.data = keyboardReportMap,
.len = sizeof(keyboardReportMap)
}
};

static esp_hid_device_config_t ble_hid_config = {
.vendor_id = 0x16C0,
.product_id = 0x05DF,
.version = 0x0100,
.device_name = "ESP Keyboard",
.manufacturer_name = "Espressif",
.serial_number = "1234567890",
.report_maps = ble_report_maps,
.report_maps_len = 1
};

#define HID_CC_RPT_MUTE 1
#define HID_CC_RPT_POWER 2
#define HID_CC_RPT_LAST 3
#define HID_CC_RPT_ASSIGN_SEL 4
#define HID_CC_RPT_PLAY 5
#define HID_CC_RPT_PAUSE 6
#define HID_CC_RPT_RECORD 7
#define HID_CC_RPT_FAST_FWD 8
#define HID_CC_RPT_REWIND 9
#define HID_CC_RPT_SCAN_NEXT_TRK 10
#define HID_CC_RPT_SCAN_PREV_TRK 11
#define HID_CC_RPT_STOP 12

#define HID_CC_RPT_CHANNEL_UP 0x10
#define HID_CC_RPT_CHANNEL_DOWN 0x30
#define HID_CC_RPT_VOLUME_UP 0x40
#define HID_CC_RPT_VOLUME_DOWN 0x80

// HID Consumer Control report bitmasks
#define HID_CC_RPT_NUMERIC_BITS 0xF0
#define HID_CC_RPT_CHANNEL_BITS 0xCF
#define HID_CC_RPT_VOLUME_BITS 0x3F
#define HID_CC_RPT_BUTTON_BITS 0xF0
#define HID_CC_RPT_SELECTION_BITS 0xCF

// Macros for the HID Consumer Control 2-byte report
#define HID_CC_RPT_SET_NUMERIC(s, x) (s)[0] &= HID_CC_RPT_NUMERIC_BITS; (s)[0] = (x)
#define HID_CC_RPT_SET_CHANNEL(s, x) (s)[0] &= HID_CC_RPT_CHANNEL_BITS; (s)[0] |= ((x) & 0x03) << 4
#define HID_CC_RPT_SET_VOLUME_UP(s) (s)[0] &= HID_CC_RPT_VOLUME_BITS; (s)[0] |= 0x40
#define HID_CC_RPT_SET_VOLUME_DOWN(s) (s)[0] &= HID_CC_RPT_VOLUME_BITS; (s)[0] |= 0x80
#define HID_CC_RPT_SET_BUTTON(s, x) (s)[1] &= HID_CC_RPT_BUTTON_BITS; (s)[1] |= (x)
#define HID_CC_RPT_SET_SELECTION(s, x) (s)[1] &= HID_CC_RPT_SELECTION_BITS; (s)[1] |= ((x) & 0x03) << 4

// HID Consumer Usage IDs (subset of the codes available in the USB HID Usage Tables spec)
#define HID_CONSUMER_POWER 48 // Power
#define HID_CONSUMER_RESET 49 // Reset
#define HID_CONSUMER_SLEEP 50 // Sleep

#define HID_CONSUMER_MENU 64 // Menu
#define HID_CONSUMER_SELECTION 128 // Selection
#define HID_CONSUMER_ASSIGN_SEL 129 // Assign Selection
#define HID_CONSUMER_MODE_STEP 130 // Mode Step
#define HID_CONSUMER_RECALL_LAST 131 // Recall Last
#define HID_CONSUMER_QUIT 148 // Quit
#define HID_CONSUMER_HELP 149 // Help
#define HID_CONSUMER_CHANNEL_UP 156 // Channel Increment
#define HID_CONSUMER_CHANNEL_DOWN 157 // Channel Decrement

#define HID_CONSUMER_PLAY 176 // Play
#define HID_CONSUMER_PAUSE 177 // Pause
#define HID_CONSUMER_RECORD 178 // Record
#define HID_CONSUMER_FAST_FORWARD 179 // Fast Forward
#define HID_CONSUMER_REWIND 180 // Rewind
#define HID_CONSUMER_SCAN_NEXT_TRK 181 // Scan Next Track
#define HID_CONSUMER_SCAN_PREV_TRK 182 // Scan Previous Track
#define HID_CONSUMER_STOP 183 // Stop
#define HID_CONSUMER_EJECT 184 // Eject
#define HID_CONSUMER_RANDOM_PLAY 185 // Random Play
#define HID_CONSUMER_SELECT_DISC 186 // Select Disk
#define HID_CONSUMER_ENTER_DISC 187 // Enter Disc
#define HID_CONSUMER_REPEAT 188 // Repeat
#define HID_CONSUMER_STOP_EJECT 204 // Stop/Eject
#define HID_CONSUMER_PLAY_PAUSE 205 // Play/Pause
#define HID_CONSUMER_PLAY_SKIP 206 // Play/Skip

#define HID_CONSUMER_VOLUME 224 // Volume
#define HID_CONSUMER_BALANCE 225 // Balance
#define HID_CONSUMER_MUTE 226 // Mute
#define HID_CONSUMER_BASS 227 // Bass
#define HID_CONSUMER_VOLUME_UP 233 // Volume Increment
#define HID_CONSUMER_VOLUME_DOWN 234 // Volume Decrement

void ble_hid_task_start_up(void)
{
if (s_ble_hid_param.task_hdl) {
// Task already exists
return;
}
/* Nimble Specific */
xTaskCreate(ble_hid_demo_task_kbd, "ble_hid_demo_task_kbd", 3 * 1024, NULL, configMAX_PRIORITIES - 3,
&s_ble_hid_param.task_hdl);
}

void ble_hid_task_shut_down(void)
{
if (s_ble_hid_param.task_hdl) {
vTaskDelete(s_ble_hid_param.task_hdl);
s_ble_hid_param.task_hdl = NULL;
}
}

static void ble_hidd_event_callback(void *handler_args, esp_event_base_t base, int32_t id, void *event_data)
{
esp_hidd_event_t event = (esp_hidd_event_t)id;
esp_hidd_event_data_t *param = (esp_hidd_event_data_t *)event_data;
static const char *TAG = "HID_DEV_BLE";

switch (event) {
case ESP_HIDD_START_EVENT: {
ESP_LOGI(TAG, "START");
esp_hid_ble_gap_adv_start();
break;
}
case ESP_HIDD_CONNECT_EVENT: {
ESP_LOGI(TAG, "CONNECT");
break;
}
case ESP_HIDD_PROTOCOL_MODE_EVENT: {
ESP_LOGI(TAG, "PROTOCOL MODE[%u]: %s", param->protocol_mode.map_index, param->protocol_mode.protocol_mode ? "REPORT" : "BOOT");
break;
}
case ESP_HIDD_CONTROL_EVENT: {
ESP_LOGI(TAG, "CONTROL[%u]: %sSUSPEND", param->control.map_index, param->control.control ? "EXIT_" : "");
if (param->control.control)
{
// exit suspend
ble_hid_task_start_up();
} else {
// suspend
ble_hid_task_shut_down();
}
break;
}
case ESP_HIDD_OUTPUT_EVENT: {
ESP_LOGI(TAG, "OUTPUT[%u]: %8s ID: %2u, Len: %d, Data:", param->output.map_index, esp_hid_usage_str(param->output.usage), param->output.report_id, param->output.length);
ESP_LOG_BUFFER_HEX(TAG, param->output.data, param->output.length);
break;
}
case ESP_HIDD_FEATURE_EVENT: {
ESP_LOGI(TAG, "FEATURE[%u]: %8s ID: %2u, Len: %d, Data:", param->feature.map_index, esp_hid_usage_str(param->feature.usage), param->feature.report_id, param->feature.length);
ESP_LOG_BUFFER_HEX(TAG, param->feature.data, param->feature.length);
break;
}
case ESP_HIDD_DISCONNECT_EVENT: {
ESP_LOGI(TAG, "DISCONNECT: %s", esp_hid_disconnect_reason_str(esp_hidd_dev_transport_get(param->disconnect.dev), param->disconnect.reason));
ble_hid_task_shut_down();
esp_hid_ble_gap_adv_start();
break;
}
case ESP_HIDD_STOP_EVENT: {
ESP_LOGI(TAG, "STOP");
break;
}
default:
break;
}
return;
}

void app_main(void)
{
esp_err_t ret;
#if HID_DEV_MODE == HIDD_IDLE_MODE
ESP_LOGE(TAG, "Please turn on BT HID device or BLE!");
return;
#endif
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK( ret );

ESP_LOGI(TAG, "setting hid gap, mode:%d", HID_DEV_MODE);
ret = esp_hid_gap_init(HID_DEV_MODE);
ESP_ERROR_CHECK( ret );

ret = esp_hid_ble_gap_adv_init(ESP_HID_APPEARANCE_KEYBOARD, ble_hid_config.device_name);

ESP_ERROR_CHECK( ret );
#if CONFIG_BT_BLE_ENABLED
if ((ret = esp_ble_gatts_register_callback(esp_hidd_gatts_event_handler)) != ESP_OK) {
ESP_LOGE(TAG, "GATTS register callback failed: %d", ret);
return;
}
#endif
ESP_LOGI(TAG, "setting ble device");
ESP_ERROR_CHECK(
esp_hidd_dev_init(&ble_hid_config, ESP_HID_TRANSPORT_BLE, ble_hidd_event_callback, &s_ble_hid_param.hid_dev));

#if CONFIG_BT_HID_DEVICE_ENABLED
ESP_LOGI(TAG, "setting device name");
esp_bt_gap_set_device_name(bt_hid_config.device_name);
ESP_LOGI(TAG, "setting cod major, peripheral");
esp_bt_cod_t cod = {0};
cod.major = ESP_BT_COD_MAJOR_DEV_PERIPHERAL;
cod.minor = ESP_BT_COD_MINOR_PERIPHERAL_POINTING;
esp_bt_gap_set_cod(cod, ESP_BT_SET_COD_MAJOR_MINOR);
vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "setting bt device");
ESP_ERROR_CHECK(
esp_hidd_dev_init(&bt_hid_config, ESP_HID_TRANSPORT_BT, bt_hidd_event_callback, &s_bt_hid_param.hid_dev));
#if CONFIG_BT_SDP_COMMON_ENABLED
ESP_ERROR_CHECK(esp_sdp_register_callback(esp_sdp_cb));
ESP_ERROR_CHECK(esp_sdp_init());
#endif /* CONFIG_BT_SDP_COMMON_ENABLED */
#endif /* CONFIG_BT_HID_DEVICE_ENABLED */
#if CONFIG_BT_NIMBLE_ENABLED
/* XXX Need to have template for store */
ble_store_config_init();

ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
/* Starting nimble task after gatts is initialized*/
ret = esp_nimble_enable(ble_hid_device_host_task);
if (ret) {
ESP_LOGE(TAG, "esp_nimble_enable failed: %d", ret);
}
#endif
}
这是范例程序,但是去除了与蓝牙键盘无关的内容
:geek: :oops: :D

k1k2kk
Posts: 1
Joined: Mon Sep 09, 2024 8:40 am

Re: 请教 尝试同时使用蓝牙HID例程的HID Media和HID 键盘 无报错错误

Postby k1k2kk » Wed Jun 11, 2025 3:39 am

解决了吗,我用ble50时一直出现这样的打印,几十秒后才能连上
W (17056) BT_HCI: hcif disc complete: hdl 0x1, rsn 0x3e
W (17056) BT_HCI: btu_hcif_hdl_command_status,opcode:0x2016,status:0x02
I (17056) GATTS_DEMO_PHY: Extended advertising start, status 0
I (17146) GATTS_DEMO_PHY: Extended advertising terminated, status 0
I (17156) GATTS_DEMO_PHY: Advertising successfully ended with a connection being created
W (17326) BT_HCI: hcif disc complete: hdl 0x1, rsn 0x3e
W (17326) BT_HCI: btu_hcif_hdl_command_status,opcode:0x2016,status:0x02
I (17326) GATTS_DEMO_PHY: Extended advertising start, status 0
I (17416) GATTS_DEMO_PHY: Extended advertising terminated, status 0
I (17416) GATTS_DEMO_PHY: Advertising successfully ended with a connection being created
W (17596) BT_HCI: hcif disc complete: hdl 0x1, rsn 0x3e
W (17596) BT_HCI: btu_hcif_hdl_command_status,opcode:0x2016,status:0x02
I (17596) GATTS_DEMO_PHY: Extended advertising start, status 0
I (17686) GATTS_DEMO_PHY: Extended advertising terminated, status 0
I (17686) GATTS_DEMO_PHY: Advertising successfully ended with a connection being created
W (17866) BT_HCI: hcif disc complete: hdl 0x1, rsn 0x3e
W (17866) BT_HCI: btu_hcif_hdl_command_status,opcode:0x2016,status:0x02

Who is online

Users browsing this forum: No registered users and 3 guests