From 46816781090465392f997b9ffd9c15b7b7b2b050 Mon Sep 17 00:00:00 2001 From: MAY Date: Wed, 14 Jan 2026 02:08:28 +0100 Subject: [PATCH 1/2] add host hid api to set/get protocol --- .../inc/ux_device_class_hid.h | 5 + .../src/ux_device_class_hid_control_request.c | 16 +- .../src/ux_device_class_hid_initialize.c | 2 + common/usbx_host_classes/CMakeLists.txt | 2 + .../usbx_host_classes/inc/ux_host_class_hid.h | 355 +++++++------- .../src/ux_host_class_hid_protocol_get.c | 146 ++++++ .../src/ux_host_class_hid_protocol_set.c | 147 ++++++ test/cmake/usbx/regression/CMakeLists.txt | 1 + ...ice_class_hid_set_protocol_callback_test.c | 463 ++++++++++++++++++ test/regression/usbxtestcontrol.c | 6 +- 10 files changed, 966 insertions(+), 177 deletions(-) create mode 100644 common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c create mode 100644 common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c create mode 100644 test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c diff --git a/common/usbx_device_classes/inc/ux_device_class_hid.h b/common/usbx_device_classes/inc/ux_device_class_hid.h index dfa588a1..73efa5a4 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -249,6 +249,7 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT UINT ux_device_class_hid_state; UINT (*ux_device_class_hid_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); UINT (*ux_device_class_hid_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); + VOID (*ux_device_class_hid_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol); VOID (*ux_slave_class_hid_instance_activate)(VOID *); VOID (*ux_slave_class_hid_instance_deactivate)(VOID *); UCHAR *ux_device_class_hid_report_address; @@ -365,6 +366,10 @@ typedef struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT ULONG ux_device_class_hid_parameter_report_length; UINT (*ux_device_class_hid_parameter_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); UINT (*ux_device_class_hid_parameter_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); + + /* Optional callback invoked when protocol changes (boot/report). */ + VOID (*ux_device_class_hid_parameter_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol); + #if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) ULONG ux_device_class_hid_parameter_event_max_number; ULONG ux_device_class_hid_parameter_event_max_length; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c index edecc7b0..cf3fdcd1 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c @@ -205,15 +205,28 @@ UX_SLAVE_CLASS_HID *hid; case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL: - /* Send the protocol. */ + /* Send the protocol to host. */ *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)hid -> ux_device_class_hid_protocol; _ux_device_stack_transfer_request(transfer_request, 1, request_length); break; case UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL: + /* Check protocol must be 0 (Boot) or 1 (Report). */ + if ((request_value != UX_DEVICE_CLASS_HID_PROTOCOL_BOOT) && + (request_value != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT)) + { + /* Invalid value: not handled. */ + return(UX_ERROR); + } + /* Accept the protocol. */ hid -> ux_device_class_hid_protocol = request_value; + + /* If there is a callback defined by the application, send the protocol to it. */ + if (hid -> ux_device_class_hid_set_protocol_callback != UX_NULL) + hid -> ux_device_class_hid_set_protocol_callback(hid, request_value); + break; default: @@ -225,4 +238,3 @@ UX_SLAVE_CLASS_HID *hid; /* It's handled. */ return(UX_SUCCESS); } - diff --git a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c index 2366cdee..88ca11da 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c @@ -8,6 +8,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ + /**************************************************************************/ /**************************************************************************/ /** */ @@ -196,6 +197,7 @@ UCHAR *buffer; /* Store the callback function. */ hid -> ux_device_class_hid_callback = hid_parameter -> ux_device_class_hid_parameter_callback; hid -> ux_device_class_hid_get_callback = hid_parameter -> ux_device_class_hid_parameter_get_callback; + hid -> ux_device_class_hid_set_protocol_callback = hid_parameter -> ux_device_class_hid_parameter_set_protocol_callback; #if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) diff --git a/common/usbx_host_classes/CMakeLists.txt b/common/usbx_host_classes/CMakeLists.txt index 47420899..11083a22 100644 --- a/common/usbx_host_classes/CMakeLists.txt +++ b/common/usbx_host_classes/CMakeLists.txt @@ -93,6 +93,8 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set_run.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_set.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_instance_clean.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_interrupt_endpoint_search.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_item_data_get.c diff --git a/common/usbx_host_classes/inc/ux_host_class_hid.h b/common/usbx_host_classes/inc/ux_host_class_hid.h index 53a8efbe..e7ff1d50 100644 --- a/common/usbx_host_classes/inc/ux_host_class_hid.h +++ b/common/usbx_host_classes/inc/ux_host_class_hid.h @@ -1,44 +1,44 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * Copyright (c) 2024 Microsoft Corporation + * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. - * + * * SPDX-License-Identifier: MIT **************************************************************************/ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ /** */ -/** HID Class */ +/** USBX Component */ +/** */ +/** Host HID Class */ /** */ /**************************************************************************/ /**************************************************************************/ -/**************************************************************************/ -/* */ -/* COMPONENT DEFINITION RELEASE */ -/* */ -/* ux_host_class_hid.h PORTABLE C */ +/**************************************************************************/ +/* */ +/* COMPONENT DEFINITION RELEASE */ +/* */ +/* ux_host_class_hid.h PORTABLE C */ /* 6.3.0 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This file contains all the header and extern functions used by the */ -/* USBX HID class. */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* USBX HID class. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* used UX prefix to refer to */ @@ -63,15 +63,15 @@ #ifndef UX_HOST_CLASS_HID_H #define UX_HOST_CLASS_HID_H -/* Determine if a C++ compiler is being used. If so, ensure that standard - C is used to process the API information. */ +/* Determine if a C++ compiler is being used. If so, ensure that standard + C is used to process the API information. */ -#ifdef __cplusplus +#ifdef __cplusplus -/* Yes, C++ compiler is present. Use standard C. */ -extern "C" { +/* Yes, C++ compiler is present. Use standard C. */ +extern "C" { -#endif +#endif /* Internal option: enable the basic USBX error checking. This define is typically used @@ -112,7 +112,7 @@ extern "C" { #define UX_HOST_CLASS_HID_TYPE_GLOBAL 0x1 #define UX_HOST_CLASS_HID_TYPE_LOCAL 0x2 #define UX_HOST_CLASS_HID_TYPE_RESERVED 0x3 - + /* Define HID Class main tags. */ @@ -121,7 +121,7 @@ extern "C" { #define UX_HOST_CLASS_HID_MAIN_TAG_FEATURE 0xb #define UX_HOST_CLASS_HID_MAIN_TAG_COLLECTION 0xa #define UX_HOST_CLASS_HID_MAIN_TAG_END_COLLECTION 0xc - + /* Define HID Class global tags. */ @@ -181,10 +181,10 @@ extern "C" { /* Define HID Class commands. */ -#define UX_HOST_CLASS_HID_GET_REPORT 0x01 +#define UX_HOST_CLASS_HID_GET_REPORT 0x01 #define UX_HOST_CLASS_HID_GET_IDLE 0x02 #define UX_HOST_CLASS_HID_GET_PROTOCOL 0x03 -#define UX_HOST_CLASS_HID_SET_REPORT 0x09 +#define UX_HOST_CLASS_HID_SET_REPORT 0x09 #define UX_HOST_CLASS_HID_SET_IDLE 0x0A #define UX_HOST_CLASS_HID_SET_PROTOCOL 0x0B @@ -202,133 +202,133 @@ extern "C" { /* Define HID Class page constants. */ -#define UX_HOST_CLASS_HID_PAGE_GENERIC_DESKTOP_CONTROLS 0x01 -#define UX_HOST_CLASS_HID_PAGE_SIMULATION_CONTROLS 0x02 -#define UX_HOST_CLASS_HID_PAGE_VR_CONTROLS 0x03 -#define UX_HOST_CLASS_HID_PAGE_SPORT_CONTROLS 0x04 -#define UX_HOST_CLASS_HID_PAGE_GAME_CONTROLS 0x05 -#define UX_HOST_CLASS_HID_PAGE_GENERIC_DEVICE_CONTROLS 0x06 -#define UX_HOST_CLASS_HID_PAGE_KEYBOARD_KEYPAD 0x07 -#define UX_HOST_CLASS_HID_PAGE_LEDS 0x08 -#define UX_HOST_CLASS_HID_PAGE_BUTTON 0x09 -#define UX_HOST_CLASS_HID_PAGE_ORDINAL 0x0A -#define UX_HOST_CLASS_HID_PAGE_TELEPHONY 0x0B -#define UX_HOST_CLASS_HID_PAGE_CONSUMER 0x0C -#define UX_HOST_CLASS_HID_PAGE_DIGITIZER 0x0D -#define UX_HOST_CLASS_HID_PAGE_PHYSICAL_INTERFACE_DEVICE 0x0F -#define UX_HOST_CLASS_HID_PAGE_UNICODE 0x10 -#define UX_HOST_CLASS_HID_PAGE_ALPHANUMERIC_DISPLAY 0x14 -#define UX_HOST_CLASS_HID_PAGE_MEDICAL_INSTRUMENTS 0x40 -#define UX_HOST_CLASS_HID_PAGE_BAR_CODE_SCANNER 0x8C -#define UX_HOST_CLASS_HID_PAGE_SCALE_PAGE 0x8D -#define UX_HOST_CLASS_HID_PAGE_MAGNETIC_STRIPE_READING 0x8E -#define UX_HOST_CLASS_HID_PAGE_CAMERA_CONTROL_PAGE 0x90 +#define UX_HOST_CLASS_HID_PAGE_GENERIC_DESKTOP_CONTROLS 0x01 +#define UX_HOST_CLASS_HID_PAGE_SIMULATION_CONTROLS 0x02 +#define UX_HOST_CLASS_HID_PAGE_VR_CONTROLS 0x03 +#define UX_HOST_CLASS_HID_PAGE_SPORT_CONTROLS 0x04 +#define UX_HOST_CLASS_HID_PAGE_GAME_CONTROLS 0x05 +#define UX_HOST_CLASS_HID_PAGE_GENERIC_DEVICE_CONTROLS 0x06 +#define UX_HOST_CLASS_HID_PAGE_KEYBOARD_KEYPAD 0x07 +#define UX_HOST_CLASS_HID_PAGE_LEDS 0x08 +#define UX_HOST_CLASS_HID_PAGE_BUTTON 0x09 +#define UX_HOST_CLASS_HID_PAGE_ORDINAL 0x0A +#define UX_HOST_CLASS_HID_PAGE_TELEPHONY 0x0B +#define UX_HOST_CLASS_HID_PAGE_CONSUMER 0x0C +#define UX_HOST_CLASS_HID_PAGE_DIGITIZER 0x0D +#define UX_HOST_CLASS_HID_PAGE_PHYSICAL_INTERFACE_DEVICE 0x0F +#define UX_HOST_CLASS_HID_PAGE_UNICODE 0x10 +#define UX_HOST_CLASS_HID_PAGE_ALPHANUMERIC_DISPLAY 0x14 +#define UX_HOST_CLASS_HID_PAGE_MEDICAL_INSTRUMENTS 0x40 +#define UX_HOST_CLASS_HID_PAGE_BAR_CODE_SCANNER 0x8C +#define UX_HOST_CLASS_HID_PAGE_SCALE_PAGE 0x8D +#define UX_HOST_CLASS_HID_PAGE_MAGNETIC_STRIPE_READING 0x8E +#define UX_HOST_CLASS_HID_PAGE_CAMERA_CONTROL_PAGE 0x90 /* Define HID Class generic desktop page constants. */ -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_UNDEFINED 0x00 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_POINTER 0x01 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOUSE 0x02 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RESERVED 0x03 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_JOYSTICK 0x04 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_GAME PAD 0x05 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYBOARD 0x06 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYPAD 0x07 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MULTI_AXIS_CONTROLLER 0x08 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_X 0x30 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Y 0x31 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Z 0x32 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RX 0x33 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RY 0x34 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RZ 0x35 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SLIDER 0x36 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_DIAL 0x37 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_WHEEL 0x38 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_HAT_SWITCH 0x39 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_COUNTED_BUFFER 0x3A -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_BYTE_COUNT 0x3B -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOTION_WAKEUP 0x3C -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_START 0x3D -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SELECT 0x3E -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VX 0x40 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VY 0x41 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VZ 0x42 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRX 0x43 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRY 0x44 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRZ 0x45 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VNO 0x46 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_FEATURE_NOTIFICATION 0x47 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTROL 0x80 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_POWER_DOWN 0x81 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SLEEP 0x82 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WAKE_UP 0x83 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTEXT_MENU 0x84 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MAIN_MENU 0x85 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_APP_MENU 0x86 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_HELP 0x87 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_EXIT 0x88 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_SELECT 0x89 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_RIGHT 0x8A -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_LEFT 0x8B -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_UP 0x8C -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_DOWN 0x8D -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_COLD_RESTART 0x8E -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WARM_RESTART 0x8F -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_UP 0x90 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_DOWN 0x91 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_RIGHT 0x92 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_LEFT 0x93 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DOCK 0xA0 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_UNDOCK 0xA1 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SETUP 0xA2 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_BREAK 0xA3 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DEBUGGER_BREAK 0xA4 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICAION_BREAK 0xA5 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICATION_DEBUGGER_BREAK 0xA6 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SPEAKER_MUTE 0xA7 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_HIBERNATE 0xA8 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INVERT 0xB0 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INTERNAL 0xB1 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_EXTERNAL 0xB2 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_BOTH 0xB3 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_DUAL 0xB4 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_TOGGLE 0xB5 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_SWAP 0xB6 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE 0xB7 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_UNDEFINED 0x00 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_POINTER 0x01 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOUSE 0x02 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RESERVED 0x03 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_JOYSTICK 0x04 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_GAME PAD 0x05 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYBOARD 0x06 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYPAD 0x07 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MULTI_AXIS_CONTROLLER 0x08 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_X 0x30 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Y 0x31 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Z 0x32 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RX 0x33 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RY 0x34 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RZ 0x35 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SLIDER 0x36 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_DIAL 0x37 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_WHEEL 0x38 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_HAT_SWITCH 0x39 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_COUNTED_BUFFER 0x3A +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_BYTE_COUNT 0x3B +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOTION_WAKEUP 0x3C +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_START 0x3D +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SELECT 0x3E +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VX 0x40 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VY 0x41 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VZ 0x42 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRX 0x43 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRY 0x44 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRZ 0x45 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VNO 0x46 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_FEATURE_NOTIFICATION 0x47 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTROL 0x80 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_POWER_DOWN 0x81 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SLEEP 0x82 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WAKE_UP 0x83 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTEXT_MENU 0x84 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MAIN_MENU 0x85 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_APP_MENU 0x86 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_HELP 0x87 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_EXIT 0x88 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_SELECT 0x89 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_RIGHT 0x8A +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_LEFT 0x8B +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_UP 0x8C +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_DOWN 0x8D +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_COLD_RESTART 0x8E +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WARM_RESTART 0x8F +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_UP 0x90 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_DOWN 0x91 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_RIGHT 0x92 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_LEFT 0x93 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DOCK 0xA0 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_UNDOCK 0xA1 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SETUP 0xA2 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_BREAK 0xA3 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DEBUGGER_BREAK 0xA4 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICAION_BREAK 0xA5 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICATION_DEBUGGER_BREAK 0xA6 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SPEAKER_MUTE 0xA7 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_HIBERNATE 0xA8 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INVERT 0xB0 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INTERNAL 0xB1 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_EXTERNAL 0xB2 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_BOTH 0xB3 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_DUAL 0xB4 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_TOGGLE 0xB5 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_SWAP 0xB6 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE 0xB7 /* Define HID Class game control page constants. */ -#define UX_HOST_CLASS_HID_GAME_CONTROL_UNDEFINED 0x00 -#define UX_HOST_CLASS_HID_GAME_CONTROL_3D_GAME_CONTROLLER 0x01 -#define UX_HOST_CLASS_HID_GAME_CONTROL_PINBALL_DEVICE 0x02 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_DEVICE 0x03 -#define UX_HOST_CLASS_HID_GAME_CONTROL_POINT_OF_VIEW 0x20 -#define UX_HOST_CLASS_HID_GAME_CONTROL_TURN_RIGHT_LEFT 0x21 -#define UX_HOST_CLASS_HID_GAME_CONTROL_PITCH_FORWARD_BACKWARD 0x22 -#define UX_HOST_CLASS_HID_GAME_CONTROL_ROLL_RIGHT_LEFT 0x23 -#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_RIGHT_LEFT 0x24 -#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_FORWARD_BACKWARD 0x25 -#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_UP_DOWN 0x26 -#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_RIGHT_LEFT 0x27 -#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_FORWARD_BACKWARD 0x28 -#define UX_HOST_CLASS_HID_GAME_CONTROL_HEIGHT_OF_POV 0x29 -#define UX_HOST_CLASS_HID_GAME_CONTROL_FLIPPER 0x2A -#define UX_HOST_CLASS_HID_GAME_CONTROL_SECONDARY_FLIPPER 0x2B -#define UX_HOST_CLASS_HID_GAME_CONTROL_BUMP 0x2C -#define UX_HOST_CLASS_HID_GAME_CONTROL_NEW_GAME 0x2D -#define UX_HOST_CLASS_HID_GAME_CONTROL_SHOOT_BALL 0x2E -#define UX_HOST_CLASS_HID_GAME_CONTROL_PLAYER 0x2F -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BOLT 0x30 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_CLIP 0x31 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SELECTOR 0x32 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SINGLE_SHOT 0x33 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BURST 0x34 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_AUTOMATIC 0x35 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SAFETY 0x36 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEAD_FIRE_JUMP 0x37 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEPAD_TRIGGER 0x39 +#define UX_HOST_CLASS_HID_GAME_CONTROL_UNDEFINED 0x00 +#define UX_HOST_CLASS_HID_GAME_CONTROL_3D_GAME_CONTROLLER 0x01 +#define UX_HOST_CLASS_HID_GAME_CONTROL_PINBALL_DEVICE 0x02 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_DEVICE 0x03 +#define UX_HOST_CLASS_HID_GAME_CONTROL_POINT_OF_VIEW 0x20 +#define UX_HOST_CLASS_HID_GAME_CONTROL_TURN_RIGHT_LEFT 0x21 +#define UX_HOST_CLASS_HID_GAME_CONTROL_PITCH_FORWARD_BACKWARD 0x22 +#define UX_HOST_CLASS_HID_GAME_CONTROL_ROLL_RIGHT_LEFT 0x23 +#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_RIGHT_LEFT 0x24 +#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_FORWARD_BACKWARD 0x25 +#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_UP_DOWN 0x26 +#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_RIGHT_LEFT 0x27 +#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_FORWARD_BACKWARD 0x28 +#define UX_HOST_CLASS_HID_GAME_CONTROL_HEIGHT_OF_POV 0x29 +#define UX_HOST_CLASS_HID_GAME_CONTROL_FLIPPER 0x2A +#define UX_HOST_CLASS_HID_GAME_CONTROL_SECONDARY_FLIPPER 0x2B +#define UX_HOST_CLASS_HID_GAME_CONTROL_BUMP 0x2C +#define UX_HOST_CLASS_HID_GAME_CONTROL_NEW_GAME 0x2D +#define UX_HOST_CLASS_HID_GAME_CONTROL_SHOOT_BALL 0x2E +#define UX_HOST_CLASS_HID_GAME_CONTROL_PLAYER 0x2F +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BOLT 0x30 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_CLIP 0x31 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SELECTOR 0x32 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SINGLE_SHOT 0x33 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BURST 0x34 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_AUTOMATIC 0x35 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SAFETY 0x36 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEAD_FIRE_JUMP 0x37 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEPAD_TRIGGER 0x39 /* Define HID Class LED page constants. */ @@ -570,7 +570,7 @@ extern "C" { #define UX_HOST_CLASS_HID_CONSUMER_ALTERNATE_AUDIO_DECREMENT 0x173 #define UX_HOST_CLASS_HID_CONSUMER_APPLICATION_LAUNCH_BUTTONS 0x174 #define UX_HOST_CLASS_HID_CONSUMER_AL_LAUNCH_BUTTON_CONFIGURATION 0x180 -#define UX_HOST_CLASS_HID_CONSUMER_AL_PROGRAMMABLE_BUTTON 0x181 +#define UX_HOST_CLASS_HID_CONSUMER_AL_PROGRAMMABLE_BUTTON 0x181 #define UX_HOST_CLASS_HID_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION 0x182 #define UX_HOST_CLASS_HID_CONSUMER_AL_WORD_PROCESSOR 0x183 #define UX_HOST_CLASS_HID_CONSUMER_AL_TEXT_EDITOR 0x184 @@ -786,6 +786,10 @@ extern "C" { #define UX_HOST_CLASS_HID_REPORT_TRANSFER_TIMEOUT 10000 #endif +/* HID protocol values. */ +#define UX_HOST_CLASS_HID_PROTOCOL_BOOT 0x00 +#define UX_HOST_CLASS_HID_PROTOCOL_REPORT 0x01 + /* Define HID Class descriptor. */ typedef struct UX_HID_DESCRIPTOR_STRUCT @@ -806,7 +810,7 @@ typedef struct UX_HID_DESCRIPTOR_STRUCT typedef struct UX_HOST_CLASS_HID_REPORT_CALLBACK_STRUCT { - struct UX_HOST_CLASS_HID_CLIENT_STRUCT + struct UX_HOST_CLASS_HID_CLIENT_STRUCT *ux_host_class_hid_report_callback_client; ULONG ux_host_class_hid_report_callback_id; ULONG ux_host_class_hid_report_callback_status; @@ -826,7 +830,7 @@ typedef struct UX_HOST_CLASS_HID_REPORT_GET_ID_STRUCT ULONG ux_host_class_hid_report_get_id; ULONG ux_host_class_hid_report_get_type; - struct UX_HOST_CLASS_HID_REPORT_STRUCT + struct UX_HOST_CLASS_HID_REPORT_STRUCT *ux_host_class_hid_report_get_report; } UX_HOST_CLASS_HID_REPORT_GET_ID; @@ -890,9 +894,9 @@ typedef struct UX_HOST_CLASS_HID_FIELD_STRUCT ULONG ux_host_class_hid_field_number_usage; ULONG *ux_host_class_hid_field_values; ULONG ux_host_class_hid_field_number_values; - struct UX_HOST_CLASS_HID_REPORT_STRUCT + struct UX_HOST_CLASS_HID_REPORT_STRUCT *ux_host_class_hid_field_report; - struct UX_HOST_CLASS_HID_FIELD_STRUCT + struct UX_HOST_CLASS_HID_FIELD_STRUCT *ux_host_class_hid_field_next_field; } UX_HOST_CLASS_HID_FIELD; @@ -904,7 +908,7 @@ typedef struct UX_HOST_CLASS_HID_REPORT_STRUCT ULONG ux_host_class_hid_report_id; ULONG ux_host_class_hid_report_type; - struct UX_HOST_CLASS_HID_FIELD_STRUCT + struct UX_HOST_CLASS_HID_FIELD_STRUCT *ux_host_class_hid_report_field; ULONG ux_host_class_hid_report_number_item; ULONG ux_host_class_hid_report_byte_length; @@ -913,7 +917,7 @@ typedef struct UX_HOST_CLASS_HID_REPORT_STRUCT VOID *ux_host_class_hid_report_callback_buffer; ULONG ux_host_class_hid_report_callback_length; VOID (*ux_host_class_hid_report_callback_function) (struct UX_HOST_CLASS_HID_REPORT_CALLBACK_STRUCT *); - struct UX_HOST_CLASS_HID_REPORT_STRUCT + struct UX_HOST_CLASS_HID_REPORT_STRUCT *ux_host_class_hid_report_next_report; } UX_HOST_CLASS_HID_REPORT; @@ -925,21 +929,21 @@ typedef struct UX_HOST_CLASS_HID_PARSER_STRUCT UX_HOST_CLASS_HID_GLOBAL_ITEM ux_host_class_hid_parser_global; - UX_HOST_CLASS_HID_GLOBAL_ITEM + UX_HOST_CLASS_HID_GLOBAL_ITEM ux_host_class_hid_parser_global_pool[UX_HOST_CLASS_HID_MAX_GLOBAL]; ULONG ux_host_class_hid_parser_number_global; - UX_HOST_CLASS_HID_LOCAL_ITEM + UX_HOST_CLASS_HID_LOCAL_ITEM ux_host_class_hid_parser_local; ULONG ux_host_class_hid_parser_application; ULONG ux_host_class_hid_parser_collection[UX_HOST_CLASS_HID_MAX_COLLECTION]; ULONG ux_host_class_hid_parser_number_collection; ULONG ux_host_class_hid_parser_main_page; ULONG ux_host_class_hid_parser_main_usage; - UX_HOST_CLASS_HID_REPORT + UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_parser_input_report; - UX_HOST_CLASS_HID_REPORT + UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_parser_output_report; - UX_HOST_CLASS_HID_REPORT + UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_parser_feature_report; } UX_HOST_CLASS_HID_PARSER; @@ -961,7 +965,7 @@ typedef struct UX_HOST_CLASS_HID_ITEM_STRUCT typedef struct UX_HOST_CLASS_HID_STRUCT { - struct UX_HOST_CLASS_HID_STRUCT + struct UX_HOST_CLASS_HID_STRUCT *ux_host_class_hid_next_instance; UX_HOST_CLASS *ux_host_class_hid_class; UX_DEVICE *ux_host_class_hid_device; @@ -972,11 +976,11 @@ typedef struct UX_HOST_CLASS_HID_STRUCT UINT ux_host_class_hid_interrupt_endpoint_status; UX_INTERFACE *ux_host_class_hid_interface; ULONG ux_host_class_hid_state; - struct UX_HID_DESCRIPTOR_STRUCT + struct UX_HID_DESCRIPTOR_STRUCT ux_host_class_hid_descriptor; - UX_HOST_CLASS_HID_PARSER + UX_HOST_CLASS_HID_PARSER ux_host_class_hid_parser; - struct UX_HOST_CLASS_HID_CLIENT_STRUCT + struct UX_HOST_CLASS_HID_CLIENT_STRUCT *ux_host_class_hid_client; #if !defined(UX_HOST_STANDALONE) UX_SEMAPHORE ux_host_class_hid_semaphore; @@ -1037,8 +1041,8 @@ typedef struct UX_HOST_CLASS_HID_CLIENT_REPORT_STRUCT UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_client_report; ULONG *ux_host_class_hid_client_report_buffer; - ULONG ux_host_class_hid_client_report_length; - ULONG ux_host_class_hid_client_report_actual_length; + ULONG ux_host_class_hid_client_report_length; + ULONG ux_host_class_hid_client_report_actual_length; UINT ux_host_class_hid_client_report_flags; } UX_HOST_CLASS_HID_CLIENT_REPORT; @@ -1055,7 +1059,7 @@ typedef struct UX_HOST_CLASS_HID_CLIENT_STRUCT UCHAR ux_host_class_hid_client_name[UX_HOST_CLASS_HID_MAX_CLIENT_NAME_LENGTH + 1]; /* "+1" for string null-terminator */ #endif UINT (*ux_host_class_hid_client_handler) (struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *); - VOID *ux_host_class_hid_client_local_instance; + VOID *ux_host_class_hid_client_local_instance; #if defined(UX_HOST_STANDALONE) VOID (*ux_host_class_hid_client_function)(struct UX_HOST_CLASS_HID_CLIENT_STRUCT *); #endif @@ -1099,7 +1103,8 @@ VOID _ux_host_class_hid_transfer_request_completed(UX_TRANSFER *transfer_requ UINT _ux_host_class_hid_tasks_run(UX_HOST_CLASS *hid_class); UINT _ux_host_class_hid_idle_set_run(UX_HOST_CLASS_HID *hid, USHORT idle_time, USHORT report_id); UINT _ux_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID_CLIENT_REPORT *client_report); - +UINT _ux_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol); +UINT _ux_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol); UINT _uxe_host_class_hid_client_register(UCHAR *hid_client_name, UINT (*hid_client_handler)(struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *)); @@ -1117,7 +1122,8 @@ UINT _uxe_host_class_hid_report_set(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID UINT _uxe_host_class_hid_idle_set_run(UX_HOST_CLASS_HID *hid, USHORT idle_time, USHORT report_id); UINT _uxe_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID_CLIENT_REPORT *client_report); - +UINT _uxe_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol); +UINT _uxe_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol); /* Define HID Class API prototypes. */ @@ -1144,6 +1150,8 @@ UINT _uxe_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS #define ux_host_class_hid_report_id_get _uxe_host_class_hid_report_id_get #define ux_host_class_hid_report_get _uxe_host_class_hid_report_get #define ux_host_class_hid_report_set _uxe_host_class_hid_report_set +#define ux_host_class_hid_protocol_set _uxe_host_class_hid_protocol_set +#define ux_host_class_hid_protocol_get _uxe_host_class_hid_protocol_get #else @@ -1159,15 +1167,16 @@ UINT _uxe_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS #define ux_host_class_hid_report_id_get _ux_host_class_hid_report_id_get #define ux_host_class_hid_report_get _ux_host_class_hid_report_get #define ux_host_class_hid_report_set _ux_host_class_hid_report_set +#define ux_host_class_hid_protocol_set _ux_host_class_hid_protocol_set +#define ux_host_class_hid_protocol_get _ux_host_class_hid_protocol_get #endif -/* Determine if a C++ compiler is being used. If so, complete the standard - C conditional started above. */ +/* Determine if a C++ compiler is being used. If so, complete the standard + C conditional started above. */ #ifdef __cplusplus -} -#endif - +} #endif +#endif diff --git a/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c b/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c new file mode 100644 index 00000000..7a8f2644 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c @@ -0,0 +1,146 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Host HID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_hid.h" +#include "ux_host_stack.h" + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_hid_protocol_get PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs a GET_PROTOCOL to the HID device to read */ +/* current protocol (BOOT=0 or REPORT=1). */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Destination for protocol */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol) +{ + +UX_ENDPOINT *control_endpoint; +UX_TRANSFER *transfer_request; +UINT status; +UCHAR proto_byte = 0xFFu; + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0) + +#if defined(UX_HOST_STANDALONE) + hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN; +#endif + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Get the default control endpoint transfer request pointer. */ + control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + +#if !defined(UX_HOST_STANDALONE) + + /* Protect thread reentry to this instance. */ + status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + return(status); + +#endif + + /* Create a transfer request for the GET_PROTOCOL request. */ + transfer_request -> ux_transfer_request_data_pointer = &proto_byte; + transfer_request -> ux_transfer_request_requested_length = 1; + transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_PROTOCOL; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = 0; + transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber; + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + +#if !defined(UX_HOST_STANDALONE) + /* Unprotect thread reentry to this instance. */ + _ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore); +#endif + + if (status == UX_SUCCESS && protocol) + *protocol = (USHORT)proto_byte; + + return(status); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _uxe_host_class_hid_protocol_get PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks errors in HID protocol get function call. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Destination for protocol */ +/* */ +/* OUTPUT */ +/* */ +/* Status */ +/* */ +/**************************************************************************/ +UINT _uxe_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol) +{ + /* Sanity check. */ + if (hid == UX_NULL || protocol == UX_NULL) + return(UX_INVALID_PARAMETER); + + /* Invoke protocol get function. */ + return(_ux_host_class_hid_protocol_get(hid, protocol)); +} diff --git a/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c b/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c new file mode 100644 index 00000000..b757cb71 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Host HID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_hid.h" +#include "ux_host_stack.h" + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_hid_protocol_set PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs a SET_PROTOCOL to the HID device to switch */ +/* between BOOT (0) and REPORT (1) protocols. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Protocol (BOOT/REPORT) */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol) +{ + +UX_ENDPOINT *control_endpoint; +UX_TRANSFER *transfer_request; +UINT status; + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0) + +#if defined(UX_HOST_STANDALONE) + hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN; +#endif + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Get the default control endpoint transfer request pointer. */ + control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + +#if !defined(UX_HOST_STANDALONE) + + /* Protect thread reentry to this instance. */ + status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + return(status); + +#endif + + /* Create a transfer request for the SET_PROTOCOL request. */ + transfer_request -> ux_transfer_request_data_pointer = UX_NULL; + transfer_request -> ux_transfer_request_requested_length = 0; + transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_PROTOCOL; + transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = (UINT)protocol; + transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber; + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + +#if !defined(UX_HOST_STANDALONE) + /* Unprotect thread reentry to this instance. */ + _ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore); +#endif + + /* Return the function status. */ + return(status); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _uxe_host_class_hid_protocol_set PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks errors in HID protocol set function call. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Protocol (BOOT/REPORT) */ +/* */ +/* OUTPUT */ +/* */ +/* Status */ +/* */ +/**************************************************************************/ +UINT _uxe_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol) +{ + /* Sanity check. */ + if (hid == UX_NULL) + return(UX_INVALID_PARAMETER); + + /* Validate protocol value: must be BOOT(0) or REPORT(1). */ + if (protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT && + protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT) + return(UX_INVALID_PARAMETER); + + /* Invoke protocol set function. */ + return(_ux_host_class_hid_protocol_set(hid, protocol)); +} diff --git a/test/cmake/usbx/regression/CMakeLists.txt b/test/cmake/usbx/regression/CMakeLists.txt index 8d29d436..68e2d775 100644 --- a/test/cmake/usbx/regression/CMakeLists.txt +++ b/test/cmake/usbx/regression/CMakeLists.txt @@ -139,6 +139,7 @@ set(ux_class_hid_test_cases ${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test2.c ${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test3.c ${SOURCE_DIR}/usbx_ux_device_class_hid_control_request_test.c + ${SOURCE_DIR}/usbx_ux_device_class_hid_set_protocol_callback_test.c ${SOURCE_DIR}/usbx_ux_device_class_hid_initialize_test.c ${SOURCE_DIR}/usbx_ux_device_class_hid_interrupt_thread_test2.c ${SOURCE_DIR}/usbx_ux_device_class_hid_read_test.c diff --git a/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c b/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c new file mode 100644 index 00000000..0167a544 --- /dev/null +++ b/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c @@ -0,0 +1,463 @@ +/* This test focuses on HID device class protocol set/get functionality and related callbacks. */ + +#include +#include "tx_api.h" +#include "ux_api.h" +#include "ux_system.h" +#include "ux_utility.h" +#include "ux_host_class_hid.h" +#include "ux_host_class_hid_keyboard.h" +#include "ux_device_class_hid.h" +#include "ux_device_stack.h" +#include "usbx_test_common_hid.h" + +/* Define constants. */ +#define UX_DEMO_DEBUG_SIZE (4096*8) +#define UX_DEMO_STACK_SIZE 1024 + +/* Define local/extern function prototypes. */ +static void demo_thread_entry(ULONG); +static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *, UX_SLAVE_CLASS_HID_EVENT *); +static VOID demo_set_protocol_callback(UX_SLAVE_CLASS_HID *hid, ULONG protocol); +static TX_THREAD tx_demo_thread_host_simulation; +static void tx_demo_thread_host_simulation_entry(ULONG); + +/* Define global data structures. */ +static UX_HOST_CLASS_HID *hid; +static UINT status; + +static UX_SLAVE_CLASS_HID_PARAMETER hid_parameter; + +static volatile UINT g_set_protocol_callback_calls = 0; +static volatile ULONG g_set_protocol_last_value = 0xFFFFFFFFu; + +static UCHAR hid_keyboard_report[] = { + + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x39, // USAGE (Caps Lock) + 0x09, 0x53, // USAGE (Num Lock) + 0x09, 0x47, // USAGE (Scroll Lock) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x95, 0x05, // REPORT_COUNT (5) + 0x75, 0x01, // REPORT_SIZE (1) + 0x05, 0x08, // USAGE_PAGE (LEDs) + 0x19, 0x01, // USAGE_MINIMUM (Num Lock) + 0x29, 0x05, // USAGE_MAXIMUM (Kana) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x03, // REPORT_SIZE (3) + 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0 // END_COLLECTION +}; +#define HID_KEYBOARD_REPORT_LENGTH (sizeof(hid_keyboard_report) / sizeof(hid_keyboard_report[0])) + + +#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52 +static UCHAR device_framework_full_speed[] = { + + /* Device descriptor */ + 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, + 0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + + /* Configuration descriptor */ + 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0, + 0x32, + + /* Interface descriptor */ + 0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, + 0x00, + + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_KEYBOARD_REPORT_LENGTH), + MSB(HID_KEYBOARD_REPORT_LENGTH), + + /* Endpoint descriptor (Interrupt) */ + 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08 + + }; + + +#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62 +static UCHAR device_framework_high_speed[] = { + + /* Device descriptor */ + 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02, + 0x03, 0x01, + + /* Device qualifier descriptor */ + 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x01, 0x00, + + /* Configuration descriptor */ + 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0, + 0x32, + + /* Interface descriptor */ + 0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, + 0x00, + + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_KEYBOARD_REPORT_LENGTH), + MSB(HID_KEYBOARD_REPORT_LENGTH), + + /* Endpoint descriptor (Interrupt) */ + 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08 + + }; + + + /* String Device Framework : + Byte 0 and 1 : Word containing the language ID : 0x0904 for US + Byte 2 : Byte containing the index of the descriptor + Byte 3 : Byte containing the length of the descriptor string + */ + +#define STRING_FRAMEWORK_LENGTH 40 +static UCHAR string_framework[] = { + + /* Manufacturer string descriptor : Index 1 */ + 0x09, 0x04, 0x01, 0x0c, + 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c, + 0x6f, 0x67, 0x69, 0x63, + + /* Product string descriptor : Index 2 */ + 0x09, 0x04, 0x02, 0x0c, + 0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62, + 0x6f, 0x61, 0x72, 0x64, + + /* Serial Number string descriptor : Index 3 */ + 0x09, 0x04, 0x03, 0x04, + 0x30, 0x30, 0x30, 0x31 + }; + + + /* Multiple languages are supported on the device, to add + a language besides english, the unicode language code must + be appended to the language_id_framework array and the length + adjusted accordingly. */ +#define LANGUAGE_ID_FRAMEWORK_LENGTH 2 +static UCHAR language_id_framework[] = { + + /* English. */ + 0x09, 0x04 + }; + + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* For further expansion of interrupt-level testing. */ +} + + + +static VOID error_callback(UINT system_level, UINT system_context, UINT error_code) +{ + + /* @BUG_FIX_PENDING: ux_dcd_sim_slave_function.c doesn't support transfer aborts, which happen during device unregistration of a class. */ + if (error_code != UX_FUNCTION_NOT_SUPPORTED) + { + + /* Failed test. */ + printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code); + test_control_return(1); + } +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void usbx_ux_device_class_hid_set_protocol_callback_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR * stack_pointer; +CHAR * memory_pointer; +UINT descriptor_size = HID_KEYBOARD_REPORT_LENGTH; + + /* Inform user. */ + printf("Running HID Set/Get Protocol Callback Test......................... "); + + /* Initialize the free memory pointer */ + stack_pointer = (CHAR *) usbx_memory; + memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2); + + /* Initialize USBX. Memory */ + status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0); + + /* Check for error. */ + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Register the error callback. */ + _ux_utility_error_callback_register(error_callback); + + /* The code below is required for installing the host portion of USBX */ + status = ux_host_stack_initialize(UX_NULL); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Register the HID client(s). */ + status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* The code below is required for installing the device portion of USBX. No call back for + device status change in this example. */ + status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED, + device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED, + string_framework, STRING_FRAMEWORK_LENGTH, + language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL); + if(status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Initialize the hid class parameters for a keyboard. */ + hid_parameter.ux_device_class_hid_parameter_report_address = hid_keyboard_report; + hid_parameter.ux_device_class_hid_parameter_report_length = HID_KEYBOARD_REPORT_LENGTH; + hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback; + hid_parameter.ux_device_class_hid_parameter_set_protocol_callback = demo_set_protocol_callback; + + /* Initialize the device hid class. The class is connected with interface 2 */ + status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry, + 1, 0, (VOID *)&hid_parameter); + if(status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + + /* Initialize the simulated device controller. */ + status = _ux_dcd_sim_slave_initialize(); + + /* Check for error. */ + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Register all the USB host controllers available in this system */ + status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0); + + /* Check for error. */ + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Create the main host simulation thread. */ + status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0, + stack_pointer, UX_DEMO_STACK_SIZE, + 20, 20, 1, TX_AUTO_START); + + /* Check for error. */ + if (status != TX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } +} + + +static void tx_demo_thread_host_simulation_entry(ULONG arg) +{ +UX_SLAVE_DEVICE *device; +UX_SLAVE_INTERFACE *interface; +UX_SLAVE_CLASS_HID *slave_hid; +UINT status; + + device = &_ux_system_slave -> ux_system_slave_device; + + /* Ensure device is configured before accessing interfaces. */ + while (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + tx_thread_sleep(10); + + /* Retrieve the HID class instance from the configured interface. */ + interface = device -> ux_slave_device_first_interface; + if (interface == UX_NULL || interface -> ux_slave_interface_class_instance == UX_NULL) + { + printf("Error on line %d, device interface/class not ready\n", __LINE__); + test_control_return(1); + } + slave_hid = interface -> ux_slave_interface_class_instance; + + /* Find the HID class */ + status = demo_class_hid_get(); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Sanity: default protocol is report (1). */ + if (ux_device_class_hid_protocol_get(slave_hid) != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, protocol not default report\n", __LINE__); + test_control_return(1); + } + + USHORT host_protocol = 0xFFFF; + status = ux_host_class_hid_protocol_get(hid, &host_protocol); + if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Default protocol is report 1. */ + if (status == UX_SUCCESS && host_protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, host get protocol not report\n", __LINE__); + test_control_return(1); + } + + /* Issue SET_PROTOCOL to BOOT (0). */ + status = ux_host_class_hid_protocol_set(hid, UX_HOST_CLASS_HID_PROTOCOL_BOOT); + if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_class_hid_protocol_get(hid, &host_protocol); + + if (g_set_protocol_callback_calls < 1 || + g_set_protocol_last_value != 0 || + host_protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value); + test_control_return(1); + } + + if (ux_device_class_hid_protocol_get(slave_hid) != UX_DEVICE_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, protocol not set to boot\n", __LINE__); + test_control_return(1); + } + + /* Issue SET_PROTOCOL to REPORT (1). */ + status = ux_host_class_hid_protocol_set(hid, UX_HOST_CLASS_HID_PROTOCOL_REPORT); + if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_class_hid_protocol_get(hid, &host_protocol); + + if (g_set_protocol_callback_calls < 2 || + g_set_protocol_last_value != 1 || + host_protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value); + test_control_return(1); + } + + if (ux_device_class_hid_protocol_get(slave_hid) != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, protocol not set to report\n", __LINE__); + test_control_return(1); + } + + + /* Now disconnect the device. */ + _ux_device_stack_disconnect(); + + /* And deinitialize the class. */ + status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry); + + /* Deinitialize the device side of usbx. */ + _ux_device_stack_uninitialize(); + + /* And finally the usbx system resources. */ + _ux_system_uninitialize(); + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event) +{ + return(UX_SUCCESS); +} + +static VOID demo_set_protocol_callback(UX_SLAVE_CLASS_HID *hid, ULONG protocol) +{ + g_set_protocol_callback_calls++; + g_set_protocol_last_value = protocol; +} diff --git a/test/regression/usbxtestcontrol.c b/test/regression/usbxtestcontrol.c index 5ffc6871..ea43612d 100644 --- a/test/regression/usbxtestcontrol.c +++ b/test/regression/usbxtestcontrol.c @@ -238,6 +238,7 @@ void usbx_ux_host_class_hid_descriptor_parse_test5_application_define(void *) void usbx_ux_host_class_hid_descriptor_parse_test6_application_define(void *); void usbx_ux_host_class_hid_descriptor_parse_test7_application_define(void *); void usbx_ux_host_class_hid_report_descriptor_get_test_application_define(void *); +void usbx_ux_device_class_hid_set_protocol_callback_test_application_define(void *); void usbx_ux_host_class_hid_remote_control_callback_test_application_define(void *); void usbx_ux_host_class_hid_interrupt_endpoint_search_test2_application_define(void *); void usbx_ux_host_class_hid_periodic_report_start_test2_application_define(void *); @@ -508,7 +509,7 @@ TEST_ENTRY test_control_tests[] = usbx_host_class_storage_max_lun_get_coverage_test_application_define, usbx_host_stack_new_endpoint_create_overage_test_application_define, - usbx_host_stack_class_unregister_coverage_test_application_define, + usbx_host_stack_class_unregister_coverage_test_application_define, usbx_storage_basic_memory_test_application_define, usbx_storage_multi_lun_test_application_define, usbx_ux_device_class_storage_request_sense_coverage_test_application_define, @@ -531,7 +532,7 @@ TEST_ENTRY test_control_tests[] = usbx_ux_device_class_storage_write_test_application_define, usbx_ux_device_class_storage_thread_test_application_define, - usbx_ux_host_class_storage_configure_overage_test_application_define, + usbx_ux_host_class_storage_configure_overage_test_application_define, usbx_ux_host_class_storage_request_sense_test_application_define, usbx_ux_host_class_storage_media_capacity_get_test_application_define, usbx_ux_host_class_storage_max_lun_get_test_application_define, @@ -799,6 +800,7 @@ TEST_ENTRY test_control_tests[] = usbx_ux_device_class_hid_descriptor_send_test_application_define, usbx_ux_device_class_hid_entry_test_application_define, usbx_ux_device_class_hid_event_get_AND_set_test_application_define, + usbx_ux_device_class_hid_set_protocol_callback_test_application_define, usbx_ux_device_class_hid_initialize_test_application_define, usbx_ux_device_class_hid_interrupt_thread_test_application_define, usbx_ux_device_class_hid_interrupt_thread_test2_application_define, From f5954fbef85a6112f1484f4accf4b0bfca23afb4 Mon Sep 17 00:00:00 2001 From: MAY Date: Wed, 14 Jan 2026 02:08:28 +0100 Subject: [PATCH 2/2] add host hid api to set/get protocol This pull request adds host HID API functions to get and set the HID protocol (boot vs report mode) and introduces an optional callback for the device side when the protocol changes. - Added new host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error checking wrappers. - Added device-side optional callback ux_device_class_hid_set_protocol_callback that is invoked when the protocol changes. - Added comprehensive test to verify the new protocol callback functionality. --- .../inc/ux_device_class_hid.h | 5 + .../src/ux_device_class_hid_control_request.c | 16 +- .../src/ux_device_class_hid_initialize.c | 2 + common/usbx_host_classes/CMakeLists.txt | 2 + .../usbx_host_classes/inc/ux_host_class_hid.h | 355 +++++++------- .../src/ux_host_class_hid_protocol_get.c | 146 ++++++ .../src/ux_host_class_hid_protocol_set.c | 147 ++++++ test/cmake/usbx/regression/CMakeLists.txt | 1 + ...ice_class_hid_set_protocol_callback_test.c | 463 ++++++++++++++++++ test/regression/usbxtestcontrol.c | 6 +- 10 files changed, 966 insertions(+), 177 deletions(-) create mode 100644 common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c create mode 100644 common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c create mode 100644 test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c diff --git a/common/usbx_device_classes/inc/ux_device_class_hid.h b/common/usbx_device_classes/inc/ux_device_class_hid.h index dfa588a1..73efa5a4 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -249,6 +249,7 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT UINT ux_device_class_hid_state; UINT (*ux_device_class_hid_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); UINT (*ux_device_class_hid_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); + VOID (*ux_device_class_hid_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol); VOID (*ux_slave_class_hid_instance_activate)(VOID *); VOID (*ux_slave_class_hid_instance_deactivate)(VOID *); UCHAR *ux_device_class_hid_report_address; @@ -365,6 +366,10 @@ typedef struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT ULONG ux_device_class_hid_parameter_report_length; UINT (*ux_device_class_hid_parameter_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); UINT (*ux_device_class_hid_parameter_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *); + + /* Optional callback invoked when protocol changes (boot/report). */ + VOID (*ux_device_class_hid_parameter_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol); + #if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) ULONG ux_device_class_hid_parameter_event_max_number; ULONG ux_device_class_hid_parameter_event_max_length; diff --git a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c index edecc7b0..cf3fdcd1 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c @@ -205,15 +205,28 @@ UX_SLAVE_CLASS_HID *hid; case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL: - /* Send the protocol. */ + /* Send the protocol to host. */ *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)hid -> ux_device_class_hid_protocol; _ux_device_stack_transfer_request(transfer_request, 1, request_length); break; case UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL: + /* Check protocol must be 0 (Boot) or 1 (Report). */ + if ((request_value != UX_DEVICE_CLASS_HID_PROTOCOL_BOOT) && + (request_value != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT)) + { + /* Invalid value: not handled. */ + return(UX_ERROR); + } + /* Accept the protocol. */ hid -> ux_device_class_hid_protocol = request_value; + + /* If there is a callback defined by the application, send the protocol to it. */ + if (hid -> ux_device_class_hid_set_protocol_callback != UX_NULL) + hid -> ux_device_class_hid_set_protocol_callback(hid, request_value); + break; default: @@ -225,4 +238,3 @@ UX_SLAVE_CLASS_HID *hid; /* It's handled. */ return(UX_SUCCESS); } - diff --git a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c index 2366cdee..88ca11da 100644 --- a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c @@ -8,6 +8,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ + /**************************************************************************/ /**************************************************************************/ /** */ @@ -196,6 +197,7 @@ UCHAR *buffer; /* Store the callback function. */ hid -> ux_device_class_hid_callback = hid_parameter -> ux_device_class_hid_parameter_callback; hid -> ux_device_class_hid_get_callback = hid_parameter -> ux_device_class_hid_parameter_get_callback; + hid -> ux_device_class_hid_set_protocol_callback = hid_parameter -> ux_device_class_hid_parameter_set_protocol_callback; #if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE) diff --git a/common/usbx_host_classes/CMakeLists.txt b/common/usbx_host_classes/CMakeLists.txt index 47420899..11083a22 100644 --- a/common/usbx_host_classes/CMakeLists.txt +++ b/common/usbx_host_classes/CMakeLists.txt @@ -93,6 +93,8 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set_run.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_set.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_get.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_instance_clean.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_interrupt_endpoint_search.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_item_data_get.c diff --git a/common/usbx_host_classes/inc/ux_host_class_hid.h b/common/usbx_host_classes/inc/ux_host_class_hid.h index 53a8efbe..e7ff1d50 100644 --- a/common/usbx_host_classes/inc/ux_host_class_hid.h +++ b/common/usbx_host_classes/inc/ux_host_class_hid.h @@ -1,44 +1,44 @@ /*************************************************************************** - * Copyright (c) 2024 Microsoft Corporation - * + * Copyright (c) 2024 Microsoft Corporation + * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. - * + * * SPDX-License-Identifier: MIT **************************************************************************/ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ /** */ -/** HID Class */ +/** USBX Component */ +/** */ +/** Host HID Class */ /** */ /**************************************************************************/ /**************************************************************************/ -/**************************************************************************/ -/* */ -/* COMPONENT DEFINITION RELEASE */ -/* */ -/* ux_host_class_hid.h PORTABLE C */ +/**************************************************************************/ +/* */ +/* COMPONENT DEFINITION RELEASE */ +/* */ +/* ux_host_class_hid.h PORTABLE C */ /* 6.3.0 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ +/* */ /* This file contains all the header and extern functions used by the */ -/* USBX HID class. */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* USBX HID class. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* used UX prefix to refer to */ @@ -63,15 +63,15 @@ #ifndef UX_HOST_CLASS_HID_H #define UX_HOST_CLASS_HID_H -/* Determine if a C++ compiler is being used. If so, ensure that standard - C is used to process the API information. */ +/* Determine if a C++ compiler is being used. If so, ensure that standard + C is used to process the API information. */ -#ifdef __cplusplus +#ifdef __cplusplus -/* Yes, C++ compiler is present. Use standard C. */ -extern "C" { +/* Yes, C++ compiler is present. Use standard C. */ +extern "C" { -#endif +#endif /* Internal option: enable the basic USBX error checking. This define is typically used @@ -112,7 +112,7 @@ extern "C" { #define UX_HOST_CLASS_HID_TYPE_GLOBAL 0x1 #define UX_HOST_CLASS_HID_TYPE_LOCAL 0x2 #define UX_HOST_CLASS_HID_TYPE_RESERVED 0x3 - + /* Define HID Class main tags. */ @@ -121,7 +121,7 @@ extern "C" { #define UX_HOST_CLASS_HID_MAIN_TAG_FEATURE 0xb #define UX_HOST_CLASS_HID_MAIN_TAG_COLLECTION 0xa #define UX_HOST_CLASS_HID_MAIN_TAG_END_COLLECTION 0xc - + /* Define HID Class global tags. */ @@ -181,10 +181,10 @@ extern "C" { /* Define HID Class commands. */ -#define UX_HOST_CLASS_HID_GET_REPORT 0x01 +#define UX_HOST_CLASS_HID_GET_REPORT 0x01 #define UX_HOST_CLASS_HID_GET_IDLE 0x02 #define UX_HOST_CLASS_HID_GET_PROTOCOL 0x03 -#define UX_HOST_CLASS_HID_SET_REPORT 0x09 +#define UX_HOST_CLASS_HID_SET_REPORT 0x09 #define UX_HOST_CLASS_HID_SET_IDLE 0x0A #define UX_HOST_CLASS_HID_SET_PROTOCOL 0x0B @@ -202,133 +202,133 @@ extern "C" { /* Define HID Class page constants. */ -#define UX_HOST_CLASS_HID_PAGE_GENERIC_DESKTOP_CONTROLS 0x01 -#define UX_HOST_CLASS_HID_PAGE_SIMULATION_CONTROLS 0x02 -#define UX_HOST_CLASS_HID_PAGE_VR_CONTROLS 0x03 -#define UX_HOST_CLASS_HID_PAGE_SPORT_CONTROLS 0x04 -#define UX_HOST_CLASS_HID_PAGE_GAME_CONTROLS 0x05 -#define UX_HOST_CLASS_HID_PAGE_GENERIC_DEVICE_CONTROLS 0x06 -#define UX_HOST_CLASS_HID_PAGE_KEYBOARD_KEYPAD 0x07 -#define UX_HOST_CLASS_HID_PAGE_LEDS 0x08 -#define UX_HOST_CLASS_HID_PAGE_BUTTON 0x09 -#define UX_HOST_CLASS_HID_PAGE_ORDINAL 0x0A -#define UX_HOST_CLASS_HID_PAGE_TELEPHONY 0x0B -#define UX_HOST_CLASS_HID_PAGE_CONSUMER 0x0C -#define UX_HOST_CLASS_HID_PAGE_DIGITIZER 0x0D -#define UX_HOST_CLASS_HID_PAGE_PHYSICAL_INTERFACE_DEVICE 0x0F -#define UX_HOST_CLASS_HID_PAGE_UNICODE 0x10 -#define UX_HOST_CLASS_HID_PAGE_ALPHANUMERIC_DISPLAY 0x14 -#define UX_HOST_CLASS_HID_PAGE_MEDICAL_INSTRUMENTS 0x40 -#define UX_HOST_CLASS_HID_PAGE_BAR_CODE_SCANNER 0x8C -#define UX_HOST_CLASS_HID_PAGE_SCALE_PAGE 0x8D -#define UX_HOST_CLASS_HID_PAGE_MAGNETIC_STRIPE_READING 0x8E -#define UX_HOST_CLASS_HID_PAGE_CAMERA_CONTROL_PAGE 0x90 +#define UX_HOST_CLASS_HID_PAGE_GENERIC_DESKTOP_CONTROLS 0x01 +#define UX_HOST_CLASS_HID_PAGE_SIMULATION_CONTROLS 0x02 +#define UX_HOST_CLASS_HID_PAGE_VR_CONTROLS 0x03 +#define UX_HOST_CLASS_HID_PAGE_SPORT_CONTROLS 0x04 +#define UX_HOST_CLASS_HID_PAGE_GAME_CONTROLS 0x05 +#define UX_HOST_CLASS_HID_PAGE_GENERIC_DEVICE_CONTROLS 0x06 +#define UX_HOST_CLASS_HID_PAGE_KEYBOARD_KEYPAD 0x07 +#define UX_HOST_CLASS_HID_PAGE_LEDS 0x08 +#define UX_HOST_CLASS_HID_PAGE_BUTTON 0x09 +#define UX_HOST_CLASS_HID_PAGE_ORDINAL 0x0A +#define UX_HOST_CLASS_HID_PAGE_TELEPHONY 0x0B +#define UX_HOST_CLASS_HID_PAGE_CONSUMER 0x0C +#define UX_HOST_CLASS_HID_PAGE_DIGITIZER 0x0D +#define UX_HOST_CLASS_HID_PAGE_PHYSICAL_INTERFACE_DEVICE 0x0F +#define UX_HOST_CLASS_HID_PAGE_UNICODE 0x10 +#define UX_HOST_CLASS_HID_PAGE_ALPHANUMERIC_DISPLAY 0x14 +#define UX_HOST_CLASS_HID_PAGE_MEDICAL_INSTRUMENTS 0x40 +#define UX_HOST_CLASS_HID_PAGE_BAR_CODE_SCANNER 0x8C +#define UX_HOST_CLASS_HID_PAGE_SCALE_PAGE 0x8D +#define UX_HOST_CLASS_HID_PAGE_MAGNETIC_STRIPE_READING 0x8E +#define UX_HOST_CLASS_HID_PAGE_CAMERA_CONTROL_PAGE 0x90 /* Define HID Class generic desktop page constants. */ -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_UNDEFINED 0x00 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_POINTER 0x01 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOUSE 0x02 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RESERVED 0x03 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_JOYSTICK 0x04 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_GAME PAD 0x05 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYBOARD 0x06 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYPAD 0x07 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MULTI_AXIS_CONTROLLER 0x08 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_X 0x30 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Y 0x31 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Z 0x32 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RX 0x33 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RY 0x34 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RZ 0x35 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SLIDER 0x36 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_DIAL 0x37 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_WHEEL 0x38 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_HAT_SWITCH 0x39 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_COUNTED_BUFFER 0x3A -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_BYTE_COUNT 0x3B -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOTION_WAKEUP 0x3C -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_START 0x3D -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SELECT 0x3E -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VX 0x40 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VY 0x41 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VZ 0x42 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRX 0x43 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRY 0x44 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRZ 0x45 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VNO 0x46 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_FEATURE_NOTIFICATION 0x47 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTROL 0x80 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_POWER_DOWN 0x81 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SLEEP 0x82 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WAKE_UP 0x83 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTEXT_MENU 0x84 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MAIN_MENU 0x85 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_APP_MENU 0x86 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_HELP 0x87 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_EXIT 0x88 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_SELECT 0x89 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_RIGHT 0x8A -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_LEFT 0x8B -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_UP 0x8C -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_DOWN 0x8D -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_COLD_RESTART 0x8E -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WARM_RESTART 0x8F -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_UP 0x90 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_DOWN 0x91 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_RIGHT 0x92 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_LEFT 0x93 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DOCK 0xA0 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_UNDOCK 0xA1 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SETUP 0xA2 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_BREAK 0xA3 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DEBUGGER_BREAK 0xA4 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICAION_BREAK 0xA5 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICATION_DEBUGGER_BREAK 0xA6 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SPEAKER_MUTE 0xA7 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_HIBERNATE 0xA8 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INVERT 0xB0 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INTERNAL 0xB1 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_EXTERNAL 0xB2 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_BOTH 0xB3 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_DUAL 0xB4 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_TOGGLE 0xB5 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_SWAP 0xB6 -#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE 0xB7 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_UNDEFINED 0x00 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_POINTER 0x01 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOUSE 0x02 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RESERVED 0x03 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_JOYSTICK 0x04 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_GAME PAD 0x05 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYBOARD 0x06 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_KEYPAD 0x07 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MULTI_AXIS_CONTROLLER 0x08 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_X 0x30 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Y 0x31 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_Z 0x32 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RX 0x33 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RY 0x34 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_RZ 0x35 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SLIDER 0x36 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_DIAL 0x37 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_WHEEL 0x38 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_HAT_SWITCH 0x39 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_COUNTED_BUFFER 0x3A +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_BYTE_COUNT 0x3B +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_MOTION_WAKEUP 0x3C +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_START 0x3D +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SELECT 0x3E +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VX 0x40 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VY 0x41 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VZ 0x42 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRX 0x43 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRY 0x44 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VBRZ 0x45 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_VNO 0x46 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_FEATURE_NOTIFICATION 0x47 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTROL 0x80 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_POWER_DOWN 0x81 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SLEEP 0x82 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WAKE_UP 0x83 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_CONTEXT_MENU 0x84 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MAIN_MENU 0x85 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_APP_MENU 0x86 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_HELP 0x87 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_EXIT 0x88 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_SELECT 0x89 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_RIGHT 0x8A +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_LEFT 0x8B +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_UP 0x8C +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_MENU_DOWN 0x8D +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_COLD_RESTART 0x8E +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_WARM_RESTART 0x8F +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_UP 0x90 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_DOWN 0x91 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_RIGHT 0x92 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_D_PAD_LEFT 0x93 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DOCK 0xA0 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_UNDOCK 0xA1 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SETUP 0xA2 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_BREAK 0xA3 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DEBUGGER_BREAK 0xA4 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICAION_BREAK 0xA5 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_APPLICATION_DEBUGGER_BREAK 0xA6 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_SPEAKER_MUTE 0xA7 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_HIBERNATE 0xA8 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INVERT 0xB0 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_INTERNAL 0xB1 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_EXTERNAL 0xB2 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_BOTH 0xB3 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_DUAL 0xB4 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_TOGGLE 0xB5 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_SWAP 0xB6 +#define UX_HOST_CLASS_HID_GENERIC_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE 0xB7 /* Define HID Class game control page constants. */ -#define UX_HOST_CLASS_HID_GAME_CONTROL_UNDEFINED 0x00 -#define UX_HOST_CLASS_HID_GAME_CONTROL_3D_GAME_CONTROLLER 0x01 -#define UX_HOST_CLASS_HID_GAME_CONTROL_PINBALL_DEVICE 0x02 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_DEVICE 0x03 -#define UX_HOST_CLASS_HID_GAME_CONTROL_POINT_OF_VIEW 0x20 -#define UX_HOST_CLASS_HID_GAME_CONTROL_TURN_RIGHT_LEFT 0x21 -#define UX_HOST_CLASS_HID_GAME_CONTROL_PITCH_FORWARD_BACKWARD 0x22 -#define UX_HOST_CLASS_HID_GAME_CONTROL_ROLL_RIGHT_LEFT 0x23 -#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_RIGHT_LEFT 0x24 -#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_FORWARD_BACKWARD 0x25 -#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_UP_DOWN 0x26 -#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_RIGHT_LEFT 0x27 -#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_FORWARD_BACKWARD 0x28 -#define UX_HOST_CLASS_HID_GAME_CONTROL_HEIGHT_OF_POV 0x29 -#define UX_HOST_CLASS_HID_GAME_CONTROL_FLIPPER 0x2A -#define UX_HOST_CLASS_HID_GAME_CONTROL_SECONDARY_FLIPPER 0x2B -#define UX_HOST_CLASS_HID_GAME_CONTROL_BUMP 0x2C -#define UX_HOST_CLASS_HID_GAME_CONTROL_NEW_GAME 0x2D -#define UX_HOST_CLASS_HID_GAME_CONTROL_SHOOT_BALL 0x2E -#define UX_HOST_CLASS_HID_GAME_CONTROL_PLAYER 0x2F -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BOLT 0x30 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_CLIP 0x31 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SELECTOR 0x32 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SINGLE_SHOT 0x33 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BURST 0x34 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_AUTOMATIC 0x35 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SAFETY 0x36 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEAD_FIRE_JUMP 0x37 -#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEPAD_TRIGGER 0x39 +#define UX_HOST_CLASS_HID_GAME_CONTROL_UNDEFINED 0x00 +#define UX_HOST_CLASS_HID_GAME_CONTROL_3D_GAME_CONTROLLER 0x01 +#define UX_HOST_CLASS_HID_GAME_CONTROL_PINBALL_DEVICE 0x02 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_DEVICE 0x03 +#define UX_HOST_CLASS_HID_GAME_CONTROL_POINT_OF_VIEW 0x20 +#define UX_HOST_CLASS_HID_GAME_CONTROL_TURN_RIGHT_LEFT 0x21 +#define UX_HOST_CLASS_HID_GAME_CONTROL_PITCH_FORWARD_BACKWARD 0x22 +#define UX_HOST_CLASS_HID_GAME_CONTROL_ROLL_RIGHT_LEFT 0x23 +#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_RIGHT_LEFT 0x24 +#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_FORWARD_BACKWARD 0x25 +#define UX_HOST_CLASS_HID_GAME_CONTROL_MOVE_UP_DOWN 0x26 +#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_RIGHT_LEFT 0x27 +#define UX_HOST_CLASS_HID_GAME_CONTROL_LEAN_FORWARD_BACKWARD 0x28 +#define UX_HOST_CLASS_HID_GAME_CONTROL_HEIGHT_OF_POV 0x29 +#define UX_HOST_CLASS_HID_GAME_CONTROL_FLIPPER 0x2A +#define UX_HOST_CLASS_HID_GAME_CONTROL_SECONDARY_FLIPPER 0x2B +#define UX_HOST_CLASS_HID_GAME_CONTROL_BUMP 0x2C +#define UX_HOST_CLASS_HID_GAME_CONTROL_NEW_GAME 0x2D +#define UX_HOST_CLASS_HID_GAME_CONTROL_SHOOT_BALL 0x2E +#define UX_HOST_CLASS_HID_GAME_CONTROL_PLAYER 0x2F +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BOLT 0x30 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_CLIP 0x31 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SELECTOR 0x32 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SINGLE_SHOT 0x33 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_BURST 0x34 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_AUTOMATIC 0x35 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GUN_SAFETY 0x36 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEAD_FIRE_JUMP 0x37 +#define UX_HOST_CLASS_HID_GAME_CONTROL_GAMEPAD_TRIGGER 0x39 /* Define HID Class LED page constants. */ @@ -570,7 +570,7 @@ extern "C" { #define UX_HOST_CLASS_HID_CONSUMER_ALTERNATE_AUDIO_DECREMENT 0x173 #define UX_HOST_CLASS_HID_CONSUMER_APPLICATION_LAUNCH_BUTTONS 0x174 #define UX_HOST_CLASS_HID_CONSUMER_AL_LAUNCH_BUTTON_CONFIGURATION 0x180 -#define UX_HOST_CLASS_HID_CONSUMER_AL_PROGRAMMABLE_BUTTON 0x181 +#define UX_HOST_CLASS_HID_CONSUMER_AL_PROGRAMMABLE_BUTTON 0x181 #define UX_HOST_CLASS_HID_CONSUMER_AL_CONSUMER_CONTROL_CONFIGURATION 0x182 #define UX_HOST_CLASS_HID_CONSUMER_AL_WORD_PROCESSOR 0x183 #define UX_HOST_CLASS_HID_CONSUMER_AL_TEXT_EDITOR 0x184 @@ -786,6 +786,10 @@ extern "C" { #define UX_HOST_CLASS_HID_REPORT_TRANSFER_TIMEOUT 10000 #endif +/* HID protocol values. */ +#define UX_HOST_CLASS_HID_PROTOCOL_BOOT 0x00 +#define UX_HOST_CLASS_HID_PROTOCOL_REPORT 0x01 + /* Define HID Class descriptor. */ typedef struct UX_HID_DESCRIPTOR_STRUCT @@ -806,7 +810,7 @@ typedef struct UX_HID_DESCRIPTOR_STRUCT typedef struct UX_HOST_CLASS_HID_REPORT_CALLBACK_STRUCT { - struct UX_HOST_CLASS_HID_CLIENT_STRUCT + struct UX_HOST_CLASS_HID_CLIENT_STRUCT *ux_host_class_hid_report_callback_client; ULONG ux_host_class_hid_report_callback_id; ULONG ux_host_class_hid_report_callback_status; @@ -826,7 +830,7 @@ typedef struct UX_HOST_CLASS_HID_REPORT_GET_ID_STRUCT ULONG ux_host_class_hid_report_get_id; ULONG ux_host_class_hid_report_get_type; - struct UX_HOST_CLASS_HID_REPORT_STRUCT + struct UX_HOST_CLASS_HID_REPORT_STRUCT *ux_host_class_hid_report_get_report; } UX_HOST_CLASS_HID_REPORT_GET_ID; @@ -890,9 +894,9 @@ typedef struct UX_HOST_CLASS_HID_FIELD_STRUCT ULONG ux_host_class_hid_field_number_usage; ULONG *ux_host_class_hid_field_values; ULONG ux_host_class_hid_field_number_values; - struct UX_HOST_CLASS_HID_REPORT_STRUCT + struct UX_HOST_CLASS_HID_REPORT_STRUCT *ux_host_class_hid_field_report; - struct UX_HOST_CLASS_HID_FIELD_STRUCT + struct UX_HOST_CLASS_HID_FIELD_STRUCT *ux_host_class_hid_field_next_field; } UX_HOST_CLASS_HID_FIELD; @@ -904,7 +908,7 @@ typedef struct UX_HOST_CLASS_HID_REPORT_STRUCT ULONG ux_host_class_hid_report_id; ULONG ux_host_class_hid_report_type; - struct UX_HOST_CLASS_HID_FIELD_STRUCT + struct UX_HOST_CLASS_HID_FIELD_STRUCT *ux_host_class_hid_report_field; ULONG ux_host_class_hid_report_number_item; ULONG ux_host_class_hid_report_byte_length; @@ -913,7 +917,7 @@ typedef struct UX_HOST_CLASS_HID_REPORT_STRUCT VOID *ux_host_class_hid_report_callback_buffer; ULONG ux_host_class_hid_report_callback_length; VOID (*ux_host_class_hid_report_callback_function) (struct UX_HOST_CLASS_HID_REPORT_CALLBACK_STRUCT *); - struct UX_HOST_CLASS_HID_REPORT_STRUCT + struct UX_HOST_CLASS_HID_REPORT_STRUCT *ux_host_class_hid_report_next_report; } UX_HOST_CLASS_HID_REPORT; @@ -925,21 +929,21 @@ typedef struct UX_HOST_CLASS_HID_PARSER_STRUCT UX_HOST_CLASS_HID_GLOBAL_ITEM ux_host_class_hid_parser_global; - UX_HOST_CLASS_HID_GLOBAL_ITEM + UX_HOST_CLASS_HID_GLOBAL_ITEM ux_host_class_hid_parser_global_pool[UX_HOST_CLASS_HID_MAX_GLOBAL]; ULONG ux_host_class_hid_parser_number_global; - UX_HOST_CLASS_HID_LOCAL_ITEM + UX_HOST_CLASS_HID_LOCAL_ITEM ux_host_class_hid_parser_local; ULONG ux_host_class_hid_parser_application; ULONG ux_host_class_hid_parser_collection[UX_HOST_CLASS_HID_MAX_COLLECTION]; ULONG ux_host_class_hid_parser_number_collection; ULONG ux_host_class_hid_parser_main_page; ULONG ux_host_class_hid_parser_main_usage; - UX_HOST_CLASS_HID_REPORT + UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_parser_input_report; - UX_HOST_CLASS_HID_REPORT + UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_parser_output_report; - UX_HOST_CLASS_HID_REPORT + UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_parser_feature_report; } UX_HOST_CLASS_HID_PARSER; @@ -961,7 +965,7 @@ typedef struct UX_HOST_CLASS_HID_ITEM_STRUCT typedef struct UX_HOST_CLASS_HID_STRUCT { - struct UX_HOST_CLASS_HID_STRUCT + struct UX_HOST_CLASS_HID_STRUCT *ux_host_class_hid_next_instance; UX_HOST_CLASS *ux_host_class_hid_class; UX_DEVICE *ux_host_class_hid_device; @@ -972,11 +976,11 @@ typedef struct UX_HOST_CLASS_HID_STRUCT UINT ux_host_class_hid_interrupt_endpoint_status; UX_INTERFACE *ux_host_class_hid_interface; ULONG ux_host_class_hid_state; - struct UX_HID_DESCRIPTOR_STRUCT + struct UX_HID_DESCRIPTOR_STRUCT ux_host_class_hid_descriptor; - UX_HOST_CLASS_HID_PARSER + UX_HOST_CLASS_HID_PARSER ux_host_class_hid_parser; - struct UX_HOST_CLASS_HID_CLIENT_STRUCT + struct UX_HOST_CLASS_HID_CLIENT_STRUCT *ux_host_class_hid_client; #if !defined(UX_HOST_STANDALONE) UX_SEMAPHORE ux_host_class_hid_semaphore; @@ -1037,8 +1041,8 @@ typedef struct UX_HOST_CLASS_HID_CLIENT_REPORT_STRUCT UX_HOST_CLASS_HID_REPORT *ux_host_class_hid_client_report; ULONG *ux_host_class_hid_client_report_buffer; - ULONG ux_host_class_hid_client_report_length; - ULONG ux_host_class_hid_client_report_actual_length; + ULONG ux_host_class_hid_client_report_length; + ULONG ux_host_class_hid_client_report_actual_length; UINT ux_host_class_hid_client_report_flags; } UX_HOST_CLASS_HID_CLIENT_REPORT; @@ -1055,7 +1059,7 @@ typedef struct UX_HOST_CLASS_HID_CLIENT_STRUCT UCHAR ux_host_class_hid_client_name[UX_HOST_CLASS_HID_MAX_CLIENT_NAME_LENGTH + 1]; /* "+1" for string null-terminator */ #endif UINT (*ux_host_class_hid_client_handler) (struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *); - VOID *ux_host_class_hid_client_local_instance; + VOID *ux_host_class_hid_client_local_instance; #if defined(UX_HOST_STANDALONE) VOID (*ux_host_class_hid_client_function)(struct UX_HOST_CLASS_HID_CLIENT_STRUCT *); #endif @@ -1099,7 +1103,8 @@ VOID _ux_host_class_hid_transfer_request_completed(UX_TRANSFER *transfer_requ UINT _ux_host_class_hid_tasks_run(UX_HOST_CLASS *hid_class); UINT _ux_host_class_hid_idle_set_run(UX_HOST_CLASS_HID *hid, USHORT idle_time, USHORT report_id); UINT _ux_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID_CLIENT_REPORT *client_report); - +UINT _ux_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol); +UINT _ux_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol); UINT _uxe_host_class_hid_client_register(UCHAR *hid_client_name, UINT (*hid_client_handler)(struct UX_HOST_CLASS_HID_CLIENT_COMMAND_STRUCT *)); @@ -1117,7 +1122,8 @@ UINT _uxe_host_class_hid_report_set(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID UINT _uxe_host_class_hid_idle_set_run(UX_HOST_CLASS_HID *hid, USHORT idle_time, USHORT report_id); UINT _uxe_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS_HID_CLIENT_REPORT *client_report); - +UINT _uxe_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol); +UINT _uxe_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol); /* Define HID Class API prototypes. */ @@ -1144,6 +1150,8 @@ UINT _uxe_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS #define ux_host_class_hid_report_id_get _uxe_host_class_hid_report_id_get #define ux_host_class_hid_report_get _uxe_host_class_hid_report_get #define ux_host_class_hid_report_set _uxe_host_class_hid_report_set +#define ux_host_class_hid_protocol_set _uxe_host_class_hid_protocol_set +#define ux_host_class_hid_protocol_get _uxe_host_class_hid_protocol_get #else @@ -1159,15 +1167,16 @@ UINT _uxe_host_class_hid_report_set_run(UX_HOST_CLASS_HID *hid, UX_HOST_CLASS #define ux_host_class_hid_report_id_get _ux_host_class_hid_report_id_get #define ux_host_class_hid_report_get _ux_host_class_hid_report_get #define ux_host_class_hid_report_set _ux_host_class_hid_report_set +#define ux_host_class_hid_protocol_set _ux_host_class_hid_protocol_set +#define ux_host_class_hid_protocol_get _ux_host_class_hid_protocol_get #endif -/* Determine if a C++ compiler is being used. If so, complete the standard - C conditional started above. */ +/* Determine if a C++ compiler is being used. If so, complete the standard + C conditional started above. */ #ifdef __cplusplus -} -#endif - +} #endif +#endif diff --git a/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c b/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c new file mode 100644 index 00000000..7a8f2644 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c @@ -0,0 +1,146 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Host HID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_hid.h" +#include "ux_host_stack.h" + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_hid_protocol_get PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs a GET_PROTOCOL to the HID device to read */ +/* current protocol (BOOT=0 or REPORT=1). */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Destination for protocol */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol) +{ + +UX_ENDPOINT *control_endpoint; +UX_TRANSFER *transfer_request; +UINT status; +UCHAR proto_byte = 0xFFu; + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0) + +#if defined(UX_HOST_STANDALONE) + hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN; +#endif + + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Get the default control endpoint transfer request pointer. */ + control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + +#if !defined(UX_HOST_STANDALONE) + + /* Protect thread reentry to this instance. */ + status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + return(status); + +#endif + + /* Create a transfer request for the GET_PROTOCOL request. */ + transfer_request -> ux_transfer_request_data_pointer = &proto_byte; + transfer_request -> ux_transfer_request_requested_length = 1; + transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_PROTOCOL; + transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = 0; + transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber; + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + +#if !defined(UX_HOST_STANDALONE) + /* Unprotect thread reentry to this instance. */ + _ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore); +#endif + + if (status == UX_SUCCESS && protocol) + *protocol = (USHORT)proto_byte; + + return(status); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _uxe_host_class_hid_protocol_get PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks errors in HID protocol get function call. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Destination for protocol */ +/* */ +/* OUTPUT */ +/* */ +/* Status */ +/* */ +/**************************************************************************/ +UINT _uxe_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol) +{ + /* Sanity check. */ + if (hid == UX_NULL || protocol == UX_NULL) + return(UX_INVALID_PARAMETER); + + /* Invoke protocol get function. */ + return(_ux_host_class_hid_protocol_get(hid, protocol)); +} diff --git a/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c b/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c new file mode 100644 index 00000000..b757cb71 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (c) 2024 Microsoft Corporation + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * SPDX-License-Identifier: MIT + **************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Host HID Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/* Include necessary system files. */ + +#define UX_SOURCE_CODE + +#include "ux_api.h" +#include "ux_host_class_hid.h" +#include "ux_host_stack.h" + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_host_class_hid_protocol_set PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs a SET_PROTOCOL to the HID device to switch */ +/* between BOOT (0) and REPORT (1) protocols. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Protocol (BOOT/REPORT) */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLED BY */ +/* */ +/* Application */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */ +/* */ +/**************************************************************************/ +UINT _ux_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol) +{ + +UX_ENDPOINT *control_endpoint; +UX_TRANSFER *transfer_request; +UINT status; + + /* Ensure the instance is valid. */ + if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS) + { + + /* If trace is enabled, insert this event into the trace buffer. */ + UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0) + +#if defined(UX_HOST_STANDALONE) + hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN; +#endif + return(UX_HOST_CLASS_INSTANCE_UNKNOWN); + } + + /* Get the default control endpoint transfer request pointer. */ + control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint; + transfer_request = &control_endpoint -> ux_endpoint_transfer_request; + +#if !defined(UX_HOST_STANDALONE) + + /* Protect thread reentry to this instance. */ + status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + return(status); + +#endif + + /* Create a transfer request for the SET_PROTOCOL request. */ + transfer_request -> ux_transfer_request_data_pointer = UX_NULL; + transfer_request -> ux_transfer_request_requested_length = 0; + transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_PROTOCOL; + transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE; + transfer_request -> ux_transfer_request_value = (UINT)protocol; + transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber; + + /* Send request to HCD layer. */ + status = _ux_host_stack_transfer_request(transfer_request); + +#if !defined(UX_HOST_STANDALONE) + /* Unprotect thread reentry to this instance. */ + _ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore); +#endif + + /* Return the function status. */ + return(status); +} + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _uxe_host_class_hid_protocol_set PORTABLE C */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function checks errors in HID protocol set function call. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to HID class */ +/* protocol Protocol (BOOT/REPORT) */ +/* */ +/* OUTPUT */ +/* */ +/* Status */ +/* */ +/**************************************************************************/ +UINT _uxe_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol) +{ + /* Sanity check. */ + if (hid == UX_NULL) + return(UX_INVALID_PARAMETER); + + /* Validate protocol value: must be BOOT(0) or REPORT(1). */ + if (protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT && + protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT) + return(UX_INVALID_PARAMETER); + + /* Invoke protocol set function. */ + return(_ux_host_class_hid_protocol_set(hid, protocol)); +} diff --git a/test/cmake/usbx/regression/CMakeLists.txt b/test/cmake/usbx/regression/CMakeLists.txt index 8d29d436..68e2d775 100644 --- a/test/cmake/usbx/regression/CMakeLists.txt +++ b/test/cmake/usbx/regression/CMakeLists.txt @@ -139,6 +139,7 @@ set(ux_class_hid_test_cases ${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test2.c ${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test3.c ${SOURCE_DIR}/usbx_ux_device_class_hid_control_request_test.c + ${SOURCE_DIR}/usbx_ux_device_class_hid_set_protocol_callback_test.c ${SOURCE_DIR}/usbx_ux_device_class_hid_initialize_test.c ${SOURCE_DIR}/usbx_ux_device_class_hid_interrupt_thread_test2.c ${SOURCE_DIR}/usbx_ux_device_class_hid_read_test.c diff --git a/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c b/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c new file mode 100644 index 00000000..0167a544 --- /dev/null +++ b/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c @@ -0,0 +1,463 @@ +/* This test focuses on HID device class protocol set/get functionality and related callbacks. */ + +#include +#include "tx_api.h" +#include "ux_api.h" +#include "ux_system.h" +#include "ux_utility.h" +#include "ux_host_class_hid.h" +#include "ux_host_class_hid_keyboard.h" +#include "ux_device_class_hid.h" +#include "ux_device_stack.h" +#include "usbx_test_common_hid.h" + +/* Define constants. */ +#define UX_DEMO_DEBUG_SIZE (4096*8) +#define UX_DEMO_STACK_SIZE 1024 + +/* Define local/extern function prototypes. */ +static void demo_thread_entry(ULONG); +static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *, UX_SLAVE_CLASS_HID_EVENT *); +static VOID demo_set_protocol_callback(UX_SLAVE_CLASS_HID *hid, ULONG protocol); +static TX_THREAD tx_demo_thread_host_simulation; +static void tx_demo_thread_host_simulation_entry(ULONG); + +/* Define global data structures. */ +static UX_HOST_CLASS_HID *hid; +static UINT status; + +static UX_SLAVE_CLASS_HID_PARAMETER hid_parameter; + +static volatile UINT g_set_protocol_callback_calls = 0; +static volatile ULONG g_set_protocol_last_value = 0xFFFFFFFFu; + +static UCHAR hid_keyboard_report[] = { + + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x06, // USAGE (Keyboard) + 0xa1, 0x01, // COLLECTION (Application) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x08, // REPORT_COUNT (8) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x09, 0x39, // USAGE (Caps Lock) + 0x09, 0x53, // USAGE (Num Lock) + 0x09, 0x47, // USAGE (Scroll Lock) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x95, 0x05, // REPORT_COUNT (5) + 0x75, 0x01, // REPORT_SIZE (1) + 0x05, 0x08, // USAGE_PAGE (LEDs) + 0x19, 0x01, // USAGE_MINIMUM (Num Lock) + 0x29, 0x05, // USAGE_MAXIMUM (Kana) + 0x91, 0x02, // OUTPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x03, // REPORT_SIZE (3) + 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) + 0x95, 0x06, // REPORT_COUNT (6) + 0x75, 0x08, // REPORT_SIZE (8) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x65, // LOGICAL_MAXIMUM (101) + 0x05, 0x07, // USAGE_PAGE (Keyboard) + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) + 0x81, 0x00, // INPUT (Data,Ary,Abs) + 0xc0 // END_COLLECTION +}; +#define HID_KEYBOARD_REPORT_LENGTH (sizeof(hid_keyboard_report) / sizeof(hid_keyboard_report[0])) + + +#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52 +static UCHAR device_framework_full_speed[] = { + + /* Device descriptor */ + 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, + 0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, + + /* Configuration descriptor */ + 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0, + 0x32, + + /* Interface descriptor */ + 0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, + 0x00, + + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_KEYBOARD_REPORT_LENGTH), + MSB(HID_KEYBOARD_REPORT_LENGTH), + + /* Endpoint descriptor (Interrupt) */ + 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08 + + }; + + +#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62 +static UCHAR device_framework_high_speed[] = { + + /* Device descriptor */ + 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02, + 0x03, 0x01, + + /* Device qualifier descriptor */ + 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, + 0x01, 0x00, + + /* Configuration descriptor */ + 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0, + 0x32, + + /* Interface descriptor */ + 0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x01, 0x00, + 0x00, + + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_KEYBOARD_REPORT_LENGTH), + MSB(HID_KEYBOARD_REPORT_LENGTH), + + /* Endpoint descriptor (Interrupt) */ + 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08 + + }; + + + /* String Device Framework : + Byte 0 and 1 : Word containing the language ID : 0x0904 for US + Byte 2 : Byte containing the index of the descriptor + Byte 3 : Byte containing the length of the descriptor string + */ + +#define STRING_FRAMEWORK_LENGTH 40 +static UCHAR string_framework[] = { + + /* Manufacturer string descriptor : Index 1 */ + 0x09, 0x04, 0x01, 0x0c, + 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c, + 0x6f, 0x67, 0x69, 0x63, + + /* Product string descriptor : Index 2 */ + 0x09, 0x04, 0x02, 0x0c, + 0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62, + 0x6f, 0x61, 0x72, 0x64, + + /* Serial Number string descriptor : Index 3 */ + 0x09, 0x04, 0x03, 0x04, + 0x30, 0x30, 0x30, 0x31 + }; + + + /* Multiple languages are supported on the device, to add + a language besides english, the unicode language code must + be appended to the language_id_framework array and the length + adjusted accordingly. */ +#define LANGUAGE_ID_FRAMEWORK_LENGTH 2 +static UCHAR language_id_framework[] = { + + /* English. */ + 0x09, 0x04 + }; + + + +/* Define the ISR dispatch. */ + +extern VOID (*test_isr_dispatch)(void); + + +/* Prototype for test control return. */ + +void test_control_return(UINT status); + + +/* Define the ISR dispatch routine. */ + +static void test_isr(void) +{ + + /* For further expansion of interrupt-level testing. */ +} + + + +static VOID error_callback(UINT system_level, UINT system_context, UINT error_code) +{ + + /* @BUG_FIX_PENDING: ux_dcd_sim_slave_function.c doesn't support transfer aborts, which happen during device unregistration of a class. */ + if (error_code != UX_FUNCTION_NOT_SUPPORTED) + { + + /* Failed test. */ + printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code); + test_control_return(1); + } +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +void test_application_define(void *first_unused_memory) +#else +void usbx_ux_device_class_hid_set_protocol_callback_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR * stack_pointer; +CHAR * memory_pointer; +UINT descriptor_size = HID_KEYBOARD_REPORT_LENGTH; + + /* Inform user. */ + printf("Running HID Set/Get Protocol Callback Test......................... "); + + /* Initialize the free memory pointer */ + stack_pointer = (CHAR *) usbx_memory; + memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2); + + /* Initialize USBX. Memory */ + status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0); + + /* Check for error. */ + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Register the error callback. */ + _ux_utility_error_callback_register(error_callback); + + /* The code below is required for installing the host portion of USBX */ + status = ux_host_stack_initialize(UX_NULL); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Register the HID client(s). */ + status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* The code below is required for installing the device portion of USBX. No call back for + device status change in this example. */ + status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED, + device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED, + string_framework, STRING_FRAMEWORK_LENGTH, + language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL); + if(status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Initialize the hid class parameters for a keyboard. */ + hid_parameter.ux_device_class_hid_parameter_report_address = hid_keyboard_report; + hid_parameter.ux_device_class_hid_parameter_report_length = HID_KEYBOARD_REPORT_LENGTH; + hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback; + hid_parameter.ux_device_class_hid_parameter_set_protocol_callback = demo_set_protocol_callback; + + /* Initialize the device hid class. The class is connected with interface 2 */ + status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry, + 1, 0, (VOID *)&hid_parameter); + if(status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + + /* Initialize the simulated device controller. */ + status = _ux_dcd_sim_slave_initialize(); + + /* Check for error. */ + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Register all the USB host controllers available in this system */ + status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0); + + /* Check for error. */ + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Create the main host simulation thread. */ + status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0, + stack_pointer, UX_DEMO_STACK_SIZE, + 20, 20, 1, TX_AUTO_START); + + /* Check for error. */ + if (status != TX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } +} + + +static void tx_demo_thread_host_simulation_entry(ULONG arg) +{ +UX_SLAVE_DEVICE *device; +UX_SLAVE_INTERFACE *interface; +UX_SLAVE_CLASS_HID *slave_hid; +UINT status; + + device = &_ux_system_slave -> ux_system_slave_device; + + /* Ensure device is configured before accessing interfaces. */ + while (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED) + tx_thread_sleep(10); + + /* Retrieve the HID class instance from the configured interface. */ + interface = device -> ux_slave_device_first_interface; + if (interface == UX_NULL || interface -> ux_slave_interface_class_instance == UX_NULL) + { + printf("Error on line %d, device interface/class not ready\n", __LINE__); + test_control_return(1); + } + slave_hid = interface -> ux_slave_interface_class_instance; + + /* Find the HID class */ + status = demo_class_hid_get(); + if (status != UX_SUCCESS) + { + + printf("Error on line %d, error code: %d\n", __LINE__, status); + test_control_return(1); + } + + /* Sanity: default protocol is report (1). */ + if (ux_device_class_hid_protocol_get(slave_hid) != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, protocol not default report\n", __LINE__); + test_control_return(1); + } + + USHORT host_protocol = 0xFFFF; + status = ux_host_class_hid_protocol_get(hid, &host_protocol); + if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Default protocol is report 1. */ + if (status == UX_SUCCESS && host_protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, host get protocol not report\n", __LINE__); + test_control_return(1); + } + + /* Issue SET_PROTOCOL to BOOT (0). */ + status = ux_host_class_hid_protocol_set(hid, UX_HOST_CLASS_HID_PROTOCOL_BOOT); + if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_class_hid_protocol_get(hid, &host_protocol); + + if (g_set_protocol_callback_calls < 1 || + g_set_protocol_last_value != 0 || + host_protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value); + test_control_return(1); + } + + if (ux_device_class_hid_protocol_get(slave_hid) != UX_DEVICE_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, protocol not set to boot\n", __LINE__); + test_control_return(1); + } + + /* Issue SET_PROTOCOL to REPORT (1). */ + status = ux_host_class_hid_protocol_set(hid, UX_HOST_CLASS_HID_PROTOCOL_REPORT); + if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_class_hid_protocol_get(hid, &host_protocol); + + if (g_set_protocol_callback_calls < 2 || + g_set_protocol_last_value != 1 || + host_protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value); + test_control_return(1); + } + + if (ux_device_class_hid_protocol_get(slave_hid) != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT) + { + printf("Error on line %d, protocol not set to report\n", __LINE__); + test_control_return(1); + } + + + /* Now disconnect the device. */ + _ux_device_stack_disconnect(); + + /* And deinitialize the class. */ + status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry); + + /* Deinitialize the device side of usbx. */ + _ux_device_stack_uninitialize(); + + /* And finally the usbx system resources. */ + _ux_system_uninitialize(); + + /* Successful test. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event) +{ + return(UX_SUCCESS); +} + +static VOID demo_set_protocol_callback(UX_SLAVE_CLASS_HID *hid, ULONG protocol) +{ + g_set_protocol_callback_calls++; + g_set_protocol_last_value = protocol; +} diff --git a/test/regression/usbxtestcontrol.c b/test/regression/usbxtestcontrol.c index 5ffc6871..ea43612d 100644 --- a/test/regression/usbxtestcontrol.c +++ b/test/regression/usbxtestcontrol.c @@ -238,6 +238,7 @@ void usbx_ux_host_class_hid_descriptor_parse_test5_application_define(void *) void usbx_ux_host_class_hid_descriptor_parse_test6_application_define(void *); void usbx_ux_host_class_hid_descriptor_parse_test7_application_define(void *); void usbx_ux_host_class_hid_report_descriptor_get_test_application_define(void *); +void usbx_ux_device_class_hid_set_protocol_callback_test_application_define(void *); void usbx_ux_host_class_hid_remote_control_callback_test_application_define(void *); void usbx_ux_host_class_hid_interrupt_endpoint_search_test2_application_define(void *); void usbx_ux_host_class_hid_periodic_report_start_test2_application_define(void *); @@ -508,7 +509,7 @@ TEST_ENTRY test_control_tests[] = usbx_host_class_storage_max_lun_get_coverage_test_application_define, usbx_host_stack_new_endpoint_create_overage_test_application_define, - usbx_host_stack_class_unregister_coverage_test_application_define, + usbx_host_stack_class_unregister_coverage_test_application_define, usbx_storage_basic_memory_test_application_define, usbx_storage_multi_lun_test_application_define, usbx_ux_device_class_storage_request_sense_coverage_test_application_define, @@ -531,7 +532,7 @@ TEST_ENTRY test_control_tests[] = usbx_ux_device_class_storage_write_test_application_define, usbx_ux_device_class_storage_thread_test_application_define, - usbx_ux_host_class_storage_configure_overage_test_application_define, + usbx_ux_host_class_storage_configure_overage_test_application_define, usbx_ux_host_class_storage_request_sense_test_application_define, usbx_ux_host_class_storage_media_capacity_get_test_application_define, usbx_ux_host_class_storage_max_lun_get_test_application_define, @@ -799,6 +800,7 @@ TEST_ENTRY test_control_tests[] = usbx_ux_device_class_hid_descriptor_send_test_application_define, usbx_ux_device_class_hid_entry_test_application_define, usbx_ux_device_class_hid_event_get_AND_set_test_application_define, + usbx_ux_device_class_hid_set_protocol_callback_test_application_define, usbx_ux_device_class_hid_initialize_test_application_define, usbx_ux_device_class_hid_interrupt_thread_test_application_define, usbx_ux_device_class_hid_interrupt_thread_test2_application_define,