1 /* This test is designed to test the simple dpump host/device class operation.  */
2 
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8 
9 #include "fx_api.h"
10 
11 #include "ux_device_class_cdc_acm.h"
12 #include "ux_device_stack.h"
13 
14 #include "ux_host_class_cdc_acm.h"
15 #include "ux_host_class_hid.h"
16 
17 #include "ux_test_dcd_sim_slave.h"
18 #include "ux_test_hcd_sim_host.h"
19 #include "ux_test_utility_sim.h"
20 
21 #include "ux_host_stack.h"
22 
23 /* Define constants.  */
24 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
25 #define                             UX_DEMO_STACK_SIZE  1024
26 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
27 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
28 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
29 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
30 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
31 #define                             UX_DEMO_MEMORY_SIZE     (96*1024)
32 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
33 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
34 
35 #define     LSB(x) ( (x) & 0x00ff)
36 #define     MSB(x) (((x) & 0xff00) >> 8)
37 
38 /* Configuration descriptor 9 bytes */
39 #define CFG_DESC(wTotalLength, bNumInterfaces, bmAttributes, bConfigurationValue)\
40     /* Configuration 1 descriptor 9 bytes */\
41     0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
42     (bNumInterfaces), (bConfigurationValue), 0x00,\
43     (bmAttributes), 0x00,
44 #define CFG_DESC_LEN 9
45 
46 #define IAD_DESC(bIfc) \
47     /* Interface association descriptor. 8 bytes.  */\
48     0x08, 0x0b, (bIfc), 0x02, 0x02, 0x02, 0x00, 0x00,
49 #define IAD_DESC_LEN 8
50 
51 #define CDC_IFC_DESC_ALL(bIfc, bIntIn, bBulkIn, bBulkOut)\
52     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */\
53     0x09, 0x04, (bIfc), 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,\
54     /* Header Functional Descriptor 5 bytes */\
55     0x05, 0x24, 0x00, 0x10, 0x01,\
56     /* ACM Functional Descriptor 4 bytes */\
57     0x04, 0x24, 0x02, 0x0f,\
58     /* Union Functional Descriptor 5 bytes */\
59     0x05, 0x24, 0x06, (bIfc), (bIfc + 1),\
60     /* Call Management Functional Descriptor 5 bytes */\
61     0x05, 0x24, 0x01, 0x03, (bIfc + 1),\
62     /* Endpoint interrupt in descriptor 7 bytes */\
63     0x07, 0x05, (bIntIn), 0x03, 0x40, 0x00, 0x10,\
64     /* Data Class Interface Descriptor Requirement 9 bytes */\
65     0x09, 0x04, (bIfc + 1), 0x00, 0x02, 0x0A, 0x00, 0x00, 0x00,\
66     /* Endpoint bulk in descriptor 7 bytes */\
67     0x07, 0x05, (bBulkIn), 0x02, 0x40, 0x00, 0x01,\
68     /* Endpoint bulk out descriptor 7 bytes */\
69     0x07, 0x05, (bBulkOut), 0x02, 0x40, 0x00, 0x01,
70 #define CDC_IFC_DESC_ALL1(bIfc, bIntIn, bBulkIn, bBulkOut)\
71     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */\
72     0x09, 0x04, (bIfc), 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,\
73     /* Header Functional Descriptor 5 bytes */\
74     0x05, 0x24, 0x00, 0x10, 0x01,\
75     /* ACM Functional Descriptor 4 bytes */\
76     0x04, 0x24, 0x02, 0x0f,\
77     /* Union Functional Descriptor 5 bytes */\
78     0x05, 0x24, 0x06, (bIfc), (bIfc + 1),\
79     /* Call Management Functional Descriptor 5 bytes */\
80     0x05, 0x24, 0x01, 0x03, (bIfc + 1),\
81     /* Endpoint interrupt in descriptor 7 bytes */\
82     0x07, 0x05, (bIntIn), 0x03, 0x40, 0x00, 0x10,\
83     /* Data Class Interface Descriptor Requirement 9 bytes */\
84     0x09, 0x04, (bIfc + 1), 0x00, 0x02, 0x0A, 0x00, 0x00, 0x00,\
85     /* Endpoint bulk out descriptor 7 bytes */\
86     0x07, 0x05, (bBulkOut), 0x02, 0x40, 0x00, 0x01,\
87     /* Endpoint bulk in descriptor 7 bytes */\
88     0x07, 0x05, (bBulkIn), 0x02, 0x40, 0x00, 0x01,
89 #define CDC_IFC_DESC_ALL_LEN (9+5+4+5+5+7+ 9+7+7)
90 
91 /* Define local/extern function prototypes.  */
92 static VOID                                test_thread_entry(ULONG);
93 static TX_THREAD                           tx_test_thread_host_simulation;
94 static TX_THREAD                           tx_test_thread_slave_simulation;
95 static VOID                                tx_test_thread_host_simulation_entry(ULONG);
96 static VOID                                tx_test_thread_slave_simulation_entry(ULONG);
97 
98 static VOID                                test_cdc_instance_activate(VOID  *cdc_instance);
99 static VOID                                test_cdc_instance_deactivate(VOID *cdc_instance);
100 static VOID                                test_cdc_instance_parameter_change(VOID *cdc_instance);
101 
102 /* Define global data structures.  */
103 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
104 
105 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control = UX_NULL;
106 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data = UX_NULL;
107 
108 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control1 = UX_NULL;
109 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data1 = UX_NULL;
110 
111 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave = UX_NULL;
112 
113 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave1 = UX_NULL;
114 
115 static UCHAR                               cdc_acm_slave_change;
116 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
117 
118 static ULONG                               error_counter;
119 
120 static ULONG                               error_callback_counter;
121 static UCHAR                               error_callback_ignore;
122 
123 static ULONG                               call_counter;
124 
125 static UCHAR                               buffer[UX_DEMO_BUFFER_SIZE];
126 
127 static UCHAR                               test_slave_code = 0;
128 static UCHAR                               test_slave_state = 0;
129 
130 /* Define device framework.  */
131 
132 static unsigned char device_framework_full_speed[] = {
133 
134     /* Device descriptor     18 bytes
135        0x02 bDeviceClass:    CDC class code
136        0x00 bDeviceSubclass: CDC class sub code
137        0x00 bDeviceProtocol: CDC Device protocol
138 
139        idVendor & idProduct - http://www.linux-usb.org/usb.ids
140     */
141     0x12, 0x01, 0x10, 0x01,
142     0xEF, 0x02, 0x01,
143     0x08,
144     0x84, 0x84, 0x00, 0x00,
145     0x00, 0x01,
146     0x01, 0x02, 03,
147     0x01, /* bNumConfigurations */
148 
149     /* Configuration 1 descriptor 9 bytes, total 75 bytes */
150     CFG_DESC(CFG_DESC_LEN + (IAD_DESC_LEN + CDC_IFC_DESC_ALL_LEN) * 2, 4, 0x40, 1)
151     /* IAD 8 bytes */
152     IAD_DESC(0)
153     /* CDC_ACM interfaces */
154     CDC_IFC_DESC_ALL(0, 0x83, 0x81, 0x02)
155     /* IAD 8 bytes */
156     IAD_DESC(2)
157     /* CDC_ACM interfaces */
158     CDC_IFC_DESC_ALL1(2, 0x86, 0x85, 0x04)
159 };
160 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      sizeof(device_framework_full_speed)
161 
162 static unsigned char device_framework_high_speed[] = {
163 
164     /* Device descriptor     18 bytes
165        0x02 bDeviceClass:    CDC class code
166        0x00 bDeviceSubclass: CDC class sub code
167        0x00 bDeviceProtocol: CDC Device protocol
168 
169        idVendor & idProduct - http://www.linux-usb.org/usb.ids
170     */
171     0x12, 0x01, 0x00, 0x02,
172     0xEF, 0x02, 0x01,
173     0x40,
174     0x84, 0x84, 0x00, 0x00,
175     0x00, 0x01,
176     0x01, 0x02, 03,
177     0x01, /* bNumConfigurations */
178 
179     /* Device qualifier descriptor 10 bytes */
180     0x0a, 0x06, 0x00, 0x02,
181     0x02, 0x00, 0x00,
182     0x40,
183     0x01,
184     0x00,
185 
186     /* Configuration 1 descriptor 9 bytes, total 75 bytes */
187     CFG_DESC(CFG_DESC_LEN + IAD_DESC_LEN + CDC_IFC_DESC_ALL_LEN, 2, 0x60, 1)
188     /* IAD 8 bytes */
189     IAD_DESC(0)
190     /* CDC_ACM interfaces */
191     CDC_IFC_DESC_ALL1(0, 0x83, 0x81, 0x02)
192     /* IAD 8 bytes */
193     IAD_DESC(2)
194     /* CDC_ACM interfaces */
195     CDC_IFC_DESC_ALL(2, 0x86, 0x85, 0x04)
196 };
197 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      sizeof(device_framework_high_speed)
198 
199 static unsigned char string_framework[] = {
200 
201     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
202     0x09, 0x04, 0x01, 0x0c,
203     0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
204     0x6f, 0x67, 0x69, 0x63,
205 
206     /* Product string descriptor : Index 2 - "EL Composite device" */
207     0x09, 0x04, 0x02, 0x13,
208     0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
209     0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
210     0x69, 0x63, 0x65,
211 
212     /* Serial Number string descriptor : Index 3 - "0001" */
213     0x09, 0x04, 0x03, 0x04,
214     0x30, 0x30, 0x30, 0x31
215 };
216 #define             STRING_FRAMEWORK_LENGTH                 sizeof(string_framework)
217 
218 /* Multiple languages are supported on the device, to add
219     a language besides english, the unicode language code must
220     be appended to the language_id_framework array and the length
221     adjusted accordingly. */
222 static unsigned char language_id_framework[] = {
223 
224     /* English. */
225     0x09, 0x04
226 };
227 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            sizeof(language_id_framework)
228 
229 /* Define the ISR dispatch.  */
230 
231 extern VOID    (*test_isr_dispatch)(void);
232 
233 
234 /* Prototype for test control return.  */
235 
236 void  test_control_return(UINT status);
237 
238 
239 /* Define the ISR dispatch routine.  */
240 
test_isr(void)241 static void    test_isr(void)
242 {
243 
244     /* For further expansion of interrupt-level testing.  */
245 }
246 
break_on_cdc_acm_all_ready(VOID)247 static UINT break_on_cdc_acm_all_ready(VOID)
248 {
249 
250     if (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL)
251         /* Do not break. */
252         return 0;
253 
254     if (cdc_acm_host_control1 == UX_NULL || cdc_acm_host_data1 == UX_NULL)
255         /* Do not break. */
256         return 0;
257 
258     if (cdc_acm_host_control->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
259         /* Do not break. */
260         return 0;
261 
262     if (cdc_acm_host_data->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
263         /* Do not break. */
264         return 0;
265 
266     if (cdc_acm_host_control1->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
267         /* Do not break. */
268         return 0;
269 
270     if (cdc_acm_host_data1->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
271         /* Do not break. */
272         return 0;
273 
274     if (cdc_acm_slave == UX_NULL || cdc_acm_slave1 == UX_NULL)
275         /* Do not break. */
276         return 0;
277 
278     /* All found, break. */
279     return 1;
280 }
281 
break_on_removal(VOID)282 static UINT break_on_removal(VOID)
283 {
284 
285     if (cdc_acm_host_control != UX_NULL || cdc_acm_host_data != UX_NULL)
286         /* Do not break. */
287         return 0;
288 
289     if (cdc_acm_host_control1 != UX_NULL || cdc_acm_host_data1 != UX_NULL)
290         /* Do not break. */
291         return 0;
292 
293     if (cdc_acm_slave != UX_NULL || cdc_acm_slave1 != UX_NULL)
294         /* Do not break. */
295         return 0;
296 
297     return 1;
298 }
299 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)300 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
301 {
302 
303 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
304 
305     switch(event)
306     {
307 
308         case UX_DEVICE_INSERTION:
309 
310             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
311             {
312                 if (cdc_acm_host_control == UX_NULL)
313                     cdc_acm_host_control = cdc_acm;
314                 else
315                     if (cdc_acm_host_control1 == UX_NULL)
316                         cdc_acm_host_control1 = cdc_acm;
317             }
318             else
319             {
320                 if (cdc_acm_host_data == UX_NULL)
321                     cdc_acm_host_data = cdc_acm;
322                 else
323                     if (cdc_acm_host_data1 == UX_NULL)
324                         cdc_acm_host_data1 = cdc_acm;
325             }
326             break;
327 
328         case UX_DEVICE_REMOVAL:
329 
330             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
331             {
332                 if (cdc_acm_host_control == cdc_acm)
333                     cdc_acm_host_control = UX_NULL;
334                 if (cdc_acm_host_control1 == cdc_acm)
335                     cdc_acm_host_control1 = UX_NULL;
336             }
337             else
338             {
339                 if (cdc_acm_host_data == cdc_acm)
340                     cdc_acm_host_data = UX_NULL;
341                 if (cdc_acm_host_data1 == cdc_acm)
342                     cdc_acm_host_data1 = UX_NULL;
343             }
344             break;
345 
346         default:
347             break;
348     }
349     return 0;
350 }
351 
test_cdc_instance_activate(VOID * cdc_instance)352 static VOID    test_cdc_instance_activate(VOID *cdc_instance)
353 {
354 
355     /* Save the CDC instance.  */
356     if (cdc_acm_slave == UX_NULL)
357         cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
358     else
359     if (cdc_acm_slave1 == UX_NULL)
360         cdc_acm_slave1 =  (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
361 }
test_cdc_instance_deactivate(VOID * cdc_instance)362 static VOID    test_cdc_instance_deactivate(VOID *cdc_instance)
363 {
364 
365     /* Reset the CDC instance.  */
366     if ((VOID *)cdc_acm_slave == cdc_instance)
367         cdc_acm_slave = UX_NULL;
368     if ((VOID *)cdc_acm_slave1 == cdc_instance)
369         cdc_acm_slave1 = UX_NULL;
370 }
371 
test_cdc_instance_parameter_change(VOID * cdc_instance)372 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
373 {
374 
375     /* Set CDC parameter change flag. */
376     cdc_acm_slave_change = UX_TRUE;
377 }
378 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)379 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
380 {
381     error_callback_counter ++;
382 
383     if (!error_callback_ignore)
384     {
385         /* Ignore UX_DEVICE_HANDLE_UNKNOWN.  */
386         if (UX_DEVICE_HANDLE_UNKNOWN == error_code)
387             return;
388         {
389             /* Failed test.  */
390             printf("#%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
391             // test_control_return(1);
392         }
393     }
394 }
395 
396 /* Define what the initial system looks like.  */
397 
398 #ifdef CTEST
test_application_define(void * first_unused_memory)399 void test_application_define(void *first_unused_memory)
400 #else
401 void usbx_ux_host_stack_class_instance_verify_test_application_define(void *first_unused_memory)
402 #endif
403 {
404 
405 UINT                    status;
406 CHAR *                  stack_pointer;
407 CHAR *                  memory_pointer;
408 
409 #if UX_TEST_MULTI_IFC_ON
410     printf("Running ux_host_stack_class_instance_verify Test.................... ");
411 #else
412     printf("Running ux_host_stack_class_instance_verify Test................SKIP SUCCESS!\n");
413     test_control_return(0);
414     return;
415 #endif
416 
417     stepinfo("\n");
418 
419     /* Initialize the free memory pointer */
420     stack_pointer = (CHAR *) usbx_memory;
421     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
422 
423     stepinfo(">>>>>>>>>>>>>>>> ux_system_initialize\n");
424 
425     /* Initialize USBX Memory */
426     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
427     /* Check for error.  */
428     if (status != UX_SUCCESS)
429     {
430 
431         printf("ERROR #%d\n", __LINE__);
432         test_control_return(1);
433     }
434 
435     /* Register the error callback. */
436     _ux_utility_error_callback_register(test_ux_error_callback);
437 
438     stepinfo(">>>>>>>>>>>>>>>> ux_host_stack_initialize\n");
439 
440     /* The code below is required for installing the host portion of USBX */
441     status =  ux_host_stack_initialize(test_host_change_function);
442     if (status != UX_SUCCESS)
443     {
444 
445         printf("ERROR #%d\n", __LINE__);
446         test_control_return(1);
447     }
448 
449     stepinfo(">>>>>>>>>>>>>>>> ux_device_stack_initialize\n");
450 
451     /* The code below is required for installing the device portion of USBX. No call back for
452        device status change in this example. */
453     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
454                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
455                                        string_framework, STRING_FRAMEWORK_LENGTH,
456                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
457     if(status!=UX_SUCCESS)
458     {
459 
460         printf("ERROR #%d\n", __LINE__);
461         test_control_return(1);
462     }
463 
464     stepinfo(">>>>>>>>>>>>>>>> ux_device_stack_class_register\n");
465 
466     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
467     parameter.ux_slave_class_cdc_acm_instance_activate   =  test_cdc_instance_activate;
468     parameter.ux_slave_class_cdc_acm_instance_deactivate =  test_cdc_instance_deactivate;
469     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
470 
471     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
472     status  =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
473                                              1,0,  &parameter);
474     status |=  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
475                                              1,2,  &parameter);
476     status |=  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
477                                              1,4,  &parameter);
478 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
479     if(status!=UX_SUCCESS)
480     {
481 
482         printf("ERROR #%d\n", __LINE__);
483         test_control_return(1);
484     }
485 #else
486     error_callback_ignore = UX_TRUE;
487 #endif
488     stepinfo(">>>>>>>>>>>>>>>> _ux_test_dcd_sim_slave_initialize\n");
489 
490     /* Initialize the simulated device controller.  */
491     status =  _ux_test_dcd_sim_slave_initialize();
492 
493     /* Check for error.  */
494     if (status != TX_SUCCESS)
495     {
496 
497         printf("ERROR #%d\n", __LINE__);
498         test_control_return(1);
499     }
500 
501     stepinfo(">>>>>>>>>>>>>>>> Create main test thread\n");
502 
503     /* Create the main host simulation thread.  */
504     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
505             stack_pointer, UX_DEMO_STACK_SIZE,
506             20, 20, 1, TX_AUTO_START);
507 
508     /* Check for error.  */
509     if (status != TX_SUCCESS)
510     {
511 
512         printf("ERROR #%d\n", __LINE__);
513         test_control_return(1);
514     }
515 
516     stepinfo(">>>>>>>>>>>>>>>> Create test thread\n");
517 
518     /* Create the main slave simulation  thread.  */
519     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
520             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
521             20, 20, 1, TX_DONT_START);
522 
523     /* Check for error.  */
524     if (status != TX_SUCCESS)
525     {
526 
527         printf("ERROR #%d\n", __LINE__);
528         test_control_return(1);
529     }
530 }
531 
tx_test_thread_host_simulation_entry(ULONG arg)532 void  tx_test_thread_host_simulation_entry(ULONG arg)
533 {
534 
535 UINT                                                status;
536 UCHAR                                               invalid_name[UX_MAX_CLASS_NAME_LENGTH + 2];
537 
538 #if !defined(UX_NAME_REFERENCED_BY_POINTER)
539     stepinfo(">>>>>>>>>>>>>>>> Test _ux_host_stack_class_instance_verify - class name C string errort\n");
540     error_callback_ignore = UX_TRUE;
541     _ux_utility_memory_set(invalid_name, ' ', sizeof(invalid_name));
542     _ux_utility_memory_copy(invalid_name, _ux_system_host_class_cdc_acm_name, 21);
543     status = _ux_host_stack_class_instance_verify(invalid_name, cdc_acm_host_control);
544     if (status != UX_ERROR)
545     {
546         printf("ERROR #%d: expect UX_ERROR but got 0x%x\n", __LINE__, status);
547         error_counter ++;
548     }
549 #if UX_MAX_CLASS_DRIVER > 1
550     error_callback_ignore = UX_FALSE;
551 #endif
552 #endif
553 
554     stepinfo(">>>>>>>>>>>>>>>> Test _ux_host_stack_class_instance_verify - no class driver\n");
555 
556     status = _ux_host_stack_class_instance_verify(_ux_system_host_class_cdc_acm_name, cdc_acm_host_control);
557     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
558     {
559         printf("ERROR #%d: expect UX_HOST_CLASS_INSTANCE_UNKNOWN but got 0x%x\n", __LINE__, status);
560         error_counter ++;
561     }
562 
563     stepinfo(">>>>>>>>>>>>>>>> ux_host_stack_class_register\n");
564 #if UX_MAX_CLASS_DRIVER > 1
565     /* Register HID class */
566     status =  ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
567     if (status != UX_SUCCESS)
568     {
569 
570         printf("ERROR #%d\n", __LINE__);
571         test_control_return(1);
572     }
573 #endif
574     /* Register CDC ACM class */
575     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
576     if (status != UX_SUCCESS)
577     {
578 
579         printf("ERROR #%d\n", __LINE__);
580         test_control_return(1);
581     }
582 
583     stepinfo(">>>>>>>>>>>>>>>> Test _ux_host_stack_class_instance_verify - no class driver active\n");
584 
585     status = _ux_host_stack_class_instance_verify(_ux_system_host_class_cdc_acm_name, cdc_acm_host_control);
586     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
587     {
588         printf("ERROR #%d: expect UX_HOST_CLASS_INSTANCE_UNKNOWN but got 0x%x\n", __LINE__, status);
589         error_counter ++;
590     }
591 
592     stepinfo(">>>>>>>>>>>>>>>> ux_host_stack_hcd_register\n");
593 
594 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
595     error_callback_ignore = UX_TRUE; /* One of interface no driver.  */
596 #endif
597 
598     /* Register HCD for test */
599     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
600     if (status != UX_SUCCESS)
601     {
602 
603         printf("ERROR #%d\n", __LINE__);
604         test_control_return(1);
605     }
606 
607     /* Test connect. */
608     stepinfo(">>>>>>>>>>>>>>>> Test connect (FS)\n");
609     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
610     ux_test_breakable_sleep(500, break_on_cdc_acm_all_ready);
611     if (!(cdc_acm_host_control
612             && cdc_acm_host_data
613             && cdc_acm_slave
614 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
615             && cdc_acm_host_control1
616             && cdc_acm_host_data1
617             && cdc_acm_slave1
618 #endif
619             ))
620     {
621 
622         printf("ERROR #%d: connect fail\n", __LINE__);
623         test_control_return(1);
624     }
625 
626     stepinfo(">>>>>>>>>>>>>>>> Test _ux_host_stack_class_instance_verify - instance no match\n");
627 
628     status = _ux_host_stack_class_instance_verify(_ux_system_host_class_cdc_acm_name, (VOID *)4);
629     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
630     {
631         printf("ERROR #%d: expect UX_HOST_CLASS_INSTANCE_UNKNOWN but got 0x%x\n", __LINE__, status);
632         error_counter ++;
633     }
634 
635     stepinfo(">>>>>>>>>>>>>>>> Test _ux_host_stack_class_instance_verify - class name not match\n");
636 
637     status = _ux_host_stack_class_instance_verify(_ux_system_host_class_hid_name, cdc_acm_host_control);
638     if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
639     {
640         printf("ERROR #%d: expect UX_HOST_CLASS_INSTANCE_UNKNOWN but got 0x%x\n", __LINE__, status);
641         error_counter ++;
642     }
643 
644     stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
645     ux_test_dcd_sim_slave_disconnect();
646     ux_test_hcd_sim_host_disconnect();
647 
648     ux_test_breakable_sleep(100, break_on_removal);
649 
650     if (cdc_acm_host_control || cdc_acm_host_data || cdc_acm_slave)
651     {
652 
653         printf("ERROR #%d: disconnect fail\n", __LINE__);
654         test_control_return(1);
655     }
656 
657     stepinfo(">>>>>>>>>>>>>>>> Deinitialize\n");
658 
659     /* Deinitialize the class.  */
660     ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
661     ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
662     ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
663 
664     /* Deinitialize the device side of usbx.  */
665     _ux_device_stack_uninitialize();
666 
667     /* And finally the usbx system resources.  */
668     _ux_system_uninitialize();
669 
670     stepinfo(">>>>>>>>>>>>>>>> Dump results\n");
671 
672     if (error_counter > 0)
673     {
674 
675         /* Test error.  */
676         printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
677         test_control_return(1);
678     }
679 
680     /* Successful test.  */
681     printf("SUCCESS!\n");
682     test_control_return(0);
683 }
684 
tx_test_thread_slave_simulation_entry(ULONG arg)685 void  tx_test_thread_slave_simulation_entry(ULONG arg)
686 {
687 
688     while(1)
689     {
690         switch (test_slave_code)
691         {
692         default:
693             break;
694         }
695         test_slave_state = 0;
696         tx_thread_suspend(&tx_test_thread_slave_simulation);
697     }
698 }
699