blob: d094b484840989f4d62f76ac2ddf7be9dd8387ba (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
* Copyright (c) 2026-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 */
/** */
/** 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_interrupt_endpoint_search PORTABLE C */
/* 6.1.12 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function searches for the handle of the only interrupt */
/* endpoint in the default alternate setting of the HID interface. */
/* The interrupt endpoint should always be there. The actual first */
/* transfer on the interrupt endpoint does not start until a HID */
/* client has claimed ownership of the HID device. */
/* */
/* INPUT */
/* */
/* hid Pointer to HID class */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_allocate Allocate memory block */
/* */
/* CALLED BY */
/* */
/* HID Class */
/* */
/**************************************************************************/
UINT _ux_host_class_hid_interrupt_endpoint_search(UX_HOST_CLASS_HID *hid)
{
UINT status = UX_ENDPOINT_HANDLE_UNKNOWN;
UX_INTERFACE *interface_ptr;
UX_ENDPOINT *endpoint;
UX_TRANSFER *transfer_request;
/* Search the interrupt endpoint. It is attached to the interface container. */
interface_ptr = hid -> ux_host_class_hid_interface;
endpoint = interface_ptr -> ux_interface_first_endpoint;
while(endpoint != UX_NULL)
{
/* Find interrupt IN endpoint. */
if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN) &&
((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_INTERRUPT_ENDPOINT))
{
/* The endpoint is correct, save it. */
hid -> ux_host_class_hid_interrupt_endpoint = endpoint;
/* Fill in the transfer request with the length requested for this endpoint. */
transfer_request = &endpoint -> ux_endpoint_transfer_request;
transfer_request -> ux_transfer_request_requested_length = hid -> ux_host_class_hid_interrupt_endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
transfer_request -> ux_transfer_request_actual_length = 0;
/* The direction is always IN for the HID interrupt endpoint. */
transfer_request -> ux_transfer_request_type = UX_REQUEST_IN;
/* There is a callback function associated with the transfer request, so we need the class instance. */
transfer_request -> ux_transfer_request_class_instance = (VOID *) hid;
/* Interrupt transactions have a completion routine. */
transfer_request -> ux_transfer_request_completion_function = _ux_host_class_hid_transfer_request_completed;
/* Transfer timeout : wait forever. */
transfer_request -> ux_transfer_request_timeout_value = UX_WAIT_FOREVER;
/* Obtain a buffer for this transaction. The buffer will always be reused. */
transfer_request -> ux_transfer_request_data_pointer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY,
transfer_request -> ux_transfer_request_requested_length);
/* If the endpoint is available and we have memory, we mark the interrupt endpoint as ready. */
if (transfer_request -> ux_transfer_request_data_pointer != UX_NULL)
{
hid -> ux_host_class_hid_interrupt_endpoint_status = UX_HOST_CLASS_HID_INTERRUPT_ENDPOINT_READY;
status = UX_SUCCESS;
#if !defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT)
/* We have found the interrupt IN endpoint, just stop searching. */
break;
#endif
}
else
{
status = UX_MEMORY_INSUFFICIENT;
break;
}
}
#if defined(UX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT)
else if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT) &&
((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_INTERRUPT_ENDPOINT))
{
/* Found the interrupt OUT endpoint, save it. */
hid -> ux_host_class_hid_interrupt_out_endpoint = endpoint;
}
#endif
/* Check next endpoint. */
endpoint = endpoint -> ux_endpoint_next_endpoint;
}
/* Return completion status. */
return(status);
}
|