From cd5f68201d0aaa6afe71d00962a6cc32be4dd12e Mon Sep 17 00:00:00 2001 From: MAY Date: Sun, 30 Nov 2025 01:05:56 +0100 Subject: [PATCH 1/3] add optional hid set protocol callback --- .../inc/ux_device_class_hid.h | 11 ++- .../src/ux_device_class_hid_control_request.c | 90 +++++++++++-------- .../src/ux_device_class_hid_initialize.c | 81 ++++++++--------- 3 files changed, 100 insertions(+), 82 deletions(-) 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 5dead7db..781f4607 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -1,10 +1,10 @@ /*************************************************************************** - * 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 **************************************************************************/ @@ -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 83305021..27e38d17 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 @@ -1,17 +1,17 @@ /*************************************************************************** - * 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 */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -28,44 +28,44 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_control_request PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_control_request PORTABLE C */ /* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function manages the based sent by the host on the control */ -/* endpoints with a CLASS or VENDOR SPECIFIC type. */ -/* */ -/* INPUT */ -/* */ -/* hid Pointer to hid class */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _ux_device_stack_transfer_request Transfer request */ +/* */ +/* This function manages the based sent by the host on the control */ +/* endpoints with a CLASS or VENDOR SPECIFIC type. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to hid class */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_device_stack_transfer_request Transfer request */ /* _ux_device_class_hid_report_get Process Get_Report request */ /* _ux_device_class_hid_report_set Process Set_Report request */ /* _ux_device_class_hid_descriptor_send Send requested descriptor */ -/* */ -/* CALLED BY */ -/* */ +/* */ +/* CALLED BY */ +/* */ /* HID Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* prefixed UX to MS_TO_TICK, */ @@ -119,10 +119,10 @@ UX_SLAVE_CLASS_HID *hid; /* Duration - upper byte of wValue. */ duration = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE + 1); - + /* Get the class container. */ class_ptr = command -> ux_slave_class_command_class_ptr; - + /* Get the storage instance from this class container. */ hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; @@ -149,8 +149,8 @@ UX_SLAVE_CLASS_HID *hid; /* Send the requested descriptor to the host. */ _ux_device_class_hid_descriptor_send(hid, request_value, request_index, request_length); - break; - + break; + case UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE: case UX_DEVICE_CLASS_HID_COMMAND_SET_IDLE: @@ -204,15 +204,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: @@ -224,4 +237,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 a23aca30..afad6a50 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 @@ -1,16 +1,16 @@ /*************************************************************************** - * 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 */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -27,46 +27,46 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_initialize PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_initialize PORTABLE C */ /* 6.3.0 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function initializes the USB HID device. */ -/* This function is called by the class register function. It is only */ -/* done once. */ -/* */ -/* INPUT */ -/* */ -/* command Pointer to hid command */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* */ +/* This function initializes the USB HID device. */ +/* This function is called by the class register function. It is only */ +/* done once. */ +/* */ +/* INPUT */ +/* */ +/* command Pointer to hid command */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_utility_memory_allocate Allocate memory */ /* _ux_utility_memory_free Free memory */ /* _ux_device_thread_create Create thread */ /* _ux_device_thread_delete Delete thread */ /* _ux_utility_event_flags_create Create event flags group */ -/* */ -/* CALLED BY */ -/* */ -/* USBX Source Code */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Source Code */ +/* */ +/* 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 */ @@ -97,7 +97,7 @@ /**************************************************************************/ UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command) { - + UX_SLAVE_CLASS_HID *hid; UX_SLAVE_CLASS_HID_PARAMETER *hid_parameter; UX_SLAVE_CLASS *class_ptr; @@ -149,9 +149,9 @@ UCHAR *buffer; #if !defined(UX_DEVICE_STANDALONE) /* Allocate some memory for the thread stack. */ - class_ptr -> ux_slave_class_thread_stack = + class_ptr -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE); - + /* Check for successful allocation. */ if (class_ptr -> ux_slave_class_thread_stack == UX_NULL) status = UX_MEMORY_INSUFFICIENT; @@ -160,7 +160,7 @@ UCHAR *buffer; a new thread. We pass a pointer to the class to the new thread. This thread does not start until we have a instance of the class. */ if (status == UX_SUCCESS) - status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", + status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", _ux_device_class_hid_interrupt_thread, (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) class_ptr -> ux_slave_class_thread_stack, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, @@ -195,6 +195,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) @@ -263,7 +264,7 @@ UCHAR *buffer; if (hid -> ux_device_class_hid_event_array != UX_NULL) { - /* Initialize the head and tail of the notification round robin buffers. + /* Initialize the head and tail of the notification round robin buffers. At first, the head and tail are pointing to the beginning of the array. */ hid -> ux_device_class_hid_event_array_head = hid -> ux_device_class_hid_event_array; hid -> ux_device_class_hid_event_array_tail = hid -> ux_device_class_hid_event_array; @@ -392,7 +393,7 @@ UCHAR *buffer; /* */ /* INPUT */ /* */ -/* command Pointer to hid command */ +/* command Pointer to hid command */ /* */ /* OUTPUT */ /* */ From 828a0fb9bd4a1cb4d43a93d0bfc1b8464c3f3cb7 Mon Sep 17 00:00:00 2001 From: MAY Date: Sat, 10 Jan 2026 15:26:53 +0100 Subject: [PATCH 2/3] add host hid api to set/get protocol update regression test to test host set/get api and device set protocol callback --- 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 | 155 +++++++ .../src/ux_host_class_hid_protocol_set.c | 157 +++++++ test/cmake/usbx/regression/CMakeLists.txt | 1 + ...ice_class_hid_set_protocol_callback_test.c | 404 ++++++++++++++++++ test/regression/usbxtestcontrol.c | 6 +- 7 files changed, 905 insertions(+), 175 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_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..46fe908a 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 for SET_PROTOCOL. */ +#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..e32021a8 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c @@ -0,0 +1,155 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * 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-10-2026 Mohamed AYED Initial Version 6.x */ +/**************************************************************************/ +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); + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + _ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore); + 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..f8ada237 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c @@ -0,0 +1,157 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * 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-10-2026 Mohamed AYED Initial Version 6.x */ +/**************************************************************************/ +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); + + /* Protect the control endpoint semaphore here. It will be unprotected in the + transfer request function. */ + status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER); + if (status != UX_SUCCESS) + { + _ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore); + 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..00a36098 --- /dev/null +++ b/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c @@ -0,0 +1,404 @@ +/* + This test verifies the optional HID set protocol callback behavior: + - Callback is invoked with correct protocol (boot=0, report=1) + - Callback receives the correct HID instance pointer + - When callback is NULL, SET_PROTOCOL still functions correctly +*/ + +#include "usbx_test_common_hid.h" + +#include "ux_host_class_hid_keyboard.h" +#include "ux_device_class_hid.h" + +#define DUMMY_USBX_MEMORY_SIZE (64*1024) +static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE]; + +static UX_SLAVE_CLASS_HID * g_hid_device = UX_NULL; + +static volatile UINT g_set_protocol_callback_calls = 0; +static volatile ULONG g_set_protocol_last_value = 0xFFFFFFFFu; +static volatile UX_SLAVE_CLASS_HID * g_set_protocol_last_hid = UX_NULL; + +static UCHAR dummy_report[8]; +static UCHAR buffer[64]; + +static UCHAR hid_report_descriptor[] = { + 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) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 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) */ + 0x29, 0x65, /* USAGE_MAXIMUM */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0xc0 /* END_COLLECTION */ +}; +#define HID_REPORT_LENGTH (sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])) + +#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52 +static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_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, 0x00, 0x00, + 0x00, + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH), + MSB(HID_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_FRAMEWORK_LENGTH_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, 0x00, 0x00, + 0x00, + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH), + MSB(HID_REPORT_LENGTH), + /* Endpoint descriptor (Interrupt) */ + 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08 +}; + +#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 +}; + +#define LANGUAGE_ID_FRAMEWORK_LENGTH 2 +static UCHAR language_id_framework[] = { 0x09, 0x04 }; + +static VOID error_callback(UINT system_level, UINT system_context, UINT error_code) +{ + /* Not expecting errors in this test; print and fail. */ + printf("Error on line %d, system_level: %u, system_context: %u, error: 0x%x\n", __LINE__, system_level, system_context, error_code); + test_control_return(1); +} + +static VOID test_hid_instance_activate(VOID *inst) +{ + g_hid_device = (UX_SLAVE_CLASS_HID *)inst; +} +static VOID test_hid_instance_deactivate(VOID *inst) +{ + if ((VOID *)g_hid_device == inst) + g_hid_device = UX_NULL; +} + +static VOID test_set_protocol_callback(UX_SLAVE_CLASS_HID *hid, ULONG protocol) +{ + g_set_protocol_callback_calls++; + g_set_protocol_last_value = protocol; + g_set_protocol_last_hid = hid; +} + +UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter); + +static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c) +{ + UX_PARAMETER_NOT_USED(a); + UX_PARAMETER_NOT_USED(b); + UX_PARAMETER_NOT_USED(c); + return 0; +} + +#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; + + printf("Running HID Set 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); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Register the error callback. */ + ux_utility_error_callback_register(error_callback); + + /* Host stack init. */ + status = ux_host_stack_initialize(ux_system_host_change_function); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\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: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Register the HID keyboard client (ensures enumeration). */ + 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: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Device stack init. */ + 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: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Initialize HID class parameters, including set_protocol callback. */ + hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor; + hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH; + hid_parameter.ux_device_class_hid_parameter_callback = UX_NULL; /* Not used in this test. */ + hid_parameter.ux_slave_class_hid_instance_activate = test_hid_instance_activate; + hid_parameter.ux_slave_class_hid_instance_deactivate = test_hid_instance_deactivate; + hid_parameter.ux_device_class_hid_parameter_set_protocol_callback = test_set_protocol_callback; + + status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry, + 1,2, (VOID *)&hid_parameter); + if(status!=UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Initialize simulated device controller and host HCD. */ + status = _ux_dcd_sim_slave_initialize(); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Wait for enumeration. */ + status = demo_class_hid_get(); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Use host HID API to set protocol. */ + + /* Fetch slave HID instance pointer. */ + UX_SLAVE_CLASS_HID *slave_hid = _ux_system_slave -> ux_system_slave_device.ux_slave_device_first_interface -> ux_slave_interface_class_instance; + + /* Sanity: default protocol is report (1). */ + if (ux_device_class_hid_protocol_get(slave_hid) != 1) + { + 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); + } + 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); + } + + /* Verify callback captured boot protocol and correct HID instance. */ + if (status == UX_SUCCESS) + { + if (g_set_protocol_callback_calls < 1 || g_set_protocol_last_value != 0 || g_set_protocol_last_hid != slave_hid) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu, hid=%p vs %p)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value, g_set_protocol_last_hid, slave_hid); + test_control_return(1); + } + if (ux_device_class_hid_protocol_get(slave_hid) != 0) + { + printf("Error on line %d, protocol not set to boot\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); + } + if (status == UX_SUCCESS && host_protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, host get protocol not 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); + } + + if (status == UX_SUCCESS) + { + if (g_set_protocol_callback_calls < 2 || g_set_protocol_last_value != 1 || g_set_protocol_last_hid != slave_hid) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu, hid=%p vs %p)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value, g_set_protocol_last_hid, slave_hid); + test_control_return(1); + } + if (ux_device_class_hid_protocol_get(slave_hid) != 1) + { + printf("Error on line %d, protocol not set to 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); + } + 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); + } + } + } + + /* Now simulate NULL callback: disable callback pointer and ensure protocol change still works. */ + slave_hid -> ux_device_class_hid_set_protocol_callback = UX_NULL; + + /* Flip to BOOT again. */ + UINT calls_before = g_set_protocol_callback_calls; + 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); + } + if (status == UX_SUCCESS) + { + if (ux_device_class_hid_protocol_get(slave_hid) != 0) + { + printf("Error on line %d, protocol not set to boot with NULL callback\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); + } + if (status == UX_SUCCESS && host_protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, host get protocol not boot with NULL callback\n", __LINE__); + test_control_return(1); + } + } + if (g_set_protocol_callback_calls != calls_before) + { + printf("Error on line %d, callback should not be invoked when NULL\n", __LINE__); + test_control_return(1); + } + } + + /* Cleanup */ + _ux_device_stack_disconnect(); + status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry); + UX_PARAMETER_NOT_USED(status); + _ux_device_stack_uninitialize(); + _ux_system_uninitialize(); + + printf("SUCCESS!\n"); + test_control_return(0); +} 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 c0d6a88d023e123b34800ecb0388f306b7076b8f Mon Sep 17 00:00:00 2001 From: MAY Date: Sun, 30 Nov 2025 01:05:56 +0100 Subject: [PATCH 3/3] add Host hid apis to set/get protocol and a callback for device hid class invoked when protocol change - add optional device hid callback ux_device_class_hid_parameter_set_protocol_callback invoked when protocol changes (boot/report). - add host hid api to set/get protocol. - update regression test to test host set/get api and device set protocol callback. --- .../inc/ux_device_class_hid.h | 11 +- .../src/ux_device_class_hid_control_request.c | 90 ++-- .../src/ux_device_class_hid_initialize.c | 81 ++-- 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 | 145 +++++++ .../src/ux_host_class_hid_protocol_set.c | 148 +++++++ test/cmake/usbx/regression/CMakeLists.txt | 1 + ...ice_class_hid_set_protocol_callback_test.c | 404 ++++++++++++++++++ test/regression/usbxtestcontrol.c | 6 +- 10 files changed, 986 insertions(+), 257 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 5dead7db..781f4607 100644 --- a/common/usbx_device_classes/inc/ux_device_class_hid.h +++ b/common/usbx_device_classes/inc/ux_device_class_hid.h @@ -1,10 +1,10 @@ /*************************************************************************** - * 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 **************************************************************************/ @@ -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 83305021..27e38d17 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 @@ -1,17 +1,17 @@ /*************************************************************************** - * 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 */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -28,44 +28,44 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_control_request PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_control_request PORTABLE C */ /* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function manages the based sent by the host on the control */ -/* endpoints with a CLASS or VENDOR SPECIFIC type. */ -/* */ -/* INPUT */ -/* */ -/* hid Pointer to hid class */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _ux_device_stack_transfer_request Transfer request */ +/* */ +/* This function manages the based sent by the host on the control */ +/* endpoints with a CLASS or VENDOR SPECIFIC type. */ +/* */ +/* INPUT */ +/* */ +/* hid Pointer to hid class */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_device_stack_transfer_request Transfer request */ /* _ux_device_class_hid_report_get Process Get_Report request */ /* _ux_device_class_hid_report_set Process Set_Report request */ /* _ux_device_class_hid_descriptor_send Send requested descriptor */ -/* */ -/* CALLED BY */ -/* */ +/* */ +/* CALLED BY */ +/* */ /* HID Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* prefixed UX to MS_TO_TICK, */ @@ -119,10 +119,10 @@ UX_SLAVE_CLASS_HID *hid; /* Duration - upper byte of wValue. */ duration = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE + 1); - + /* Get the class container. */ class_ptr = command -> ux_slave_class_command_class_ptr; - + /* Get the storage instance from this class container. */ hid = (UX_SLAVE_CLASS_HID *) class_ptr -> ux_slave_class_instance; @@ -149,8 +149,8 @@ UX_SLAVE_CLASS_HID *hid; /* Send the requested descriptor to the host. */ _ux_device_class_hid_descriptor_send(hid, request_value, request_index, request_length); - break; - + break; + case UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE: case UX_DEVICE_CLASS_HID_COMMAND_SET_IDLE: @@ -204,15 +204,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: @@ -224,4 +237,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 a23aca30..afad6a50 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 @@ -1,16 +1,16 @@ /*************************************************************************** - * 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 */ +/** */ +/** USBX Component */ /** */ /** Device HID Class */ /** */ @@ -27,46 +27,46 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_hid_initialize PORTABLE C */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_hid_initialize PORTABLE C */ /* 6.3.0 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function initializes the USB HID device. */ -/* This function is called by the class register function. It is only */ -/* done once. */ -/* */ -/* INPUT */ -/* */ -/* command Pointer to hid command */ -/* */ -/* OUTPUT */ -/* */ -/* Completion Status */ -/* */ -/* CALLS */ -/* */ +/* */ +/* This function initializes the USB HID device. */ +/* This function is called by the class register function. It is only */ +/* done once. */ +/* */ +/* INPUT */ +/* */ +/* command Pointer to hid command */ +/* */ +/* OUTPUT */ +/* */ +/* Completion Status */ +/* */ +/* CALLS */ +/* */ /* _ux_utility_memory_allocate Allocate memory */ /* _ux_utility_memory_free Free memory */ /* _ux_device_thread_create Create thread */ /* _ux_device_thread_delete Delete thread */ /* _ux_utility_event_flags_create Create event flags group */ -/* */ -/* CALLED BY */ -/* */ -/* USBX Source Code */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* CALLED BY */ +/* */ +/* USBX Source Code */ +/* */ +/* 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 */ @@ -97,7 +97,7 @@ /**************************************************************************/ UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command) { - + UX_SLAVE_CLASS_HID *hid; UX_SLAVE_CLASS_HID_PARAMETER *hid_parameter; UX_SLAVE_CLASS *class_ptr; @@ -149,9 +149,9 @@ UCHAR *buffer; #if !defined(UX_DEVICE_STANDALONE) /* Allocate some memory for the thread stack. */ - class_ptr -> ux_slave_class_thread_stack = + class_ptr -> ux_slave_class_thread_stack = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE); - + /* Check for successful allocation. */ if (class_ptr -> ux_slave_class_thread_stack == UX_NULL) status = UX_MEMORY_INSUFFICIENT; @@ -160,7 +160,7 @@ UCHAR *buffer; a new thread. We pass a pointer to the class to the new thread. This thread does not start until we have a instance of the class. */ if (status == UX_SUCCESS) - status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", + status = _ux_device_thread_create(&class_ptr -> ux_slave_class_thread, "ux_slave_hid_thread", _ux_device_class_hid_interrupt_thread, (ULONG) (ALIGN_TYPE) class_ptr, (VOID *) class_ptr -> ux_slave_class_thread_stack, UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, @@ -195,6 +195,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) @@ -263,7 +264,7 @@ UCHAR *buffer; if (hid -> ux_device_class_hid_event_array != UX_NULL) { - /* Initialize the head and tail of the notification round robin buffers. + /* Initialize the head and tail of the notification round robin buffers. At first, the head and tail are pointing to the beginning of the array. */ hid -> ux_device_class_hid_event_array_head = hid -> ux_device_class_hid_event_array; hid -> ux_device_class_hid_event_array_tail = hid -> ux_device_class_hid_event_array; @@ -392,7 +393,7 @@ UCHAR *buffer; /* */ /* INPUT */ /* */ -/* command Pointer to hid command */ +/* command Pointer to hid command */ /* */ /* OUTPUT */ /* */ 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..46fe908a 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 for SET_PROTOCOL. */ +#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..7f4c04b5 --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_get.c @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * 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-10-2026 Mohamed AYED Initial Version 6.x */ +/**************************************************************************/ +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 = 0x00; + + /* 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..46f7359b --- /dev/null +++ b/common/usbx_host_classes/src/ux_host_class_hid_protocol_set.c @@ -0,0 +1,148 @@ +/*************************************************************************** + * Copyright (c) 2025-present Eclipse ThreadX Contributors + * + * 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-10-2026 Mohamed AYED Initial Version 6.x */ +/**************************************************************************/ +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..00a36098 --- /dev/null +++ b/test/regression/usbx_ux_device_class_hid_set_protocol_callback_test.c @@ -0,0 +1,404 @@ +/* + This test verifies the optional HID set protocol callback behavior: + - Callback is invoked with correct protocol (boot=0, report=1) + - Callback receives the correct HID instance pointer + - When callback is NULL, SET_PROTOCOL still functions correctly +*/ + +#include "usbx_test_common_hid.h" + +#include "ux_host_class_hid_keyboard.h" +#include "ux_device_class_hid.h" + +#define DUMMY_USBX_MEMORY_SIZE (64*1024) +static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE]; + +static UX_SLAVE_CLASS_HID * g_hid_device = UX_NULL; + +static volatile UINT g_set_protocol_callback_calls = 0; +static volatile ULONG g_set_protocol_last_value = 0xFFFFFFFFu; +static volatile UX_SLAVE_CLASS_HID * g_set_protocol_last_hid = UX_NULL; + +static UCHAR dummy_report[8]; +static UCHAR buffer[64]; + +static UCHAR hid_report_descriptor[] = { + 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) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 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) */ + 0x29, 0x65, /* USAGE_MAXIMUM */ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ + 0xc0 /* END_COLLECTION */ +}; +#define HID_REPORT_LENGTH (sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])) + +#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52 +static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_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, 0x00, 0x00, + 0x00, + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH), + MSB(HID_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_FRAMEWORK_LENGTH_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, 0x00, 0x00, + 0x00, + /* HID descriptor */ + 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH), + MSB(HID_REPORT_LENGTH), + /* Endpoint descriptor (Interrupt) */ + 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08 +}; + +#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 +}; + +#define LANGUAGE_ID_FRAMEWORK_LENGTH 2 +static UCHAR language_id_framework[] = { 0x09, 0x04 }; + +static VOID error_callback(UINT system_level, UINT system_context, UINT error_code) +{ + /* Not expecting errors in this test; print and fail. */ + printf("Error on line %d, system_level: %u, system_context: %u, error: 0x%x\n", __LINE__, system_level, system_context, error_code); + test_control_return(1); +} + +static VOID test_hid_instance_activate(VOID *inst) +{ + g_hid_device = (UX_SLAVE_CLASS_HID *)inst; +} +static VOID test_hid_instance_deactivate(VOID *inst) +{ + if ((VOID *)g_hid_device == inst) + g_hid_device = UX_NULL; +} + +static VOID test_set_protocol_callback(UX_SLAVE_CLASS_HID *hid, ULONG protocol) +{ + g_set_protocol_callback_calls++; + g_set_protocol_last_value = protocol; + g_set_protocol_last_hid = hid; +} + +UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter); + +static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c) +{ + UX_PARAMETER_NOT_USED(a); + UX_PARAMETER_NOT_USED(b); + UX_PARAMETER_NOT_USED(c); + return 0; +} + +#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; + + printf("Running HID Set 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); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Register the error callback. */ + ux_utility_error_callback_register(error_callback); + + /* Host stack init. */ + status = ux_host_stack_initialize(ux_system_host_change_function); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\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: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Register the HID keyboard client (ensures enumeration). */ + 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: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Device stack init. */ + 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: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Initialize HID class parameters, including set_protocol callback. */ + hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor; + hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH; + hid_parameter.ux_device_class_hid_parameter_callback = UX_NULL; /* Not used in this test. */ + hid_parameter.ux_slave_class_hid_instance_activate = test_hid_instance_activate; + hid_parameter.ux_slave_class_hid_instance_deactivate = test_hid_instance_deactivate; + hid_parameter.ux_device_class_hid_parameter_set_protocol_callback = test_set_protocol_callback; + + status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry, + 1,2, (VOID *)&hid_parameter); + if(status!=UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Initialize simulated device controller and host HCD. */ + status = _ux_dcd_sim_slave_initialize(); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Wait for enumeration. */ + status = demo_class_hid_get(); + if (status != UX_SUCCESS) + { + printf("Error on line %d, error code: 0x%x\n", __LINE__, status); + test_control_return(1); + } + + /* Use host HID API to set protocol. */ + + /* Fetch slave HID instance pointer. */ + UX_SLAVE_CLASS_HID *slave_hid = _ux_system_slave -> ux_system_slave_device.ux_slave_device_first_interface -> ux_slave_interface_class_instance; + + /* Sanity: default protocol is report (1). */ + if (ux_device_class_hid_protocol_get(slave_hid) != 1) + { + 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); + } + 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); + } + + /* Verify callback captured boot protocol and correct HID instance. */ + if (status == UX_SUCCESS) + { + if (g_set_protocol_callback_calls < 1 || g_set_protocol_last_value != 0 || g_set_protocol_last_hid != slave_hid) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu, hid=%p vs %p)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value, g_set_protocol_last_hid, slave_hid); + test_control_return(1); + } + if (ux_device_class_hid_protocol_get(slave_hid) != 0) + { + printf("Error on line %d, protocol not set to boot\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); + } + if (status == UX_SUCCESS && host_protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, host get protocol not 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); + } + + if (status == UX_SUCCESS) + { + if (g_set_protocol_callback_calls < 2 || g_set_protocol_last_value != 1 || g_set_protocol_last_hid != slave_hid) + { + printf("Error on line %d, callback verification failed (calls=%u, val=%lu, hid=%p vs %p)\n", + __LINE__, g_set_protocol_callback_calls, g_set_protocol_last_value, g_set_protocol_last_hid, slave_hid); + test_control_return(1); + } + if (ux_device_class_hid_protocol_get(slave_hid) != 1) + { + printf("Error on line %d, protocol not set to 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); + } + 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); + } + } + } + + /* Now simulate NULL callback: disable callback pointer and ensure protocol change still works. */ + slave_hid -> ux_device_class_hid_set_protocol_callback = UX_NULL; + + /* Flip to BOOT again. */ + UINT calls_before = g_set_protocol_callback_calls; + 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); + } + if (status == UX_SUCCESS) + { + if (ux_device_class_hid_protocol_get(slave_hid) != 0) + { + printf("Error on line %d, protocol not set to boot with NULL callback\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); + } + if (status == UX_SUCCESS && host_protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT) + { + printf("Error on line %d, host get protocol not boot with NULL callback\n", __LINE__); + test_control_return(1); + } + } + if (g_set_protocol_callback_calls != calls_before) + { + printf("Error on line %d, callback should not be invoked when NULL\n", __LINE__); + test_control_return(1); + } + } + + /* Cleanup */ + _ux_device_stack_disconnect(); + status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry); + UX_PARAMETER_NOT_USED(status); + _ux_device_stack_uninitialize(); + _ux_system_uninitialize(); + + printf("SUCCESS!\n"); + test_control_return(0); +} 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,