USB device-mode support (#613)

This commit is contained in:
Shadowtrance
2026-08-13 05:29:35 +10:00
committed by GitHub
parent 37c507544b
commit cc8be3faef
94 changed files with 3466 additions and 399 deletions
@@ -11,6 +11,7 @@
#include <host/ble_hs_mbuf.h>
#include <services/gap/ble_svc_gap.h>
#include <services/gatt/ble_svc_gatt.h>
#include <tactility/drivers/hid_report_descriptors.h>
#include <cstring>
@@ -58,77 +59,10 @@ static uint8_t hid_protocol_mode = 0x01; // 0x00=Boot, 0x01=Report
// ============================================================================
// Per-profile HID Report Maps
// ============================================================================
// Keyboard + Consumer (IDs 1 and 2)
static const uint8_t hid_rpt_map_kb_consumer[] = {
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01,
0x85, 0x01,
0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01,
0x75, 0x01, 0x95, 0x08, 0x81, 0x02,
0x75, 0x08, 0x95, 0x01, 0x81, 0x01,
0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x75, 0x01, 0x95, 0x05, 0x91, 0x02,
0x75, 0x03, 0x95, 0x01, 0x91, 0x01,
0x15, 0x00, 0x25, 0x73, 0x05, 0x07, 0x19, 0x00, 0x29, 0x73,
0x75, 0x08, 0x95, 0x06, 0x81, 0x00,
0xC0,
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01,
0x85, 0x02,
0x15, 0x00, 0x26, 0xFF, 0x03, 0x19, 0x00, 0x2A, 0xFF, 0x03,
0x75, 0x10, 0x95, 0x01, 0x81, 0x00,
0xC0,
};
// Mouse only (ID 1, 4 bytes)
static const uint8_t hid_rpt_map_mouse[] = {
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01,
0x85, 0x01,
0x09, 0x01, 0xA1, 0x00,
0x05, 0x09, 0x19, 0x01, 0x29, 0x05,
0x15, 0x00, 0x25, 0x01, 0x95, 0x05, 0x75, 0x01, 0x81, 0x02,
0x95, 0x01, 0x75, 0x03, 0x81, 0x01,
0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38,
0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06,
0xC0, 0xC0,
};
// Keyboard + Consumer + Mouse (IDs 1, 2, 3)
static const uint8_t hid_rpt_map_kb_mouse[] = {
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01,
0x85, 0x01,
0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01,
0x75, 0x01, 0x95, 0x08, 0x81, 0x02,
0x75, 0x08, 0x95, 0x01, 0x81, 0x01,
0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x75, 0x01, 0x95, 0x05, 0x91, 0x02,
0x75, 0x03, 0x95, 0x01, 0x91, 0x01,
0x15, 0x00, 0x25, 0x73, 0x05, 0x07, 0x19, 0x00, 0x29, 0x73,
0x75, 0x08, 0x95, 0x06, 0x81, 0x00,
0xC0,
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01,
0x85, 0x02,
0x15, 0x00, 0x26, 0xFF, 0x03, 0x19, 0x00, 0x2A, 0xFF, 0x03,
0x75, 0x10, 0x95, 0x01, 0x81, 0x00,
0xC0,
0x05, 0x01, 0x09, 0x02, 0xA1, 0x01,
0x85, 0x03,
0x09, 0x01, 0xA1, 0x00,
0x05, 0x09, 0x19, 0x01, 0x29, 0x05,
0x15, 0x00, 0x25, 0x01, 0x95, 0x05, 0x75, 0x01, 0x81, 0x02,
0x95, 0x01, 0x75, 0x03, 0x81, 0x01,
0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x38,
0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06,
0xC0, 0xC0,
};
// Gamepad only (ID 1, 8 bytes)
static const uint8_t hid_rpt_map_gamepad[] = {
0x05, 0x01, 0x09, 0x05, 0xA1, 0x01,
0x85, 0x01,
0x05, 0x09, 0x19, 0x01, 0x29, 0x10,
0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x10, 0x81, 0x02,
0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x35, 0x09, 0x33, 0x09, 0x34,
0x15, 0x81, 0x25, 0x7F, 0x75, 0x08, 0x95, 0x06, 0x81, 0x02,
0xC0,
};
//
// Shared with esp32_usb_hid_device.cpp - see hid_report_descriptors.h for the byte tables
// (report ID scheme, per-field layout) - HID report descriptors are transport-independent
// so the same bytes apply verbatim whether carried over USB or BLE GATT.
// ---- Per-profile Report Reference descriptor data ----
// Format: {Report ID, Report Type} — Type: 1=Input, 2=Output
@@ -181,6 +115,7 @@ static int hid_chr_access(uint16_t /*conn_handle*/, uint16_t attr_handle,
size_t report_len = 8;
if (attr_handle == hid_consumer_input_handle) report_len = 2;
else if (attr_handle == hid_mouse_input_handle) report_len = 4;
else if (attr_handle == hid_gamepad_input_handle) report_len = 8;
int rc = os_mbuf_append(ctxt->om, zeros, report_len);
return (rc == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
@@ -354,10 +289,10 @@ bool ble_hid_switch_profile(struct Device* device, BleHidProfile profile) {
const uint8_t* new_rpt_map = nullptr;
size_t new_rpt_map_len = 0;
switch (profile) {
case BleHidProfile::KbConsumer: svcs = gatt_svcs_kb_consumer; new_rpt_map = hid_rpt_map_kb_consumer; new_rpt_map_len = sizeof(hid_rpt_map_kb_consumer); break;
case BleHidProfile::Mouse: svcs = gatt_svcs_mouse; new_rpt_map = hid_rpt_map_mouse; new_rpt_map_len = sizeof(hid_rpt_map_mouse); break;
case BleHidProfile::KbMouse: svcs = gatt_svcs_kb_mouse; new_rpt_map = hid_rpt_map_kb_mouse; new_rpt_map_len = sizeof(hid_rpt_map_kb_mouse); break;
case BleHidProfile::Gamepad: svcs = gatt_svcs_gamepad; new_rpt_map = hid_rpt_map_gamepad; new_rpt_map_len = sizeof(hid_rpt_map_gamepad); break;
case BleHidProfile::KbConsumer: svcs = gatt_svcs_kb_consumer; new_rpt_map = hid_report_map_keyboard_consumer; new_rpt_map_len = hid_report_map_keyboard_consumer_len; break;
case BleHidProfile::Mouse: svcs = gatt_svcs_mouse; new_rpt_map = hid_report_map_mouse; new_rpt_map_len = hid_report_map_mouse_len; break;
case BleHidProfile::KbMouse: svcs = gatt_svcs_kb_mouse; new_rpt_map = hid_report_map_keyboard_consumer_mouse; new_rpt_map_len = hid_report_map_keyboard_consumer_mouse_len; break;
case BleHidProfile::Gamepad: svcs = gatt_svcs_gamepad; new_rpt_map = hid_report_map_gamepad; new_rpt_map_len = hid_report_map_gamepad_len; break;
default: svcs = gatt_svcs_none; break;
}