diff --git a/src/gfx_main.c b/src/gfx_main.c index c0bcdcf..69b4deb 100644 --- a/src/gfx_main.c +++ b/src/gfx_main.c @@ -286,11 +286,12 @@ void gfx_set_byte_offsets_text(void) hid_data_location_t * x = xlat_get_x_location(); hid_data_location_t * y = xlat_get_y_location(); hid_data_location_t * key = xlat_get_key_location(); + uint8_t interface = xlat_get_found_interface(); if (button->found && x->found && y->found && XLAT_MODE_KEY != xlat_get_mode()) { - sprintf(text, "Mouse Data: click@%d motion@%d,%d", button->byte_offset, x->byte_offset, y->byte_offset); + sprintf(text, "Mouse Data (#%d): click@%d motion@%d,%d", interface, button->byte_offset, x->byte_offset, y->byte_offset); } else if (key->found && XLAT_MODE_KEY == xlat_get_mode()) { - sprintf(text, "Keyboard Data: pressed@%d", key->byte_offset); + sprintf(text, "Keyboard Data (#%d): pressed@%d", interface, key->byte_offset); } else { // offsets not found sprintf(text, "Data: offsets not found"); diff --git a/src/gfx_settings.c b/src/gfx_settings.c index 0852d02..f3dd6cb 100644 --- a/src/gfx_settings.c +++ b/src/gfx_settings.c @@ -27,6 +27,7 @@ lv_dropdown_t *edge_dropdown; lv_slider_t *debounce_dropdown; lv_dropdown_t *trigger_dropdown; lv_dropdown_t *detection_dropdown; +lv_dropdown_t *interface_dropdown; lv_obj_t *prev_screen = NULL; // Pointer to store previous screen LV_IMG_DECLARE(xlat_logo); @@ -109,6 +110,21 @@ static void event_handler(lv_event_t* e) xlat_set_mode(XLAT_MODE_CLICK); } } + else if (obj == (lv_obj_t *)interface_dropdown) { + // Interface number changed + uint16_t sel = lv_dropdown_get_selected(obj); + + switch (sel) { + // Auto + case 0: + xlat_set_interface_selection(XLAT_INTERFACE_AUTO); + break; + + // Any specific interface number + default: + xlat_set_interface_selection(XLAT_INTERFACE_0 + sel - 1); + } + } else { printf("Unknown event\n"); } @@ -165,6 +181,16 @@ void gfx_settings_create_page(lv_obj_t *previous_screen) lv_dropdown_set_options((lv_obj_t *) detection_dropdown, "Click [M]\nMotion [M]\nKey [K]"); lv_obj_add_event_cb((struct _lv_obj_t *) detection_dropdown, event_handler, LV_EVENT_VALUE_CHANGED, NULL); + // Interface selection label + lv_obj_t *interface_label = lv_label_create(settings_screen); + lv_label_set_text(interface_label, "Interface Number:"); + lv_obj_align_to(interface_label, detection_mode, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 30); + + // Interface selection dropdown + interface_dropdown = (lv_dropdown_t *) lv_dropdown_create(settings_screen); + lv_dropdown_set_options((lv_obj_t *) interface_dropdown, "AUTO\n0\n1\n2\n3\n4\n5\n6\n7\n8"); + lv_obj_add_event_cb((struct _lv_obj_t *) interface_dropdown, event_handler, LV_EVENT_VALUE_CHANGED, NULL); + // If we don't add this label, the y-value of the last item will be 0 lv_obj_t *debounce_label2 = lv_label_create(settings_screen); lv_label_set_text(debounce_label2, ""); @@ -182,6 +208,7 @@ void gfx_settings_create_page(lv_obj_t *previous_screen) lv_obj_align((struct _lv_obj_t *) debounce_dropdown, LV_ALIGN_DEFAULT, max_width + widget_gap, lv_obj_get_y(debounce_label) - 10); lv_obj_align((struct _lv_obj_t *) trigger_dropdown, LV_ALIGN_DEFAULT, max_width + widget_gap, lv_obj_get_y(trigger_label) - 10); lv_obj_align((struct _lv_obj_t *) detection_dropdown, LV_ALIGN_DEFAULT, max_width + widget_gap, lv_obj_get_y(detection_mode) - 10); + lv_obj_align((struct _lv_obj_t *) interface_dropdown, LV_ALIGN_DEFAULT, max_width + widget_gap, lv_obj_get_y(interface_label) - 10); // Print all y-values for debugging //printf("edge_label y: %d\n", lv_obj_get_y(edge_label)); @@ -240,5 +267,19 @@ void gfx_settings_create_page(lv_obj_t *previous_screen) // Display current auto-trigger level lv_dropdown_set_selected((lv_obj_t *) trigger_dropdown, xlat_auto_trigger_level_is_high()); -} + // Display current interface selection + uint16_t interface_index = 0; + xlat_interface_t interface_selection = xlat_get_interface_selection(); + + switch (interface_selection) { + case XLAT_INTERFACE_AUTO: + interface_index = 0; + break; + + default: + interface_index = 1 + interface_selection - XLAT_INTERFACE_0; + } + + lv_dropdown_set_selected((lv_obj_t *) interface_dropdown, interface_index); +} diff --git a/src/usb/usbh_hid.c b/src/usb/usbh_hid.c index ada0e93..8d1399e 100644 --- a/src/usb/usbh_hid.c +++ b/src/usb/usbh_hid.c @@ -66,12 +66,20 @@ static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost) uint8_t num = 0U; uint8_t interface; - // First try to find a Mouse or Keyboard interface depending on the detection mode, specifically: - interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, (XLAT_MODE_KEY == xlat_get_mode()) ? HID_KEYBRD_BOOT_CODE : HID_MOUSE_BOOT_CODE); - - // Broaden the search criteria to no specific protocol - if (interface == 0xFFU) { - interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, 0xFFU); + // Handle the AUTO interface detection mode + if (XLAT_INTERFACE_AUTO == xlat_get_interface_selection()) { + // First try to find a Mouse or Keyboard interface depending on the detection mode, specifically: + interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, (XLAT_MODE_KEY == xlat_get_mode()) ? HID_KEYBRD_BOOT_CODE : HID_MOUSE_BOOT_CODE); + + // Broaden the search criteria to no specific protocol + if (interface == 0xFFU) { + interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, 0xFFU); + } + } + // Use the selected interface + else + { + interface = xlat_get_interface_selection() - XLAT_INTERFACE_0;; } #if 0 @@ -98,6 +106,8 @@ static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost) return USBH_FAIL; } + xlat_set_found_interface(interface); + phost->pActiveClass->pData = (HID_HandleTypeDef *)USBH_malloc(sizeof(HID_HandleTypeDef)); HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData; diff --git a/src/xlat.c b/src/xlat.c index d47981e..0747f3d 100644 --- a/src/xlat.c +++ b/src/xlat.c @@ -43,10 +43,12 @@ static volatile uint_fast8_t gpio_irq_producer = 0; static volatile uint_fast8_t gpio_irq_consumer = 0; // SETTINGS -volatile bool xlat_initialized = false; -static xlat_mode_t xlat_mode = XLAT_MODE_CLICK; -static bool hid_using_reportid = false; -static bool auto_trigger_level_high = false; +volatile bool xlat_initialized = false; +static xlat_mode_t xlat_mode = XLAT_MODE_CLICK; +static bool hid_using_reportid = false; +static bool auto_trigger_level_high = false; +static xlat_interface_t xlat_interface = XLAT_INTERFACE_AUTO; +static uint8_t found_interface = 0xFF; // The Razer optical switches will constantly trigger the GPIO interrupt, while pressed // Waveform looks like this in ASCII art: @@ -690,6 +692,26 @@ bool xlat_auto_trigger_level_is_high(void) return auto_trigger_level_high; } +void xlat_set_interface_selection(xlat_interface_t number) +{ + xlat_interface = number; +} + +xlat_interface_t xlat_get_interface_selection() +{ + return xlat_interface; +} + +void xlat_set_found_interface(uint8_t number) +{ + found_interface = number; +} + +uint8_t xlat_get_found_interface() +{ + return found_interface; +} + void xlat_print_measurement(void) { // print the new measurement to the console in csv format diff --git a/src/xlat.h b/src/xlat.h index 088aecc..ed31fb8 100644 --- a/src/xlat.h +++ b/src/xlat.h @@ -49,6 +49,19 @@ typedef enum xlat_mode { XLAT_MODE_KEY, } xlat_mode_t; +typedef enum xlat_interface { + XLAT_INTERFACE_AUTO = -1, + XLAT_INTERFACE_0 = 0, + XLAT_INTERFACE_1, + XLAT_INTERFACE_2, + XLAT_INTERFACE_3, + XLAT_INTERFACE_4, + XLAT_INTERFACE_5, + XLAT_INTERFACE_6, + XLAT_INTERFACE_7, + XLAT_INTERFACE_8, +} xlat_interface_t; + extern volatile bool xlat_initialized; void xlat_init(void); @@ -91,4 +104,10 @@ void xlat_auto_trigger_action(void); void xlat_auto_trigger_level_set(bool high); bool xlat_auto_trigger_level_is_high(void); +void xlat_set_interface_selection(xlat_interface_t number); +xlat_interface_t xlat_get_interface_selection(); + +void xlat_set_found_interface(uint8_t number); +uint8_t xlat_get_found_interface(); + #endif //XLAT_H