From 0aa4addf2d414dabbcab751111b0085778cb0420 Mon Sep 17 00:00:00 2001 From: Hrvoje Cavrak Date: Tue, 25 Jun 2024 10:24:41 +0200 Subject: [PATCH] NKRO and CC bugfix, remove printf from PIO in non-debug env --- Pico-PIO-USB/src/pio_usb.h | 2 + Pico-PIO-USB/src/pio_usb_host.c | 84 ++++++++++++++++----------------- src/handlers.c | 5 +- src/hid_parser.c | 6 ++- src/hid_report.c | 31 ++++++------ src/include/hid_parser.h | 1 + src/include/tusb_config.h | 1 - src/keyboard.c | 8 +++- src/setup.c | 5 +- src/usb.c | 39 ++++++--------- 10 files changed, 92 insertions(+), 90 deletions(-) diff --git a/Pico-PIO-USB/src/pio_usb.h b/Pico-PIO-USB/src/pio_usb.h index 8a970e7..5de4598 100644 --- a/Pico-PIO-USB/src/pio_usb.h +++ b/Pico-PIO-USB/src/pio_usb.h @@ -32,6 +32,8 @@ int pio_usb_set_out_data(endpoint_t *ep, const uint8_t *buffer, uint8_t len); // Misc functions int pio_usb_kbd_set_leds(usb_device_t *device, uint8_t port, uint8_t value); +extern int dh_debug_printf(const char *format, ...); + #ifdef __cplusplus } #endif diff --git a/Pico-PIO-USB/src/pio_usb_host.c b/Pico-PIO-USB/src/pio_usb_host.c index 157844a..0e96a49 100644 --- a/Pico-PIO-USB/src/pio_usb_host.c +++ b/Pico-PIO-USB/src/pio_usb_host.c @@ -414,7 +414,7 @@ bool pio_usb_host_send_setup(uint8_t root_idx, uint8_t device_address, uint8_t const setup_packet[8]) { endpoint_t *ep = _find_ep(root_idx, device_address, 0); if (!ep) { - printf("cannot find ep 0x00\r\n"); + dh_debug_printf("cannot find ep 0x00\r\n"); return false; } @@ -430,7 +430,7 @@ bool pio_usb_host_endpoint_transfer(uint8_t root_idx, uint8_t device_address, uint16_t buflen) { endpoint_t *ep = _find_ep(root_idx, device_address, ep_address); if (!ep) { - printf("no endpoint 0x%02X\r\n", ep_address); + dh_debug_printf("no endpoint 0x%02X\r\n", ep_address); return false; } @@ -449,7 +449,7 @@ bool pio_usb_host_endpoint_abort_transfer(uint8_t root_idx, uint8_t device_addre uint8_t ep_address) { endpoint_t *ep = _find_ep(root_idx, device_address, ep_address); if (!ep) { - printf("no endpoint 0x%02X\r\n", ep_address); + dh_debug_printf("no endpoint 0x%02X\r\n", ep_address); return false; } @@ -679,13 +679,13 @@ static int __no_inline_not_in_flash_func(control_out_protocol)( } if (time_us_64() - start_time >= timeout) { - printf("control out[timeout]\n"); + dh_debug_printf("control out[timeout]\n"); res = -2; } else if (pipe->operation == CONTROL_ERROR) { - printf("control out[error]\n"); + dh_debug_printf("control out[error]\n"); res = -1; } else if (pipe->operation == CONTROL_COMPLETE) { - printf("control out[complete]\n"); + dh_debug_printf("control out[complete]\n"); res = 0; } pipe->operation = CONTROL_NONE; @@ -723,13 +723,13 @@ static int __no_inline_not_in_flash_func(control_in_protocol)( } if (time_us_64() - start_time >= timeout) { - printf("control in[timeout]\n"); + dh_debug_printf("control in[timeout]\n"); res = -2; } else if (pipe->operation == CONTROL_ERROR) { - printf("control in[error]\n"); + dh_debug_printf("control in[error]\n"); res = -1; } else if (pipe->operation == CONTROL_COMPLETE) { - printf("control in[complete]\n"); + dh_debug_printf("control in[complete]\n"); res = 0; } pipe->operation = CONTROL_NONE; @@ -763,18 +763,18 @@ static int get_hub_port_status(usb_device_t *device, uint8_t port, static int initialize_hub(usb_device_t *device) { uint8_t rx_buffer[16]; int res = 0; - printf("USB Hub detected\n"); + dh_debug_printf("USB Hub detected\n"); usb_setup_packet_t get_hub_desc_request = GET_HUB_DESCRPTOR_REQUEST; control_in_protocol(device, (uint8_t *)&get_hub_desc_request, sizeof(get_hub_desc_request), rx_buffer, 8); const hub_descriptor_t *desc = (hub_descriptor_t *)rx_buffer; uint8_t port_num = desc->port_num; - printf("\tTurn on port powers\n"); + dh_debug_printf("\tTurn on port powers\n"); for (int idx = 0; idx < port_num; idx++) { res = set_hub_feature(device, idx, HUB_SET_PORT_POWER); if (res != 0) { - printf("\tFailed to turn on ports\n"); + dh_debug_printf("\tFailed to turn on ports\n"); break; } } @@ -837,7 +837,7 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { uint8_t idx_product = desc->product; uint8_t idx_serial = desc->serial; - printf("Enumerating %04x:%04x, class:%d, address:%d\n", device->vid, + dh_debug_printf("Enumerating %04x:%04x, class:%d, address:%d\n", device->vid, device->pid, device->device_class, address); usb_setup_packet_t set_address_request = SET_ADDRESS_REQ_DEFAULT; @@ -862,9 +862,9 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { if (idx_manufacture != 0) { res = get_string_descriptor(device, idx_manufacture, rx_buffer, str); if (res == 0) { - printf("Manufacture:%s\n", str); + dh_debug_printf("Manufacture:%s\n", str); } else { - printf("Failed to get string descriptor (Manufacture)\n"); + dh_debug_printf("Failed to get string descriptor (Manufacture)\n"); } stdio_flush(); } @@ -872,9 +872,9 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { if (idx_product != 0) { res = get_string_descriptor(device, idx_product, rx_buffer, str); if (res == 0) { - printf("Product:%s\n", str); + dh_debug_printf("Product:%s\n", str); } else { - printf("Failed to get string descriptor (Product)\n"); + dh_debug_printf("Failed to get string descriptor (Product)\n"); } stdio_flush(); } @@ -882,9 +882,9 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { if (idx_serial != 0) { res = get_string_descriptor(device, idx_serial, rx_buffer, str); if (res == 0) { - printf("Serial:%s\n", str); + dh_debug_printf("Serial:%s\n", str); } else { - printf("Failed to get string descriptor (Serial)\n"); + dh_debug_printf("Failed to get string descriptor (Serial)\n"); } stdio_flush(); } @@ -943,7 +943,7 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { case DESC_TYPE_INTERFACE: { const interface_descriptor_t *d = (const interface_descriptor_t *)descriptor; - printf( + dh_debug_printf( "inum:%d, altsetting:%d, numep:%d, iclass:%d, isubclass:%d, " "iprotcol:%d, iface:%d\n", d->inum, d->altsetting, d->numep, d->iclass, d->isubclass, @@ -954,7 +954,7 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { case DESC_TYPE_ENDPOINT: { const endpoint_descriptor_t *d = (const endpoint_descriptor_t *)descriptor; - printf("\t\t\tepaddr:0x%02x, attr:%d, size:%d, interval:%d\n", + dh_debug_printf("\t\t\tepaddr:0x%02x, attr:%d, size:%d, interval:%d\n", d->epaddr, d->attr, d->max_size[0] | (d->max_size[1] << 8), d->interval); @@ -983,13 +983,13 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { ep->need_pre = !device->is_root && !device->is_fullspeed; ep->is_tx = (d->epaddr & 0x80) ? false : true; } else { - printf("No empty EP\n"); + dh_debug_printf("No empty EP\n"); } } } break; case DESC_TYPE_HID: { const hid_descriptor_t *d = (const hid_descriptor_t *)descriptor; - printf( + dh_debug_printf( "\tbcdHID:%x.%x, country:%d, desc num:%d, desc_type:%d, " "desc_size:%d\n", d->bcd_hid[1], d->bcd_hid[0], d->contry_code, d->num_desc, @@ -1011,11 +1011,11 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { control_in_protocol( device, (uint8_t *)&get_hid_report_descrpitor_request, sizeof(get_hid_report_descrpitor_request), rx_buffer, desc_len); - printf("\t\tReport descriptor:"); + dh_debug_printf("\t\tReport descriptor:"); for (int i = 0; i < desc_len; i++) { - printf("%02x ", device->control_pipe.rx_buffer[i]); + dh_debug_printf("%02x ", device->control_pipe.rx_buffer[i]); } - printf("\n"); + dh_debug_printf("\n"); stdio_flush(); } break; @@ -1044,7 +1044,7 @@ static int enumerate_device(usb_device_t *device, uint8_t address) { } static void device_disconnect(usb_device_t *device) { - printf("Disconnect device %d\n", device->address); + dh_debug_printf("Disconnect device %d\n", device->address); for (int port = 0; port < PIO_USB_HUB_PORT_CNT; port++) { if (device->child_devices[port] != 0) { device_disconnect(&pio_usb_device[device->child_devices[port]]); @@ -1086,7 +1086,7 @@ static int assign_new_device_to_port(usb_device_t *hub_device, uint8_t port, boo pio_usb_device[idx].connected = true; pio_usb_device[idx].is_fullspeed = !is_ls; pio_usb_device[idx].event = EVENT_CONNECT; - printf("Assign device %d to %d-%d\n", idx, hub_device->address, port); + dh_debug_printf("Assign device %d to %d-%d\n", idx, hub_device->address, port); endpoint_descriptor_t ep0_desc = { sizeof(endpoint_descriptor_t), DESC_TYPE_ENDPOINT, 0x00, 0x00, { 0x08, 0x00 }, 0x00 @@ -1097,7 +1097,7 @@ static int assign_new_device_to_port(usb_device_t *hub_device, uint8_t port, boo return 0; } - printf("Failed to assign device\n"); + dh_debug_printf("Failed to assign device\n"); return -1; } @@ -1114,22 +1114,22 @@ static void __no_inline_not_in_flash_func(process_hub_event)( hub_port_status_t status; int res = get_hub_port_status(device, port, &status); if (res != 0) { - printf("Failed to get port%d-%d status\n", device->address, port); + dh_debug_printf("Failed to get port%d-%d status\n", device->address, port); continue; } - printf("port%d-%d status:%d %d\n", device->address, port, + dh_debug_printf("port%d-%d status:%d %d\n", device->address, port, status.port_change, status.port_status); if (status.port_change & HUB_CHANGE_PORT_CONNECTION) { if (status.port_status & HUB_STAT_PORT_CONNECTION) { - printf("new device on port %d, reset port\n", port); + dh_debug_printf("new device on port %d, reset port\n", port); if (device->child_devices[port] != 0) { - printf("device is already assigned. disconnect previous\n"); + dh_debug_printf("device is already assigned. disconnect previous\n"); device_disconnect(&pio_usb_device[device->child_devices[port]]); } if (device->root->addr0_exists) { - printf("Address 0 already exists\n"); + dh_debug_printf("Address 0 already exists\n"); continue; } @@ -1137,17 +1137,17 @@ static void __no_inline_not_in_flash_func(process_hub_event)( set_hub_feature(device, port, HUB_SET_PORT_RESET); device->root->addr0_exists = true; } else { - printf("No vacant in device pool\n"); + dh_debug_printf("No vacant in device pool\n"); } } else { - printf("device removed from port %d\n", port); + dh_debug_printf("device removed from port %d\n", port); if (device->child_devices[port] != 0) { device_disconnect(&pio_usb_device[device->child_devices[port]]); } } clear_hub_feature(device, port, HUB_CLR_PORT_CONNECTION); } else if (status.port_change & HUB_CHANGE_PORT_RESET) { - printf("reset port %d complete\n", port); + dh_debug_printf("reset port %d complete\n", port); res = clear_hub_feature(device, port, HUB_CLR_PORT_RESET); if (res == 0) { assign_new_device_to_port(device, port, @@ -1164,7 +1164,7 @@ static void __no_inline_not_in_flash_func(process_hub_event)( void __no_inline_not_in_flash_func(pio_usb_host_task)(void) { for (int root_idx = 0; root_idx < PIO_USB_ROOT_PORT_CNT; root_idx++) { if (pio_usb_root_port[root_idx].event == EVENT_CONNECT) { - printf("Root %d connected\n", root_idx); + dh_debug_printf("Root %d connected\n", root_idx); int dev_idx = device_pool_vacant(); if (dev_idx >= 0) { on_device_connect(&pio_port[0], &pio_usb_root_port[root_idx], dev_idx); @@ -1172,7 +1172,7 @@ void __no_inline_not_in_flash_func(pio_usb_host_task)(void) { } pio_usb_root_port[root_idx].event = EVENT_NONE; } else if (pio_usb_root_port[root_idx].event == EVENT_DISCONNECT) { - printf("Root %d disconnected\n", root_idx); + dh_debug_printf("Root %d disconnected\n", root_idx); pio_usb_host_close_device( root_idx, pio_usb_root_port[root_idx].root_device->address); pio_usb_root_port[root_idx].root_device->connected = false; @@ -1187,7 +1187,7 @@ void __no_inline_not_in_flash_func(pio_usb_host_task)(void) { if (device->event == EVENT_CONNECT) { device->event = EVENT_NONE; - printf("Device %d Connected\n", idx); + dh_debug_printf("Device %d Connected\n", idx); int res = enumerate_device(device, idx + 1); if (res == 0) { device->enumerated = true; @@ -1198,7 +1198,7 @@ void __no_inline_not_in_flash_func(pio_usb_host_task)(void) { } if (res != 0) { - printf("Enumeration failed(%d)\n", res); + dh_debug_printf("Enumeration failed(%d)\n", res); // retry if (device->is_root) { device->root->event = EVENT_DISCONNECT; @@ -1210,7 +1210,7 @@ void __no_inline_not_in_flash_func(pio_usb_host_task)(void) { } } else if (device->event == EVENT_DISCONNECT) { device->event = EVENT_NONE; - printf("Disconnect\n"); + dh_debug_printf("Disconnect\n"); device_disconnect(device); } else if (device->event == EVENT_HUB_PORT_CHANGE) { process_hub_event(device); diff --git a/src/handlers.c b/src/handlers.c index ea09858..c89a7ab 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -117,8 +117,9 @@ void config_enable_hotkey_handler(device_t *state, hid_keyboard_report_t *report watchdog_hw->scratch[5] = MAGIC_WORD_1; watchdog_hw->scratch[6] = MAGIC_WORD_2; } - - reboot(); + + release_all_keys(state); + state->reboot_requested = true; }; diff --git a/src/hid_parser.c b/src/hid_parser.c index 94ae72c..78de004 100644 --- a/src/hid_parser.c +++ b/src/hid_parser.c @@ -46,7 +46,7 @@ void update_usage(parser_state_t *parser, int i) { *(parser->p_usage + i) = *(parser->p_usage + i - 1); } -void store_element(parser_state_t *parser, report_val_t *val, int i, uint32_t data, uint16_t size) { +void store_element(parser_state_t *parser, report_val_t *val, int i, uint32_t data, uint16_t size, hid_interface_t *iface) { *val = (report_val_t){ .offset = parser->offset_in_bits, .offset_idx = parser->offset_in_bits >> 3, @@ -63,6 +63,8 @@ void store_element(parser_state_t *parser, report_val_t *val, int i, uint32_t da .global_usage = parser->global_usage, .report_id = parser->report_id }; + + iface->uses_report_id |= (parser->report_id != 0); } void handle_global_item(parser_state_t *parser, item_t *item) { @@ -102,7 +104,7 @@ void handle_main_input(parser_state_t *parser, item_t *item, hid_interface_t *if for (int i = 0; i < count; i++) { update_usage(parser, i); - store_element(parser, &val, i, item->val, size); + store_element(parser, &val, i, item->val, size, iface); /* Use the parsed data to populate internal device structures */ extract_data(iface, &val); diff --git a/src/hid_report.c b/src/hid_report.c index 0a7842b..1c6d340 100644 --- a/src/hid_report.c +++ b/src/hid_report.c @@ -55,7 +55,7 @@ int32_t get_report_value(uint8_t *report, report_val_t *val) { } /* After processing the descriptor, assign the values so we can later use them to interpret reports */ -void handle_consumer_control_values(report_val_t *src, report_val_t *dst, hid_interface_t *iface) { +void handle_consumer_control_values(report_val_t *src, report_val_t *dst, hid_interface_t *iface) { if (src->offset > MAX_CC_BUTTONS) { return; } @@ -90,10 +90,6 @@ void handle_keyboard_descriptor_values(report_val_t *src, report_val_t *dst, hid if (src->item_type == CONSTANT) return; - /* Make note if we're using a report ID or not */ - if (src->report_id > 0) - iface->keyboard.uses_report_id = true; - /* Detect and handle modifier keys. <= if modifier is less + constant padding? */ if (src->size <= MODIFIER_BIT_LENGTH && src->data_type == VARIABLE) { /* To make sure this really is the modifier key, we expect e.g. left control to be @@ -236,10 +232,11 @@ int32_t _extract_kbd_boot(uint8_t *raw_report, int len, hid_keyboard_report_t *r return KBD_REPORT_LENGTH; } -int32_t _extract_kbd_other(uint8_t *raw_report, int len, keyboard_t *kb, hid_keyboard_report_t *report) { +int32_t _extract_kbd_other(uint8_t *raw_report, int len, hid_interface_t *iface, hid_keyboard_report_t *report) { uint8_t *src = raw_report; + keyboard_t *kb = &iface->keyboard; - if (kb->uses_report_id) + if (iface->uses_report_id) src++; report->modifier = src[kb->modifier.offset_idx]; @@ -251,11 +248,12 @@ int32_t _extract_kbd_other(uint8_t *raw_report, int len, keyboard_t *kb, hid_key return KBD_REPORT_LENGTH; } -int32_t _extract_kbd_nkro(uint8_t *raw_report, int len, keyboard_t *kb, hid_keyboard_report_t *report) { +int32_t _extract_kbd_nkro(uint8_t *raw_report, int len, hid_interface_t *iface, hid_keyboard_report_t *report) { uint8_t *ptr = raw_report; + keyboard_t *kb = &iface->keyboard; /* Skip report ID */ - if (kb->uses_report_id) + if (iface->uses_report_id) ptr++; /* We expect array of bits mapping 1:1 from usage_min to usage_max, otherwise panic */ @@ -282,19 +280,20 @@ int32_t extract_kbd_data( /* Clear the report to start fresh */ memset(report, 0, KBD_REPORT_LENGTH); - /* NKRO is a special case */ - if (report_id == iface->keyboard.nkro.report_id - && iface->keyboard.is_nkro - && itf == HID_ITF_PROTOCOL_NONE) - return _extract_kbd_nkro(raw_report, len, &iface->keyboard, report); - + /* If we're in boot protocol mode, then it's easy to decide. */ if (iface->protocol == HID_PROTOCOL_BOOT) return _extract_kbd_boot(raw_report, len, report); + /* NKRO is a special case */ + if (report_id > 0 + && report_id == iface->keyboard.nkro.report_id + && iface->keyboard.is_nkro) + return _extract_kbd_nkro(raw_report, len, iface, report); + /* If we're getting 8 bytes of report, it's safe to assume standard modifier + reserved + keys */ if (len == KBD_REPORT_LENGTH || len == KBD_REPORT_LENGTH + 1) return _extract_kbd_boot(raw_report, len, report); /* This is something completely different, look at the report */ - return _extract_kbd_other(raw_report, len, &iface->keyboard, report); + return _extract_kbd_other(raw_report, len, iface, report); } \ No newline at end of file diff --git a/src/include/hid_parser.h b/src/include/hid_parser.h index 08c89a0..0926ee5 100644 --- a/src/include/hid_parser.h +++ b/src/include/hid_parser.h @@ -138,6 +138,7 @@ struct hid_interface_t { report_t system; process_report_f report_handler[MAX_REPORTS]; uint8_t protocol; + bool uses_report_id; }; typedef struct { diff --git a/src/include/tusb_config.h b/src/include/tusb_config.h index 1215abd..3d1d5f1 100644 --- a/src/include/tusb_config.h +++ b/src/include/tusb_config.h @@ -86,7 +86,6 @@ //------------- DEBUG -------------// #ifdef DH_DEBUG #define CFG_TUD_CDC 1 -#define CFG_TUD_LOG_LEVEL 3 #define CFG_TUSB_DEBUG_PRINTF dh_debug_printf extern int dh_debug_printf(const char *__restrict __format, ...); diff --git a/src/keyboard.c b/src/keyboard.c index 785907f..ac66cb4 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -162,7 +162,7 @@ void process_kbd_queue_task(device_t *state) { void queue_kbd_report(hid_keyboard_report_t *report, device_t *state) { /* It wouldn't be fun to queue up a bunch of messages and then dump them all on host */ if (!state->tud_connected) - return; + return; queue_try_add(&state->kbd_queue, report); } @@ -214,6 +214,10 @@ void process_keyboard_report(uint8_t *raw_report, int length, uint8_t itf, hid_i if (length < KBD_REPORT_LENGTH) return; + /* No more keys accepted if we're about to reboot */ + if (global_state.reboot_requested) + return; + extract_kbd_data(raw_report, length, itf, iface, &new_report); /* Check if any hotkey was pressed */ @@ -240,7 +244,7 @@ void process_keyboard_report(uint8_t *raw_report, int length, uint8_t itf, hid_i void process_consumer_report(uint8_t *raw_report, int length, uint8_t itf, hid_interface_t *iface) { uint8_t new_report[CONSUMER_CONTROL_LENGTH] = {0}; uint16_t *report_ptr = (uint16_t *)new_report; - + /* If consumer control is variable, read the values from cc_array and send as array. */ if (iface->consumer.is_variable) { for (int i = 0; i < MAX_CC_BUTTONS && i < 8 * (length - 1); i++) { diff --git a/src/setup.c b/src/setup.c index b02d366..f3c8cfd 100644 --- a/src/setup.c +++ b/src/setup.c @@ -55,7 +55,10 @@ void pio_usb_host_config(device_t *state) { static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; config.pin_dp = PIO_USB_DP_PIN_DEFAULT; - tuh_hid_set_default_protocol(HID_PROTOCOL_REPORT); + /* Board B is always report mode, board A is default-boot if configured */ + if (state->board_role == OUTPUT_B || ENFORCE_KEYBOARD_BOOT_PROTOCOL == 0) + tuh_hid_set_default_protocol(HID_PROTOCOL_REPORT); + tuh_configure(BOARD_TUH_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &config); /* Initialize and configure TinyUSB Host */ diff --git a/src/usb.c b/src/usb.c index 29d6dbf..4dd567e 100644 --- a/src/usb.c +++ b/src/usb.c @@ -141,7 +141,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_re return; /* Parse the report descriptor into our internal structure. */ - parse_report_descriptor(iface, desc_report, desc_len); + parse_report_descriptor(iface, desc_report, desc_len); switch (itf_protocol) { case HID_ITF_PROTOCOL_KEYBOARD: @@ -150,9 +150,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_re if (global_state.config.force_kbd_boot_protocol) tuh_hid_set_protocol(dev_addr, instance, HID_PROTOCOL_BOOT); - - iface->keyboard.uses_report_id = iface->keyboard.report_id > 0; - + /* Keeping this is required for setting leds from device set_report callback */ global_state.kbd_dev_addr = dev_addr; global_state.kbd_instance = instance; @@ -168,8 +166,6 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_re if (tuh_hid_get_protocol(dev_addr, instance) == HID_PROTOCOL_BOOT) { tuh_hid_set_protocol(dev_addr, instance, HID_PROTOCOL_REPORT); } - - iface->mouse.uses_report_id = iface->mouse.report_id > 0; break; case HID_ITF_PROTOCOL_NONE: @@ -198,26 +194,21 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons if (instance >= MAX_INTERFACES) return; - switch (itf_protocol) { - case HID_ITF_PROTOCOL_KEYBOARD: - process_keyboard_report((uint8_t *)report, len, itf_protocol, iface); - break; + if (iface->uses_report_id) { + uint8_t report_id = report[0]; - case HID_ITF_PROTOCOL_MOUSE: - process_mouse_report((uint8_t *)report, len, itf_protocol, iface); - break; + if (report_id < MAX_REPORTS) { + process_report_f receiver = iface->report_handler[report_id]; - /* This can be NKRO keyboard, consumer control, system, mouse, anything. */ - case HID_ITF_PROTOCOL_NONE: - uint8_t report_id = report[0]; - - if (report_id < MAX_REPORTS) { - process_report_f receiver = iface->report_handler[report_id]; - - if (receiver != NULL) - receiver((uint8_t *)report, len, itf_protocol, iface); - } - break; + if (receiver != NULL) + receiver((uint8_t *)report, len, itf_protocol, iface); + } + } + else if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { + process_keyboard_report((uint8_t *)report, len, itf_protocol, iface); + } + else if (itf_protocol == HID_ITF_PROTOCOL_MOUSE) { + process_mouse_report((uint8_t *)report, len, itf_protocol, iface); } /* Continue requesting reports */