1 /* This file tests the ux_device_class_hid API. */
2
3 #include "usbx_test_common_hid.h"
4
5 #include "ux_test_dcd_sim_slave.h"
6 #include "ux_test_hcd_sim_host.h"
7 #include "ux_test_utility_sim.h"
8
9 #include "ux_host_class_hid_mouse.h"
10 #include "ux_host_class_hid_keyboard.h"
11 #include "ux_host_class_hid_remote_control.h"
12
13
14 static UCHAR hid_keyboard_report[] = {
15
16 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
17 0x09, 0x06, // USAGE (Keyboard)
18 0xa1, 0x01, // COLLECTION (Application)
19 0x05, 0x07, // USAGE_PAGE (Keyboard)
20 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
21 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
22 0x15, 0x00, // LOGICAL_MINIMUM (0)
23 0x25, 0x01, // LOGICAL_MAXIMUM (1)
24 0x75, 0x01, // REPORT_SIZE (1)
25 0x95, 0x08, // REPORT_COUNT (8)
26 0x81, 0x02, // INPUT (Data,Var,Abs)
27 0x95, 0x01, // REPORT_COUNT (1)
28 0x75, 0x08, // REPORT_SIZE (8)
29 0x81, 0x03, // INPUT (Cnst,Var,Abs)
30 0x95, 0x05, // REPORT_COUNT (5)
31 0x75, 0x01, // REPORT_SIZE (1)
32 0x05, 0x08, // USAGE_PAGE (LEDs)
33 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
34 0x29, 0x05, // USAGE_MAXIMUM (Kana)
35 0x91, 0x02, // OUTPUT (Data,Var,Abs)
36 0x95, 0x01, // REPORT_COUNT (1)
37 0x75, 0x03, // REPORT_SIZE (3)
38 0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
39 0x95, 0x06, // REPORT_COUNT (6)
40 0x75, 0x08, // REPORT_SIZE (8)
41 0x15, 0x00, // LOGICAL_MINIMUM (0)
42 0x25, 0x65, // LOGICAL_MAXIMUM (101)
43 0x05, 0x07, // USAGE_PAGE (Keyboard)
44 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
45 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
46 0x81, 0x00, // INPUT (Data,Ary,Abs)
47 0xc0, // END_COLLECTION
48
49 0xa1, 0x01, // COLLECTION (Application)
50 0x19, 0x01, // USAGE_MINIMUM (1)
51 0x29, 0x04, // USAGE_MAXIMUM (4)
52 0x75, 0x04, // REPORT_SIZE (4)
53 0x95, 0x04, // REPORT_COUNT (4)
54 0xb1, 0x02, // FEATURE (Data,Var,Abs)
55 0x85, 0x02, // REPORT_ID (2)
56 0x19, 0x05, // USAGE_MINIMUM (5)
57 0x29, 0x07, // USAGE_MAXIMUM (7)
58 0x75, 0x08, // REPORT_SIZE (8)
59 0x95, 0x03, // REPORT_COUNT (3)
60 0xb1, 0x02, // FEATURE (Data,Var,Abs)
61 0x85, 0x04, // REPORT_ID (4)
62 0x09, 0x08, // USAGE (8)
63 0x75, 0x10, // REPORT_SIZE (16)
64 0x95, 0x01, // REPORT_COUNT (1)
65 0xb1, 0x02, // FEATURE (Data,Var,Abs)
66 0xc0, // END_COLLECTION
67 };
68 #define HID_KEYBOARD_REPORT_LENGTH sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0])
69
70
71 static UCHAR hid_mouse_report[] = {
72
73 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
74 0x09, 0x02, // USAGE (Mouse)
75 0xa1, 0x01, // COLLECTION (Application)
76 0x09, 0x01, // USAGE (Pointer)
77 0xa1, 0x00, // COLLECTION (Physical)
78 0x05, 0x09, // USAGE_PAGE (Button)
79 0x19, 0x01, // USAGE_MINIMUM (Button 1)
80 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
81 0x15, 0x00, // LOGICAL_MINIMUM (0)
82 0x25, 0x01, // LOGICAL_MAXIMUM (1)
83 0x95, 0x03, // REPORT_COUNT (3)
84 0x75, 0x01, // REPORT_SIZE (1)
85 0x81, 0x02, // INPUT (Data,Var,Abs)
86 0x95, 0x01, // REPORT_COUNT (1)
87 0x75, 0x05, // REPORT_SIZE (5)
88 0x81, 0x03, // INPUT (Cnst,Var,Abs)
89 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
90 0x09, 0x30, // USAGE (X)
91 0x09, 0x31, // USAGE (Y)
92 0x15, 0x81, // LOGICAL_MINIMUM (-127)
93 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
94 0x75, 0x08, // REPORT_SIZE (8)
95 0x95, 0x02, // REPORT_COUNT (2)
96 0x81, 0x06, // INPUT (Data,Var,Rel)
97 0x09, 0x38, // USAGE (Mouse Wheel)
98 0x15, 0x81, // LOGICAL_MINIMUM (-127)
99 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
100 0x75, 0x08, // REPORT_SIZE (8)
101 0x95, 0x01, // REPORT_COUNT (1)
102 0x81, 0x06, // INPUT (Data,Var,Rel)
103 0xc0, // END_COLLECTION
104 0xc0, // END_COLLECTION
105 };
106 #define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
107
108 static UCHAR hid_remote_control_report[] = {
109
110 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
111 0x09, 0x01, // USAGE (Consumer Control)
112 0xa1, 0x01, // COLLECTION (Application)
113 0x09, 0x02, // USAGE (Numeric Key Pad)
114 0xa1, 0x02, // COLLECTION (Logical)
115 0x05, 0x09, // USAGE_PAGE (Button)
116 0x19, 0x01, // USAGE_MINIMUM (Button 1)
117 0x29, 0x0a, // USAGE_MAXIMUM (Button 10)
118 0x15, 0x01, // LOGICAL_MINIMUM (1)
119 0x25, 0x0a, // LOGICAL_MAXIMUM (10)
120 0x75, 0x04, // REPORT_SIZE (4)
121 0x95, 0x01, // REPORT_COUNT (1)
122 0x81, 0x00, // INPUT (Data,Ary,Abs)
123 0xc0, // END_COLLECTION
124 0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
125 0x09, 0x86, // USAGE (Channel)
126 0x09, 0xe0, // USAGE (Volume)
127 0x15, 0xff, // LOGICAL_MINIMUM (-1)
128 0x25, 0x01, // LOGICAL_MAXIMUM (1)
129 0x75, 0x02, // REPORT_SIZE (2)
130 0x95, 0x02, // REPORT_COUNT (2)
131 0x81, 0x46, // INPUT (Data,Var,Rel,Null)
132 0xc0 // END_COLLECTION
133 };
134 #define HID_REMOTE_CONTROL_REPORT_LENGTH (sizeof(hid_remote_control_report)/sizeof(hid_remote_control_report[0]))
135
136 /* Configuration descriptor 9 bytes */
137 #define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
138 /* Configuration 1 descriptor 9 bytes */\
139 0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
140 (bNumInterfaces), (bConfigurationValue), 0x00,\
141 0x40, 0x00,
142 #define CFG_DESC_LEN (9)
143
144
145 /* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
146 #define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
147 /* Interface descriptor */\
148 0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
149 /* HID descriptor */\
150 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
151 MSB(report_len),\
152 /* Endpoint descriptor (Interrupt) */\
153 0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
154 #define HID_IFC_DESC_ALL_LEN (9+9+7)
155
156
157 static UCHAR device_framework_full_speed[] = {
158
159 /* Device descriptor */
160 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
161 0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x01,
163
164 CFG_DESC(CFG_DESC_LEN+3*HID_IFC_DESC_ALL_LEN, 2, 1)
165 /* Keyboard */
166 HID_IFC_DESC_ALL(0, HID_KEYBOARD_REPORT_LENGTH, 0x82)
167 /* Mouse */
168 HID_IFC_DESC_ALL(1, HID_MOUSE_REPORT_LENGTH, 0x81)
169 /* Remote control */
170 HID_IFC_DESC_ALL(2, HID_REMOTE_CONTROL_REPORT_LENGTH, 0x83)
171 };
172 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
173
174
175 static UCHAR device_framework_high_speed[] = {
176
177 /* Device descriptor */
178 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
179 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
180 0x03, 0x01,
181
182 /* Device qualifier descriptor */
183 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
184 0x01, 0x00,
185
186 CFG_DESC(CFG_DESC_LEN+3*HID_IFC_DESC_ALL_LEN, 2, 1)
187 /* Keyboard */
188 HID_IFC_DESC_ALL(0, HID_KEYBOARD_REPORT_LENGTH, 0x82)
189 /* Mouse */
190 HID_IFC_DESC_ALL(1, HID_MOUSE_REPORT_LENGTH, 0x81)
191 /* Remote control */
192 HID_IFC_DESC_ALL(2, HID_REMOTE_CONTROL_REPORT_LENGTH, 0x83)
193 };
194 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
195
196
197 /* String Device Framework :
198 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
199 Byte 2 : Byte containing the index of the descriptor
200 Byte 3 : Byte containing the length of the descriptor string
201 */
202 static UCHAR string_framework[] = {
203
204 /* Manufacturer string descriptor : Index 1 */
205 0x09, 0x04, 0x01, 0x0c,
206 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
207 0x6f, 0x67, 0x69, 0x63,
208
209 /* Product string descriptor : Index 2 */
210 0x09, 0x04, 0x02, 0x0c,
211 0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
212 0x6f, 0x61, 0x72, 0x64,
213
214 /* Serial Number string descriptor : Index 3 */
215 0x09, 0x04, 0x03, 0x04,
216 0x30, 0x30, 0x30, 0x31
217 };
218 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
219
220
221 /* Multiple languages are supported on the device, to add
222 a language besides english, the unicode language code must
223 be appended to the language_id_framework array and the length
224 adjusted accordingly. */
225 static UCHAR language_id_framework[] = {
226
227 /* English. */
228 0x09, 0x04
229 };
230 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
231
232 static UX_HOST_CLASS_HID *hid = UX_NULL;
233 static UX_HOST_CLASS_HID_MOUSE *hid_mouse = UX_NULL;
234 static UX_HOST_CLASS_HID_KEYBOARD *hid_keyboard = UX_NULL;
235 static UX_HOST_CLASS_HID_REMOTE_CONTROL *hid_remote_control = UX_NULL;
236
237 static UX_SLAVE_CLASS_HID *hid_mouse_slave = UX_NULL;
238 static UX_SLAVE_CLASS_HID *hid_keyboard_slave = UX_NULL;
239 static UX_SLAVE_CLASS_HID *hid_remote_control_slave = UX_NULL;
240
241 static UX_SLAVE_CLASS_HID_PARAMETER hid_mouse_parameter;
242 static UX_SLAVE_CLASS_HID_PARAMETER hid_keyboard_parameter;
243 static UX_SLAVE_CLASS_HID_PARAMETER hid_remote_control_parameter;
244
245 static ULONG rsc_mem_alloc_cnt_on_set_cfg;
246 static ULONG rsc_enum_mem_alloc_count;
247 static ULONG rsc_hid_mem_alloc_count;
248
249 static ULONG error_callback_counter;
250 static UCHAR error_callback_ignore;
251
252 static ULONG error_counter = 0;
253
_is_mouse(UX_HOST_CLASS_HID_CLIENT * client)254 static UINT _is_mouse(UX_HOST_CLASS_HID_CLIENT *client)
255 {
256 return(UX_SUCCESS == _ux_utility_memory_compare(client->ux_host_class_hid_client_name,
257 _ux_system_host_class_hid_client_mouse_name,
258 _ux_utility_string_length_get(_ux_system_host_class_hid_client_mouse_name)));
259 }
_is_keyboard(UX_HOST_CLASS_HID_CLIENT * client)260 static UINT _is_keyboard(UX_HOST_CLASS_HID_CLIENT *client)
261 {
262 return(UX_SUCCESS == _ux_utility_memory_compare(client->ux_host_class_hid_client_name,
263 _ux_system_host_class_hid_client_keyboard_name,
264 _ux_utility_string_length_get(_ux_system_host_class_hid_client_keyboard_name)));
265 }
ux_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)266 static UINT ux_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
267 {
268
269 UX_HOST_CLASS_HID_CLIENT *client = (UX_HOST_CLASS_HID_CLIENT *)inst;
270
271 // if(event >= UX_HID_CLIENT_INSERTION) printf("hChg: ev %lx, cls %p, inst %p, %s\n", event, cls, inst, _is_mouse(client) ? "Mouse" : _is_keyboard(client) ? "Keyboard" : "Remote Control");
272 switch(event)
273 {
274
275 case UX_HID_CLIENT_INSERTION:
276 if (_is_mouse(client))
277 hid_mouse = (UX_HOST_CLASS_HID_MOUSE *)client->ux_host_class_hid_client_local_instance;
278 else
279 {
280 if (_is_keyboard(client))
281 hid_keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)client->ux_host_class_hid_client_local_instance;
282 else
283 hid_remote_control = (UX_HOST_CLASS_HID_REMOTE_CONTROL *)client->ux_host_class_hid_client_local_instance;
284 }
285 break;
286
287 case UX_HID_CLIENT_REMOVAL:
288 if (_is_mouse(client))
289 hid_mouse = UX_NULL;
290 else
291 {
292 if (_is_keyboard(client))
293 hid_keyboard = UX_NULL;
294 else
295 hid_remote_control = UX_NULL;
296 }
297 break;
298
299 default:
300 break;
301 }
302 return 0;
303 }
304
mouse_instance_activate_callback(VOID * parameter)305 static VOID mouse_instance_activate_callback(VOID *parameter)
306 {
307 // printf("dMouse: %p\n", parameter);
308 hid_mouse_slave = (UX_SLAVE_CLASS_HID *)parameter;
309 }
310
keyboard_instance_activate_callback(VOID * parameter)311 static VOID keyboard_instance_activate_callback(VOID *parameter)
312 {
313 // printf("dKeyboard: %p\n", parameter);
314 hid_keyboard_slave = (UX_SLAVE_CLASS_HID *)parameter;
315 }
316
remote_control_instance_activate_callback(VOID * parameter)317 static VOID remote_control_instance_activate_callback(VOID *parameter)
318 {
319 // printf("dKeyboard: %p\n", parameter);
320 hid_remote_control_slave = (UX_SLAVE_CLASS_HID *)parameter;
321 }
322
instance_deactivate_callback(VOID * parameter)323 static VOID instance_deactivate_callback(VOID *parameter)
324 {
325 // printf("dRm: %p\n", parameter);
326 if ((VOID *)hid_mouse_slave == parameter)
327 hid_mouse_slave = UX_NULL;
328
329 if ((VOID *)hid_keyboard_slave == parameter)
330 hid_keyboard_slave = UX_NULL;
331
332 if ((VOID *)hid_remote_control_slave == parameter)
333 hid_remote_control_slave = UX_NULL;
334 }
335
error_callback(UINT system_level,UINT system_context,UINT error_code)336 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
337 {
338 if (error_code == UX_MEMORY_INSUFFICIENT)
339 error_callback_counter ++;
340 // printf("ERROR #%d: 0x%x, 0x%x, 0x%x\n", __LINE__, system_level, system_context, error_code);
341 }
342
break_on_all_activated(VOID)343 static UINT break_on_all_activated(VOID)
344 {
345
346 if (hid_mouse_slave == UX_NULL)
347 return 0;
348 if (hid_keyboard_slave == UX_NULL)
349 return 0;
350 if (hid_remote_control_slave == UX_NULL)
351 return 0;
352 if (hid_mouse == UX_NULL)
353 return 0;
354 if (hid_keyboard == UX_NULL)
355 return 0;
356 if (hid_remote_control == UX_NULL)
357 return 0;
358
359 return 1;
360 }
361
362
break_on_all_removed(VOID)363 static UINT break_on_all_removed(VOID)
364 {
365 if (hid_mouse_slave || hid_keyboard_slave || hid_remote_control_slave)
366 return 0;
367 if (hid_mouse || hid_keyboard || hid_remote_control)
368 return 0;
369
370 return 1;
371 }
372
373
sleep_break_on_error(VOID)374 static UINT sleep_break_on_error(VOID)
375 {
376
377 if (error_callback_counter >= 3)
378 return error_callback_counter;
379
380 return UX_SUCCESS;
381 }
382
383
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)384 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
385 {
386 rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
387 }
388
389 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
390
391 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
392 /* function, request to match,
393 port action, port status,
394 request action, request EP, request data, request actual length, request status,
395 status, additional callback,
396 no_return */
397 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
398 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
399 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
400 UX_SUCCESS, ux_test_hcd_entry_set_cfg,
401 UX_TRUE}, /* Invoke callback & continue */
402 { 0 }
403 };
404
405 /* Define what the initial system looks like. */
406
407 #ifdef CTEST
test_application_define(void * first_unused_memory)408 void test_application_define(void *first_unused_memory)
409 #else
410 void usbx_ux_device_class_hid_basic_memory_test_application_define(void *first_unused_memory)
411 #endif
412 {
413
414 UINT status;
415 CHAR *stack_pointer;
416 CHAR *memory_pointer;
417 ULONG mem_free;
418 ULONG alloc_count;
419 ULONG test_n;
420
421 /* Inform user. */
422 printf("Running UX Class HID Basic Memory test ............................. ");
423 stepinfo("\n");
424
425 /* Initialize memory logger. */
426 ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
427 ux_test_utility_sim_mem_alloc_count_reset();
428
429 /* Initialize the free memory pointer */
430 stack_pointer = (CHAR *) usbx_memory;
431 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
432
433 /* Initialize USBX. Memory */
434 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
435
436 /* Check for error. */
437 if (status != UX_SUCCESS)
438 {
439
440 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
441 test_control_return(1);
442 }
443
444 /* Register the error callback. */
445 _ux_utility_error_callback_register(error_callback);
446
447 /* The code below is required for installing the host portion of USBX */
448 status = ux_host_stack_initialize(ux_system_host_change_function);
449 if (status != UX_SUCCESS)
450 {
451
452 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
453 test_control_return(1);
454 }
455
456 status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
457 if (status != UX_SUCCESS)
458 {
459
460 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
461 test_control_return(1);
462 }
463
464 /* Register the HID client(s). */
465 status |= ux_host_class_hid_client_register(_ux_system_host_class_hid_client_mouse_name, ux_host_class_hid_mouse_entry);
466 status |= ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
467 status |= ux_host_class_hid_client_register(_ux_system_host_class_hid_client_remote_control_name, ux_host_class_hid_remote_control_entry);
468 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
469 if (status != UX_SUCCESS)
470 {
471
472 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
473 test_control_return(1);
474 }
475 #endif
476
477 /* The code below is required for installing the device portion of USBX. No call back for
478 device status change in this example. */
479 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
480 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
481 string_framework, STRING_FRAMEWORK_LENGTH,
482 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
483 if(status!=UX_SUCCESS)
484 {
485
486 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
487 test_control_return(1);
488 }
489
490 /* Initialize the hid class parameters for mouse and keyboard. */
491 hid_mouse_parameter.ux_device_class_hid_parameter_report_address = hid_mouse_report;
492 hid_mouse_parameter.ux_device_class_hid_parameter_report_length = HID_MOUSE_REPORT_LENGTH;
493 hid_mouse_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
494 hid_mouse_parameter.ux_slave_class_hid_instance_activate = mouse_instance_activate_callback;
495 hid_mouse_parameter.ux_slave_class_hid_instance_deactivate = instance_deactivate_callback;
496
497 hid_keyboard_parameter.ux_device_class_hid_parameter_report_address = hid_keyboard_report;
498 hid_keyboard_parameter.ux_device_class_hid_parameter_report_length = HID_KEYBOARD_REPORT_LENGTH;
499 hid_keyboard_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
500 hid_keyboard_parameter.ux_slave_class_hid_instance_activate = keyboard_instance_activate_callback;
501 hid_keyboard_parameter.ux_slave_class_hid_instance_deactivate = instance_deactivate_callback;
502
503 hid_remote_control_parameter.ux_device_class_hid_parameter_report_address = hid_remote_control_report;
504 hid_remote_control_parameter.ux_device_class_hid_parameter_report_length = HID_REMOTE_CONTROL_REPORT_LENGTH;
505 hid_remote_control_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
506 hid_remote_control_parameter.ux_slave_class_hid_instance_activate = remote_control_instance_activate_callback;
507 hid_remote_control_parameter.ux_slave_class_hid_instance_deactivate = instance_deactivate_callback;
508
509 stepinfo(">>>>>>>>>> Test HID Class Initialize/deinitialize memory\n");
510
511 stepinfo(">>>>>>>>>> - Reset counts\n");
512 ux_test_utility_sim_mem_alloc_count_reset();
513 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
514
515 stepinfo(">>>>>>>>>> - _class_register\n");
516
517 /* Initilize the device hid class. */
518 status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
519 1,1, (VOID *)&hid_mouse_parameter);
520 status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
521 1,0, (VOID *)&hid_keyboard_parameter);
522 status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
523 1,2, (VOID *)&hid_remote_control_parameter);
524 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
525 if(status!=UX_SUCCESS)
526 {
527
528 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
529 test_control_return(1);
530 }
531 #endif
532 #if 1
533 /* Log create counts when instances active for further tests. */
534 alloc_count = ux_test_utility_sim_mem_alloc_count();
535
536 /* Lock log base for tests. */
537 ux_test_utility_sim_mem_alloc_log_lock();
538
539 stepinfo("init & uninit alloc : %ld\n", alloc_count);
540 stepinfo("mem free : %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
541
542 if (alloc_count) stepinfo(">>>>>>>>>> - Init/deinit memory errors test\n");
543 mem_free = (~0);
544 for (test_n = 0; test_n < alloc_count; test_n ++)
545 {
546
547 stepinfo("%4ld / %4ld\n", test_n, alloc_count - 1);
548
549 /* Unregister. */
550 ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
551 ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
552 ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
553
554 /* Update memory free level (disconnect) */
555 if (mem_free == (~0))
556 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
557 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
558 {
559
560 printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
561 error_counter ++;
562 test_control_return(1);
563 }
564
565 /* Set memory error generation */
566 ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
567
568 /* Register. */
569 status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
570 1,1, (VOID *)&hid_mouse_parameter);
571 status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
572 1,0, (VOID *)&hid_keyboard_parameter);
573 status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
574 1,2, (VOID *)&hid_remote_control_parameter);
575 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
576 /* Check error */
577 if (status == UX_SUCCESS)
578 {
579
580 printf("ERROR #%d.%ld: registered when there is memory error\n", __LINE__, test_n);
581 error_counter ++;
582 }
583 #endif
584
585 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
586 }
587 ux_test_utility_sim_mem_alloc_error_generation_stop();
588 if (alloc_count) stepinfo("\n");
589
590 /* Unregister. */
591 ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
592 ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
593 ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
594
595 /* Register. */
596 status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
597 1,1, (VOID *)&hid_mouse_parameter);
598 status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
599 1,0, (VOID *)&hid_keyboard_parameter);
600 status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
601 1,2, (VOID *)&hid_remote_control_parameter);
602 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
603 if(status!=UX_SUCCESS)
604 {
605
606 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
607 test_control_return(1);
608 }
609 #endif
610 #endif
611 /* Initialize the simulated device controller. */
612 status = _ux_dcd_sim_slave_initialize();
613
614 /* Check for error. */
615 if (status != UX_SUCCESS)
616 {
617
618 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
619 test_control_return(1);
620 }
621
622 /* Register all the USB host controllers available in this system */
623 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
624
625 /* Check for error. */
626 if (status != UX_SUCCESS)
627 {
628
629 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
630 test_control_return(1);
631 }
632
633 /* Create the main host simulation thread. */
634 status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
635 stack_pointer, UX_DEMO_STACK_SIZE,
636 20, 20, 1, TX_AUTO_START);
637
638 /* Check for error. */
639 if (status != TX_SUCCESS)
640 {
641
642 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
643 test_control_return(1);
644 }
645
646 #if defined(UX_DEVICE_STANDALONE)
647
648 /* Create the main device simulation thread. */
649 status = tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
650 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
651 20, 20, 1, TX_AUTO_START);
652
653 /* Check for error. */
654 if (status != TX_SUCCESS)
655 {
656
657 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
658 test_control_return(1);
659 }
660 #endif
661 }
662
663 #if defined(UX_DEVICE_STANDALONE)
tx_demo_thread_device_simulation_entry(ULONG arg)664 static void tx_demo_thread_device_simulation_entry(ULONG arg)
665 {
666 while(1)
667 {
668 ux_system_tasks_run();
669 tx_thread_relinquish();
670 }
671 }
672 #endif
673
tx_demo_thread_host_simulation_entry(ULONG arg)674 static void tx_demo_thread_host_simulation_entry(ULONG arg)
675 {
676
677 UINT status;
678 UX_DEVICE *device;
679 ULONG mem_free;
680 ULONG alloc_count;
681 ULONG test_n;
682 UX_HCD *hcd;
683
684
685 stepinfo(">>>>>>>>>> Thread start\n");
686
687 hcd = &_ux_system_host->ux_system_host_hcd_array[0];
688
689 ux_test_breakable_sleep(500, break_on_all_activated);
690
691 /* Get device instance. */
692 status = ux_host_stack_device_get(0, &device);
693
694 if (status != UX_SUCCESS)
695 {
696 printf("ERROR #%d: get_device fail, 0x%x\n", __LINE__, status);
697 test_control_return(1);
698 }
699
700 stepinfo(">>>>>>>>>> Disconnect\n");
701
702 ux_test_dcd_sim_slave_disconnect();
703 ux_test_hcd_sim_host_disconnect();
704
705 if (hid_keyboard || hid_mouse)
706 {
707 printf("ERROR #%d\n", __LINE__);
708 test_control_return(1);
709 }
710
711 stepinfo(">>>>>>>>>> Reset counts\n");
712
713 ux_test_utility_sim_mem_alloc_count_reset();
714 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
715
716 rsc_mem_alloc_cnt_on_set_cfg = 0;
717 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
718
719 stepinfo(">>>>>>>>>> Connect\n");
720
721 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
722 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
723 ux_test_breakable_sleep(500, break_on_all_activated);
724
725 /* Log create counts for further tests. */
726 rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
727
728 /* Log create counts when instances active for further tests. */
729 alloc_count = ux_test_utility_sim_mem_alloc_count();
730
731 /* Lock log base for tests. */
732 ux_test_utility_sim_mem_alloc_log_lock();
733
734 rsc_hid_mem_alloc_count = alloc_count - rsc_enum_mem_alloc_count;
735
736 stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
737 stepinfo("hid mem : %ld\n", rsc_hid_mem_alloc_count);
738 stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
739
740 if (hid_mouse == UX_NULL
741 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
742 || hid_keyboard == UX_NULL
743 #endif
744 )
745 {
746 printf("ERROR #%d: %p %p\n", __LINE__, hid_keyboard, hid_mouse);
747 test_control_return(1);
748 }
749
750 /* Simulate detach and attach for FS enumeration,
751 and test possible memory allocation error handlings.
752 */
753 if (rsc_hid_mem_alloc_count) stepinfo(">>>>>>>>>> Memory errors enumeration test\n");
754 mem_free = (~0);
755 for (test_n = 0; test_n < rsc_hid_mem_alloc_count; test_n ++)
756 {
757
758 stepinfo("%4ld / %4ld\n", test_n, rsc_hid_mem_alloc_count - 1);
759
760 /* Disconnect. */
761 ux_test_dcd_sim_slave_disconnect();
762 ux_test_hcd_sim_host_disconnect();
763
764 /* Check number of devices. */
765 if (hcd->ux_hcd_nb_devices != 0)
766 {
767 printf("ERROR #%d.%ld: number of devices (%d) must be 0\n", __LINE__, test_n, hcd->ux_hcd_nb_devices);
768 error_counter ++;
769 }
770
771 /* Update memory free level (disconnect) */
772 if (mem_free == (~0))
773 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
774 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
775 {
776
777 printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
778 error_counter ++;
779 test_control_return(1);
780 }
781
782 /* Set memory error generation */
783 ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
784
785 /* Connect. */
786 error_callback_counter = 0;
787 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
788 #if 1 /* @nick */
789 ux_test_hcd_sim_host_connect_no_wait(UX_FULL_SPEED_DEVICE);
790
791 /* Wait for enum thread to complete. */
792 ux_test_wait_for_enum_thread_completion();
793 #else
794 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
795
796 /* Wait and break on errors. */
797 ux_test_breakable_sleep(400, sleep_break_on_error);
798 #endif
799
800 /* Check error */
801 if (hid_mouse && hid_keyboard && hid_mouse_slave && hid_keyboard_slave && hid_remote_control && hid_remote_control_slave)
802 {
803
804 printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
805 error_counter ++;
806 }
807 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
808 ux_test_utility_sim_mem_alloc_error_generation_stop();
809 }
810 if (alloc_count) stepinfo("\n");
811
812 stepinfo(">>>>>>>>>> Test done\n");
813
814 /* Now disconnect the device. */
815 _ux_device_stack_disconnect();
816
817 /* And deinitialize the class. */
818 status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
819
820 /* Deinitialize the device side of usbx. */
821 _ux_device_stack_uninitialize();
822
823 /* And finally the usbx system resources. */
824 _ux_system_uninitialize();
825
826 if (error_counter)
827 {
828 printf("FAIL %ld errors!\n", error_counter);
829 test_control_return(1);
830 }
831
832 /* Successful test. */
833 printf("SUCCESS!\n");
834 test_control_return(0);
835 }
836
demo_thread_hid_callback(UX_SLAVE_CLASS_HID * class,UX_SLAVE_CLASS_HID_EVENT * event)837 static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
838 {
839 return(UX_SUCCESS);
840 }
841