Skip to content

Commit f5954fb

Browse files
committed
add host hid api to set/get protocol
This pull request adds host HID API functions to get and set the HID protocol (boot vs report mode) and introduces an optional callback for the device side when the protocol changes. - Added new host-side APIs ux_host_class_hid_protocol_set() and ux_host_class_hid_protocol_get() with error checking wrappers. - Added device-side optional callback ux_device_class_hid_set_protocol_callback that is invoked when the protocol changes. - Added comprehensive test to verify the new protocol callback functionality.
1 parent fa1d17a commit f5954fb

File tree

10 files changed

+966
-177
lines changed

10 files changed

+966
-177
lines changed

common/usbx_device_classes/inc/ux_device_class_hid.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ typedef struct UX_SLAVE_CLASS_HID_STRUCT
249249
UINT ux_device_class_hid_state;
250250
UINT (*ux_device_class_hid_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
251251
UINT (*ux_device_class_hid_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
252+
VOID (*ux_device_class_hid_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol);
252253
VOID (*ux_slave_class_hid_instance_activate)(VOID *);
253254
VOID (*ux_slave_class_hid_instance_deactivate)(VOID *);
254255
UCHAR *ux_device_class_hid_report_address;
@@ -365,6 +366,10 @@ typedef struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT
365366
ULONG ux_device_class_hid_parameter_report_length;
366367
UINT (*ux_device_class_hid_parameter_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
367368
UINT (*ux_device_class_hid_parameter_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
369+
370+
/* Optional callback invoked when protocol changes (boot/report). */
371+
VOID (*ux_device_class_hid_parameter_set_protocol_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, ULONG protocol);
372+
368373
#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE)
369374
ULONG ux_device_class_hid_parameter_event_max_number;
370375
ULONG ux_device_class_hid_parameter_event_max_length;

common/usbx_device_classes/src/ux_device_class_hid_control_request.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,15 +205,28 @@ UX_SLAVE_CLASS_HID *hid;
205205

206206
case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL:
207207

208-
/* Send the protocol. */
208+
/* Send the protocol to host. */
209209
*transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR)hid -> ux_device_class_hid_protocol;
210210
_ux_device_stack_transfer_request(transfer_request, 1, request_length);
211211
break;
212212

213213
case UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL:
214214

215+
/* Check protocol must be 0 (Boot) or 1 (Report). */
216+
if ((request_value != UX_DEVICE_CLASS_HID_PROTOCOL_BOOT) &&
217+
(request_value != UX_DEVICE_CLASS_HID_PROTOCOL_REPORT))
218+
{
219+
/* Invalid value: not handled. */
220+
return(UX_ERROR);
221+
}
222+
215223
/* Accept the protocol. */
216224
hid -> ux_device_class_hid_protocol = request_value;
225+
226+
/* If there is a callback defined by the application, send the protocol to it. */
227+
if (hid -> ux_device_class_hid_set_protocol_callback != UX_NULL)
228+
hid -> ux_device_class_hid_set_protocol_callback(hid, request_value);
229+
217230
break;
218231

219232
default:
@@ -225,4 +238,3 @@ UX_SLAVE_CLASS_HID *hid;
225238
/* It's handled. */
226239
return(UX_SUCCESS);
227240
}
228-

common/usbx_device_classes/src/ux_device_class_hid_initialize.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* SPDX-License-Identifier: MIT
99
**************************************************************************/
1010

11+
1112
/**************************************************************************/
1213
/**************************************************************************/
1314
/** */
@@ -196,6 +197,7 @@ UCHAR *buffer;
196197
/* Store the callback function. */
197198
hid -> ux_device_class_hid_callback = hid_parameter -> ux_device_class_hid_parameter_callback;
198199
hid -> ux_device_class_hid_get_callback = hid_parameter -> ux_device_class_hid_parameter_get_callback;
200+
hid -> ux_device_class_hid_set_protocol_callback = hid_parameter -> ux_device_class_hid_parameter_set_protocol_callback;
199201

200202
#if defined(UX_DEVICE_CLASS_HID_FLEXIBLE_EVENTS_QUEUE)
201203

common/usbx_host_classes/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ target_sources(${PROJECT_NAME} PRIVATE
9393
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_get.c
9494
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set.c
9595
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_idle_set_run.c
96+
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_set.c
97+
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_protocol_get.c
9698
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_instance_clean.c
9799
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_interrupt_endpoint_search.c
98100
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_hid_item_data_get.c

common/usbx_host_classes/inc/ux_host_class_hid.h

Lines changed: 182 additions & 173 deletions
Large diffs are not rendered by default.
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/***************************************************************************
2+
* Copyright (c) 2024 Microsoft Corporation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the MIT License which is available at
6+
* https://opensource.org/licenses/MIT.
7+
*
8+
* SPDX-License-Identifier: MIT
9+
**************************************************************************/
10+
11+
12+
/**************************************************************************/
13+
/**************************************************************************/
14+
/** */
15+
/** USBX Component */
16+
/** */
17+
/** Host HID Class */
18+
/** */
19+
/**************************************************************************/
20+
/**************************************************************************/
21+
22+
/* Include necessary system files. */
23+
24+
#define UX_SOURCE_CODE
25+
26+
#include "ux_api.h"
27+
#include "ux_host_class_hid.h"
28+
#include "ux_host_stack.h"
29+
30+
/**************************************************************************/
31+
/* */
32+
/* FUNCTION RELEASE */
33+
/* */
34+
/* _ux_host_class_hid_protocol_get PORTABLE C */
35+
/* */
36+
/* DESCRIPTION */
37+
/* */
38+
/* This function performs a GET_PROTOCOL to the HID device to read */
39+
/* current protocol (BOOT=0 or REPORT=1). */
40+
/* */
41+
/* INPUT */
42+
/* */
43+
/* hid Pointer to HID class */
44+
/* protocol Destination for protocol */
45+
/* */
46+
/* OUTPUT */
47+
/* */
48+
/* Completion Status */
49+
/* */
50+
/* CALLED BY */
51+
/* */
52+
/* Application */
53+
/* */
54+
/* RELEASE HISTORY */
55+
/* */
56+
/* DATE NAME DESCRIPTION */
57+
/* */
58+
/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */
59+
/* */
60+
/**************************************************************************/
61+
UINT _ux_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol)
62+
{
63+
64+
UX_ENDPOINT *control_endpoint;
65+
UX_TRANSFER *transfer_request;
66+
UINT status;
67+
UCHAR proto_byte = 0xFFu;
68+
69+
/* Ensure the instance is valid. */
70+
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS)
71+
{
72+
73+
/* If trace is enabled, insert this event into the trace buffer. */
74+
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)
75+
76+
#if defined(UX_HOST_STANDALONE)
77+
hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN;
78+
#endif
79+
80+
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
81+
}
82+
83+
/* Get the default control endpoint transfer request pointer. */
84+
control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint;
85+
transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
86+
87+
#if !defined(UX_HOST_STANDALONE)
88+
89+
/* Protect thread reentry to this instance. */
90+
status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER);
91+
if (status != UX_SUCCESS)
92+
return(status);
93+
94+
#endif
95+
96+
/* Create a transfer request for the GET_PROTOCOL request. */
97+
transfer_request -> ux_transfer_request_data_pointer = &proto_byte;
98+
transfer_request -> ux_transfer_request_requested_length = 1;
99+
transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_PROTOCOL;
100+
transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
101+
transfer_request -> ux_transfer_request_value = 0;
102+
transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
103+
104+
/* Send request to HCD layer. */
105+
status = _ux_host_stack_transfer_request(transfer_request);
106+
107+
#if !defined(UX_HOST_STANDALONE)
108+
/* Unprotect thread reentry to this instance. */
109+
_ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore);
110+
#endif
111+
112+
if (status == UX_SUCCESS && protocol)
113+
*protocol = (USHORT)proto_byte;
114+
115+
return(status);
116+
}
117+
118+
/**************************************************************************/
119+
/* */
120+
/* FUNCTION RELEASE */
121+
/* */
122+
/* _uxe_host_class_hid_protocol_get PORTABLE C */
123+
/* */
124+
/* DESCRIPTION */
125+
/* */
126+
/* This function checks errors in HID protocol get function call. */
127+
/* */
128+
/* INPUT */
129+
/* */
130+
/* hid Pointer to HID class */
131+
/* protocol Destination for protocol */
132+
/* */
133+
/* OUTPUT */
134+
/* */
135+
/* Status */
136+
/* */
137+
/**************************************************************************/
138+
UINT _uxe_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol)
139+
{
140+
/* Sanity check. */
141+
if (hid == UX_NULL || protocol == UX_NULL)
142+
return(UX_INVALID_PARAMETER);
143+
144+
/* Invoke protocol get function. */
145+
return(_ux_host_class_hid_protocol_get(hid, protocol));
146+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/***************************************************************************
2+
* Copyright (c) 2024 Microsoft Corporation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the MIT License which is available at
6+
* https://opensource.org/licenses/MIT.
7+
*
8+
* SPDX-License-Identifier: MIT
9+
**************************************************************************/
10+
11+
12+
/**************************************************************************/
13+
/**************************************************************************/
14+
/** */
15+
/** USBX Component */
16+
/** */
17+
/** Host HID Class */
18+
/** */
19+
/**************************************************************************/
20+
/**************************************************************************/
21+
22+
/* Include necessary system files. */
23+
24+
#define UX_SOURCE_CODE
25+
26+
#include "ux_api.h"
27+
#include "ux_host_class_hid.h"
28+
#include "ux_host_stack.h"
29+
30+
/**************************************************************************/
31+
/* */
32+
/* FUNCTION RELEASE */
33+
/* */
34+
/* _ux_host_class_hid_protocol_set PORTABLE C */
35+
/* */
36+
/* DESCRIPTION */
37+
/* */
38+
/* This function performs a SET_PROTOCOL to the HID device to switch */
39+
/* between BOOT (0) and REPORT (1) protocols. */
40+
/* */
41+
/* INPUT */
42+
/* */
43+
/* hid Pointer to HID class */
44+
/* protocol Protocol (BOOT/REPORT) */
45+
/* */
46+
/* OUTPUT */
47+
/* */
48+
/* Completion Status */
49+
/* */
50+
/* CALLED BY */
51+
/* */
52+
/* Application */
53+
/* */
54+
/* RELEASE HISTORY */
55+
/* */
56+
/* DATE NAME DESCRIPTION */
57+
/* */
58+
/* 01-15-2026 Mohamed AYED Initial Version 6.4.6 */
59+
/* */
60+
/**************************************************************************/
61+
UINT _ux_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol)
62+
{
63+
64+
UX_ENDPOINT *control_endpoint;
65+
UX_TRANSFER *transfer_request;
66+
UINT status;
67+
68+
/* Ensure the instance is valid. */
69+
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS)
70+
{
71+
72+
/* If trace is enabled, insert this event into the trace buffer. */
73+
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)
74+
75+
#if defined(UX_HOST_STANDALONE)
76+
hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN;
77+
#endif
78+
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
79+
}
80+
81+
/* Get the default control endpoint transfer request pointer. */
82+
control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint;
83+
transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
84+
85+
#if !defined(UX_HOST_STANDALONE)
86+
87+
/* Protect thread reentry to this instance. */
88+
status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER);
89+
if (status != UX_SUCCESS)
90+
return(status);
91+
92+
#endif
93+
94+
/* Create a transfer request for the SET_PROTOCOL request. */
95+
transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
96+
transfer_request -> ux_transfer_request_requested_length = 0;
97+
transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_PROTOCOL;
98+
transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
99+
transfer_request -> ux_transfer_request_value = (UINT)protocol;
100+
transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
101+
102+
/* Send request to HCD layer. */
103+
status = _ux_host_stack_transfer_request(transfer_request);
104+
105+
#if !defined(UX_HOST_STANDALONE)
106+
/* Unprotect thread reentry to this instance. */
107+
_ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore);
108+
#endif
109+
110+
/* Return the function status. */
111+
return(status);
112+
}
113+
114+
/**************************************************************************/
115+
/* */
116+
/* FUNCTION RELEASE */
117+
/* */
118+
/* _uxe_host_class_hid_protocol_set PORTABLE C */
119+
/* */
120+
/* DESCRIPTION */
121+
/* */
122+
/* This function checks errors in HID protocol set function call. */
123+
/* */
124+
/* INPUT */
125+
/* */
126+
/* hid Pointer to HID class */
127+
/* protocol Protocol (BOOT/REPORT) */
128+
/* */
129+
/* OUTPUT */
130+
/* */
131+
/* Status */
132+
/* */
133+
/**************************************************************************/
134+
UINT _uxe_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol)
135+
{
136+
/* Sanity check. */
137+
if (hid == UX_NULL)
138+
return(UX_INVALID_PARAMETER);
139+
140+
/* Validate protocol value: must be BOOT(0) or REPORT(1). */
141+
if (protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT &&
142+
protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT)
143+
return(UX_INVALID_PARAMETER);
144+
145+
/* Invoke protocol set function. */
146+
return(_ux_host_class_hid_protocol_set(hid, protocol));
147+
}

0 commit comments

Comments
 (0)