1 /* This file tests _ux_device_class_hid_control_request(). Note that the 4 requests we're testing
2 (GET_IDLE, SET_IDLE, GET_PROTOCOL, and SET_PROTOCOL) have yet to be implemented on the device;
3 Therefore, right now, not much is done in the way of checking output. */
4
5 #include "usbx_test_common_hid.h"
6
7 #include "ux_host_class_hid_keyboard.h"
8 #include "ux_device_class_hid.h"
9
10
11 #define DUMMY_USBX_MEMORY_SIZE (64*1024)
12 static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
13
14 static UX_SLAVE_CLASS_HID * hid_device;
15
16 static UCHAR event_buffer[8];
17 static UCHAR dummy_report[7];
18 static UCHAR buffer[64];
19 static UINT set_report_test_started;
20 static UCHAR error_is_expected = UX_FALSE;
21
22 static UCHAR hid_report_descriptor[] = {
23
24 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
25 0x09, 0x06, // USAGE (Keyboard)
26 0xa1, 0x01, // COLLECTION (Application)
27 0x05, 0x07, // USAGE_PAGE (Keyboard)
28 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
29 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
30 0x15, 0x00, // LOGICAL_MINIMUM (0)
31 0x25, 0x01, // LOGICAL_MAXIMUM (1)
32 0x75, 0x01, // REPORT_SIZE (1)
33 0x95, 0x08, // REPORT_COUNT (8)
34 0x81, 0x02, // INPUT (Data,Var,Abs)
35 0x95, 0x01, // REPORT_COUNT (1)
36 0x75, 0x08, // REPORT_SIZE (8)
37 0x81, 0x03, // INPUT (Cnst,Var,Abs)
38 0x95, 0x05, // REPORT_COUNT (5)
39 0x75, 0x01, // REPORT_SIZE (1)
40 0x05, 0x08, // USAGE_PAGE (LEDs)
41 0x19, 0x01, // USAGE_MINIMUM (Num Lock)
42 0x29, 0x05, // USAGE_MAXIMUM (Kana)
43 0x91, 0x02, // OUTPUT (Data,Var,Abs)
44 0x95, 0x01, // REPORT_COUNT (1)
45 0x75, 0x03, // REPORT_SIZE (3)
46 0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
47 0x95, 0x06, // REPORT_COUNT (6)
48 0x75, 0x08, // REPORT_SIZE (8)
49 0x15, 0x00, // LOGICAL_MINIMUM (0)
50 0x25, 0x65, // LOGICAL_MAXIMUM (101)
51 0x05, 0x07, // USAGE_PAGE (Keyboard)
52 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
53 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
54 0x81, 0x00, // INPUT (Data,Ary,Abs)
55 0xc0 // END_COLLECTION
56 };
57 #define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
58
59
60 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
61 static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
62
63 /* Device descriptor */
64 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
65 0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x01,
67
68 /* Configuration descriptor */
69 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
70 0x32,
71
72 /* Interface descriptor */
73 0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
74 0x00,
75
76 /* HID descriptor */
77 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
78 MSB(HID_REPORT_LENGTH),
79
80 /* Endpoint descriptor (Interrupt) */
81 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
82
83 };
84
85
86 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
87 static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
88
89 /* Device descriptor */
90 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
91 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
92 0x03, 0x01,
93
94 /* Device qualifier descriptor */
95 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
96 0x01, 0x00,
97
98 /* Configuration descriptor */
99 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
100 0x32,
101
102 /* Interface descriptor */
103 0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
104 0x00,
105
106 /* HID descriptor */
107 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
108 MSB(HID_REPORT_LENGTH),
109
110 /* Endpoint descriptor (Interrupt) */
111 0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
112
113 };
114
115
116 /* String Device Framework :
117 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
118 Byte 2 : Byte containing the index of the descriptor
119 Byte 3 : Byte containing the length of the descriptor string
120 */
121
122 #define STRING_FRAMEWORK_LENGTH 40
123 static UCHAR string_framework[] = {
124
125 /* Manufacturer string descriptor : Index 1 */
126 0x09, 0x04, 0x01, 0x0c,
127 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
128 0x6f, 0x67, 0x69, 0x63,
129
130 /* Product string descriptor : Index 2 */
131 0x09, 0x04, 0x02, 0x0c,
132 0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
133 0x6f, 0x61, 0x72, 0x64,
134
135 /* Serial Number string descriptor : Index 3 */
136 0x09, 0x04, 0x03, 0x04,
137 0x30, 0x30, 0x30, 0x31
138 };
139
140
141 /* Multiple languages are supported on the device, to add
142 a language besides english, the unicode language code must
143 be appended to the language_id_framework array and the length
144 adjusted accordingly. */
145 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
146 static UCHAR language_id_framework[] = {
147
148 /* English. */
149 0x09, 0x04
150 };
151
152
153 UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
154
155
ux_system_host_change_function(ULONG a,UX_HOST_CLASS * b,VOID * c)156 static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
157 {
158 return 0;
159 }
160
error_callback(UINT system_level,UINT system_context,UINT error_code)161 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
162 {
163
164 /* Failed test. */
165 if (!error_is_expected)
166 {
167 /* Ignore protocol errors. */
168 if (error_code == UX_TRANSFER_STALLED)
169 return;
170
171 printf("Error on line %d, system_level: %d, system_context: %d, error code: 0x%x\n", __LINE__, system_level, system_context, error_code);
172 test_control_return(1);
173 }
174 }
175
demo_hid_instance_activate(VOID * inst)176 static VOID demo_hid_instance_activate(VOID *inst)
177 {
178 hid_device = (UX_SLAVE_CLASS_HID *)inst;
179 }
demo_hid_instance_deactivate(VOID * inst)180 static VOID demo_hid_instance_deactivate(VOID *inst)
181 {
182 if ((VOID *)hid_device == inst)
183 hid_device = UX_NULL;
184 }
185
186 /* Define what the initial system looks like. */
187
188 #ifdef CTEST
test_application_define(void * first_unused_memory)189 void test_application_define(void *first_unused_memory)
190 #else
191 void usbx_ux_device_class_hid_control_request_test_application_define(void *first_unused_memory)
192 #endif
193 {
194
195 UINT status;
196 CHAR * stack_pointer;
197 CHAR * memory_pointer;
198
199
200 /* Inform user. */
201 printf("Running ux_device_hid_control_request Test.......................... ");
202
203 /* Initialize the free memory pointer */
204 stack_pointer = (CHAR *) usbx_memory;
205 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
206
207 /* Initialize USBX. Memory */
208 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
209
210 /* Check for error. */
211 if (status != UX_SUCCESS)
212 {
213
214 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
215 test_control_return(1);
216 }
217
218 /* Register the error callback. */
219 _ux_utility_error_callback_register(error_callback);
220
221 /* The code below is required for installing the host portion of USBX */
222 status = ux_host_stack_initialize(ux_system_host_change_function);
223 if (status != UX_SUCCESS)
224 {
225
226 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
227 test_control_return(1);
228 }
229
230 status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
231 if (status != UX_SUCCESS)
232 {
233
234 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
235 test_control_return(1);
236 }
237
238 /* Register the HID client(s). */
239 status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
240 if (status != UX_SUCCESS)
241 {
242
243 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
244 test_control_return(1);
245 }
246
247 /* The code below is required for installing the device portion of USBX. No call back for
248 device status change in this example. */
249 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
250 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
251 string_framework, STRING_FRAMEWORK_LENGTH,
252 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
253 if(status!=UX_SUCCESS)
254 {
255
256 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
257 test_control_return(1);
258 }
259
260 /* Initialize the hid class parameters. */
261 hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
262 hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
263 hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
264 hid_parameter.ux_slave_class_hid_instance_activate = demo_hid_instance_activate;
265 hid_parameter.ux_slave_class_hid_instance_deactivate = demo_hid_instance_deactivate;
266
267 /* Initilize the device hid class. The class is connected with interface 2 */
268 status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
269 1,2, (VOID *)&hid_parameter);
270 if(status!=UX_SUCCESS)
271 {
272
273 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
274 test_control_return(1);
275 }
276
277 /* Initialize the simulated device controller. */
278 status = _ux_dcd_sim_slave_initialize();
279
280 /* Check for error. */
281 if (status != UX_SUCCESS)
282 {
283
284 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
285 test_control_return(1);
286 }
287
288 /* Register all the USB host controllers available in this system */
289 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
290
291 /* Check for error. */
292 if (status != UX_SUCCESS)
293 {
294
295 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
296 test_control_return(1);
297 }
298
299 /* Create the main host simulation thread. */
300 status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
301 stack_pointer, UX_DEMO_STACK_SIZE,
302 20, 20, 1, TX_AUTO_START);
303
304 /* Check for error. */
305 if (status != TX_SUCCESS)
306 {
307
308 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
309 test_control_return(1);
310 }
311
312 #if defined(UX_DEVICE_STANDALONE)
313
314 /* Create the main device simulation thread. */
315 status = tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
316 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
317 20, 20, 1, TX_AUTO_START);
318
319 /* Check for error. */
320 if (status != TX_SUCCESS)
321 {
322
323 printf("ERROR #%d, code 0x%x\n", __LINE__, status);
324 test_control_return(1);
325 }
326 #endif
327 }
328
329 #if defined(UX_DEVICE_STANDALONE)
tx_demo_thread_device_simulation_entry(ULONG arg)330 static void tx_demo_thread_device_simulation_entry(ULONG arg)
331 {
332 while(1)
333 {
334 ux_system_tasks_run();
335 tx_thread_relinquish();
336 }
337 }
338 #endif
339
demo_thread_hid_callback(UX_SLAVE_CLASS_HID * class,UX_SLAVE_CLASS_HID_EVENT * event)340 static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
341 {
342
343 UINT status;
344
345
346 if (set_report_test_started == 1)
347 {
348
349 status = ux_utility_memory_compare(event -> ux_device_class_hid_event_buffer, dummy_report, sizeof(dummy_report));
350 if (status != UX_SUCCESS)
351 {
352
353 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
354 test_control_return(1);
355 }
356 }
357
358 return(UX_SUCCESS);
359 }
360
tx_demo_thread_host_simulation_entry(ULONG arg)361 static void tx_demo_thread_host_simulation_entry(ULONG arg)
362 {
363
364 UINT status;
365 UX_ENDPOINT *control_endpoint;
366 UX_TRANSFER *transfer_request;
367 UX_HOST_CLASS_HID_KEYBOARD *keyboard;
368 UX_SLAVE_CLASS *slave_class;
369 ULONG idle_time;
370 ULONG report_id;
371 UX_SLAVE_CLASS_HID_EVENT hid_event;
372 UX_SLAVE_CLASS_HID *slave_hid;
373 UINT max_get_report_attempts = 5;
374
375
376 /* Find the HID class */
377 status = demo_class_hid_get();
378 if (status != UX_SUCCESS)
379 {
380
381 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
382 test_control_return(1);
383 }
384
385 /* Get the HID client */
386 hid_client = hid -> ux_host_class_hid_client;
387
388 /* Check if the instance of the keyboard is live */
389 while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
390 tx_thread_sleep(10);
391
392 /* Get the keyboard instance */
393 keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
394
395 /* Set idle time and report id. */
396 idle_time = 0;
397 report_id = 0;
398
399 /* Get the slave hid class and hid instance. */
400 slave_class = _ux_system_slave -> ux_system_slave_device.ux_slave_device_first_interface -> ux_slave_interface_class;
401 slave_hid = _ux_system_slave -> ux_system_slave_device.ux_slave_device_first_interface -> ux_slave_interface_class_instance;
402
403 /* Get the endpoint and transfer request. */
404 control_endpoint = &hid -> ux_host_class_hid_device -> ux_device_control_endpoint;
405 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
406
407 #if !defined(UX_DEVICE_STANDALONE)
408
409 /* Suspend the device interrupt thread so it doesn't get take reports,
410 thus preventing us from using a control transfer to get them. */
411 status = ux_utility_thread_suspend(&slave_class -> ux_slave_class_thread);
412 if (status != UX_SUCCESS)
413 {
414
415 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
416 test_control_return(1);
417 }
418 #else
419
420 /* Set HID state to EXIT, no IDLE/Event processing. */
421 slave_hid -> ux_device_class_hid_event_state = UX_STATE_EXIT;
422 tx_thread_sleep(1);
423 #endif
424
425 /* Set event buffer. */
426 event_buffer[0] = 0x01;
427 event_buffer[1] = 0x02;
428 event_buffer[2] = 0x03;
429 event_buffer[3] = 0x04;
430 event_buffer[4] = 0x05;
431 event_buffer[5] = 0x06;
432 event_buffer[6] = 0x07;
433 event_buffer[7] = 0x08;
434
435 /**************************************************/
436 /** Test case: 'case UX_DEVICE_CLASS_HID_COMMAND_GET_REPORT:' **/
437 /**************************************************/
438
439 /* Set the hid event. */
440 hid_event.ux_device_class_hid_event_length = sizeof(event_buffer);
441 ux_utility_memory_copy(hid_event.ux_device_class_hid_event_buffer, event_buffer, hid_event.ux_device_class_hid_event_length);
442
443 /* Add the event. */
444 status = ux_device_class_hid_event_set(slave_hid, &hid_event);
445 if (status != UX_SUCCESS)
446 {
447
448 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
449 test_control_return(1);
450 }
451
452 /* Create a transfer request for the GET_REPORT request. */
453 transfer_request -> ux_transfer_request_data_pointer = buffer;
454 transfer_request -> ux_transfer_request_requested_length = hid_event.ux_device_class_hid_event_length;
455 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_REPORT;
456 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
457 transfer_request -> ux_transfer_request_value = (UINT)((UX_HOST_CLASS_HID_REPORT_TYPE_INPUT << 8) | report_id);
458 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
459
460 /* Send request to HCD layer. */
461 status = ux_host_stack_transfer_request(transfer_request);
462 if (status != UX_SUCCESS)
463 {
464
465 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
466 test_control_return(1);
467 }
468
469 status = ux_utility_memory_compare(buffer, event_buffer, hid_event.ux_device_class_hid_event_length);
470 if (status != UX_SUCCESS)
471 {
472
473 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
474 test_control_return(1);
475 }
476
477 /**************************************************/
478 /** Test case: 'case UX_DEVICE_CLASS_HID_COMMAND_SET_REPORT:' **/
479 /**************************************************/
480
481 /* Create a transfer request for the SET_REPORT request. */
482 /* NOTE: Right now, the size of the dummy report must not be 8 bytes. This is due to a bug in sim_transaction_schedule(). Refer to bug file. */
483 transfer_request -> ux_transfer_request_data_pointer = dummy_report;
484 transfer_request -> ux_transfer_request_requested_length = sizeof(dummy_report);
485 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_REPORT;
486 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
487 transfer_request -> ux_transfer_request_value = (UINT)((UX_HOST_CLASS_HID_REPORT_TYPE_OUTPUT << 8) | report_id);
488 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
489
490 set_report_test_started = 1;
491
492 /* Send request to HCD layer. */
493 status = ux_host_stack_transfer_request(transfer_request);
494 if (status != UX_SUCCESS)
495 {
496
497 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
498 test_control_return(1);
499 }
500
501 /**************************************************/
502 /** Test case: 'case UX_DEVICE_CLASS_HID_COMMAND_GET_IDLE:' **/
503 /**************************************************/
504
505 /* Create a transfer request for the GET_IDLE request. */
506 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
507 transfer_request -> ux_transfer_request_requested_length = 0;
508 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_IDLE;
509 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
510 transfer_request -> ux_transfer_request_value = (UINT)((idle_time << 8) | report_id);
511 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
512
513 /* Send request to HCD layer. */
514 status = ux_host_stack_transfer_request(transfer_request);
515 if (status != UX_SUCCESS)
516 {
517
518 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
519 test_control_return(1);
520 }
521
522 /**************************************************/
523 /** Test case: 'case UX_DEVICE_CLASS_HID_COMMAND_SET_IDLE:' **/
524 /**************************************************/
525
526 /* Create a transfer request for the SET_IDLE request. */
527 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
528 transfer_request -> ux_transfer_request_requested_length = 0;
529 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_IDLE;
530 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
531 transfer_request -> ux_transfer_request_value = (UINT)((idle_time << 8) | report_id);
532 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
533
534 /* Send request to HCD layer. */
535 status = ux_host_stack_transfer_request(transfer_request);
536 if (status != UX_SUCCESS)
537 {
538
539 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
540 test_control_return(1);
541 }
542
543 /**************************************************/
544 /** Test case: 'case UX_DEVICE_CLASS_HID_COMMAND_GET_PROTOCOL:' **/
545 /**************************************************/
546
547 /* Default protocol should be report protocol. */
548 if (ux_device_class_hid_protocol_get(hid_device) != 1)
549 {
550
551 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
552 test_control_return(1);
553 }
554
555 /* Create a transfer request for the GET_PROTOCOL request. */
556 transfer_request -> ux_transfer_request_data_pointer = dummy_report;
557 transfer_request -> ux_transfer_request_requested_length = 1;
558 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_PROTOCOL;
559 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
560 transfer_request -> ux_transfer_request_value = 0;
561 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
562
563 /* Send request to HCD layer. */
564 dummy_report[0] = 0xFF;
565 status = ux_host_stack_transfer_request(transfer_request);
566 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
567 {
568
569 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
570 test_control_return(1);
571 }
572
573 /* Before protocol change it must be report protocol (1). */
574 if (status == UX_SUCCESS && dummy_report[0] != 1)
575 {
576
577 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
578 test_control_return(1);
579 }
580
581 /**************************************************/
582 /** Test case: 'case UX_DEVICE_CLASS_HID_COMMAND_SET_PROTOCOL:' **/
583 /**************************************************/
584
585 /* Create a transfer request for the SET_PROTOCOL request. */
586 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
587 transfer_request -> ux_transfer_request_requested_length = 0;
588 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_SET_PROTOCOL;
589 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
590 transfer_request -> ux_transfer_request_value = 0; /* boot report */
591 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
592
593 /* Send request to HCD layer. */
594 status = ux_host_stack_transfer_request(transfer_request);
595 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
596 {
597
598 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
599 test_control_return(1);
600 }
601
602 /* Protocol should be boot protocol. */
603 if (status == UX_SUCCESS &&
604 ux_device_class_hid_protocol_get(hid_device) != 0)
605 {
606
607 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
608 test_control_return(1);
609 }
610
611 /* Create a transfer request for the GET_PROTOCOL request. */
612 transfer_request -> ux_transfer_request_data_pointer = dummy_report;
613 transfer_request -> ux_transfer_request_requested_length = 1;
614 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_HID_GET_PROTOCOL;
615 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
616 transfer_request -> ux_transfer_request_value = 0;
617 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
618
619 /* Send request to HCD layer. */
620 dummy_report[0] = 0xFF;
621 status = ux_host_stack_transfer_request(transfer_request);
622 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
623 {
624
625 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
626 test_control_return(1);
627 }
628
629 /* After protocol change it must be boot device (0). */
630 if (status == UX_SUCCESS && dummy_report[0] != 0)
631 {
632
633 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
634 test_control_return(1);
635 }
636
637 /**************************************************/
638 /** Test case: 'default:' (unknown request) **/
639 /**************************************************/
640
641 /* Create a transfer request for the an unknown request. */
642 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
643 transfer_request -> ux_transfer_request_requested_length = 0;
644 transfer_request -> ux_transfer_request_function = 0xdeadbeef;
645 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
646 transfer_request -> ux_transfer_request_value = 0;
647 transfer_request -> ux_transfer_request_index = hid -> ux_host_class_hid_interface -> ux_interface_descriptor.bInterfaceNumber;
648
649 /* We expect error here */
650 error_is_expected = UX_TRUE;
651
652 /* Send request to HCD layer. */
653 status = ux_host_stack_transfer_request(transfer_request);
654 if (status == UX_SUCCESS)
655 {
656
657 printf("Error on line %d, report error expected here\n", __LINE__);
658 test_control_return(1);
659 }
660 error_is_expected = UX_FALSE;
661
662 /* Now disconnect the device. */
663 _ux_device_stack_disconnect();
664
665 /* And deinitialize the class. */
666 status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
667
668 /* Deinitialize the device side of usbx. */
669 _ux_device_stack_uninitialize();
670
671 /* And finally the usbx system resources. */
672 _ux_system_uninitialize();
673
674 /* Successful test. */
675 printf("SUCCESS!\n");
676 test_control_return(0);
677 }
678