1 /* This file tests basic HID functionalities.  */
2 
3 #include "usbx_test_common_hid.h"
4 
5 #define DUMMY_USBX_MEMORY_SIZE (64*1024)
6 static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
7 
8 static UCHAR hid_keyboard_report[] = {
9 
10     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
11     0x09, 0x06,                    // USAGE (Keyboard)
12     0xa1, 0x01,                    // COLLECTION (Application)
13 
14     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
15     0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
16     0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
17     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
18     0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
19     0x75, 0x01,                    //   REPORT_SIZE (1)
20     0x95, 0x08,                    //   REPORT_COUNT (8)
21     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
22 
23     0x95, 0x01,                    //   REPORT_COUNT (1)
24     0x75, 0x08,                    //   REPORT_SIZE (8)
25     0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)
26 
27     0x95, 0x05,                    //   REPORT_COUNT (5)
28     0x75, 0x01,                    //   REPORT_SIZE (1)
29     0x05, 0x08,                    //   USAGE_PAGE (LEDs)
30     0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
31     0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
32     0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
33 
34     0x95, 0x01,                    //   REPORT_COUNT (1)
35     0x75, 0x03,                    //   REPORT_SIZE (3)
36     0x91, 0x03,                    //   OUTPUT (Cnst,Var,Abs)
37 
38     0x95, 0x06,                    //   REPORT_COUNT (6)
39     0x75, 0x08,                    //   REPORT_SIZE (8)
40     0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
41     0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
42     0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
43     0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
44     0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
45     0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
46 
47     0xc0                           // END_COLLECTION
48 };
49 #define HID_KEYBOARD_REPORT_LENGTH sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0])
50 
51 static UCHAR hid_mouse_report[] = {
52 
53     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
54     0x09, 0x02,                    // USAGE (Mouse)
55     0xa1, 0x01,                    // COLLECTION (Application)
56     0x85, 0x01,                    //   REPORT_ID (1)
57     0x09, 0x01,                    //   USAGE (Pointer)
58     0xa1, 0x00,                    //   COLLECTION (Physical)
59     0x05, 0x09,                    //     USAGE_PAGE (Button)
60     0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
61     0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)
62     0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
63     0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
64     0x95, 0x03,                    //     REPORT_COUNT (3)
65     0x75, 0x01,                    //     REPORT_SIZE (1)
66     0x81, 0x02,                    //     INPUT (Data,Var,Abs)
67     0x95, 0x01,                    //     REPORT_COUNT (1)
68     0x75, 0x05,                    //     REPORT_SIZE (5)
69     0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)
70     0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
71     0x09, 0x30,                    //     USAGE (X)
72     0x09, 0x31,                    //     USAGE (Y)
73     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
74     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
75     0x75, 0x08,                    //     REPORT_SIZE (8)
76     0x95, 0x02,                    //     REPORT_COUNT (2)
77     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
78     0x09, 0x38,                    //     USAGE (Mouse Wheel)
79     0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
80     0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
81     0x75, 0x08,                    //     REPORT_SIZE (8)
82     0x95, 0x01,                    //     REPORT_COUNT (1)
83     0x81, 0x06,                    //     INPUT (Data,Var,Rel)
84     0xc0,                          //   END_COLLECTION
85     0xc0                           // END_COLLECTION
86 };
87 #define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
88 
89 static UCHAR hid_report_descriptor[] = {
90 
91     0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
92     0x09, 0x06,                    // USAGE (Keyboard)
93     0xa1, 0x01,                    // COLLECTION (Application)
94 
95     0x19, 0x01,                    //   USAGE_MINIMUM (1)
96     0x29, 0x04,                    //   USAGE_MAXIMUM (4)
97     0x75, 0x04,                    //   REPORT_SIZE (4)
98     0x95, 0x04,                    //   REPORT_COUNT (4)
99     0xb1, 0x02,                    //   FEATURE (Data,Var,Abs)
100 
101     0x85, 0x02,                    //   REPORT_ID (2)
102     0x19, 0x05,                    //   USAGE_MINIMUM (5)
103     0x29, 0x07,                    //   USAGE_MAXIMUM (7)
104     0x75, 0x08,                    //   REPORT_SIZE (8)
105     0x95, 0x03,                    //   REPORT_COUNT (3)
106     0xb1, 0x02,                    //   FEATURE (Data,Var,Abs)
107 
108     0x85, 0x04,                    //   REPORT_ID (4)
109     0x09, 0x08,                    //   USAGE (8)
110     0x75, 0x10,                    //   REPORT_SIZE (16)
111     0x95, 0x01,                    //   REPORT_COUNT (1)
112     0xb1, 0x02,                    //   FEATURE (Data,Var,Abs)
113 
114     /* USBX requires at least one input report. */
115     0x09, 0x01,                    //   USAGE (1)
116     0x75, 0x10,                    //   REPORT_SIZE (16)
117     0x95, 0x01,                    //   REPORT_COUNT (1)
118     0x81, 0x02,                    //   INPUT (Data,Var,Abs)
119 
120     /* USBX expects keyboards to have at least one output report, otherwise it's an error. */
121     0x95, 0x05,                    //   REPORT_COUNT (5)
122     0x75, 0x01,                    //   REPORT_SIZE (1)
123     0x05, 0x08,                    //   USAGE_PAGE (LEDs)
124     0x19, 0x01,                    //   USAGE_MINIMUM (Num Lock)
125     0x29, 0x05,                    //   USAGE_MAXIMUM (Kana)
126     0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
127 
128     0xc0,                          // END_COLLECTION
129 };
130 #define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
131 
132 
133 /* Configuration descriptor 9 bytes */
134 #define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
135     /* Configuration 1 descriptor 9 bytes */\
136     0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
137     (bNumInterfaces), (bConfigurationValue), 0x00,\
138     0x40, 0x00,
139 #define CFG_DESC_LEN (9)
140 
141 
142 /* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
143 #define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
144     /* Interface descriptor */\
145     0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
146     /* HID descriptor */\
147     0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
148         MSB(report_len),\
149     /* Endpoint descriptor (Interrupt) */\
150     0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
151 #define HID_IFC_DESC_ALL_LEN (9+9+7)
152 
153 static UCHAR device_framework_full_speed[] = {
154 
155     /* Device descriptor */
156     0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
157     0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
158     0x00, 0x01,
159 
160     CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
161     /* Keyboard */
162     HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
163 };
164 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
165 
166 static UCHAR device_framework_high_speed[] = {
167 
168     /* Device descriptor */
169     0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
170     0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
171     0x03, 0x01,
172 
173     /* Device qualifier descriptor */
174     0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
175     0x01, 0x00,
176 
177     CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
178     /* Keyboard */
179     HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
180 };
181 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
182 
183 
184 /* String Device Framework :
185     Byte 0 and 1 : Word containing the language ID : 0x0904 for US
186     Byte 2       : Byte containing the index of the descriptor
187     Byte 3       : Byte containing the length of the descriptor string
188 */
189 static UCHAR string_framework[] = {
190 
191     /* Manufacturer string descriptor : Index 1 */
192     0x09, 0x04, 0x01, 0x0c,
193     0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
194     0x6f, 0x67, 0x69, 0x63,
195 
196     /* Product string descriptor : Index 2 */
197     0x09, 0x04, 0x02, 0x0c,
198     0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
199     0x6f, 0x61, 0x72, 0x64,
200 
201     /* Serial Number string descriptor : Index 3 */
202     0x09, 0x04, 0x03, 0x04,
203     0x30, 0x30, 0x30, 0x31
204 };
205 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
206 
207 
208 /* Multiple languages are supported on the device, to add
209     a language besides english, the unicode language code must
210     be appended to the language_id_framework array and the length
211     adjusted accordingly. */
212 static UCHAR language_id_framework[] = {
213 
214     /* English. */
215     0x09, 0x04
216 };
217 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
218 
219 
220 UINT  _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
221 
222 
ux_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)223 static UINT ux_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
224 {
225     switch(event)
226     {
227     case UX_HID_CLIENT_INSERTION:
228         break;
229     case UX_HID_CLIENT_REMOVAL:
230         break;
231 #if defined(UX_HOST_STANDALONE)
232     case UX_STANDALONE_WAIT_BACKGROUND_TASK:
233         /* Let other threads to run.  */
234         tx_thread_relinquish();
235         break;
236 #endif
237     default:
238         break;
239     }
240     return 0;
241 }
242 
error_callback(UINT system_level,UINT system_context,UINT error_code)243 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
244 {
245 }
246 
247 /* Define what the initial system looks like.  */
248 
249 #ifdef CTEST
test_application_define(void * first_unused_memory)250 void test_application_define(void *first_unused_memory)
251 #else
252 void    usbx_class_hid_basic_test_application_define(void *first_unused_memory)
253 #endif
254 {
255 
256 UINT status;
257 CHAR *                          stack_pointer;
258 CHAR *                          memory_pointer;
259 
260 
261     /* Inform user.  */
262     printf("Running HID Class Basic Test........................................ ");
263 
264     /* Initialize the free memory pointer */
265     stack_pointer = (CHAR *) usbx_memory;
266     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
267 
268     /* Initialize USBX. Memory */
269     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
270 
271     /* Check for error.  */
272     if (status != UX_SUCCESS)
273     {
274 
275         printf("Error on line %d, error code: %d\n", __LINE__, status);
276         test_control_return(1);
277     }
278 
279     /* Register the error callback. */
280     _ux_utility_error_callback_register(error_callback);
281 
282     /* The code below is required for installing the host portion of USBX */
283     status =  ux_host_stack_initialize(ux_system_host_change_function);
284     if (status != UX_SUCCESS)
285     {
286 
287         printf("Error on line %d, error code: %d\n", __LINE__, status);
288         test_control_return(1);
289     }
290 
291     status =  ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
292     if (status != UX_SUCCESS)
293     {
294 
295         printf("Error on line %d, error code: %d\n", __LINE__, status);
296         test_control_return(1);
297     }
298 
299     /* No client registered, just HID.  */
300 
301     /* The code below is required for installing the device portion of USBX. No call back for
302        device status change in this example. */
303     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
304                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
305                                        string_framework, STRING_FRAMEWORK_LENGTH,
306                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
307     if(status!=UX_SUCCESS)
308     {
309 
310         printf("Error on line %d, error code: %d\n", __LINE__, status);
311         test_control_return(1);
312     }
313 
314     /* Initialize the hid class parameters.  */
315     hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
316     hid_parameter.ux_device_class_hid_parameter_report_length  = HID_REPORT_LENGTH;
317     hid_parameter.ux_device_class_hid_parameter_callback       = demo_thread_hid_set_callback;
318     hid_parameter.ux_device_class_hid_parameter_get_callback   = demo_thread_hid_get_callback;
319 
320     hid_parameter.ux_slave_class_hid_instance_activate = demo_device_hid_instance_activate;
321     hid_parameter.ux_slave_class_hid_instance_deactivate = demo_device_hid_instance_deactivate;
322 
323     /* Initilize the device hid class. The class is connected with interface 2 */
324     status =  ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
325                                              1, 0, (VOID *)&hid_parameter);
326     if(status!=UX_SUCCESS)
327     {
328 
329         printf("Error on line %d, error code: %d\n", __LINE__, status);
330         test_control_return(1);
331     }
332 
333     /* Initialize the simulated device controller.  */
334     status =  _ux_dcd_sim_slave_initialize();
335 
336     /* Check for error.  */
337     if (status != UX_SUCCESS)
338     {
339 
340         printf("Error on line %d, error code: %d\n", __LINE__, status);
341         test_control_return(1);
342     }
343 
344     /* Register all the USB host controllers available in this system */
345     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
346 
347     /* Check for error.  */
348     if (status != UX_SUCCESS)
349     {
350 
351         printf("Error on line %d, error code: %d\n", __LINE__, status);
352         test_control_return(1);
353     }
354 
355     /* Create the main device simulation thread.  */
356     status =  tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
357             stack_pointer, UX_DEMO_STACK_SIZE,
358             20, 20, 1, TX_AUTO_START);
359 
360     /* Check for error.  */
361     if (status != TX_SUCCESS)
362     {
363 
364         printf("Error on line %d, error code: %d\n", __LINE__, status);
365         test_control_return(1);
366     }
367     stack_pointer += UX_DEMO_STACK_SIZE;
368 
369     /* Create the main host simulation thread.  */
370     status =  tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
371             stack_pointer, 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("Error on line %d, error code: %d\n", __LINE__, status);
379         test_control_return(1);
380     }
381 }
382 
tx_demo_thread_device_simulation_entry(ULONG arg)383 static void  tx_demo_thread_device_simulation_entry(ULONG arg)
384 {
385     while(1)
386     {
387 #if defined(UX_DEVICE_STANDALONE)
388         ux_system_tasks_run();
389 #else
390         tx_thread_suspend(&tx_demo_thread_device_simulation);
391 #endif
392     }
393 }
394 
demo_wait(ULONG tick,UINT (* check)())395 static UINT demo_wait(ULONG tick, UINT (*check)())
396 {
397 ULONG   t0, t1;
398 UINT    status;
399 
400     t0 = tx_time_get();
401     while(1)
402     {
403 #if defined(UX_HOST_STANDALONE)
404         ux_system_tasks_run();
405 #endif
406         if (check)
407         {
408             status = check();
409             if (status == UX_SUCCESS)
410                 break;
411         }
412         t1 = tx_time_get();
413         if (_ux_utility_time_elapsed(t0, t1) >= tick)
414         {
415             return(UX_TIMEOUT);
416         }
417     }
418     return(UX_SUCCESS);
419 }
420 
demo_class_hid_wait(ULONG tick)421 static UINT demo_class_hid_wait(ULONG tick)
422 {
423     return(demo_wait(tick, demo_class_hid_get));
424 }
425 
test_hid_idle_requests(VOID)426 static void  test_hid_idle_requests(VOID)
427 {
428 USHORT      idle_time;
429 UINT        status;
430 INT         i;
431 #define N_TEST_IDLES      4
432 USHORT      test_idles[N_TEST_IDLES] = {1, 8, 20, 0};
433 ULONG       mem_level = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
434 
435 
436     /* Get input report.  */
437     hid_report_id.ux_host_class_hid_report_get_report = UX_NULL;
438     hid_report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
439     status = _ux_host_class_hid_report_id_get(hid, &hid_report_id);
440     UX_TEST_ASSERT(status == UX_SUCCESS);
441 
442     status = _ux_host_class_hid_idle_get(hid, &idle_time, hid_report_id.ux_host_class_hid_report_get_id);
443     UX_TEST_ASSERT(status == UX_SUCCESS);
444     test_idles[N_TEST_IDLES - 1] = idle_time;
445 
446     for (i = 0; i < N_TEST_IDLES; i ++)
447     {
448         status = _ux_host_class_hid_idle_set(hid, test_idles[i], hid_report_id.ux_host_class_hid_report_get_id);
449         UX_TEST_ASSERT(status == UX_SUCCESS);
450         status = _ux_host_class_hid_idle_get(hid, &idle_time, hid_report_id.ux_host_class_hid_report_get_id);
451         UX_TEST_ASSERT(status == UX_SUCCESS);
452         UX_TEST_ASSERT(idle_time == test_idles[i]);
453     }
454 
455     UX_TEST_ASSERT(mem_level == _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
456 }
457 
test_hid_report_requests(VOID)458 static void  test_hid_report_requests(VOID)
459 {
460 ULONG       tmp_bytes[2];
461 UINT        status;
462 INT         i;
463 #define N_TEST_REPORT_REQS 5
464 ULONG       mem_level = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
465 
466     /* Get output report.  */
467     hid_report_id.ux_host_class_hid_report_get_report = UX_NULL;
468     hid_report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_FEATURE;
469     status = _ux_host_class_hid_report_id_get(hid, &hid_report_id);
470     UX_TEST_ASSERT(status == UX_SUCCESS);
471 
472     /* Memorize the report pointer.  */
473     client_report.ux_host_class_hid_client_report = hid_report_id.ux_host_class_hid_report_get_report;
474 
475     /* The report set is raw since the LEDs mask is already in the right format.  */
476     client_report.ux_host_class_hid_client_report_flags = UX_HOST_CLASS_HID_REPORT_RAW;
477 
478     /* The length of this report is 2 byte (16 bits).  */
479     client_report.ux_host_class_hid_client_report_length = 2;
480 
481     /* The output report buffer is the LED mask field.  */
482     client_report.ux_host_class_hid_client_report_buffer = tmp_bytes;
483 
484     for (i = 0; i < N_TEST_REPORT_REQS; i ++)
485     {
486         _ux_utility_memory_set(tmp_bytes, i, sizeof(tmp_bytes));
487         status = _ux_host_class_hid_report_set(hid, &client_report);
488         UX_TEST_ASSERT(status == UX_SUCCESS);
489 
490         _ux_utility_memory_set(tmp_bytes, 0xFF, sizeof(tmp_bytes));
491         status = _ux_host_class_hid_report_get(hid, &client_report);
492         UX_TEST_ASSERT_MESSAGE(status == UX_SUCCESS, "0x%x\n", status);
493         UX_TEST_ASSERT(*(UCHAR *)tmp_bytes == i);
494     }
495 
496     UX_TEST_ASSERT(mem_level == _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
497 }
498 
499 static ULONG test_hid_report_callback_count = 0;
500 static ULONG test_hid_report_callback_wait = 0;
test_hid_report_callback(UX_HOST_CLASS_HID_REPORT_CALLBACK * callback)501 static VOID test_hid_report_callback(UX_HOST_CLASS_HID_REPORT_CALLBACK *callback)
502 {
503     test_hid_report_callback_count ++;
504 }
test_hid_report_callback_count_check(VOID)505 static UINT test_hid_report_callback_count_check(VOID)
506 {
507     return(test_hid_report_callback_count >= test_hid_report_callback_wait ?
508                 UX_SUCCESS : UX_ERROR);
509 }
test_hid_periodic_reports(VOID)510 static void  test_hid_periodic_reports(VOID)
511 {
512 UINT        status;
513 ULONG       mem_level;
514 
515     /* Get input report.  */
516     hid_report_id.ux_host_class_hid_report_get_report = UX_NULL;
517     hid_report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
518     status = _ux_host_class_hid_report_id_get(hid, &hid_report_id);
519     UX_TEST_ASSERT(status == UX_SUCCESS);
520 
521     /* Initialize the report callback.  */
522     hid_report_callback.ux_host_class_hid_report_callback_id =       hid_report_id.ux_host_class_hid_report_get_id;
523     hid_report_callback.ux_host_class_hid_report_callback_function = test_hid_report_callback;
524     hid_report_callback.ux_host_class_hid_report_callback_buffer =   UX_NULL;
525     hid_report_callback.ux_host_class_hid_report_callback_flags =    UX_HOST_CLASS_HID_REPORT_RAW;
526     hid_report_callback.ux_host_class_hid_report_callback_length =   hid_report_id.ux_host_class_hid_report_get_report->ux_host_class_hid_report_byte_length;
527 
528     /* Register the report call back when data comes it on this report.  */
529     status =  _ux_host_class_hid_report_callback_register(hid, &hid_report_callback);
530     UX_TEST_ASSERT(status == UX_SUCCESS);
531 
532     /* Start background report reading.  */
533     _ux_host_class_hid_periodic_report_start(hid);
534 
535     mem_level = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
536 
537     device_hid_event.ux_device_class_hid_event_length = 4;
538     device_hid_event.ux_device_class_hid_event_buffer[0] = 0;
539     device_hid_event.ux_device_class_hid_event_buffer[1] = 0;
540     device_hid_event.ux_device_class_hid_event_buffer[2] = '0';
541     device_hid_event.ux_device_class_hid_event_buffer[3] = '1';
542 
543     test_hid_report_callback_count = 0;
544     test_hid_report_callback_wait = 1;
545     _ux_device_class_hid_event_set(device_hid, &device_hid_event);
546     demo_wait(10, test_hid_report_callback_count_check);
547     UX_TEST_ASSERT(test_hid_report_callback_count == 1);
548 
549     test_hid_report_callback_count = 0;
550     test_hid_report_callback_wait = 2;
551     _ux_device_class_hid_event_set(device_hid, &device_hid_event);
552     _ux_device_class_hid_event_set(device_hid, &device_hid_event);
553     demo_wait(10, test_hid_report_callback_count_check);
554     UX_TEST_ASSERT(test_hid_report_callback_count == 2);
555 
556     UX_TEST_ASSERT(mem_level == _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
557 }
558 
tx_demo_thread_host_simulation_entry(ULONG arg)559 static void  tx_demo_thread_host_simulation_entry(ULONG arg)
560 {
561 
562 UINT status;
563 
564     /* Find the HID class */
565     status = demo_class_hid_wait(100);
566     UX_TEST_ASSERT(status == UX_SUCCESS);
567 
568 
569     test_hid_idle_requests();
570     test_hid_report_requests();
571     test_hid_periodic_reports();
572 
573     /* Now disconnect the device.  */
574     _ux_device_stack_disconnect();
575 
576     /* And deinitialize the class.  */
577     status =  ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
578 
579     /* Deinitialize the device side of usbx.  */
580     _ux_device_stack_uninitialize();
581 
582     /* And finally the usbx system resources.  */
583     _ux_system_uninitialize();
584 
585     /* Successful test.  */
586     printf("SUCCESS!\n");
587     test_control_return(0);
588 }
589 
demo_thread_hid_set_callback(UX_SLAVE_CLASS_HID * class,UX_SLAVE_CLASS_HID_EVENT * event)590 static UINT    demo_thread_hid_set_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
591 {
592     _ux_utility_memory_copy(&device_hid_event, event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
593     return(UX_SUCCESS);
594 }
demo_thread_hid_get_callback(UX_SLAVE_CLASS_HID * class,UX_SLAVE_CLASS_HID_EVENT * event)595 static UINT    demo_thread_hid_get_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
596 {
597     _ux_utility_memory_copy(event, &device_hid_event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
598     return(UX_SUCCESS);
599 }
600 
demo_device_hid_instance_activate(VOID * inst)601 static void                         demo_device_hid_instance_activate(VOID *inst)
602 {
603     if (device_hid == UX_NULL)
604         device_hid = (UX_SLAVE_CLASS_HID *)inst;
605 }
demo_device_hid_instance_deactivate(VOID * inst)606 static void                         demo_device_hid_instance_deactivate(VOID *inst)
607 {
608     if (inst == (VOID *)device_hid)
609         device_hid = UX_NULL;
610 }
611