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