From 03e52d871ee3d43cb9dce03a17b06fa9ed9f606b Mon Sep 17 00:00:00 2001 From: Jacek Fedorynski Date: Thu, 11 Apr 2024 17:26:01 +0200 Subject: [PATCH] [wip] Boot/report protocol switching --- firmware/src/globals.cc | 3 +++ firmware/src/globals.h | 3 +++ firmware/src/main.cc | 5 +++++ firmware/src/our_descriptor.cc | 38 +++++++++++++++++++++++++++++++++- firmware/src/our_descriptor.h | 3 +++ firmware/src/remapper.cc | 26 +++++++++++++++++++++-- firmware/src/tinyusb_stuff.cc | 8 +++++++ 7 files changed, 83 insertions(+), 3 deletions(-) diff --git a/firmware/src/globals.cc b/firmware/src/globals.cc index 8f705c6..61db0ea 100644 --- a/firmware/src/globals.cc +++ b/firmware/src/globals.cc @@ -47,3 +47,6 @@ uint8_t gpio_out_state[4] = { 0 }; uint16_t digipot_state[NDIGIPOTS] = { 0 }; std::vector quirks; + +bool boot_protocol_keyboard = false; +bool boot_protocol_updated = false; diff --git a/firmware/src/globals.h b/firmware/src/globals.h index 40a1fec..71ccaff 100644 --- a/firmware/src/globals.h +++ b/firmware/src/globals.h @@ -62,4 +62,7 @@ extern uint16_t digipot_state[NDIGIPOTS]; extern std::vector quirks; +extern bool boot_protocol_keyboard; +extern bool boot_protocol_updated; + #endif diff --git a/firmware/src/main.cc b/firmware/src/main.cc index bba4e5f..986cdcd 100644 --- a/firmware/src/main.cc +++ b/firmware/src/main.cc @@ -272,6 +272,11 @@ int main() { #endif } tud_task(); + if (boot_protocol_updated) { + parse_our_descriptor(); + boot_protocol_updated = false; + config_updated = true; + } if (config_updated) { set_mapping_from_config(); config_updated = false; diff --git a/firmware/src/our_descriptor.cc b/firmware/src/our_descriptor.cc index 71fe2c4..c1bef3b 100644 --- a/firmware/src/our_descriptor.cc +++ b/firmware/src/our_descriptor.cc @@ -491,7 +491,7 @@ uint8_t const our_report_descriptor_stadia[] = { void kb_mouse_handle_set_report(uint8_t report_id, const uint8_t* buffer, uint16_t reqlen) { if (report_id == REPORT_ID_MULTIPLIER && reqlen >= 1) { memcpy(&resolution_multiplier, buffer, 1); - } else if (report_id == REPORT_ID_LEDS) { + } else if (boot_protocol_keyboard || (report_id == REPORT_ID_LEDS)) { handle_received_report(buffer, reqlen, OUR_OUT_INTERFACE, report_id); } } @@ -574,3 +574,39 @@ const uint8_t config_report_descriptor[] = { }; const uint32_t config_report_descriptor_length = sizeof(config_report_descriptor); + +// This isn't sent to the host. +uint8_t const boot_kb_report_descriptor[] = { + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x05, 0x07, // Usage Page (Kbrd/Keypad) + 0x19, 0xE0, // Usage Minimum (0xE0) + 0x29, 0xE7, // Usage Maximum (0xE7) + 0x75, 0x01, // Report Size (1) + 0x95, 0x08, // Report Count (8) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x75, 0x08, // Report Size (8) + 0x95, 0x01, // Report Count (1) + 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x07, // Usage Page (Kbrd/Keypad) + 0x19, 0x00, // Usage Minimum (0x00) + 0x2A, 0x91, 0x00, // Usage Maximum (0x91) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x95, 0x06, // Report Count (6) + 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x08, // Usage Page (LEDs) + 0x19, 0x01, // Usage Minimum (Num Lock) + 0x29, 0x03, // Usage Maximum (Scroll Lock) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x03, // Report Count (3) + 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0x95, 0x05, // Report Count (5) + 0x91, 0x03, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0xC0, // End Collection +}; + +const uint32_t boot_kb_report_descriptor_length = sizeof(boot_kb_report_descriptor); diff --git a/firmware/src/our_descriptor.h b/firmware/src/our_descriptor.h index a4dc90c..13c37c2 100644 --- a/firmware/src/our_descriptor.h +++ b/firmware/src/our_descriptor.h @@ -45,4 +45,7 @@ extern const our_descriptor_def_t our_descriptors[]; extern const uint8_t config_report_descriptor[]; extern const uint32_t config_report_descriptor_length; +extern const uint8_t boot_kb_report_descriptor[]; +extern const uint32_t boot_kb_report_descriptor_length; + #endif diff --git a/firmware/src/remapper.cc b/firmware/src/remapper.cc index 59e418c..09ab6e5 100644 --- a/firmware/src/remapper.cc +++ b/firmware/src/remapper.cc @@ -1591,13 +1591,35 @@ void update_their_descriptor_derivates() { void parse_our_descriptor() { std::unordered_map> our_feature_usages; + our_usages.clear(); + our_usages_rle.clear(); + their_usages.erase(OUR_OUT_INTERFACE); + has_report_id_theirs.erase(OUR_OUT_INTERFACE); + our_usages_flat.clear(); + our_array_range_usages.clear(); + + for (unsigned int i = 0; i < report_ids.size(); i++) { + uint8_t report_id = report_ids[i]; + delete[] reports[report_id]; + delete[] prev_reports[report_id]; + delete[] report_masks_relative[report_id]; + delete[] report_masks_absolute[report_id]; + } + + report_ids.clear(); + memset(report_sizes, 0, sizeof(report_sizes)); + memset(reports, 0, sizeof(reports)); + memset(prev_reports, 0, sizeof(prev_reports)); + memset(report_masks_relative, 0, sizeof(report_masks_relative)); + memset(report_masks_absolute, 0, sizeof(report_masks_absolute)); + auto report_sizes_map = parse_descriptor( our_usages, their_usages[OUR_OUT_INTERFACE], our_feature_usages, has_report_id_theirs[OUR_OUT_INTERFACE], - our_descriptor->descriptor, - our_descriptor->descriptor_length); + boot_protocol_keyboard ? boot_kb_report_descriptor : our_descriptor->descriptor, + boot_protocol_keyboard ? boot_kb_report_descriptor_length : our_descriptor->descriptor_length); for (auto const& [report_id, size] : report_sizes_map[ReportType::INPUT]) { report_sizes[report_id] = size; diff --git a/firmware/src/tinyusb_stuff.cc b/firmware/src/tinyusb_stuff.cc index 5a77319..fc83ad2 100644 --- a/firmware/src/tinyusb_stuff.cc +++ b/firmware/src/tinyusb_stuff.cc @@ -196,6 +196,14 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep } } +void tud_hid_set_protocol_cb(uint8_t instance, uint8_t protocol) { + printf("tud_hid_set_protocol_cb %d %d\n", instance, protocol); + boot_protocol_keyboard = (protocol == HID_PROTOCOL_BOOT); + boot_protocol_updated = true; +} + void tud_mount_cb() { reset_resolution_multiplier(); + boot_protocol_keyboard = false; + boot_protocol_updated = true; }