Skip to content

Commit

Permalink
Merge pull request teamfinalmouse#9 from WootingKb/fix/reportID-usage
Browse files Browse the repository at this point in the history
  • Loading branch information
maximevince authored Apr 30, 2024
2 parents 01be21f + be97f72 commit ca00497
Show file tree
Hide file tree
Showing 12 changed files with 716 additions and 153 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ name: Build XLAT firmware
on:
push:
branches:
- main
- '**'
pull_request:
branches:
- main
- '**'

jobs:
build:
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ set(USB_Sources
src/usb/usbh_pipes.c
src/usb/usbh_hid.c
src/usb/usbh_hid_mouse.c
src/usb/usbh_hid_keyboard.c
)

add_definitions(
Expand Down
10 changes: 7 additions & 3 deletions src/gfx_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,16 @@ void gfx_set_byte_offsets_text(void)
hid_data_location_t * button = xlat_get_button_location();
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) {
sprintf(text, "Data: click@%d motion@%d,%d", button->byte_offset, x->byte_offset, y->byte_offset);
if (button->found && x->found && y->found && XLAT_MODE_KEY != xlat_get_mode()) {
sprintf(text, "Mouse Data (#%d): id@%d click@%d motion@%d,%d", interface, xlat_get_reportid(), button->byte_offset, x->byte_offset, y->byte_offset);
} else if (key->found && XLAT_MODE_KEY == xlat_get_mode()) {
sprintf(text, "Keyboard Data (#%d): id@%d pressed@%d", interface, xlat_get_reportid(), key->byte_offset);
} else {
// offsets not found
sprintf(text, "Data: offsets not found");
sprintf(text, (XLAT_MODE_KEY == xlat_get_mode()) ? "Keyboard Data: offsets not found" : "Mouse Data: offsets not found");
}

lv_checkbox_set_text(hid_offsets_label, text);
Expand Down
72 changes: 61 additions & 11 deletions src/gfx_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -92,12 +93,36 @@ static void event_handler(lv_event_t* e)
else if (obj == (lv_obj_t *)detection_dropdown) {
// Detection mode changed
uint16_t sel = lv_dropdown_get_selected(obj);
if (sel == 0) {
// Click
xlat_set_mode(XLAT_MODE_CLICK);
} else {
// Motion
xlat_set_mode(XLAT_MODE_MOTION);

switch (sel) {
// Motion [M]
case 1:
xlat_set_mode(XLAT_MODE_MOTION);
break;

// Key [K]
case 2:
xlat_set_mode(XLAT_MODE_KEY);
break;

// Click [M]
default:
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 {
Expand Down Expand Up @@ -146,16 +171,26 @@ void gfx_settings_create_page(lv_obj_t *previous_screen)
lv_obj_add_event_cb((struct _lv_obj_t *) trigger_dropdown, event_handler, LV_EVENT_VALUE_CHANGED, NULL);


// Click vs. motion detection label
// Click, motion & key detection label
lv_obj_t *detection_mode = lv_label_create(settings_screen);
lv_label_set_text(detection_mode, "Detection Mode:");
lv_obj_align_to(detection_mode, trigger_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 30);

// Click vs. motion detection dropdown
// Click, motion & key detection dropdown
detection_dropdown = (lv_dropdown_t *) lv_dropdown_create(settings_screen);
lv_dropdown_set_options((lv_obj_t *) detection_dropdown, "Click\nMotion");
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, "");
Expand All @@ -173,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));
Expand Down Expand Up @@ -222,7 +258,7 @@ void gfx_settings_create_page(lv_obj_t *previous_screen)
lv_dropdown_set_selected((lv_obj_t *) debounce_dropdown, debounce_index);

// Display current detection mode
lv_dropdown_set_selected((lv_obj_t *) detection_dropdown, xlat_get_mode() == XLAT_MODE_MOTION);
lv_dropdown_set_selected((lv_obj_t *) detection_dropdown, xlat_get_mode());


// Display current detection edge
Expand All @@ -231,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);
}
3 changes: 2 additions & 1 deletion src/usb/usb_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
break;
}

case HOST_USER_NO_SUPPORTED_CLASS:
case HOST_USER_CLASS_ACTIVE: {
// Compose vidpid string
uint16_t vid = phost->device.DevDesc.idVendor;
uint16_t pid = phost->device.DevDesc.idProduct;
printf("USB HID device connected: 0x%04X:%04X\n", vid, pid);
printf("USB device connected: 0x%04X:%04X\n", vid, pid);
memset(vidpid_string, 0, sizeof(vidpid_string));
snprintf(vidpid_string, sizeof(vidpid_string), "0x%04X:%04X", vid, pid);
vidpid_string[sizeof(vidpid_string) - 1] = '\0';
Expand Down
28 changes: 22 additions & 6 deletions src/usb/usbh_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "usbh_core.h"
#include "usbh_hid.h"
#include "usb_host.h"
#include "Common/Common.h"


/** @addtogroup USBH_LIB
Expand Down Expand Up @@ -480,6 +481,8 @@ USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
{
__IO USBH_StatusTypeDef status = USBH_FAIL;
uint8_t idx = 0U;
uint8_t i = 0U;
bool stop = false;

/* check for Host pending port disconnect event */
if (phost->device.is_disconnected == 1U)
Expand Down Expand Up @@ -706,12 +709,16 @@ USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
{
phost->pActiveClass = NULL;

for (idx = 0U; idx < USBH_MAX_NUM_SUPPORTED_CLASS; idx++)
for (idx = 0U, stop = false; idx < USBH_MAX_NUM_SUPPORTED_CLASS && !stop; idx++)
{
if (phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[0].bInterfaceClass)
// Check if the device has an interface where the class is supported
for (i = 0U; i < USBH_MAX_NUM_INTERFACES && !stop; i++)
{
phost->pActiveClass = phost->pClass[idx];
break;
if (phost->pClass[idx]->ClassCode == phost->device.CfgDesc.Itf_Desc[i].bInterfaceClass)
{
phost->pActiveClass = phost->pClass[idx];
stop = true;
}
}
}

Expand All @@ -722,8 +729,11 @@ USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
phost->gState = HOST_CLASS_REQUEST;
USBH_UsrLog("%s class started.", phost->pActiveClass->Name);

/* Inform user that a class has been activated */
phost->pUser(phost, HOST_USER_CLASS_SELECTED);
if (phost->pUser != NULL)
{
/* Inform user that a class has been activated */
phost->pUser(phost, HOST_USER_CLASS_SELECTED);
}
}
else
{
Expand All @@ -735,6 +745,12 @@ USBH_StatusTypeDef USBH_Process(USBH_HandleTypeDef *phost)
{
phost->gState = HOST_ABORT_STATE;
USBH_UsrLog("No registered class for this device.");

if (phost->pUser != NULL)
{
/* Inform user that a class has been activated */
phost->pUser(phost, HOST_USER_NO_SUPPORTED_CLASS);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/usb/usbh_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ extern "C" {
#define HOST_USER_CONNECTION 0x04U
#define HOST_USER_DISCONNECTION 0x05U
#define HOST_USER_UNRECOVERED_ERROR 0x06U
#define HOST_USER_NO_SUPPORTED_CLASS 0x07U


/**
Expand Down
45 changes: 30 additions & 15 deletions src/usb/usbh_hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "usbh_hid_parser.h"
#include "xlat.h"
#include "usbh_hid_mouse.h"
#include "usbh_hid_keyboard.h"


static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost);
Expand Down Expand Up @@ -65,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 interface, specifically:
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, HID_MOUSE_BOOT_CODE);
// 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);
// 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
Expand All @@ -97,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;

Expand All @@ -113,13 +124,14 @@ static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost)
/*Decode Bootclass Protocol: Mouse or Keyboard, see HID_KEYBRD_BOOT_CODE, HID_MOUSE_BOOT_CODE */
if (phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE) {
USBH_UsrLog("KeyBoard device found! (iface: %d)", interface);
HID_Handle->Init = USBH_HID_KeyboardInit;
} else if (phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol == HID_MOUSE_BOOT_CODE) {
USBH_UsrLog("Mouse device found! (iface: %d)", interface);
HID_Handle->Init = USBH_HID_MouseInit;
} else {
USBH_UsrLog("bInterfaceProtocol %d not supported. Assuming Mouse... (iface: %d)",
phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol, interface);
HID_Handle->Init = USBH_HID_MouseInit;
USBH_UsrLog("bInterfaceProtocol %d not supported. Assuming %s... (iface: %d)",
phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol, (XLAT_MODE_KEY == xlat_get_mode()) ? "Keyboard" : "Mouse", interface);
HID_Handle->Init = (XLAT_MODE_KEY == xlat_get_mode()) ? USBH_HID_KeyboardInit : USBH_HID_MouseInit;
}

HID_Handle->state = USBH_HID_INIT;
Expand Down Expand Up @@ -260,8 +272,11 @@ static USBH_StatusTypeDef USBH_HID_ClassRequest(USBH_HandleTypeDef *phost)
if (classReqStatus == USBH_OK) {
HID_Handle->ctl_state = USBH_HID_REQ_IDLE;

/* all requests performed*/
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
if (phost->pUser != NULL)
{
/* all requests performed*/
phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
}
status = USBH_OK;
} else if (classReqStatus == USBH_NOT_SUPPORTED) {
USBH_ErrLog("Control error: HID: Device Set protocol request failed");
Expand Down Expand Up @@ -525,7 +540,7 @@ USBH_StatusTypeDef USBH_HID_SetIdle(USBH_HandleTypeDef *phost,
phost->Control.setup.b.bRequest = USB_HID_SET_IDLE;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)duration << 8U) | (uint32_t)reportId);

phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wIndex.w = phost->device.current_interface;
phost->Control.setup.b.wLength.w = 0U;

return USBH_CtlReq(phost, NULL, 0U);
Expand Down Expand Up @@ -556,7 +571,7 @@ USBH_StatusTypeDef USBH_HID_SetReport(USBH_HandleTypeDef *phost,
phost->Control.setup.b.bRequest = USB_HID_SET_REPORT;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)reportType << 8U) | (uint32_t)reportId);

phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wIndex.w = phost->device.current_interface;
phost->Control.setup.b.wLength.w = reportLen;

return USBH_CtlReq(phost, reportBuff, (uint16_t)reportLen);
Expand Down Expand Up @@ -587,7 +602,7 @@ USBH_StatusTypeDef USBH_HID_GetReport(USBH_HandleTypeDef *phost,
phost->Control.setup.b.bRequest = USB_HID_GET_REPORT;
phost->Control.setup.b.wValue.w = (uint16_t)(((uint32_t)reportType << 8U) | (uint32_t)reportId);

phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wIndex.w = phost->device.current_interface;
phost->Control.setup.b.wLength.w = reportLen;

return USBH_CtlReq(phost, reportBuff, (uint16_t)reportLen);
Expand All @@ -613,7 +628,7 @@ USBH_StatusTypeDef USBH_HID_SetProtocol(USBH_HandleTypeDef *phost,
phost->Control.setup.b.wValue.w = 1U;
}

phost->Control.setup.b.wIndex.w = 0U;
phost->Control.setup.b.wIndex.w = phost->device.current_interface;
phost->Control.setup.b.wLength.w = 0U;

return USBH_CtlReq(phost, NULL, 0U);
Expand Down Expand Up @@ -686,7 +701,7 @@ HID_TypeTypeDef USBH_HID_GetDeviceType(USBH_HandleTypeDef *phost)
} else if (InterfaceProtocol == HID_MOUSE_BOOT_CODE) {
type = HID_MOUSE;
} else {
type = HID_MOUSE; // fallback to mouse as well
type = HID_UNKNOWN;
}
}
return type;
Expand Down
Loading

0 comments on commit ca00497

Please sign in to comment.