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 /**************************************************************************/
25 /*                                                                        */
26 /*  COMPONENT DEFINITION                                   RELEASE        */
27 /*                                                                        */
28 /*    ux_device_class_hid.h                               PORTABLE C      */
29 /*                                                           6.1.12       */
30 /*  AUTHOR                                                                */
31 /*                                                                        */
32 /*    Chaoqiong Xiao, Microsoft Corporation                               */
33 /*                                                                        */
34 /*  DESCRIPTION                                                           */
35 /*                                                                        */
36 /*    This file contains all the header and extern functions used by the  */
37 /*    USBX HID class.                                                     */
38 /*                                                                        */
39 /*  RELEASE HISTORY                                                       */
40 /*                                                                        */
41 /*    DATE              NAME                      DESCRIPTION             */
42 /*                                                                        */
43 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
44 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
45 /*                                            used UX prefix to refer to  */
46 /*                                            TX symbols instead of using */
47 /*                                            them directly,              */
48 /*                                            resulting in version 6.1    */
49 /*  12-31-2020     Chaoqiong Xiao           Modified comment(s),          */
50 /*                                            added Get/Set Protocol      */
51 /*                                            request support,            */
52 /*                                            resulting in version 6.1.3  */
53 /*  08-02-2021     Chaoqiong Xiao           Modified comment(s),          */
54 /*                                            added extern "C" keyword    */
55 /*                                            for compatibility with C++, */
56 /*                                            resulting in version 6.1.8  */
57 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
58 /*                                            added standalone support,   */
59 /*                                            added interrupt OUT support,*/
60 /*                                            resulting in version 6.1.10 */
61 /*  04-25-2022     Chaoqiong Xiao           Modified comment(s),          */
62 /*                                            added receiver callback,    */
63 /*                                            resulting in version 6.1.11 */
64 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
65 /*                                            added standalone int out,   */
66 /*                                            resulting in version 6.1.12 */
67 /*                                                                        */
68 /**************************************************************************/
69 
70 #ifndef UX_DEVICE_CLASS_HID_H
71 #define UX_DEVICE_CLASS_HID_H
72 
73 /* Determine if a C++ compiler is being used.  If so, ensure that standard
74    C is used to process the API information.  */
75 
76 #ifdef   __cplusplus
77 
78 /* Yes, C++ compiler is present.  Use standard C.  */
79 extern   "C" {
80 
81 #endif
82 
83 /* Device HID Compile Options.  */
84 
85 /* If defined, interrupt OUT transfer is supported.  */
86 /* #define UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT  */
87 
88 /* Use UX general thread stack size for receiver thread.  */
89 #define UX_DEVICE_CLASS_HID_RECEIVER_THREAD_STACK_SIZE              UX_THREAD_STACK_SIZE
90 
91 /* Use UX general thread stack size for HID class thread.  */
92 #define UX_DEVICE_CLASS_HID_THREAD_STACK_SIZE                       UX_THREAD_STACK_SIZE
93 
94 
95 /* Define HID Class constants.  */
96 
97 #define UX_DEVICE_CLASS_HID_CLASS                                   0x03
98 #define UX_DEVICE_CLASS_HID_SUBCLASS                                0X00
99 #define UX_DEVICE_CLASS_HID_PROTOCOL                                0X00
100 
101 /* Define HID Class commands.  */
102 
103 #define UX_DEVICE_CLASS_HID_COMMAND_GET_REPORT                      0x01
104 #define UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE                        0x02
105 #define UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL                    0x03
106 #define UX_DEVICE_CLASS_HID_COMMAND_SET_REPORT                      0x09
107 #define UX_DEVICE_CLASS_HID_COMMAND_SET_IDLE                        0x0A
108 #define UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL                    0x0B
109 
110 /* Define HID Class Descriptor types.  */
111 
112 #define UX_DEVICE_CLASS_HID_DESCRIPTOR_HID                          0x21
113 #define UX_DEVICE_CLASS_HID_DESCRIPTOR_REPORT                       0x22
114 #define UX_DEVICE_CLASS_HID_DESCRIPTOR_PHYSICAL                     0x23
115 
116 /* Define HID Report Types.  */
117 
118 #define UX_DEVICE_CLASS_HID_REPORT_TYPE_INPUT                       0x1
119 #define UX_DEVICE_CLASS_HID_REPORT_TYPE_OUTPUT                      0x2
120 #define UX_DEVICE_CLASS_HID_REPORT_TYPE_FEATURE                     0x3
121 
122 /* Define HID Protocols.  */
123 
124 #define UX_DEVICE_CLASS_HID_PROTOCOL_BOOT                           0
125 #define UX_DEVICE_CLASS_HID_PROTOCOL_REPORT                         1
126 
127 /* Define HID standalone read/receiver states.  */
128 
129 #define UX_DEVICE_CLASS_HID_READ_START                              (UX_STATE_STEP + 1)
130 #define UX_DEVICE_CLASS_HID_READ_WAIT                               (UX_STATE_STEP + 2)
131 
132 #define UX_DEVICE_CLASS_HID_RECEIVER_START                          (UX_STATE_STEP + 3)
133 #define UX_DEVICE_CLASS_HID_RECEIVER_WAIT                           (UX_STATE_STEP + 4)
134 #define UX_DEVICE_CLASS_HID_RECEIVER_ERROR                          (UX_STATE_STEP + 5)
135 
136 
137 /* Define HID event info structure.  */
138 
139 #ifndef UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH
140 #define UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH                     32
141 #endif
142 
143 /* Ensure the event buffer can fit inside the control endpoint's data buffer.  */
144 #if UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH
145 #error "Error: the event buffer cannot fit inside the control endpoint's data buffer. Reduce UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH such that it is less than or equal to UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH."
146 #endif
147 
148 /* Ensure the event buffer can fit inside the interrupt endpoint's data buffer.  */
149 #if UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH > UX_SLAVE_REQUEST_DATA_MAX_LENGTH
150 #error "Error: the event buffer cannot fit inside the interrupt endpoint's data buffer. Reduce UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH such that it is less than or equal to UX_SLAVE_REQUEST_DATA_MAX_LENGTH."
151 #endif
152 
153 #ifndef UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE
154 #define UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE                        16
155 #endif
156 
157 #define UX_DEVICE_CLASS_HID_NEW_EVENT                               1u
158 #define UX_DEVICE_CLASS_HID_NEW_IDLE_RATE                           2u
159 #define UX_DEVICE_CLASS_HID_EVENTS_MASK                             3u /* Mask _NEW_EVENT and _NEW_IDLE_RATE  */
160 
161 #define UX_DEVICE_CLASS_HID_RECEIVER_RESTART                        4u
162 
163 #define UX_DEVICE_CLASS_HID_EVENTS_ALL_MASK                         7u /* Mask all event flags.  */
164 
165 typedef struct UX_SLAVE_CLASS_HID_EVENT_STRUCT
166 {
167     ULONG                   ux_device_class_hid_event_report_id;
168     ULONG                   ux_device_class_hid_event_report_type;
169     UCHAR                   ux_device_class_hid_event_buffer[UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH];
170     ULONG                   ux_device_class_hid_event_length;
171 
172 } UX_SLAVE_CLASS_HID_EVENT;
173 
174 /* Define HID structure.  */
175 
176 typedef struct UX_SLAVE_CLASS_HID_STRUCT
177 {
178 
179     UX_SLAVE_INTERFACE              *ux_slave_class_hid_interface;
180     UX_SLAVE_ENDPOINT               *ux_device_class_hid_interrupt_endpoint;
181     UINT                            ux_device_class_hid_state;
182     UINT                            (*ux_device_class_hid_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
183     UINT                            (*ux_device_class_hid_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
184     VOID                            (*ux_slave_class_hid_instance_activate)(VOID *);
185     VOID                            (*ux_slave_class_hid_instance_deactivate)(VOID *);
186     UCHAR                           *ux_device_class_hid_report_address;
187     ULONG                           ux_device_class_hid_report_id;
188     ULONG                           ux_device_class_hid_report_length;
189 #if !defined(UX_DEVICE_STANDALONE)
190     UX_EVENT_FLAGS_GROUP            ux_device_class_hid_event_flags_group;
191 #else
192     UINT                            ux_device_class_hid_event_state;
193     ULONG                           ux_device_class_hid_event_wait_start;
194     UX_SLAVE_CLASS_HID_EVENT        ux_device_class_hid_event;
195 #endif
196     ULONG                           ux_device_class_hid_event_idle_rate;
197     ULONG                           ux_device_class_hid_event_wait_timeout;
198     ULONG                           ux_device_class_hid_protocol;
199     UX_SLAVE_CLASS_HID_EVENT        *ux_device_class_hid_event_array;
200     UX_SLAVE_CLASS_HID_EVENT        *ux_device_class_hid_event_array_head;
201     UX_SLAVE_CLASS_HID_EVENT        *ux_device_class_hid_event_array_tail;
202     UX_SLAVE_CLASS_HID_EVENT        *ux_device_class_hid_event_array_end;
203 
204 #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT)
205     UX_SLAVE_ENDPOINT               *ux_device_class_hid_read_endpoint;
206     struct UX_DEVICE_CLASS_HID_RECEIVER_STRUCT
207                                     *ux_device_class_hid_receiver;
208 #if !defined(UX_DEVICE_STANDALONE)
209     UX_MUTEX                        ux_device_class_hid_read_mutex;
210 #else
211     UCHAR                           *ux_device_class_hid_read_buffer;
212     ULONG                           ux_device_class_hid_read_requested_length;
213     ULONG                           ux_device_class_hid_read_actual_length;
214     ULONG                           ux_device_class_hid_read_transfer_length;
215     UINT                            ux_device_class_hid_read_state;
216     UINT                            ux_device_class_hid_read_status;
217 #endif
218 #endif
219 
220 } UX_SLAVE_CLASS_HID;
221 
222 
223 /* HID interrupt OUT support extensions.  */
224 
225 typedef struct UX_DEVICE_CLASS_HID_RECEIVED_EVENT_STRUCT
226 {
227     ULONG                   ux_device_class_hid_received_event_length;
228     UCHAR                   *ux_device_class_hid_received_event_data;
229 } UX_DEVICE_CLASS_HID_RECEIVED_EVENT;
230 
231 typedef struct UX_DEVICE_CLASS_HID_RECEIVER_STRUCT
232 {
233 
234     VOID                    (*ux_device_class_hid_receiver_uninitialize)(struct UX_DEVICE_CLASS_HID_RECEIVER_STRUCT *receiver);
235     VOID                    (*ux_device_class_hid_receiver_event_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid);
236 
237     ULONG                   ux_device_class_hid_receiver_event_buffer_size;
238     UX_DEVICE_CLASS_HID_RECEIVED_EVENT
239                             *ux_device_class_hid_receiver_events;
240     UX_DEVICE_CLASS_HID_RECEIVED_EVENT
241                             *ux_device_class_hid_receiver_events_end;
242     UX_DEVICE_CLASS_HID_RECEIVED_EVENT
243                             *ux_device_class_hid_receiver_event_read_pos;
244     UX_DEVICE_CLASS_HID_RECEIVED_EVENT
245                             *ux_device_class_hid_receiver_event_save_pos;
246 
247 #if !defined(UX_DEVICE_STANDALONE)
248     UX_THREAD               ux_device_class_hid_receiver_thread;
249 #else
250     UINT                    (*ux_device_class_hid_receiver_tasks_run)(struct UX_SLAVE_CLASS_HID_STRUCT *hid);
251 #endif
252 } UX_DEVICE_CLASS_HID_RECEIVER;
253 
254 
255 /* Define HID initialization command structure.  */
256 
257 typedef struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT
258 {
259 
260     VOID                    (*ux_slave_class_hid_instance_activate)(VOID *);
261     VOID                    (*ux_slave_class_hid_instance_deactivate)(VOID *);
262     UCHAR                   *ux_device_class_hid_parameter_report_address;
263     ULONG                   ux_device_class_hid_parameter_report_id;
264     ULONG                   ux_device_class_hid_parameter_report_length;
265     UINT                    (*ux_device_class_hid_parameter_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
266     UINT                    (*ux_device_class_hid_parameter_get_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid, UX_SLAVE_CLASS_HID_EVENT *);
267 #if defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT)
268     UINT                    (*ux_device_class_hid_parameter_receiver_initialize)(UX_SLAVE_CLASS_HID *hid, struct UX_SLAVE_CLASS_HID_PARAMETER_STRUCT *parameter, UX_DEVICE_CLASS_HID_RECEIVER **receiver);
269     ULONG                   ux_device_class_hid_parameter_receiver_event_max_number;
270     ULONG                   ux_device_class_hid_parameter_receiver_event_max_length;
271     VOID                    (*ux_device_class_hid_parameter_receiver_event_callback)(struct UX_SLAVE_CLASS_HID_STRUCT *hid);
272 #endif
273 
274 } UX_SLAVE_CLASS_HID_PARAMETER;
275 
276 
277 /* Define HID Class function prototypes.  */
278 UINT  _ux_device_class_hid_descriptor_send(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_type,
279                                             ULONG request_index, ULONG host_length);
280 UINT  _ux_device_class_hid_activate(UX_SLAVE_CLASS_COMMAND *command);
281 UINT  _ux_device_class_hid_deactivate(UX_SLAVE_CLASS_COMMAND *command);
282 UINT  _ux_device_class_hid_control_request(UX_SLAVE_CLASS_COMMAND *command);
283 UINT  _ux_device_class_hid_entry(UX_SLAVE_CLASS_COMMAND *command);
284 VOID  _ux_device_class_hid_interrupt_thread(ULONG hid_class);
285 UINT  _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command);
286 UINT  _ux_device_class_hid_uninitialize(UX_SLAVE_CLASS_COMMAND *command);
287 UINT  _ux_device_class_hid_event_set(UX_SLAVE_CLASS_HID *hid,
288                                       UX_SLAVE_CLASS_HID_EVENT *hid_event);
289 UINT  _ux_device_class_hid_event_get(UX_SLAVE_CLASS_HID *hid,
290                                       UX_SLAVE_CLASS_HID_EVENT *hid_event);
291 UINT  _ux_device_class_hid_report_set(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_type,
292                                             ULONG request_index, ULONG host_length);
293 UINT  _ux_device_class_hid_report_get(UX_SLAVE_CLASS_HID *hid, ULONG descriptor_type,
294                                             ULONG request_index, ULONG host_length);
295 
296 UINT  _ux_device_class_hid_tasks_run(VOID *class_instance);
297 
298 UINT  _ux_device_class_hid_read(UX_SLAVE_CLASS_HID *hid,
299                                 UCHAR *buffer, ULONG requested_length,
300                                 ULONG *actual_length);
301 
302 VOID  _ux_device_class_hid_receiver_thread(ULONG hid_class);
303 UINT  _ux_device_class_hid_receiver_initialize(UX_SLAVE_CLASS_HID *hid,
304                                     UX_SLAVE_CLASS_HID_PARAMETER *parameter,
305                                     UX_DEVICE_CLASS_HID_RECEIVER **receiver);
306 VOID  _ux_device_class_hid_receiver_uninitialize(UX_DEVICE_CLASS_HID_RECEIVER *receiver);
307 UINT  _ux_device_class_hid_receiver_event_get(UX_SLAVE_CLASS_HID *hid,
308                                 UX_DEVICE_CLASS_HID_RECEIVED_EVENT *event);
309 UINT  _ux_device_class_hid_receiver_event_free(UX_SLAVE_CLASS_HID *hid);
310 
311 UINT  _ux_device_class_hid_read_run(UX_SLAVE_CLASS_HID *hid,
312                                 UCHAR *buffer, ULONG requested_length,
313                                 ULONG *actual_length);
314 UINT  _ux_device_class_hid_receiver_tasks_run(UX_SLAVE_CLASS_HID *hid);
315 
316 /* Define Device HID Class API prototypes.  */
317 
318 #define ux_device_class_hid_entry        _ux_device_class_hid_entry
319 #define ux_device_class_hid_event_set    _ux_device_class_hid_event_set
320 #define ux_device_class_hid_event_get    _ux_device_class_hid_event_get
321 #define ux_device_class_hid_report_set   _ux_device_class_hid_report_set
322 #define ux_device_class_hid_report_get   _ux_device_class_hid_report_get
323 
324 #define ux_device_class_hid_protocol_get(hid)   (hid -> ux_device_class_hid_protocol)
325 
326 #define ux_device_class_hid_read                _ux_device_class_hid_read
327 #define ux_device_class_hid_read_run            _ux_device_class_hid_read_run
328 
329 #define ux_device_class_hid_receiver_initialize _ux_device_class_hid_receiver_initialize
330 #define ux_device_class_hid_receiver_event_get  _ux_device_class_hid_receiver_event_get
331 #define ux_device_class_hid_receiver_event_free _ux_device_class_hid_receiver_event_free
332 
333 /* Determine if a C++ compiler is being used.  If so, complete the standard
334    C conditional started above.  */
335 #ifdef __cplusplus
336 }
337 #endif
338 
339 #endif
340