1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** USBX Component */
17 /** */
18 /** HID Class */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 /* Include necessary system files. */
25
26 #define UX_SOURCE_CODE
27
28 #include "ux_api.h"
29 #include "ux_host_class_hid.h"
30 #include "ux_host_stack.h"
31
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _ux_host_class_hid_interrupt_endpoint_search PORTABLE C */
38 /* 6.1.12 */
39 /* AUTHOR */
40 /* */
41 /* Chaoqiong Xiao, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function searches for the handle of the only interrupt */
46 /* endpoint in the default alternate setting of the HID interface. */
47 /* The interrupt endpoint should always be there. The actual first */
48 /* transfer on the interrupt endpoint does not start until a HID */
49 /* client has claimed ownership of the HID device. */
50 /* */
51 /* INPUT */
52 /* */
53 /* hid Pointer to HID class */
54 /* */
55 /* OUTPUT */
56 /* */
57 /* Completion Status */
58 /* */
59 /* CALLS */
60 /* */
61 /* _ux_utility_memory_allocate Allocate memory block */
62 /* */
63 /* CALLED BY */
64 /* */
65 /* HID Class */
66 /* */
67 /* RELEASE HISTORY */
68 /* */
69 /* DATE NAME DESCRIPTION */
70 /* */
71 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
72 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
73 /* resulting in version 6.1 */
74 /* 01-31-2022 Xiuwen Cai, CQ Xiao Modified comment(s), */
75 /* added interrupt OUT support,*/
76 /* added timeout initialize, */
77 /* resulting in version 6.1.10 */
78 /* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
79 /* fixed parameter/variable */
80 /* names conflict C++ keyword, */
81 /* resulting in version 6.1.12 */
82 /* */
83 /**************************************************************************/
_ux_host_class_hid_interrupt_endpoint_search(UX_HOST_CLASS_HID * hid)84 UINT _ux_host_class_hid_interrupt_endpoint_search(UX_HOST_CLASS_HID *hid)
85 {
86
87 UINT status = UX_ENDPOINT_HANDLE_UNKNOWN;
88 UX_INTERFACE *interface_ptr;
89 UX_ENDPOINT *endpoint;
90 UX_TRANSFER *transfer_request;
91
92
93 /* Search the interrupt endpoint. It is attached to the interface container. */
94 interface_ptr = hid -> ux_host_class_hid_interface;
95 endpoint = interface_ptr -> ux_interface_first_endpoint;
96 while(endpoint != UX_NULL)
97 {
98
99 /* Find interrupt IN endpoint. */
100 if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN) &&
101 ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_INTERRUPT_ENDPOINT))
102 {
103
104 /* The endpoint is correct, save it. */
105 hid -> ux_host_class_hid_interrupt_endpoint = endpoint;
106
107 /* Fill in the transfer request with the length requested for this endpoint. */
108 transfer_request = &endpoint -> ux_endpoint_transfer_request;
109 transfer_request -> ux_transfer_request_requested_length = hid -> ux_host_class_hid_interrupt_endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
110 transfer_request -> ux_transfer_request_actual_length = 0;
111
112 /* The direction is always IN for the HID interrupt endpoint. */
113 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN;
114
115 /* There is a callback function associated with the transfer request, so we need the class instance. */
116 transfer_request -> ux_transfer_request_class_instance = (VOID *) hid;
117
118 /* Interrupt transactions have a completion routine. */
119 transfer_request -> ux_transfer_request_completion_function = _ux_host_class_hid_transfer_request_completed;
120
121 /* Transfer timeout : wait forever. */
122 transfer_request -> ux_transfer_request_timeout_value = UX_WAIT_FOREVER;
123
124 /* Obtain a buffer for this transaction. The buffer will always be reused. */
125 transfer_request -> ux_transfer_request_data_pointer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY,
126 transfer_request -> ux_transfer_request_requested_length);
127
128 /* If the endpoint is available and we have memory, we mark the interrupt endpoint as ready. */
129 if (transfer_request -> ux_transfer_request_data_pointer != UX_NULL)
130 {
131 hid -> ux_host_class_hid_interrupt_endpoint_status = UX_HOST_CLASS_HID_INTERRUPT_ENDPOINT_READY;
132 status = UX_SUCCESS;
133 #if !defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT)
134
135 /* We have found the interrupt IN endpoint, just stop searching. */
136 break;
137 #endif
138 }
139 else
140 {
141 status = UX_MEMORY_INSUFFICIENT;
142 break;
143 }
144 }
145 #if defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT)
146 else if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT) &&
147 ((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_INTERRUPT_ENDPOINT))
148 {
149
150 /* Found the interrupt OUT endpoint, save it. */
151 hid -> ux_host_class_hid_interrupt_out_endpoint = endpoint;
152 }
153 #endif
154
155 /* Check next endpoint. */
156 endpoint = endpoint -> ux_endpoint_next_endpoint;
157 }
158
159 /* Return completion status. */
160 return(status);
161 }
162
163