Skip to content

Commit 43466b2

Browse files
committed
add host hid api to set/get protocol
1 parent fa1d17a commit 43466b2

File tree

10 files changed

+837
-177
lines changed

10 files changed

+837
-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: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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+
/**************************************************************************/
51+
UINT _ux_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol)
52+
{
53+
54+
UX_ENDPOINT *control_endpoint;
55+
UX_TRANSFER *transfer_request;
56+
UINT status;
57+
UCHAR proto_byte = 0xFFu;
58+
59+
/* Ensure the instance is valid. */
60+
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS)
61+
{
62+
63+
/* If trace is enabled, insert this event into the trace buffer. */
64+
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)
65+
66+
#if defined(UX_HOST_STANDALONE)
67+
hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN;
68+
#endif
69+
70+
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
71+
}
72+
73+
/* Get the default control endpoint transfer request pointer. */
74+
control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint;
75+
transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
76+
77+
78+
#if !defined(UX_HOST_STANDALONE)
79+
80+
/* Protect thread reentry to this instance. */
81+
status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER);
82+
if (status != UX_SUCCESS)
83+
return(status);
84+
85+
#endif
86+
87+
/* Create a transfer request for the GET_PROTOCOL request. */
88+
transfer_request -> ux_transfer_request_data_pointer = &proto_byte;
89+
transfer_request -> ux_transfer_request_requested_length = 1;
90+
transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_PROTOCOL;
91+
transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
92+
transfer_request -> ux_transfer_request_value = 0;
93+
transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
94+
95+
/* Send request to HCD layer. */
96+
status = _ux_host_stack_transfer_request(transfer_request);
97+
98+
#if !defined(UX_HOST_STANDALONE)
99+
/* Unprotect thread reentry to this instance. */
100+
_ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore);
101+
#endif
102+
103+
if (status == UX_SUCCESS && protocol)
104+
*protocol = (USHORT)proto_byte;
105+
106+
return(status);
107+
}
108+
109+
/**************************************************************************/
110+
/* */
111+
/* FUNCTION RELEASE */
112+
/* */
113+
/* _uxe_host_class_hid_protocol_get PORTABLE C */
114+
/* */
115+
/* DESCRIPTION */
116+
/* */
117+
/* This function checks errors in HID protocol get function call. */
118+
/* */
119+
/* INPUT */
120+
/* */
121+
/* hid Pointer to HID class */
122+
/* protocol Destination for protocol */
123+
/* */
124+
/* OUTPUT */
125+
/* */
126+
/* Status */
127+
/* */
128+
/**************************************************************************/
129+
UINT _uxe_host_class_hid_protocol_get(UX_HOST_CLASS_HID *hid, USHORT *protocol)
130+
{
131+
/* Sanity check. */
132+
if (hid == UX_NULL || protocol == UX_NULL)
133+
return(UX_INVALID_PARAMETER);
134+
135+
/* Invoke protocol get function. */
136+
return(_ux_host_class_hid_protocol_get(hid, protocol));
137+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
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+
/**************************************************************************/
51+
UINT _ux_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol)
52+
{
53+
54+
UX_ENDPOINT *control_endpoint;
55+
UX_TRANSFER *transfer_request;
56+
UINT status;
57+
58+
/* Ensure the instance is valid. */
59+
if (_ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, (VOID *) hid) != UX_SUCCESS)
60+
{
61+
62+
/* If trace is enabled, insert this event into the trace buffer. */
63+
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, hid, 0, 0, UX_TRACE_ERRORS, 0, 0)
64+
65+
#if defined(UX_HOST_STANDALONE)
66+
hid -> ux_host_class_hid_status = UX_HOST_CLASS_INSTANCE_UNKNOWN;
67+
#endif
68+
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
69+
}
70+
71+
/* Get the default control endpoint transfer request pointer. */
72+
control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint;
73+
transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
74+
75+
76+
#if !defined(UX_HOST_STANDALONE)
77+
78+
/* Protect thread reentry to this instance. */
79+
status = _ux_host_semaphore_get(&hid -> ux_host_class_hid_semaphore, UX_WAIT_FOREVER);
80+
if (status != UX_SUCCESS)
81+
return(status);
82+
83+
#endif
84+
85+
/* Create a transfer request for the SET_PROTOCOL request. */
86+
transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
87+
transfer_request -> ux_transfer_request_requested_length = 0;
88+
transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_PROTOCOL;
89+
transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
90+
transfer_request -> ux_transfer_request_value = (UINT)protocol;
91+
transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
92+
93+
/* Send request to HCD layer. */
94+
status = _ux_host_stack_transfer_request(transfer_request);
95+
96+
#if !defined(UX_HOST_STANDALONE)
97+
/* Unprotect thread reentry to this instance. */
98+
_ux_host_semaphore_put(&hid -> ux_host_class_hid_semaphore);
99+
#endif
100+
101+
/* Return the function status. */
102+
return(status);
103+
}
104+
105+
/**************************************************************************/
106+
/* */
107+
/* FUNCTION RELEASE */
108+
/* */
109+
/* _uxe_host_class_hid_protocol_set PORTABLE C */
110+
/* */
111+
/* DESCRIPTION */
112+
/* */
113+
/* This function checks errors in HID protocol set function call. */
114+
/* */
115+
/* INPUT */
116+
/* */
117+
/* hid Pointer to HID class */
118+
/* protocol Protocol (BOOT/REPORT) */
119+
/* */
120+
/* OUTPUT */
121+
/* */
122+
/* Status */
123+
/* */
124+
/**************************************************************************/
125+
UINT _uxe_host_class_hid_protocol_set(UX_HOST_CLASS_HID *hid, USHORT protocol)
126+
{
127+
/* Sanity check. */
128+
if (hid == UX_NULL)
129+
return(UX_INVALID_PARAMETER);
130+
131+
/* Validate protocol value: must be BOOT(0) or REPORT(1). */
132+
if (protocol != UX_HOST_CLASS_HID_PROTOCOL_BOOT &&
133+
protocol != UX_HOST_CLASS_HID_PROTOCOL_REPORT)
134+
return(UX_INVALID_PARAMETER);
135+
136+
/* Invoke protocol set function. */
137+
return(_ux_host_class_hid_protocol_set(hid, protocol));
138+
}

test/cmake/usbx/regression/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ set(ux_class_hid_test_cases
139139
${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test2.c
140140
${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test3.c
141141
${SOURCE_DIR}/usbx_ux_device_class_hid_control_request_test.c
142+
${SOURCE_DIR}/usbx_ux_device_class_hid_set_protocol_callback_test.c
142143
${SOURCE_DIR}/usbx_ux_device_class_hid_initialize_test.c
143144
${SOURCE_DIR}/usbx_ux_device_class_hid_interrupt_thread_test2.c
144145
${SOURCE_DIR}/usbx_ux_device_class_hid_read_test.c

0 commit comments

Comments
 (0)