1 /* This file tests that the host correctly receives the keys the device sends to it. */
2 
3 #include "usbx_test_common_hid.h"
4 
5 #include "ux_host_class_hid_keyboard.h"
6 
7 #define HOST_WAIT_TIME  1
8 #define SLAVE_WAIT_TIME (6*HOST_WAIT_TIME)
9 
10 #ifndef UX_HID_KEYBOARD_PHANTOM_STATE
11 #define UX_HID_KEYBOARD_PHANTOM_STATE 0x01
12 #endif
13 #define KEY_START (UX_HID_KEYBOARD_PHANTOM_STATE+1)
14 
15 static UCHAR ux_host_class_hid_keyboard_regular_array[] =
16 {
17    0,0,0,0,
18    'a','b','c','d','e','f','g','h','i','j','k','l','m','n',
19    'o','p','q','r','s','t','u','v','w','x','y','z',
20    '1','2','3','4','5','6','7','8','9','0',
21    0x0d,0x1b,0x08,0x07,0x20,'-','=','[',']',
22    '\\','#',';',0x27,'`',',','.','/',0xf0,
23    0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,
24    0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2,
25    '/','*','-','+',
26    0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
27    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
28 };
29 
30 static UCHAR ux_host_class_hid_keyboard_capslock_array[] =
31 {
32    0,0,0,0,
33    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
34    '1','2','3','4','5','6','7','8','9','0',
35    0x0d,0x1b,0x08,0x07,0x20,'-','=','[',']',
36    '\\','#',';',0x27,'`',',','.','/',0xf0,
37    0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,
38    0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2,
39    '/','*','-','+',
40    0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
41    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42 };
43 
44 static UCHAR ux_host_class_hid_keyboard_shift_array[] =
45 {
46    0,0,0,0,
47    'A','B','C','D','E','F','G','H','I','J','K','L','M','N',
48    'O','P','Q','R','S','T','U','V','W','X','Y','Z',
49    '!','@','#','$','%','^','&','*','(',')',
50    0x0d,0x1b,0x08,0x07,0x20,'_','+','{','}',
51    '|','~',':','"','~','<','>','?',0xf0,
52    0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,
53    0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2,
54    '/','*','-','+',
55    0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
56    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
57 };
58 
59 static UCHAR ux_host_class_hid_keyboard_shift_capslock_array[] =
60 {
61    0,0,0,0,
62    'a','b','c','d','e','f','g','h','i','j', 'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
63    '!','@','#','$','%','^','&','*','(',')',
64    0x0d,0x1b,0x08,0x07,0x20,'_','+','{','}',
65    '|','~',':','"','~','<','>','?',0xf0,
66    0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,
67    0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcb,0xd0,0xc8,0xf2,
68    '/','*','-','+',
69    0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
70    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
71 };
72 
73 static UCHAR ux_host_class_hid_keyboard_numlock_on_array[] =
74 {
75    '/','*','-','+',
76    0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
77 };
78 
79 static UCHAR ux_host_class_hid_keyboard_numlock_off_array[] =
80 {
81    '/','*','-','+',
82    0x0d,0xcf,0xd0,0xd1,0xcb,'5',0xcd,0xc7,0xc8,0xc9,0xd2,0xd3,'\\',0x00,0x00,'=',
83 };
84 
85 
86 #define DUMMY_USBX_MEMORY_SIZE (64*1024)
87 static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
88 
89 static volatile ULONG test_host_phase = 0;
90 static volatile ULONG test_slave_phase = 0;
91 
92 static UCHAR hid_report_descriptor[] = {
93 
94     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
95     0x09, 0x06,                    // USAGE (Keyboard)
96     0xa1, 0x01,                    // COLLECTION (Application)
97     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
98     0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
99     0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
100     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
101     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
102     0x75, 0x01,                    //   REPORT_SIZE (1)
103     0x95, 0x08,                    //   REPORT_COUNT (8)
104     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
105     0x95, 0x01,                    //   REPORT_COUNT (1)
106     0x75, 0x08,                    //   REPORT_SIZE (8)
107     0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
108     0x95, 0x05,                    //   REPORT_COUNT (5)
109     0x75, 0x01,                    //   REPORT_SIZE (1)
110     0x05, 0x08,                    //   USAGE_PAGE (LEDs)
111     0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
112     0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
113     0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
114     0x95, 0x01,                    //   REPORT_COUNT (1)
115     0x75, 0x03,                    //   REPORT_SIZE (3)
116     0x91, 0x03,                    //   OUTPUT (Cnst,Var,Abs)
117     0x95, 0x06,                    //   REPORT_COUNT (6)
118     0x75, 0x08,                    //   REPORT_SIZE (8)
119     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
120     0x25, ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array) + 1,  //   LOGICAL_MAXIMUM ()
121     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
122     0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
123     0x29, ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array) + 1,  //   USAGE_MAXIMUM ()
124     0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
125     0xc0                           // END_COLLECTION
126 };
127 #define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
128 
129 
130 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
131 static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
132 
133     /* Device descriptor */
134         0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
135         0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
136         0x00, 0x01,
137 
138     /* Configuration descriptor */
139         0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
140         0x32,
141 
142     /* Interface descriptor */
143         0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
144         0x00,
145 
146     /* HID descriptor */
147         0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
148         MSB(HID_REPORT_LENGTH),
149 
150     /* Endpoint descriptor (Interrupt) */
151         0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
152 
153     };
154 
155 
156 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
157 static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
158 
159     /* Device descriptor */
160         0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
161         0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
162         0x03, 0x01,
163 
164     /* Device qualifier descriptor */
165         0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
166         0x01, 0x00,
167 
168     /* Configuration descriptor */
169         0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
170         0x32,
171 
172     /* Interface descriptor */
173         0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
174         0x00,
175 
176     /* HID descriptor */
177         0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
178         MSB(HID_REPORT_LENGTH),
179 
180     /* Endpoint descriptor (Interrupt) */
181         0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
182 
183     };
184 
185 
186     /* String Device Framework :
187      Byte 0 and 1 : Word containing the language ID : 0x0904 for US
188      Byte 2       : Byte containing the index of the descriptor
189      Byte 3       : Byte containing the length of the descriptor string
190     */
191 
192 #define STRING_FRAMEWORK_LENGTH 40
193 static UCHAR string_framework[] = {
194 
195     /* Manufacturer string descriptor : Index 1 */
196         0x09, 0x04, 0x01, 0x0c,
197         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
198         0x6f, 0x67, 0x69, 0x63,
199 
200     /* Product string descriptor : Index 2 */
201         0x09, 0x04, 0x02, 0x0c,
202         0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
203         0x6f, 0x61, 0x72, 0x64,
204 
205     /* Serial Number string descriptor : Index 3 */
206         0x09, 0x04, 0x03, 0x04,
207         0x30, 0x30, 0x30, 0x31
208     };
209 
210 
211     /* Multiple languages are supported on the device, to add
212        a language besides english, the unicode language code must
213        be appended to the language_id_framework array and the length
214        adjusted accordingly. */
215 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
216 static UCHAR language_id_framework[] = {
217 
218     /* English. */
219         0x09, 0x04
220     };
221 
222 
223 UINT  _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
224 
225 
ux_system_host_change_function(ULONG a,UX_HOST_CLASS * b,VOID * c)226 static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
227 {
228     return 0;
229 }
230 
error_callback(UINT system_level,UINT system_context,UINT error_code)231 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
232 {
233 
234     /* @BUG_FIX_PENDING: ux_dcd_sim_slave_function.c doesn't support transfer aborts, which happen during device unregistration of a class. */
235     if (error_code != UX_FUNCTION_NOT_SUPPORTED &&
236         error_code != UX_BUFFER_OVERFLOW /* Key queue overflow! */)
237     {
238 
239         /* Failed test.  */
240         printf("Error on line %d, system_level: %d, system_context: %d, error code: 0x%x\n", __LINE__, system_level, system_context, error_code);
241         test_control_return(1);
242     }
243 }
244 
245 /* Define what the initial system looks like.  */
246 
247 #ifdef CTEST
test_application_define(void * first_unused_memory)248 void test_application_define(void *first_unused_memory)
249 #else
250 void    usbx_hid_keyboard_key_test_application_define(void *first_unused_memory)
251 #endif
252 {
253 
254 UINT status;
255 CHAR *                          stack_pointer;
256 CHAR *                          memory_pointer;
257 
258 
259     /* Inform user.  */
260     printf("Running HID Keyboard Key Test....................................... ");
261 
262     /* Initialize the free memory pointer */
263     stack_pointer = (CHAR *) usbx_memory;
264     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
265 
266     /* Initialize USBX. Memory */
267     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
268 
269     /* Check for error.  */
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     /* Register the error callback. */
278     _ux_utility_error_callback_register(error_callback);
279 
280     /* The code below is required for installing the host portion of USBX */
281     status =  ux_host_stack_initialize(ux_system_host_change_function);
282     if (status != UX_SUCCESS)
283     {
284 
285         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
286         test_control_return(1);
287     }
288 
289     status =  ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
290     if (status != UX_SUCCESS)
291     {
292 
293         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
294         test_control_return(1);
295     }
296 
297     /* Register the HID client(s).  */
298     status =  ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
299     if (status != UX_SUCCESS)
300     {
301 
302         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
303         test_control_return(1);
304     }
305 
306     /* The code below is required for installing the device portion of USBX. No call back for
307        device status change in this example. */
308     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
309                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
310                                        string_framework, STRING_FRAMEWORK_LENGTH,
311                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
312     if(status!=UX_SUCCESS)
313     {
314 
315         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
316         test_control_return(1);
317     }
318 
319     /* Initialize the hid class parameters.  */
320     hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
321     hid_parameter.ux_device_class_hid_parameter_report_length  = HID_REPORT_LENGTH;
322     hid_parameter.ux_device_class_hid_parameter_callback       = demo_thread_hid_callback;
323 
324     /* Initialize the device hid class. The class is connected with interface 2 */
325     status =  ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
326                                                 1,2, (VOID *)&hid_parameter);
327     if(status!=UX_SUCCESS)
328     {
329 
330         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
331         test_control_return(1);
332     }
333 
334     /* Initialize the simulated device controller.  */
335     status =  _ux_dcd_sim_slave_initialize();
336 
337     /* Check for error.  */
338     if (status != UX_SUCCESS)
339     {
340 
341         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
342         test_control_return(1);
343     }
344 
345     /* Register all the USB host controllers available in this system */
346     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
347 
348     /* Check for error.  */
349     if (status != UX_SUCCESS)
350     {
351 
352         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
353         test_control_return(1);
354     }
355 
356     /* Create the main host simulation thread.  */
357     status =  tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
358             stack_pointer, UX_DEMO_STACK_SIZE,
359             20, 20, 1, TX_AUTO_START);
360 
361     /* Check for error.  */
362     if (status != TX_SUCCESS)
363     {
364 
365         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
366         test_control_return(1);
367     }
368 
369     /* Create the main demo thread.  */
370     status =  tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
371             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
372             20, 20, 1, TX_AUTO_START);
373 
374     /* Check for error.  */
375     if (status != TX_SUCCESS)
376     {
377 
378         printf("Running HID Keyboard Basic Functionality Test....................... ERROR #10\n");
379         test_control_return(1);
380     }
381 
382 }
383 
384 
_wait_key(UX_HOST_CLASS_HID_KEYBOARD * keyboard,ULONG * keyboard_key,ULONG * keyboard_state)385 static UINT  _wait_key(UX_HOST_CLASS_HID_KEYBOARD *keyboard, ULONG *keyboard_key, ULONG *keyboard_state)
386 {
387 
388 UINT        status;
389 UINT        i;
390 
391 
392     for(i = 0; i < 200; i ++)
393     {
394         status = ux_host_class_hid_keyboard_key_get(keyboard, keyboard_key, keyboard_state);
395         if (status == UX_SUCCESS)
396         {
397             // printf("Key: %lx,%lx\n", *keyboard_key, *keyboard_state);
398 
399 #if defined(UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_LOCK_KEYS) || defined(UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_MODIFIER_KEYS)
400             if (*keyboard_state & UX_HID_KEYBOARD_STATE_FUNCTION)
401                 continue;
402 #endif
403 
404 #if !defined(UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_KEY_DOWN_ONLY)
405             if (*keyboard_state & UX_HID_KEYBOARD_STATE_KEY_UP)
406                 continue;
407 #endif
408             return UX_SUCCESS;
409         }
410         _ux_utility_delay_ms(1);
411     }
412     return UX_ERROR;
413 }
414 
415 
tx_demo_phase_sync(ULONG in_host,ULONG nb_loop,ULONG tick_in_loop)416 static UINT  tx_demo_phase_sync(ULONG in_host, ULONG nb_loop, ULONG tick_in_loop)
417 {
418 
419 ULONG i;
420 
421 
422     for (i = 0; i < nb_loop; i ++)
423     {
424         if (in_host)
425         {
426             if (test_host_phase <= test_slave_phase)
427                 return UX_SUCCESS;
428         }
429         else
430         {
431             if (test_slave_phase <= test_host_phase)
432                 return UX_SUCCESS;
433         }
434         _ux_utility_thread_sleep(tick_in_loop);
435     }
436     return UX_ERROR;
437 }
438 
tx_demo_thread_host_simulation_entry(ULONG arg)439 static void  tx_demo_thread_host_simulation_entry(ULONG arg)
440 {
441 
442 UINT                            status;
443 UX_HOST_CLASS_HID_KEYBOARD      *keyboard;
444 ULONG                           keyboard_key;
445 ULONG                           keyboard_state;
446 ULONG                           expected_key;
447 ULONG                           num_keypad_keys;
448 ULONG                           i, n;
449 UCHAR                           *test_array[4] = {
450     ux_host_class_hid_keyboard_regular_array,
451     ux_host_class_hid_keyboard_shift_array,
452     ux_host_class_hid_keyboard_capslock_array,
453     ux_host_class_hid_keyboard_shift_capslock_array
454 };
455 
456     /* Find the HID class */
457     status = demo_class_hid_get();
458     if (status != UX_SUCCESS)
459     {
460 
461         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
462         test_control_return(1);
463     }
464 
465     /* Get the HID client */
466     hid_client = hid -> ux_host_class_hid_client;
467 
468     /* Check if the instance of the keyboard is live */
469     while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
470         tx_thread_sleep(10);
471 
472     /* Get the keyboard instance */
473     keyboard =  (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
474 
475     /**************************************************************************/
476     /** 1. Test receiving maximum keys at once.                              **/
477     test_host_phase ++;
478     // printf("###### host step: %ld ######\n", test_host_phase);
479 
480     for (i = 4; i < 10; i++)
481     {
482 
483         status = _wait_key(keyboard, &keyboard_key, &keyboard_state);
484         if (status != UX_SUCCESS)
485         {
486             printf("ERROR #%d: code 0x%x\n", __LINE__, status);
487             test_control_return(1);
488         }
489 
490         expected_key = ux_host_class_hid_keyboard_regular_array[i];
491 
492         if (keyboard_key != expected_key)
493         {
494 
495             printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
496             test_control_return(1);
497         }
498     }
499 
500     /**************************************************************************/
501     /** 2. Test keys.                                                        **/
502     test_host_phase ++;
503     // printf("###### host step: %ld ######\n", test_host_phase);
504 
505     for (n = 0; n < 4; n ++)
506     {
507         for (i = KEY_START; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
508         {
509 
510             /* These keys change the keyboard state and are not retrievable. */
511             if (i == UX_HID_LED_KEY_CAPS_LOCK ||
512                 i == UX_HID_LED_KEY_NUM_LOCK ||
513                 i == UX_HID_LED_KEY_SCROLL_LOCK)
514                 continue;
515 
516             status = _wait_key(keyboard, &keyboard_key, &keyboard_state);
517             if (status != UX_SUCCESS)
518             {
519                 printf("ERROR #%d: code 0x%x\n", __LINE__, status);
520                 test_control_return(1);
521             }
522 
523             // printf("test key: %lx @ %lx\n", keyboard_key, keyboard_state);
524             expected_key = test_array[n][i];
525 
526             if (keyboard_key != expected_key)
527             {
528 
529                 printf("Error on line %d, test %ld.%ld, state 0x%lx, key 0x%lx <> 0x%lx\n", __LINE__, n, i, keyboard_state, expected_key, keyboard_key);
530                 test_control_return(1);
531             }
532         }
533     }
534 
535     /**************************************************************************/
536     /** 3. Test number pad keys.                                             **/
537     test_host_phase ++;
538     // printf("###### host step: %ld ######\n", test_host_phase);
539 
540     /** Test numlock on keys.                                                **/
541 
542     num_keypad_keys = (UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE - UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE) + 1;
543 
544     for (i = 0; i < ARRAY_COUNT(ux_host_class_hid_keyboard_numlock_on_array); i++)
545     {
546 
547         status = _wait_key(keyboard, &keyboard_key, &keyboard_state);
548         if (status != UX_SUCCESS)
549         {
550             printf("ERROR #%d: code 0x%x\n", __LINE__, status);
551             test_control_return(1);
552         }
553 
554         expected_key = ux_host_class_hid_keyboard_numlock_on_array[i];
555 
556         if (keyboard_key != ux_host_class_hid_keyboard_numlock_on_array[i])
557         {
558 
559             printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
560             test_control_return(1);
561         }
562     }
563 
564     /** Test numlock off keys. **/
565 
566     for (i = 0; i < ARRAY_COUNT(ux_host_class_hid_keyboard_numlock_off_array); i++)
567     {
568 
569         status = _wait_key(keyboard, &keyboard_key, &keyboard_state);
570         if (status != UX_SUCCESS)
571         {
572             printf("ERROR #%d: code 0x%x\n", __LINE__, status);
573             test_control_return(1);
574         }
575 
576         // printf("test key: %lx @ %lx\n", keyboard_key, keyboard_state);
577 
578         expected_key = ux_host_class_hid_keyboard_numlock_off_array[i];
579 
580         if (keyboard_key != ux_host_class_hid_keyboard_numlock_off_array[i])
581         {
582 
583             printf("Error on line %d, test %ld, state 0x%lx, key 0x%lx <> 0x%lx\n", __LINE__, i, keyboard_state, expected_key, keyboard_key);
584             test_control_return(1);
585         }
586     }
587 
588     /**************************************************************************/
589     /** 4. Test states.                                                      **/
590     test_host_phase ++;
591     // printf("###### host step: %ld ######\n", test_host_phase);
592 
593     /** Test keyboard on states. **/
594 
595     status = _wait_key(keyboard, &keyboard_key, &keyboard_state);
596     if (status != UX_SUCCESS)
597     {
598         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
599         test_control_return(1);
600     }
601 
602     /* Ensure every bit is enabled (represented by 0xff07 (search for "Define HID Keyboard States." in ux_host_class_hid_keyboard.h)). */
603     if ((keyboard_state & 0xFFFF) != 0xff07)
604     {
605 
606         printf("Error on line %d, test %ld.%ld, state 0x%lx\n", __LINE__, n, i, keyboard_state);
607         test_control_return(1);
608     }
609 
610     /** Test keyboard off states. **/
611 
612     status = _wait_key(keyboard, &keyboard_key, &keyboard_state);
613     if (status != UX_SUCCESS)
614     {
615         printf("ERROR #%d: code 0x%x\n", __LINE__, status);
616         test_control_return(1);
617     }
618 
619     /* Ensure every bit is disabled. */
620     if ((keyboard_state & 0xFFFF) != 0x0000)
621     {
622 
623         printf("Error on line %d, test %ld.%ld, state 0x%lx\n", __LINE__, n, i, keyboard_state);
624         test_control_return(1);
625     }
626 
627     /**************************************************************************/
628     /** 5. Test raw key.                                                     **/
629 
630     /* Disable decode. */
631     ux_host_class_hid_keyboard_ioctl(keyboard, UX_HID_KEYBOARD_IOCTL_DISABLE_KEYS_DECODE, UX_NULL);
632     test_host_phase ++;
633     // printf("###### host step: %ld ######\n", test_host_phase);
634 
635     for (i = KEY_START; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
636     {
637 #if 0
638         /* These keys change the keyboard state and are not retrievable. */
639         if (i == UX_HID_LED_KEY_CAPS_LOCK ||
640             i == UX_HID_LED_KEY_NUM_LOCK ||
641             i == UX_HID_LED_KEY_SCROLL_LOCK)
642             continue;
643 #endif
644 
645         status = _wait_key(keyboard, &keyboard_key, &keyboard_state);
646         if (status != UX_SUCCESS)
647         {
648             printf("ERROR #%d: code 0x%x\n", __LINE__, status);
649             test_control_return(1);
650         }
651 
652         expected_key = i;
653 
654         if (keyboard_key != expected_key)
655         {
656 
657             printf("Error on line %d, test %ld, 0x%lx <> 0x%lx\n", __LINE__, i, expected_key, keyboard_key);
658             // test_control_return(1);
659         }
660     }
661 
662     /**************************************************************************/
663     /** 6. Test invalid key.                                                 **/
664 
665     /* Enable decode. */
666     ux_host_class_hid_keyboard_ioctl(keyboard, UX_HID_KEYBOARD_IOCTL_ENABLE_KEYS_DECODE, UX_NULL);
667     test_host_phase ++;
668     // printf("###### host step: %ld ######\n", test_host_phase);
669 
670     /* Wait slave execute. */
671     if (tx_demo_phase_sync(UX_TRUE, 10, SLAVE_WAIT_TIME) != UX_SUCCESS)
672     {
673         printf("Error in line %d, thread phase error %ld <> %ld!\n", __LINE__, test_host_phase, test_slave_phase);
674         test_control_return(1);
675     }
676 
677     /* Wait a invalid key (discarded). */
678     ux_utility_thread_sleep(HOST_WAIT_TIME * 2);
679 
680     /**************************************************************************/
681     /** 7. Test key array overflow.                                          **/
682 
683     /* Flush keys.  */
684     do {
685         status = ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state);
686     } while(status == UX_SUCCESS);
687 
688     /* No read, test array full. */
689     ux_host_class_hid_keyboard_ioctl(keyboard, UX_HID_KEYBOARD_IOCTL_DISABLE_KEYS_DECODE, UX_NULL);
690     test_host_phase ++;
691     // printf("###### host step: %ld ######\n", test_host_phase);
692 
693     /* Wait until test done. */
694     while(test_slave_phase != 0)
695         _ux_utility_delay_ms(10);
696 
697     /* There are keys remain in key array. */
698     for (i = 0; i < UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH / 2 - 1; i ++)
699     {
700 
701         status = ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state);
702         if(status != UX_SUCCESS)
703         {
704             printf("Error on line %d.%ld, error code 0x%x\n", __LINE__, i, status);
705             test_control_return(1);
706         }
707         if (keyboard_key != 5)
708         {
709             printf("Error on line %d, key 0x%lx,0x%lx @ %ld\n", __LINE__, keyboard_key, keyboard_state, i);
710             test_control_return(1);
711         }
712     }
713     status = ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state);
714     if(status == UX_SUCCESS)
715     {
716         printf("Error on line %d, error code 0x%x\n", __LINE__, status);
717     }
718 
719     /* Now disconnect the device.  */
720     _ux_device_stack_disconnect();
721 
722     /* And deinitialize the class.  */
723     status =  ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
724 
725     /* Deinitialize the device side of usbx.  */
726     _ux_device_stack_uninitialize();
727 
728     /* And finally the usbx system resources.  */
729     _ux_system_uninitialize();
730 
731     /* Successful test.  */
732     printf("SUCCESS!\n");
733     test_control_return(0);
734 }
735 
demo_thread_hid_callback(UX_SLAVE_CLASS_HID * class,UX_SLAVE_CLASS_HID_EVENT * event)736 static UINT    demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
737 {
738     return(UX_SUCCESS);
739 }
740 
tx_demo_thread_slave_simulation_entry(ULONG arg)741 static void  tx_demo_thread_slave_simulation_entry(ULONG arg)
742 {
743 
744 UINT                            status;
745 UX_SLAVE_DEVICE                 *device;
746 UX_SLAVE_INTERFACE              *interface;
747 UX_SLAVE_CLASS_HID              *hid;
748 UX_SLAVE_CLASS_HID_EVENT        hid_event;
749 UINT                            i, n;
750 UCHAR                           state_modifier[2] = {0, (0x01 << 1)};
751 
752     /* Get the pointer to the device.  */
753     device =  &_ux_system_slave -> ux_system_slave_device;
754 
755     /* reset the HID event structure.  */
756     ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
757 
758     /* Is the device configured ? */
759     while (device->ux_slave_device_state != UX_DEVICE_CONFIGURED)
760 
761         /* Then wait.  */
762         tx_thread_sleep(10);
763 
764     /* Get the interface.  We use the first interface, this is a simple device.  */
765     interface = device->ux_slave_device_first_interface;
766 
767     /* Form that interface, derive the HID owner.  */
768     hid = interface->ux_slave_interface_class_instance;
769 
770     /**************************************************************************/
771     /** 1. Test receiving maximum keys at once.  **/
772     test_slave_phase ++;
773     // printf("****** slave step: %ld ******\n", test_slave_phase);
774 
775     hid_event.ux_device_class_hid_event_length = 8;
776 
777     /* Modification byte. */
778     hid_event.ux_device_class_hid_event_buffer[0] = 0;
779 
780     /* Reserved byte. */
781     hid_event.ux_device_class_hid_event_buffer[1] = 0;
782 
783     /* Set keys. */
784     for (i = 0; i < 6; i++)
785         hid_event.ux_device_class_hid_event_buffer[2 + i] = 4 + i;
786 
787     ux_device_class_hid_event_set(hid, &hid_event);
788 #if 0
789     /* Release keys. */
790     for (i = 0; i < 6; i++)
791         hid_event.ux_device_class_hid_event_buffer[2 + i] = 0;
792 
793     ux_device_class_hid_event_set(hid, &hid_event);
794 #endif
795     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
796 
797     /* Reset for next test. */
798     ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
799 
800     /**************************************************************************/
801     /** 2. Test keys.                                                        **/
802     test_slave_phase ++;
803     // printf("****** slave step: %ld ******\n", test_slave_phase);
804 
805     /** Test regular keys with/without SHIFT. Only go up to maximum value specified by report descriptor. **/
806 
807     for (n = 0; n < 2; n ++)
808     {
809 
810         for (i = KEY_START; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
811         {
812 
813             /* These keys change the keyboard state and are not retrievable. */
814             if (i == UX_HID_LED_KEY_CAPS_LOCK ||
815                 i == UX_HID_LED_KEY_NUM_LOCK ||
816                 i == UX_HID_LED_KEY_SCROLL_LOCK)
817                 continue;
818 
819             hid_event.ux_device_class_hid_event_length = 8;
820 
821             /* Modification byte. */
822             hid_event.ux_device_class_hid_event_buffer[0] = state_modifier[n];
823 
824             /* Reserved byte. */
825             hid_event.ux_device_class_hid_event_buffer[1] = 0;
826 
827             /* Key byte. */
828             hid_event.ux_device_class_hid_event_buffer[2] = i;
829 
830             status = ux_device_class_hid_event_set(hid, &hid_event);
831             if (status != UX_SUCCESS)
832             {
833 
834                 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
835                 test_control_return(1);
836             }
837 
838             ux_utility_thread_sleep(SLAVE_WAIT_TIME);
839         }
840 
841     }
842     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
843 
844     /** Test CAPS LOCK with/without SHIFT keys. Only go up to maximum value specified by report descriptor. **/
845 
846     /* Turn CAPS LOCK on. */
847     hid_event.ux_device_class_hid_event_length = 8;
848     hid_event.ux_device_class_hid_event_buffer[0] = 0;
849     hid_event.ux_device_class_hid_event_buffer[1] = 0;
850     hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
851     status = ux_device_class_hid_event_set(hid, &hid_event);
852     if (status != UX_SUCCESS)
853     {
854 
855         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
856         test_control_return(1);
857     }
858 
859     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
860 
861     for (n = 0; n < 2; n ++)
862     {
863 
864         for (i = KEY_START; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
865         {
866 
867             /* These keys change the keyboard state and are not retrievable. */
868             if (i == UX_HID_LED_KEY_CAPS_LOCK ||
869                 i == UX_HID_LED_KEY_NUM_LOCK ||
870                 i == UX_HID_LED_KEY_SCROLL_LOCK)
871                 continue;
872 
873             hid_event.ux_device_class_hid_event_length = 8;
874 
875             /* Modification byte. */
876             hid_event.ux_device_class_hid_event_buffer[0] = state_modifier[n];
877 
878             /* Reserved byte. */
879             hid_event.ux_device_class_hid_event_buffer[1] = 0;
880 
881             /* Key byte. */
882             hid_event.ux_device_class_hid_event_buffer[2] = i;
883 
884             status = ux_device_class_hid_event_set(hid, &hid_event);
885             if (status != UX_SUCCESS)
886             {
887 
888                 /* ERROR */
889                 printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
890                 test_control_return(1);
891             }
892 
893             ux_utility_thread_sleep(SLAVE_WAIT_TIME);
894         }
895     }
896     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
897 
898     /* Turn CAPS LOCK off. */
899     hid_event.ux_device_class_hid_event_length = 8;
900     hid_event.ux_device_class_hid_event_buffer[0] = 0;
901     hid_event.ux_device_class_hid_event_buffer[1] = 0;
902     hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
903     status = ux_device_class_hid_event_set(hid, &hid_event);
904     if (status != UX_SUCCESS)
905     {
906 
907         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
908         test_control_return(1);
909     }
910 
911     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
912 
913     /**************************************************************************/
914     /** 3. Test num pad keys.                                                **/
915     test_slave_phase ++;
916     // printf("****** slave step: %ld ******\n", test_slave_phase);
917 
918     /** Test NUM LOCK on keys. NUM LOCK is on by default. **/
919 
920     for (i = UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE; i <= UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE; i++)
921     {
922 
923         hid_event.ux_device_class_hid_event_length = 8;
924 
925         /* Modification byte. */
926         hid_event.ux_device_class_hid_event_buffer[0] = 0;
927 
928         /* Reserved byte. */
929         hid_event.ux_device_class_hid_event_buffer[1] = 0;
930 
931         /* Key byte. */
932         hid_event.ux_device_class_hid_event_buffer[2] = i;
933 
934         status = ux_device_class_hid_event_set(hid, &hid_event);
935         if (status != UX_SUCCESS)
936         {
937 
938             printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
939             test_control_return(1);
940         }
941 
942         ux_utility_thread_sleep(SLAVE_WAIT_TIME);
943     }
944     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
945 
946     /** Test NUM LOCK off keys. **/
947 
948     /* Turn NUM LOCK off. */
949     hid_event.ux_device_class_hid_event_length = 8;
950     hid_event.ux_device_class_hid_event_buffer[0] = 0;
951     hid_event.ux_device_class_hid_event_buffer[1] = 0;
952     hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_NUM_LOCK;
953     ux_device_class_hid_event_set(hid, &hid_event);
954 
955     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
956 
957     for (i = UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE; i <= UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE; i++)
958     {
959 
960         hid_event.ux_device_class_hid_event_length = 8;
961 
962         /* Modification byte. */
963         hid_event.ux_device_class_hid_event_buffer[0] = 0;
964 
965         /* Reserved byte. */
966         hid_event.ux_device_class_hid_event_buffer[1] = 0;
967 
968         /* Key byte. */
969         hid_event.ux_device_class_hid_event_buffer[2] = i;
970 
971         status = ux_device_class_hid_event_set(hid, &hid_event);
972         if (status != UX_SUCCESS)
973         {
974 
975             printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
976             test_control_return(1);
977         }
978 
979         ux_utility_thread_sleep(SLAVE_WAIT_TIME);
980     }
981     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
982 
983     /* Turn NUM LOCK on. */
984     hid_event.ux_device_class_hid_event_length = 8;
985     hid_event.ux_device_class_hid_event_buffer[0] = 0;
986     hid_event.ux_device_class_hid_event_buffer[1] = 0;
987     hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_NUM_LOCK;
988     status = ux_device_class_hid_event_set(hid, &hid_event);
989     if (status != UX_SUCCESS)
990     {
991 
992         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
993         test_control_return(1);
994     }
995 
996     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
997 
998     /**************************************************************************/
999     /** 4. Test states.                                                      **/
1000     test_slave_phase ++;
1001     // printf("****** slave step: %ld ******\n", test_slave_phase);
1002 
1003     /** Test key states. **/
1004 
1005     /* Enable every bit in key state. */
1006     hid_event.ux_device_class_hid_event_length = 8;
1007     hid_event.ux_device_class_hid_event_buffer[0] = 0xff;
1008     hid_event.ux_device_class_hid_event_buffer[1] = 0;
1009     hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
1010     hid_event.ux_device_class_hid_event_buffer[3] = UX_HID_LED_KEY_SCROLL_LOCK;
1011     hid_event.ux_device_class_hid_event_buffer[4] = UX_HID_LED_KEY_NUM_LOCK;
1012 
1013     status = ux_device_class_hid_event_set(hid, &hid_event);
1014     if (status != UX_SUCCESS)
1015     {
1016 
1017         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1018         test_control_return(1);
1019     }
1020 
1021     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1022 
1023     /* Add a key so the host can receive it, allowing checking of key state. */
1024     hid_event.ux_device_class_hid_event_length = 8;
1025     hid_event.ux_device_class_hid_event_buffer[0] = 0xff;
1026     hid_event.ux_device_class_hid_event_buffer[1] = 0;
1027     hid_event.ux_device_class_hid_event_buffer[2] = 0;
1028     hid_event.ux_device_class_hid_event_buffer[3] = 0;
1029     hid_event.ux_device_class_hid_event_buffer[4] = 0x04;
1030 
1031     status = ux_device_class_hid_event_set(hid, &hid_event);
1032     if (status != UX_SUCCESS)
1033     {
1034 
1035         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1036         test_control_return(1);
1037     }
1038 
1039     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1040 
1041     /** Test key states. **/
1042 
1043     /* Disable every bit in key state. */
1044     hid_event.ux_device_class_hid_event_length = 8;
1045     hid_event.ux_device_class_hid_event_buffer[0] = 0x00;
1046     hid_event.ux_device_class_hid_event_buffer[1] = 0;
1047     hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
1048     hid_event.ux_device_class_hid_event_buffer[3] = UX_HID_LED_KEY_SCROLL_LOCK;
1049     hid_event.ux_device_class_hid_event_buffer[4] = UX_HID_LED_KEY_NUM_LOCK;
1050 
1051     /* Add a different key so the host can receive it, allowing checking of key state. */
1052     hid_event.ux_device_class_hid_event_buffer[5] = 0x05;
1053 
1054     status = ux_device_class_hid_event_set(hid, &hid_event);
1055     if (status != UX_SUCCESS)
1056     {
1057 
1058         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1059         test_control_return(1);
1060     }
1061 
1062     hid_event.ux_device_class_hid_event_buffer[2] = 0;
1063     hid_event.ux_device_class_hid_event_buffer[3] = 0;
1064     hid_event.ux_device_class_hid_event_buffer[4] = 0;
1065     hid_event.ux_device_class_hid_event_buffer[5] = 0;
1066 
1067     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1068 
1069     /**************************************************************************/
1070     /** 5. Test raw key.                                                     **/
1071     test_slave_phase ++;
1072     // printf("****** slave step: %ld ******\n", test_slave_phase);
1073 
1074     /* Wait decode mode change. */
1075     if (tx_demo_phase_sync(UX_FALSE, 20, SLAVE_WAIT_TIME) != UX_SUCCESS)
1076     {
1077         printf("Error in line %d, thread phase error %ld <> %ld!\n", __LINE__, test_host_phase, test_slave_phase);
1078         test_control_return(1);
1079     }
1080 
1081     /** Test raw key. **/
1082 
1083     for (i = KEY_START; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
1084     {
1085 
1086         hid_event.ux_device_class_hid_event_length = 8;
1087 
1088         /* Modification byte. */
1089         hid_event.ux_device_class_hid_event_buffer[0] = 0;
1090 
1091         /* Reserved byte. */
1092         hid_event.ux_device_class_hid_event_buffer[1] = 0;
1093 
1094         /* Key byte. */
1095         hid_event.ux_device_class_hid_event_buffer[2] = i;
1096 
1097         status = ux_device_class_hid_event_set(hid, &hid_event);
1098         if (status != UX_SUCCESS)
1099         {
1100 
1101             printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1102             test_control_return(1);
1103         }
1104 
1105         ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1106     }
1107     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1108 
1109     /**************************************************************************/
1110     /** 6. Test invalid key.                                                 **/
1111     test_slave_phase ++;
1112     // printf("****** slave step: %ld ******\n", test_slave_phase);
1113 
1114     /* Wait decode mode change. */
1115     if (tx_demo_phase_sync(UX_FALSE, 10, SLAVE_WAIT_TIME) != UX_SUCCESS)
1116     {
1117         printf("Error in line %d, thread phase error %ld <> %ld!\n", __LINE__, test_host_phase, test_slave_phase);
1118         test_control_return(1);
1119     }
1120 
1121     /* Key byte. */
1122     hid_event.ux_device_class_hid_event_buffer[2] = ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array);
1123 
1124     status = ux_device_class_hid_event_set(hid, &hid_event);
1125     if (status != UX_SUCCESS)
1126     {
1127 
1128         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1129         test_control_return(1);
1130     }
1131     /* Key byte release. */
1132     hid_event.ux_device_class_hid_event_buffer[2] = 0;
1133 
1134     status = ux_device_class_hid_event_set(hid, &hid_event);
1135     if (status != UX_SUCCESS)
1136     {
1137 
1138         printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1139         test_control_return(1);
1140     }
1141     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1142 
1143     /**************************************************************************/
1144     /** 7. Test key array overflow.                                          **/
1145     test_slave_phase ++;
1146     // printf("****** slave step: %ld ******\n", test_slave_phase);
1147 
1148     /* Wait decode mode change. */
1149     if (tx_demo_phase_sync(UX_FALSE, 10, SLAVE_WAIT_TIME) != UX_SUCCESS)
1150     {
1151         printf("Error in line %d, thread phase error %ld <> %ld!\n", __LINE__, test_host_phase, test_slave_phase);
1152         test_control_return(1);
1153     }
1154 
1155     /** Test key array full. **/
1156 
1157     for (i = 0; i < UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH + 1; i++)
1158     {
1159 
1160         /* Press key.  */
1161         hid_event.ux_device_class_hid_event_length = 8;
1162         hid_event.ux_device_class_hid_event_buffer[0] = 0;
1163         hid_event.ux_device_class_hid_event_buffer[1] = 0;
1164         hid_event.ux_device_class_hid_event_buffer[2] = 5;
1165         status = ux_device_class_hid_event_set(hid, &hid_event);
1166         if (status != UX_SUCCESS)
1167         {
1168 
1169             printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1170             test_control_return(1);
1171         }
1172 
1173         ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1174 
1175         /* Release previous key.  */
1176         hid_event.ux_device_class_hid_event_length = 8;
1177         hid_event.ux_device_class_hid_event_buffer[0] = 0;
1178         hid_event.ux_device_class_hid_event_buffer[1] = 0;
1179         hid_event.ux_device_class_hid_event_buffer[2] = 0;
1180         status = ux_device_class_hid_event_set(hid, &hid_event);
1181         if (status != UX_SUCCESS)
1182         {
1183 
1184             printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
1185             test_control_return(1);
1186         }
1187 
1188         ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1189     }
1190     ux_utility_thread_sleep(SLAVE_WAIT_TIME);
1191 
1192     /* All done. */
1193     test_slave_phase = 0;
1194 }