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 tx_thread_sleep(10);
357 } while (status != UX_SUCCESS);
358
359 /* We still need to wait for the cdc_acm status to be live */
360 while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
361 tx_thread_sleep(10);
362
363 /* Isolate both the control and data interfaces. */
364 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
365 {
366 /* This is the data interface. */
367 cdc_acm_host_data = cdc_acm_host;
368
369 /* In that case, the second one should be the control interface. */
370 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
371
372 /* Check error. */
373 if (status != UX_SUCCESS)
374 return(status);
375
376 /* Check for the control interfaces. */
377 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
378 {
379
380 /* This is the control interface. */
381 cdc_acm_host_control = cdc_acm_host;
382
383 return(UX_SUCCESS);
384
385 }
386 }
387 else
388 {
389 /* Check for the control interfaces. */
390 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
391 {
392
393 /* This is the control interface. */
394 cdc_acm_host_control = cdc_acm_host;
395
396 /* In that case, the second one should be the data interface. */
397 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
398
399 /* Check error. */
400 if (status != UX_SUCCESS)
401 return(status);
402
403 /* Check for the data interface. */
404 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
405 {
406
407 /* This is the data interface. */
408 cdc_acm_host_data = cdc_acm_host;
409
410 return(UX_SUCCESS);
411
412 }
413 }
414 }
415
416 /* Return ERROR. */
417 return(UX_ERROR);
418 }
419
demo_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)420 static UINT demo_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
421 {
422
423 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
424
425 switch(event)
426 {
427
428 case UX_DEVICE_INSERTION:
429
430 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
431 cdc_acm_host_control = cdc_acm;
432 else
433 cdc_acm_host_data = cdc_acm;
434 break;
435
436 case UX_DEVICE_REMOVAL:
437
438 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
439 cdc_acm_host_control = UX_NULL;
440 else
441 cdc_acm_host_data = UX_NULL;
442 break;
443
444 default:
445 break;
446 }
447 return 0;
448 }
449
test_cdc_instance_activate(VOID * cdc_instance)450 static VOID test_cdc_instance_activate(VOID *cdc_instance)
451 {
452
453 /* Save the CDC instance. */
454 cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
455 }
test_cdc_instance_deactivate(VOID * cdc_instance)456 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
457 {
458
459 /* Reset the CDC instance. */
460 cdc_acm_slave = UX_NULL;
461 }
462
test_cdc_instance_parameter_change(VOID * cdc_instance)463 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
464 {
465
466 /* Set CDC parameter change flag. */
467 cdc_acm_slave_change = UX_TRUE;
468 }
469
test_swap_framework_bulk_ep_descriptors(VOID)470 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
471 {
472 UCHAR tmp;
473
474 tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
475 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
476 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
477
478 tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
479 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
480 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
481 }
482
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * _params)483 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
484 {
485
486 set_cfg_counter ++;
487
488 rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
489
490 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
491 rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
492 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
493 }
494
495 /* Define what the initial system looks like. */
496
497 #ifdef CTEST
test_application_define(void * first_unused_memory)498 void test_application_define(void *first_unused_memory)
499 #else
500 void usbx_standalone_device_cdc_acm_basic_memory_test_application_define(void *first_unused_memory)
501 #endif
502 {
503
504 UINT status;
505 CHAR * stack_pointer;
506 CHAR * memory_pointer;
507
508 /* Inform user. */
509 printf("Running STANDALONE CDC ACM Basic Memory Test........................ ");
510
511 /* Reset testing counts. */
512 ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
513 ux_test_utility_sim_mem_alloc_count_reset();
514 ux_test_utility_sim_mutex_create_count_reset();
515 ux_test_utility_sim_sem_create_count_reset();
516 ux_test_utility_sim_sem_get_count_reset();
517 /* Reset error generations */
518 ux_test_utility_sim_sem_error_generation_stop();
519 ux_test_utility_sim_mutex_error_generation_stop();
520 ux_test_utility_sim_sem_get_error_generation_stop();
521
522 /* Initialize the free memory pointer */
523 stack_pointer = (CHAR *) usbx_memory;
524 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
525
526 /* Initialize USBX Memory */
527 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
528
529 /* Check for error. */
530 if (status != UX_SUCCESS)
531 {
532
533 printf("ERROR #1\n");
534 test_control_return(1);
535 }
536
537 /* Register the error callback. */
538 _ux_utility_error_callback_register(error_callback);
539
540 /* The code below is required for installing the host portion of USBX */
541 status = ux_host_stack_initialize(demo_system_host_change_function);
542 if (status != UX_SUCCESS)
543 {
544
545 printf("ERROR #2\n");
546 test_control_return(1);
547 }
548
549 /* Register CDC-ACM class. */
550 status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
551 if (status != UX_SUCCESS)
552 {
553
554 printf("ERROR #3\n");
555 test_control_return(1);
556 }
557
558 /* The code below is required for installing the device portion of USBX. No call back for
559 device status change in this example. */
560 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
561 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
562 string_framework, STRING_FRAMEWORK_LENGTH,
563 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
564 if(status!=UX_SUCCESS)
565 {
566
567 printf("ERROR #5\n");
568 test_control_return(1);
569 }
570
571 /* Set the parameters for callback when insertion/extraction of a CDC device. */
572 parameter.ux_slave_class_cdc_acm_instance_activate = test_cdc_instance_activate;
573 parameter.ux_slave_class_cdc_acm_instance_deactivate = test_cdc_instance_deactivate;
574 parameter.ux_slave_class_cdc_acm_parameter_change = test_cdc_instance_parameter_change;
575
576 /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
577 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
578 1,0, ¶meter);
579
580 if(status!=UX_SUCCESS)
581 {
582
583 printf("ERROR #6\n");
584 test_control_return(1);
585 }
586
587 /* Initialize the simulated device controller. */
588 status = _ux_dcd_sim_slave_initialize();
589
590 /* Check for error. */
591 if (status != TX_SUCCESS)
592 {
593
594 printf("ERROR #7\n");
595 test_control_return(1);
596 }
597
598 /* Register all the USB host controllers available in this system */
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 #4\n");
604 test_control_return(1);
605 }
606
607 /* Create the main host simulation thread. */
608 status = tx_thread_create(&ux_test_thread_host_simulation, "tx demo host simulation", ux_test_thread_host_simulation_entry, 0,
609 stack_pointer, UX_DEMO_STACK_SIZE,
610 20, 20, 1, TX_AUTO_START);
611
612 /* Check for error. */
613 if (status != TX_SUCCESS)
614 {
615
616 printf("ERROR #8\n");
617 test_control_return(1);
618 }
619
620 /* Create the main slave simulation thread. */
621 status = tx_thread_create(&ux_test_thread_slave_simulation, "tx demo slave simulation", ux_test_thread_slave_simulation_entry, 0,
622 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
623 20, 20, 1, TX_AUTO_START);
624
625 /* Check for error. */
626 if (status != TX_SUCCESS)
627 {
628
629 printf("ERROR #9\n");
630 test_control_return(1);
631 }
632 }
633
ux_test_thread_host_simulation_entry(ULONG arg)634 void ux_test_thread_host_simulation_entry(ULONG arg)
635 {
636
637 UINT status;
638 UX_SLAVE_CLASS_CDC_ACM * cdc_acm_slave_bak;
639 UX_HOST_CLASS_CDC_ACM * cdc_acm_host_ctrl_bak;
640 UX_HOST_CLASS_CDC_ACM * cdc_acm_host_data_bak;
641 ULONG test_n;
642 ULONG mem_free;
643 ULONG retry;
644
645 stepinfo("\n");
646
647 /* Find the cdc_acm class and wait for the link to be up. */
648 status = demo_class_cdc_acm_get();
649 if (status != UX_SUCCESS)
650 {
651
652 /* CDC ACM basic test error. */
653 printf("ERROR #10\n");
654 test_control_return(1);
655 }
656
657 /* Save slave instance for later tests. */
658 cdc_acm_slave_bak = cdc_acm_slave;
659 /* Save host instances for later tests. */
660 cdc_acm_host_ctrl_bak = cdc_acm_host_control;
661 cdc_acm_host_data_bak = cdc_acm_host_data;
662
663 /* Test disconnect. */
664 ux_test_dcd_sim_slave_disconnect();
665 ux_test_hcd_sim_host_disconnect();
666
667 /* Reset testing counts. */
668 ux_test_utility_sim_mem_alloc_count_reset();
669 ux_test_utility_sim_mutex_create_count_reset();
670 ux_test_utility_sim_sem_create_count_reset();
671 ux_test_utility_sim_sem_get_count_reset();
672 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
673
674 /* Save free memory usage. */
675 mem_free = _ux_system->ux_system_regular_memory_pool_free;
676 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
677 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
678 for (retry = 0; (retry < 10) && (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL); retry ++)
679 tx_thread_sleep(10);
680
681 /* Log create counts for further tests. */
682 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
683 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
684 rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
685 /* Log create counts when instances active for further tests. */
686 rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
687 rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
688 rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
689
690 /* Lock log base for tests. */
691 ux_test_utility_sim_mem_alloc_log_lock();
692
693 stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
694 stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
695 stepinfo("mem free: %ld, %ld\n", _ux_system->ux_system_regular_memory_pool_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
696
697 /* Simulate detach and attach for FS enumeration,
698 and check if there is memory error in normal enumeration.
699 */
700 stepinfo(">>>>>>>>>>>> Enumeration test\n");
701 mem_free = (~0);
702 for (test_n = 0; test_n < 3; test_n++)
703 {
704 stepinfo("%4ld / 2\n", test_n);
705
706 /* Disconnect. */
707 ux_test_dcd_sim_slave_disconnect();
708 ux_test_hcd_sim_host_disconnect();
709
710 /* Update memory free level (disconnect) */
711 if (mem_free == (~0))
712 mem_free = _ux_system->ux_system_regular_memory_pool_free;
713 else if (mem_free != _ux_system->ux_system_regular_memory_pool_free)
714 {
715
716 printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system->ux_system_regular_memory_pool_free);
717 test_control_return(1);
718 }
719
720 /* Connect. */
721 error_callback_counter = 0;
722 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
723 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
724
725 /* Wait and break on error. */
726 ux_test_breakable_sleep(100, sleep_break_on_error);
727
728 /* Check */
729 if (!cdc_acm_host_control || !cdc_acm_host_data)
730 {
731
732 printf("ERROR #12.%ld: Enumeration fail\n", test_n);
733 test_control_return(1);
734 }
735 }
736
737 /* Simulate detach and attach for FS enumeration,
738 and test possible memory allocation error handlings.
739 */
740 if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
741 mem_free = (~0);
742 for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
743 {
744
745 stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
746
747 /* Disconnect. */
748 ux_test_dcd_sim_slave_disconnect();
749 ux_test_hcd_sim_host_disconnect();
750
751 /* Update memory free level (disconnect) */
752 if (mem_free == (~0))
753 mem_free = _ux_system->ux_system_regular_memory_pool_free;
754 else if (mem_free != _ux_system->ux_system_regular_memory_pool_free)
755 {
756
757 printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system->ux_system_regular_memory_pool_free);
758 test_control_return(1);
759 }
760
761 /* Set memory error generation */
762 ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
763
764 /* Connect. */
765 error_callback_counter = 0;
766 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
767 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
768
769 /* Wait and break on errors. */
770 ux_test_breakable_sleep(100, sleep_break_on_error);
771
772 /* Check error */
773 if (cdc_acm_host_control && cdc_acm_host_data)
774 {
775
776 printf("ERROR #12.%ld: device detected when there is memory error\n", test_n);
777 test_control_return(1);
778 }
779 stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
780 }
781 ux_test_utility_sim_mem_alloc_error_generation_stop();
782 if (rsc_cdc_mem_alloc_count) stepinfo("\n");
783
784 /* Finally disconnect the device. */
785 ux_device_stack_disconnect();
786
787 /* And deinitialize the class. */
788 status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
789
790 /* Deinitialize the device side of usbx. */
791 _ux_device_stack_uninitialize();
792
793 /* And finally the usbx system resources. */
794 _ux_system_uninitialize();
795
796 /* Successful test. */
797 printf("SUCCESS!\n");
798 test_control_return(0);
799
800 }
801
ux_test_thread_slave_simulation_entry(ULONG arg)802 void ux_test_thread_slave_simulation_entry(ULONG arg)
803 {
804
805 while(1)
806 {
807
808 /* Keep running device stack tasks. */
809 ux_system_tasks_run();
810 tx_thread_relinquish();
811 }
812 }
813