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 #include "ux_host_class_cdc_acm.h"
14 
15 #include "ux_test_dcd_sim_slave.h"
16 #include "ux_test_hcd_sim_host.h"
17 #include "ux_test_utility_sim.h"
18 
19 /* Define constants.  */
20 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
21 #define                             UX_DEMO_STACK_SIZE  1024
22 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
23 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
24 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
25 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
26 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
27 #define                             UX_DEMO_MEMORY_SIZE     (64*1024)
28 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
29 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
30 
31 /* Define local/extern function prototypes.  */
32 static TX_THREAD   ux_test_thread_host_simulation;
33 static TX_THREAD   ux_test_thread_slave_simulation;
34 static void        ux_test_thread_host_simulation_entry(ULONG);
35 static void        ux_test_thread_slave_simulation_entry(ULONG);
36 
37 static VOID        test_cdc_instance_activate(VOID  *cdc_instance);
38 static VOID        test_cdc_instance_deactivate(VOID *cdc_instance);
39 static VOID        test_cdc_instance_parameter_change(VOID *cdc_instance);
40 
41 static VOID        ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
42 
43 /* Define global data structures.  */
44 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
45 static UX_HOST_CLASS                       *class_driver;
46 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
47 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
48 
49 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
50 static UCHAR                               cdc_acm_slave_change;
51 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
52 
53 static ULONG                               set_cfg_counter;
54 
55 static ULONG                               rsc_mem_alloc_cnt_on_set_cfg;
56 static ULONG                               rsc_sem_on_set_cfg;
57 static ULONG                               rsc_sem_get_on_set_cfg;
58 static ULONG                               rsc_mutex_on_set_cfg;
59 
60 static ULONG                               rsc_enum_sem_usage;
61 static ULONG                               rsc_enum_sem_get_count;
62 static ULONG                               rsc_enum_mutex_usage;
63 static ULONG                               rsc_enum_mem_alloc_count;
64 
65 static ULONG                               rsc_cdc_sem_usage;
66 static ULONG                               rsc_cdc_sem_get_count;
67 static ULONG                               rsc_cdc_mutex_usage;
68 static ULONG                               rsc_cdc_mem_alloc_count;
69 
70 static ULONG                               interaction_count;
71 
72 static UCHAR                               error_callback_ignore = UX_TRUE;
73 static ULONG                               error_callback_counter;
74 
75 /* Define device framework.  */
76 
77 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      93
78 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      103
79 #define             STRING_FRAMEWORK_LENGTH                 47
80 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            2
81 
82 static unsigned char device_framework_full_speed[] = {
83 
84     /* Device descriptor     18 bytes
85        0x02 bDeviceClass:    CDC class code
86        0x00 bDeviceSubclass: CDC class sub code
87        0x00 bDeviceProtocol: CDC Device protocol
88 
89        idVendor & idProduct - http://www.linux-usb.org/usb.ids
90     */
91     0x12, 0x01, 0x10, 0x01,
92     0xEF, 0x02, 0x01,
93     0x08,
94     0x84, 0x84, 0x00, 0x00,
95     0x00, 0x01,
96     0x01, 0x02, 03,
97     0x01,
98 
99     /* Configuration 1 descriptor 9 bytes */
100     0x09, 0x02, 0x4b, 0x00,
101     0x02, 0x01, 0x00,
102     0x40, 0x00,
103 
104     /* Interface association descriptor. 8 bytes.  */
105     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
106 
107     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */
108     0x09, 0x04, 0x00,
109     0x00,
110     0x01,
111     0x02, 0x02, 0x01,
112     0x00,
113 
114     /* Header Functional Descriptor 5 bytes */
115     0x05, 0x24, 0x00,
116     0x10, 0x01,
117 
118     /* ACM Functional Descriptor 4 bytes */
119     0x04, 0x24, 0x02,
120     0x0f,
121 
122     /* Union Functional Descriptor 5 bytes */
123     0x05, 0x24, 0x06,
124     0x00,                          /* Master interface */
125     0x01,                          /* Slave interface  */
126 
127     /* Call Management Functional Descriptor 5 bytes */
128     0x05, 0x24, 0x01,
129     0x03,
130     0x01,                          /* Data interface   */
131 
132     /* Endpoint 0x83 descriptor 7 bytes */
133     0x07, 0x05, 0x83,
134     0x03,
135     0x08, 0x00,
136     0xFF,
137 
138     /* Data Class Interface Descriptor Requirement 9 bytes */
139     0x09, 0x04, 0x01,
140     0x00,
141     0x02,
142     0x0A, 0x00, 0x00,
143     0x00,
144 
145     /* Endpoint 0x02 descriptor 7 bytes */
146     0x07, 0x05, 0x02, /* @ 93 - 14 + 2 = 81 */
147     0x02,
148     0x40, 0x00,
149     0x00,
150 
151     /* Endpoint 0x81 descriptor 7 bytes */
152     0x07, 0x05, 0x81, /* @ 93 - 7 + 2 = 88 */
153     0x02,
154     0x40, 0x00,
155     0x00,
156 
157 };
158 
159 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
160 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
161 
162 static unsigned char device_framework_high_speed[] = {
163 
164     /* Device descriptor
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,
178 
179     /* Device qualifier descriptor */
180     0x0a, 0x06, 0x00, 0x02,
181     0x02, 0x00, 0x00,
182     0x40,
183     0x01,
184     0x00,
185 
186     /* Configuration 1 descriptor */
187     0x09, 0x02, 0x4b, 0x00,
188     0x02, 0x01, 0x00,
189     0x40, 0x00,
190 
191     /* Interface association descriptor. */
192     0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
193 
194     /* Communication Class Interface Descriptor Requirement */
195     0x09, 0x04, 0x00,
196     0x00,
197     0x01,
198     0x02, 0x02, 0x01,
199     0x00,
200 
201     /* Header Functional Descriptor */
202     0x05, 0x24, 0x00,
203     0x10, 0x01,
204 
205     /* ACM Functional Descriptor */
206     0x04, 0x24, 0x02,
207     0x0f,
208 
209     /* Union Functional Descriptor */
210     0x05, 0x24, 0x06,
211     0x00,
212     0x01,
213 
214     /* Call Management Functional Descriptor */
215     0x05, 0x24, 0x01,
216     0x00,
217     0x01,
218 
219     /* Endpoint 0x83 descriptor */
220     0x07, 0x05, 0x83,
221     0x03,
222     0x08, 0x00,
223     0xFF,
224 
225     /* Data Class Interface Descriptor Requirement */
226     0x09, 0x04, 0x01,
227     0x00,
228     0x02,
229     0x0A, 0x00, 0x00,
230     0x00,
231 
232     /* Endpoint 0x02 descriptor */
233     0x07, 0x05, 0x02, /* @ 103 - 14 + 2 = 91 */
234     0x02,
235     0x40, 0x00,
236     0x00,
237 
238     /* Endpoint 0x81 descriptor */
239     0x07, 0x05, 0x81, /* @ 103 - 7 + 2 = 98 */
240     0x02,
241     0x40, 0x00,
242     0x00,
243 
244 };
245 
246 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
247 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
248 
249 static unsigned char string_framework[] = {
250 
251     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
252         0x09, 0x04, 0x01, 0x0c,
253         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
254         0x6f, 0x67, 0x69, 0x63,
255 
256     /* Product string descriptor : Index 2 - "EL Composite device" */
257         0x09, 0x04, 0x02, 0x13,
258         0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
259         0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
260         0x69, 0x63, 0x65,
261 
262     /* Serial Number string descriptor : Index 3 - "0001" */
263         0x09, 0x04, 0x03, 0x04,
264         0x30, 0x30, 0x30, 0x31
265     };
266 
267 
268     /* Multiple languages are supported on the device, to add
269        a language besides english, the unicode language code must
270        be appended to the language_id_framework array and the length
271        adjusted accordingly. */
272 static unsigned char language_id_framework[] = {
273 
274     /* English. */
275         0x09, 0x04
276     };
277 
278 /* Setup requests */
279 
280 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
281 
282 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
283 /* function, request to match,
284    port action, port status,
285    request action, request EP, request data, request actual length, request status,
286    status, additional callback,
287    no_return */
288 {   UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
289         UX_FALSE, UX_TEST_PORT_STATUS_DISC,
290         UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
291         UX_SUCCESS, ux_test_hcd_entry_set_cfg,
292         UX_TRUE}, /* Invoke callback & continue */
293 {   0   }
294 };
295 
296 /* Define the ISR dispatch.  */
297 
298 extern VOID    (*test_isr_dispatch)(void);
299 
300 
301 /* Prototype for test control return.  */
302 
303 void  test_control_return(UINT status);
304 
305 
306 /* Define the ISR dispatch routine.  */
307 
test_isr(void)308 static void    test_isr(void)
309 {
310 
311     /* For further expansion of interrupt-level testing.  */
312 }
313 
error_callback(UINT system_level,UINT system_context,UINT error_code)314 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
315 {
316 
317     error_callback_counter ++;
318 
319     if (!error_callback_ignore)
320     {
321         {
322             /* Failed test.  */
323             printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
324             test_control_return(1);
325         }
326     }
327 }
328 
sleep_break_on_error(VOID)329 static UINT  sleep_break_on_error(VOID)
330 {
331 
332     if (error_callback_counter >= 3)
333         return error_callback_counter;
334 
335     return UX_SUCCESS;
336 }
337 
demo_class_cdc_acm_get(void)338 static UINT  demo_class_cdc_acm_get(void)
339 {
340 
341 UINT                                status;
342 UX_HOST_CLASS                       *class;
343 UX_HOST_CLASS_CDC_ACM               *cdc_acm_host;
344 
345 
346     /* Find the main cdc_acm container */
347     status =  ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
348     if (status != UX_SUCCESS)
349         return(status);
350 
351     /* We get the first instance of the cdc_acm device */
352     do
353     {
354 
355         status =  ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
356 #if defined(UX_HOST_STANDALONE)
357         ux_system_tasks_run();
358 #else
359         tx_thread_sleep(10);
360 #endif
361     } while (status != UX_SUCCESS);
362 
363     /* We still need to wait for the cdc_acm status to be live */
364     while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
365     {
366 #if defined(UX_HOST_STANDALONE)
367         ux_system_tasks_run();
368 #else
369         tx_thread_sleep(10);
370 #endif
371     }
372 
373     /* Isolate both the control and data interfaces.  */
374     if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
375     {
376         /* This is the data interface.  */
377         cdc_acm_host_data = cdc_acm_host;
378 
379         /* In that case, the second one should be the control interface.  */
380         status =  ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
381 
382         /* Check error.  */
383         if (status != UX_SUCCESS)
384             return(status);
385 
386         /* Check for the control interfaces.  */
387         if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
388         {
389 
390             /* This is the control interface.  */
391             cdc_acm_host_control = cdc_acm_host;
392 
393             return(UX_SUCCESS);
394 
395         }
396     }
397     else
398     {
399         /* Check for the control interfaces.  */
400         if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
401         {
402 
403             /* This is the control interface.  */
404             cdc_acm_host_control = cdc_acm_host;
405 
406             /* In that case, the second one should be the data interface.  */
407             status =  ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
408 
409             /* Check error.  */
410             if (status != UX_SUCCESS)
411                 return(status);
412 
413             /* Check for the data interface.  */
414             if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
415             {
416 
417                 /* This is the data interface.  */
418                 cdc_acm_host_data = cdc_acm_host;
419 
420                 return(UX_SUCCESS);
421 
422             }
423         }
424     }
425 
426     /* Return ERROR.  */
427     return(UX_ERROR);
428 }
429 
demo_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)430 static UINT demo_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
431 {
432 
433 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
434 
435     switch(event)
436     {
437 
438         case UX_DEVICE_INSERTION:
439 
440             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
441                 cdc_acm_host_control = cdc_acm;
442             else
443                 cdc_acm_host_data = cdc_acm;
444             break;
445 
446         case UX_DEVICE_REMOVAL:
447 
448             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
449                 cdc_acm_host_control = UX_NULL;
450             else
451                 cdc_acm_host_data = UX_NULL;
452             break;
453 
454 #if defined(UX_HOST_STANDALONE)
455         case UX_STANDALONE_WAIT_BACKGROUND_TASK:
456             tx_thread_relinquish();
457             break;
458 #endif
459 
460         default:
461             break;
462     }
463     return 0;
464 }
465 
test_cdc_instance_activate(VOID * cdc_instance)466 static VOID    test_cdc_instance_activate(VOID *cdc_instance)
467 {
468 
469     /* Save the CDC instance.  */
470     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
471 }
test_cdc_instance_deactivate(VOID * cdc_instance)472 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
473 {
474 
475     /* Reset the CDC instance.  */
476     cdc_acm_slave = UX_NULL;
477 }
478 
test_cdc_instance_parameter_change(VOID * cdc_instance)479 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
480 {
481 
482     /* Set CDC parameter change flag. */
483     cdc_acm_slave_change = UX_TRUE;
484 }
485 
test_swap_framework_bulk_ep_descriptors(VOID)486 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
487 {
488 UCHAR tmp;
489 
490     tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
491     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
492     device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
493 
494     tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
495     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
496     device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
497 }
498 
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)499 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
500 {
501 
502     set_cfg_counter ++;
503 
504     rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
505 
506     rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
507     rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
508     rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
509 }
510 
511 /* Define what the initial system looks like.  */
512 
513 #ifdef CTEST
test_application_define(void * first_unused_memory)514 void test_application_define(void *first_unused_memory)
515 #else
516 void    usbx_standalone_cdc_acm_basic_memory_test_application_define(void *first_unused_memory)
517 #endif
518 {
519 
520 UINT                    status;
521 CHAR *                  stack_pointer;
522 CHAR *                  memory_pointer;
523 
524     /* Inform user.  */
525     printf("Running STANDALONE CDC ACM Basic Memory Test........................ ");
526 
527     /* Reset testing counts. */
528     ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
529     ux_test_utility_sim_mem_alloc_count_reset();
530     ux_test_utility_sim_mutex_create_count_reset();
531     ux_test_utility_sim_sem_create_count_reset();
532     ux_test_utility_sim_sem_get_count_reset();
533     /* Reset error generations */
534     ux_test_utility_sim_sem_error_generation_stop();
535     ux_test_utility_sim_mutex_error_generation_stop();
536     ux_test_utility_sim_sem_get_error_generation_stop();
537 
538     /* Initialize the free memory pointer */
539     stack_pointer = (CHAR *) usbx_memory;
540     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
541 
542     /* Initialize USBX Memory */
543     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
544 
545     /* Check for error.  */
546     if (status != UX_SUCCESS)
547     {
548 
549         printf("ERROR #1\n");
550         test_control_return(1);
551     }
552 
553     /* Register the error callback. */
554     _ux_utility_error_callback_register(error_callback);
555 
556     /* The code below is required for installing the host portion of USBX */
557     status =  ux_host_stack_initialize(demo_system_host_change_function);
558     if (status != UX_SUCCESS)
559     {
560 
561         printf("ERROR #2\n");
562         test_control_return(1);
563     }
564 
565     /* Register CDC-ACM class.  */
566     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
567     if (status != UX_SUCCESS)
568     {
569 
570         printf("ERROR #3\n");
571         test_control_return(1);
572     }
573 
574     /* The code below is required for installing the device portion of USBX. No call back for
575        device status change in this example. */
576     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
577                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
578                                        string_framework, STRING_FRAMEWORK_LENGTH,
579                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
580     if(status!=UX_SUCCESS)
581     {
582 
583         printf("ERROR #5\n");
584         test_control_return(1);
585     }
586 
587     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
588     parameter.ux_slave_class_cdc_acm_instance_activate   =  test_cdc_instance_activate;
589     parameter.ux_slave_class_cdc_acm_instance_deactivate =  test_cdc_instance_deactivate;
590     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
591 
592     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
593     status =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
594                                              1,0,  &parameter);
595 
596     if(status!=UX_SUCCESS)
597     {
598 
599         printf("ERROR #6\n");
600         test_control_return(1);
601     }
602 
603     /* Initialize the simulated device controller.  */
604     status =  _ux_dcd_sim_slave_initialize();
605 
606     /* Check for error.  */
607     if (status != TX_SUCCESS)
608     {
609 
610         printf("ERROR #7\n");
611         test_control_return(1);
612     }
613 
614     /* Register all the USB host controllers available in this system */
615     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
616     if (status != UX_SUCCESS)
617     {
618 
619         printf("ERROR #4\n");
620         test_control_return(1);
621     }
622 
623     /* Create the main host simulation thread.  */
624     status =  tx_thread_create(&ux_test_thread_host_simulation, "tx demo host simulation", ux_test_thread_host_simulation_entry, 0,
625             stack_pointer, UX_DEMO_STACK_SIZE,
626             20, 20, 1, TX_AUTO_START);
627 
628     /* Check for error.  */
629     if (status != TX_SUCCESS)
630     {
631 
632         printf("ERROR #8\n");
633         test_control_return(1);
634     }
635 
636     /* Create the main slave simulation  thread.  */
637     status =  tx_thread_create(&ux_test_thread_slave_simulation, "tx demo slave simulation", ux_test_thread_slave_simulation_entry, 0,
638             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
639             20, 20, 1, TX_AUTO_START);
640 
641     /* Check for error.  */
642     if (status != TX_SUCCESS)
643     {
644 
645         printf("ERROR #9\n");
646         test_control_return(1);
647     }
648 }
649 
ux_test_thread_host_simulation_entry(ULONG arg)650 void  ux_test_thread_host_simulation_entry(ULONG arg)
651 {
652 
653 UINT                                                status;
654 UX_SLAVE_CLASS_CDC_ACM *                            cdc_acm_slave_bak;
655 UX_HOST_CLASS_CDC_ACM *                             cdc_acm_host_ctrl_bak;
656 UX_HOST_CLASS_CDC_ACM *                             cdc_acm_host_data_bak;
657 ULONG                                               test_n;
658 ULONG                                               mem_free;
659 ULONG                                               retry;
660 
661     stepinfo("\n");
662 
663     /* Find the cdc_acm class and wait for the link to be up.  */
664     status =  demo_class_cdc_acm_get();
665     if (status != UX_SUCCESS)
666     {
667 
668         /* CDC ACM basic test error.  */
669         printf("ERROR #10\n");
670         test_control_return(1);
671     }
672 
673     /* Save slave instance for later tests. */
674     cdc_acm_slave_bak = cdc_acm_slave;
675     /* Save host instances for later tests. */
676     cdc_acm_host_ctrl_bak = cdc_acm_host_control;
677     cdc_acm_host_data_bak = cdc_acm_host_data;
678 
679     /* Test disconnect. */
680     ux_test_dcd_sim_slave_disconnect();
681     ux_test_hcd_sim_host_disconnect();
682 
683     /* Reset testing counts. */
684     ux_test_utility_sim_mem_alloc_count_reset();
685     ux_test_utility_sim_mutex_create_count_reset();
686     ux_test_utility_sim_sem_create_count_reset();
687     ux_test_utility_sim_sem_get_count_reset();
688     ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
689 
690     /* Save free memory usage. */
691     mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
692     ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
693     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
694     for (retry = 0; (retry < 10) && (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL); retry ++)
695         tx_thread_sleep(10);
696 
697     /* Log create counts for further tests. */
698     rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
699     rsc_enum_sem_usage = rsc_sem_on_set_cfg;
700     rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
701     /* Log create counts when instances active for further tests. */
702     rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
703     rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
704     rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
705 
706     /* Lock log base for tests. */
707     ux_test_utility_sim_mem_alloc_log_lock();
708 
709     stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
710     stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
711     stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
712 
713     /* Simulate detach and attach for FS enumeration,
714        and check if there is memory error in normal enumeration.
715      */
716     stepinfo(">>>>>>>>>>>> Enumeration test\n");
717     mem_free = (~0);
718     for (test_n = 0; test_n < 3; test_n++)
719     {
720         stepinfo("%4ld / 2\n", test_n);
721 
722         /* Disconnect. */
723         ux_test_dcd_sim_slave_disconnect();
724         ux_test_hcd_sim_host_disconnect();
725 
726         /* Update memory free level (disconnect) */
727         if (mem_free == (~0))
728             mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
729         else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
730         {
731 
732             printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
733             test_control_return(1);
734         }
735 
736         /* Connect. */
737         error_callback_counter = 0;
738         ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
739         ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
740 
741         /* Wait and break on error. */
742         ux_test_breakable_sleep(100, sleep_break_on_error);
743 
744         /* Check */
745         if (!cdc_acm_host_control || !cdc_acm_host_data)
746         {
747 
748             printf("ERROR #12.%ld: Enumeration fail\n", test_n);
749             test_control_return(1);
750         }
751     }
752 
753     /* Simulate detach and attach for FS enumeration,
754        and test possible memory allocation error handlings.
755      */
756     if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
757     mem_free = (~0);
758     for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
759     {
760 
761         stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
762 
763         /* Disconnect. */
764         ux_test_dcd_sim_slave_disconnect();
765         ux_test_hcd_sim_host_disconnect();
766 
767         /* Update memory free level (disconnect) */
768         if (mem_free == (~0))
769             mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
770         else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
771         {
772 
773             printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
774             test_control_return(1);
775         }
776 
777         /* Set memory error generation */
778         ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
779 
780         /* Connect. */
781         error_callback_counter = 0;
782         ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
783         ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
784 
785         /* Wait and break on errors. */
786         ux_test_breakable_sleep(100, sleep_break_on_error);
787 
788         /* Check error */
789         if (cdc_acm_host_control && cdc_acm_host_data)
790         {
791 
792             printf("ERROR #12.%ld: device detected when there is memory error\n", test_n);
793             test_control_return(1);
794         }
795         stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
796     }
797     ux_test_utility_sim_mem_alloc_error_generation_stop();
798     if (rsc_cdc_mem_alloc_count) stepinfo("\n");
799 
800     /* Finally disconnect the device. */
801     ux_device_stack_disconnect();
802 
803     /* And deinitialize the class.  */
804     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
805 
806     /* Deinitialize the device side of usbx.  */
807     _ux_device_stack_uninitialize();
808 
809     /* And finally the usbx system resources.  */
810     _ux_system_uninitialize();
811 
812     /* Successful test.  */
813     printf("SUCCESS!\n");
814     test_control_return(0);
815 
816 }
817 
ux_test_thread_slave_simulation_entry(ULONG arg)818 void  ux_test_thread_slave_simulation_entry(ULONG arg)
819 {
820 
821     while(1)
822     {
823 
824         /* Keep running device stack tasks.  */
825         ux_system_tasks_run();
826         tx_thread_relinquish();
827     }
828 }
829