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 VOID test_thread_entry(ULONG);
33 static TX_THREAD tx_test_thread_host_simulation;
34 static TX_THREAD tx_test_thread_slave_simulation;
35 static VOID tx_test_thread_host_simulation_entry(ULONG);
36 static VOID tx_test_thread_slave_simulation_entry(ULONG);
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 UINT test_slave_change_function(ULONG change);
42
43 static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
44 static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
45 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
46
47 static VOID ux_test_system_host_enum_hub_function(VOID);
48
49 /* Define global data structures. */
50 UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
51 UX_HOST_CLASS *class_driver;
52 UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
53 UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
54 ULONG command_received_count;
55 UCHAR cdc_acm_reception_buffer[UX_DEMO_RECEPTION_BUFFER_SIZE];
56 UCHAR cdc_acm_xmit_buffer[UX_DEMO_XMIT_BUFFER_SIZE];
57 UX_HOST_CLASS_CDC_ACM_RECEPTION cdc_acm_reception;
58 UCHAR *global_reception_buffer;
59 ULONG global_reception_size;
60
61 UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
62 UCHAR cdc_acm_slave_change;
63 UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
64 UCHAR buffer[UX_DEMO_BUFFER_SIZE];
65 ULONG echo_mode;
66
67 ULONG enum_counter;
68
69 ULONG error_counter;
70
71 ULONG set_cfg_counter;
72
73 ULONG rsc_mem_free_on_set_cfg;
74 ULONG rsc_sem_on_set_cfg;
75 ULONG rsc_sem_get_on_set_cfg;
76 ULONG rsc_mutex_on_set_cfg;
77
78 ULONG rsc_enum_sem_usage;
79 ULONG rsc_enum_sem_get_count;
80 ULONG rsc_enum_mutex_usage;
81 ULONG rsc_enum_mem_usage;
82
83 /* Define device framework. */
84
85 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 93
86 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 103
87 #define STRING_FRAMEWORK_LENGTH 47
88 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
89
90 static unsigned char device_framework_full_speed[] = {
91
92 /* Device descriptor 18 bytes
93 0x02 bDeviceClass: CDC class code
94 0x00 bDeviceSubclass: CDC class sub code
95 0x00 bDeviceProtocol: CDC Device protocol
96
97 idVendor & idProduct - http://www.linux-usb.org/usb.ids
98 */
99 0x12, 0x01, 0x10, 0x01,
100 0xEF, 0x02, 0x01,
101 0x08,
102 0x84, 0x84, 0x00, 0x00,
103 0x00, 0x01,
104 0x01, 0x02, 03,
105 0x01,
106
107 /* Configuration 1 descriptor 9 bytes */
108 0x09, 0x02, 0x4b, 0x00,
109 0x02, 0x01, 0x00,
110 0x40, 0x00,
111
112 /* Interface association descriptor. 8 bytes. */
113 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
114
115 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
116 0x09, 0x04, 0x00,
117 0x00,
118 0x01,
119 0x02, 0x02, 0x01,
120 0x00,
121
122 /* Header Functional Descriptor 5 bytes */
123 0x05, 0x24, 0x00,
124 0x10, 0x01,
125
126 /* ACM Functional Descriptor 4 bytes */
127 0x04, 0x24, 0x02,
128 0x0f,
129
130 /* Union Functional Descriptor 5 bytes */
131 0x05, 0x24, 0x06,
132 0x00, /* Master interface */
133 0x01, /* Slave interface */
134
135 /* Call Management Functional Descriptor 5 bytes */
136 0x05, 0x24, 0x01,
137 0x03,
138 0x01, /* Data interface */
139
140 /* Endpoint 0x83 descriptor 7 bytes */
141 0x07, 0x05, 0x83,
142 0x03,
143 0x08, 0x00,
144 0xFF,
145
146 /* Data Class Interface Descriptor Requirement 9 bytes */
147 0x09, 0x04, 0x01,
148 0x00,
149 0x02,
150 0x0A, 0x00, 0x00,
151 0x00,
152
153 /* Endpoint 0x81 descriptor 7 bytes */
154 0x07, 0x05, 0x81, /* @ 93 - 14 + 2 = 81 */
155 0x02,
156 0x40, 0x00,
157 0x00,
158
159 /* Endpoint 0x02 descriptor 7 bytes */
160 0x07, 0x05, 0x02, /* @ 93 - 7 + 2 = 88 */
161 0x02,
162 0x40, 0x00,
163 0x00,
164
165 };
166
167 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
168 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
169
170 static unsigned char device_framework_high_speed[] = {
171
172 /* Device descriptor
173 0x02 bDeviceClass: CDC class code
174 0x00 bDeviceSubclass: CDC class sub code
175 0x00 bDeviceProtocol: CDC Device protocol
176
177 idVendor & idProduct - http://www.linux-usb.org/usb.ids
178 */
179 0x12, 0x01, 0x00, 0x02,
180 0xEF, 0x02, 0x01,
181 0x40,
182 0x84, 0x84, 0x00, 0x00,
183 0x00, 0x01,
184 0x01, 0x02, 03,
185 0x01,
186
187 /* Device qualifier descriptor */
188 0x0a, 0x06, 0x00, 0x02,
189 0x02, 0x00, 0x00,
190 0x40,
191 0x01,
192 0x00,
193
194 /* Configuration 1 descriptor */
195 0x09, 0x02, 0x4b, 0x00,
196 0x02, 0x01, 0x00,
197 0x40, 0x00,
198
199 /* Interface association descriptor. */
200 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
201
202 /* Communication Class Interface Descriptor Requirement */
203 0x09, 0x04, 0x00,
204 0x00,
205 0x01,
206 0x02, 0x02, 0x01,
207 0x00,
208
209 /* Header Functional Descriptor */
210 0x05, 0x24, 0x00,
211 0x10, 0x01,
212
213 /* ACM Functional Descriptor */
214 0x04, 0x24, 0x02,
215 0x0f,
216
217 /* Union Functional Descriptor */
218 0x05, 0x24, 0x06,
219 0x00,
220 0x01,
221
222 /* Call Management Functional Descriptor */
223 0x05, 0x24, 0x01,
224 0x00,
225 0x01,
226
227 /* Endpoint 0x83 descriptor */
228 0x07, 0x05, 0x83,
229 0x03,
230 0x08, 0x00,
231 0xFF,
232
233 /* Data Class Interface Descriptor Requirement */
234 0x09, 0x04, 0x01,
235 0x00,
236 0x02,
237 0x0A, 0x00, 0x00,
238 0x00,
239
240 /* Endpoint 0x81 descriptor */
241 0x07, 0x05, 0x81, /* @ 103 - 14 + 2 = 91 */
242 0x02,
243 0x40, 0x00,
244 0x00,
245
246 /* Endpoint 0x02 descriptor */
247 0x07, 0x05, 0x02, /* @ 103 - 7 + 2 = 98 */
248 0x02,
249 0x40, 0x00,
250 0x00,
251
252 };
253
254 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
255 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
256
257 static unsigned char string_framework[] = {
258
259 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
260 0x09, 0x04, 0x01, 0x0c,
261 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
262 0x6f, 0x67, 0x69, 0x63,
263
264 /* Product string descriptor : Index 2 - "EL Composite device" */
265 0x09, 0x04, 0x02, 0x13,
266 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
267 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
268 0x69, 0x63, 0x65,
269
270 /* Serial Number string descriptor : Index 3 - "0001" */
271 0x09, 0x04, 0x03, 0x04,
272 0x30, 0x30, 0x30, 0x31
273 };
274
275
276 /* Multiple languages are supported on the device, to add
277 a language besides english, the unicode language code must
278 be appended to the language_id_framework array and the length
279 adjusted accordingly. */
280 static unsigned char language_id_framework[] = {
281
282 /* English. */
283 0x09, 0x04
284 };
285
286 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
287 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
288 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
289 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
290
291 /* Test interactions */
292
293 /* Disconnect on RESET:
294 * Host still create the EP0 and expects first SETUP request failure.
295 */
296
297 static UX_TEST_HCD_SIM_ACTION disconnect_on_reset[] = {
298 /* function, request to match,
299 port action, port status,
300 request action, request EP, request data, request actual length, request status,
301 status, additional callback,
302 no_return */
303 { UX_HCD_RESET_PORT, NULL,
304 UX_TRUE , UX_TEST_PORT_STATUS_DISC,
305 0 , 0, UX_NULL, 0, 0,
306 UX_SUCCESS, ux_test_hcd_entry_disconnect},
307 #if 0
308 { UX_HCD_CREATE_ENDPOINT, NULL,
309 UX_FALSE, 0,
310 0 , 0, UX_NULL, 0, 0,
311 UX_ERROR , ux_test_hcd_entry_should_not_be_called},
312 #endif
313 { UX_HCD_TRANSFER_REQUEST, NULL,
314 UX_FALSE, 0,
315 0 , 0, UX_NULL, 0, 0,
316 UX_ERROR , UX_NULL}, /* Request just fail on disconnect */
317 { UX_HCD_TRANSFER_REQUEST, NULL,
318 UX_FALSE, 0,
319 0 , 0, UX_NULL, 0, 0,
320 UX_ERROR , UX_NULL},
321 { UX_HCD_TRANSFER_REQUEST, NULL,
322 UX_FALSE, 0,
323 0 , 0, UX_NULL, 0, 0,
324 UX_ERROR , UX_NULL},
325 { 0 }
326 };
327
328 static UX_TEST_HCD_SIM_ACTION endpoint0_create_fail[] = {
329 /* function, request to match,
330 port action, port status,
331 request action, request EP, request data, request actual length, request status,
332 status, additional callback,
333 no_return */
334 { UX_HCD_CREATE_ENDPOINT, NULL,
335 UX_FALSE, 0,
336 0 , 0, UX_NULL, 0, 0,
337 UX_ERROR},
338 { UX_HCD_CREATE_ENDPOINT, NULL,
339 UX_FALSE, 0,
340 0 , 0, UX_NULL, 0, 0,
341 UX_ERROR},
342 { UX_HCD_CREATE_ENDPOINT, NULL,
343 UX_FALSE, 0,
344 0 , 0, UX_NULL, 0, 0,
345 UX_ERROR},
346 { UX_HCD_TRANSFER_REQUEST, NULL,
347 UX_FALSE, 0,
348 0 , 0, UX_NULL, 0, 0,
349 UX_ERROR , ux_test_hcd_entry_should_not_be_called},
350 { 0 }
351 };
352
353 static UX_TEST_HCD_SIM_ACTION disconnect_on_SetAddress[] = {
354 /* function, request to match,
355 port action, port status,
356 request action, request EP, request data, request actual length, request status,
357 status, additional callback,
358 no_return */
359 { UX_HCD_TRANSFER_REQUEST, &_SetAddress,
360 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
361 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
362 UX_ERROR},
363 { UX_HCD_TRANSFER_REQUEST, &_SetAddress,
364 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
365 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
366 UX_ERROR},
367 { UX_HCD_TRANSFER_REQUEST, &_SetAddress,
368 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
369 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
370 UX_ERROR},
371 { 0 }
372 };
373
374 static UX_TEST_HCD_SIM_ACTION disconnect_on_GetDevDescr[] = {
375 /* function, request to match,
376 port action, port status,
377 request action, request EP, request data, request actual length, request status,
378 status, additional callback,
379 no_return */
380 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
381 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
382 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
383 UX_ERROR},
384 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
385 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
386 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
387 UX_ERROR},
388 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
389 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
390 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
391 0, UX_NULL,
392 UX_TRUE},
393 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
394 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
395 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
396 UX_ERROR},
397 { 0 }
398 };
399
400 static UX_TEST_HCD_SIM_ACTION disconnect_on_GetCfgDescr[] = {
401 /* function, request to match,
402 port action, port status,
403 request action, request EP, request data, request actual length, request status,
404 status, additional callback,
405 no_return */
406 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
407 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
408 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
409 UX_ERROR}, /* First try */
410 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
411 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
412 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
413 UX_ERROR}, /* Second try */
414 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
415 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
416 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
417 UX_SUCCESS, UX_NULL,
418 UX_TRUE}, /* Last try first run */
419 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
420 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
421 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
422 UX_ERROR},
423 { 0 }
424 };
425
426 static UX_TEST_HCD_SIM_ACTION disconnect_on_SetCfg[] = {
427 /* function, request to match,
428 port action, port status,
429 request action, request EP, request data, request actual length, request status,
430 status, additional callback,
431 no_return */
432 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
433 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
434 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
435 UX_ERROR}, /* First try */
436 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
437 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
438 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
439 UX_ERROR}, /* Second try */
440 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
441 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
442 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
443 UX_ERROR}, /* Last try */
444 { 0 }
445 };
446
447 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
448 /* function, request to match,
449 port action, port status,
450 request action, request EP, request data, request actual length, request status,
451 status, additional callback,
452 no_return */
453 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
454 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
455 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
456 UX_SUCCESS, ux_test_hcd_entry_set_cfg,
457 UX_TRUE}, /* Invoke callback & continue */
458 { 0 }
459 };
460
461 static UX_TEST_HCD_SIM_ACTION normal_enum_replace[] = {
462 /* function, request to match,
463 port action, port status,
464 request action, request EP, request data, request actual length, request status,
465 status, additional callback,
466 no_return */
467 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
468 UX_FALSE, 0,
469 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
470 UX_SUCCESS, UX_NULL},
471 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
472 UX_FALSE, 0,
473 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
474 UX_SUCCESS, UX_NULL},
475 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
476 UX_FALSE, 0,
477 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
478 UX_SUCCESS, UX_NULL},
479 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
480 UX_FALSE, 0,
481 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 18, 0,
482 UX_SUCCESS, UX_NULL},
483 { 0 }
484 }
485 ;
486
487 /* Define the ISR dispatch. */
488
489 extern VOID (*test_isr_dispatch)(void);
490
491
492 /* Prototype for test control return. */
493
494 void test_control_return(UINT status);
495
496
497 /* Define the ISR dispatch routine. */
498
test_isr(void)499 static void test_isr(void)
500 {
501
502 /* For further expansion of interrupt-level testing. */
503 }
504
505
test_class_cdc_acm_get(void)506 static UINT test_class_cdc_acm_get(void)
507 {
508
509 UINT status;
510 UX_HOST_CLASS *class;
511 UX_HOST_CLASS_CDC_ACM *cdc_acm_host;
512
513
514 /* Find the main cdc_acm container */
515 status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
516 if (status != UX_SUCCESS)
517 return(status);
518
519 /* We get the first instance of the cdc_acm device */
520 do
521 {
522
523 status = ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
524 tx_thread_sleep(10);
525 } while (status != UX_SUCCESS);
526
527 /* We still need to wait for the cdc_acm status to be live */
528 while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
529 tx_thread_sleep(10);
530
531 /* Isolate both the control and data interfaces. */
532 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
533 {
534 /* This is the data interface. */
535 cdc_acm_host_data = cdc_acm_host;
536
537 /* In that case, the second one should be the control interface. */
538 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
539
540 /* Check error. */
541 if (status != UX_SUCCESS)
542 return(status);
543
544 /* Check for the control interfaces. */
545 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
546 {
547
548 /* This is the control interface. */
549 cdc_acm_host_control = cdc_acm_host;
550
551 return(UX_SUCCESS);
552
553 }
554 }
555 else
556 {
557 /* Check for the control interfaces. */
558 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
559 {
560
561 /* This is the control interface. */
562 cdc_acm_host_control = cdc_acm_host;
563
564 /* In that case, the second one should be the data interface. */
565 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
566
567 /* Check error. */
568 if (status != UX_SUCCESS)
569 return(status);
570
571 /* Check for the data interface. */
572 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
573 {
574
575 /* This is the data interface. */
576 cdc_acm_host_data = cdc_acm_host;
577
578 return(UX_SUCCESS);
579
580 }
581 }
582 }
583
584 /* Return ERROR. */
585 return(UX_ERROR);
586 }
587
test_slave_change_function(ULONG change)588 static UINT test_slave_change_function(ULONG change)
589 {
590 return 0;
591 }
592
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)593 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
594 {
595
596 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
597
598 switch(event)
599 {
600
601 case UX_DEVICE_INSERTION:
602
603 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
604 cdc_acm_host_control = cdc_acm;
605 else
606 cdc_acm_host_data = cdc_acm;
607 break;
608
609 case UX_DEVICE_REMOVAL:
610
611 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
612 cdc_acm_host_control = UX_NULL;
613 else
614 cdc_acm_host_data = UX_NULL;
615 break;
616
617 default:
618 break;
619 }
620 return 0;
621 }
622
test_cdc_instance_activate(VOID * cdc_instance)623 static VOID test_cdc_instance_activate(VOID *cdc_instance)
624 {
625
626 /* Save the CDC instance. */
627 cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
628 }
test_cdc_instance_deactivate(VOID * cdc_instance)629 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
630 {
631
632 /* Reset the CDC instance. */
633 cdc_acm_slave = UX_NULL;
634 }
635
test_cdc_instance_parameter_change(VOID * cdc_instance)636 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
637 {
638
639 /* Set CDC parameter change flag. */
640 cdc_acm_slave_change = UX_TRUE;
641 }
642
test_swap_framework_bulk_ep_descriptors(VOID)643 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
644 {
645 UCHAR tmp;
646
647 tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
648 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
649 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
650
651 tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
652 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
653 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
654 }
655
656
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)657 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
658 {
659 int x = 0;
660 }
661
ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION * action,VOID * params)662 static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params)
663 {
664
665 error_counter ++;
666 }
667
ux_test_hcd_entry_disconnect(UX_TEST_ACTION * action,VOID * params)668 static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params)
669 {
670
671 ux_test_dcd_sim_slave_disconnect();
672 }
673
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)674 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
675 {
676
677 set_cfg_counter ++;
678
679 rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
680 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
681 rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
682 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
683 }
684
ux_test_system_host_enum_hub_function(VOID)685 static VOID ux_test_system_host_enum_hub_function(VOID)
686 {
687 enum_counter ++;
688 }
689
690 /* Define what the initial system looks like. */
691
692 #ifdef CTEST
test_application_define(void * first_unused_memory)693 void test_application_define(void *first_unused_memory)
694 #else
695 void usbx_host_device_basic_test_application_define(void *first_unused_memory)
696 #endif
697 {
698
699 UINT status;
700 CHAR * stack_pointer;
701 CHAR * memory_pointer;
702
703
704 printf("Running Host & Device Basic Functionality Test...................... ");
705
706 /* Reset testing counts. */
707 ux_test_utility_sim_mutex_create_count_reset();
708 ux_test_utility_sim_sem_create_count_reset();
709 ux_test_utility_sim_sem_get_count_reset();
710 /* Reset error generations */
711 ux_test_utility_sim_sem_error_generation_stop();
712 ux_test_utility_sim_mutex_error_generation_stop();
713 ux_test_utility_sim_sem_get_error_generation_stop();
714
715 /* Initialize the free memory pointer */
716 stack_pointer = (CHAR *) usbx_memory;
717 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
718
719 /* Initialize USBX Memory */
720 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
721
722 /* Check for error. */
723 if (status != UX_SUCCESS)
724 {
725
726 printf(" ERROR #1\n");
727 test_control_return(1);
728 }
729
730 /* Register the error callback. */
731 _ux_utility_error_callback_register(test_ux_error_callback);
732
733 /* The code below is required for installing the host portion of USBX */
734 status = ux_host_stack_initialize(test_host_change_function);
735 if (status != UX_SUCCESS)
736 {
737
738 printf(" ERROR #2\n");
739 test_control_return(1);
740 }
741
742 /* Register CDC-ACM class. */
743 status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
744 if (status != UX_SUCCESS)
745 {
746
747 printf(" ERROR #3\n");
748 test_control_return(1);
749 }
750
751 /* Simulates hub enum function */
752 enum_counter = 0;
753 #if UX_MAX_DEVICES > 1
754 _ux_system_host->ux_system_host_enum_hub_function = ux_test_system_host_enum_hub_function;
755 #endif
756
757 /* The code below is required for installing the device portion of USBX. No call back for
758 device status change in this example. */
759 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
760 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
761 string_framework, STRING_FRAMEWORK_LENGTH,
762 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
763 test_slave_change_function);
764 if(status!=UX_SUCCESS)
765 {
766
767 printf(" ERROR #5\n");
768 test_control_return(1);
769 }
770
771 /* Set the parameters for callback when insertion/extraction of a CDC device. */
772 parameter.ux_slave_class_cdc_acm_instance_activate = test_cdc_instance_activate;
773 parameter.ux_slave_class_cdc_acm_instance_deactivate = test_cdc_instance_deactivate;
774 parameter.ux_slave_class_cdc_acm_parameter_change = test_cdc_instance_parameter_change;
775
776 /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
777 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
778 1,0, ¶meter);
779
780 if(status!=UX_SUCCESS)
781 {
782
783 printf(" ERROR #7\n");
784 test_control_return(1);
785 }
786
787 /* Initialize the simulated device controller. */
788 status = _ux_test_dcd_sim_slave_initialize();
789
790 /* Check for error. */
791 if (status != TX_SUCCESS)
792 {
793
794 printf(" ERROR #8\n");
795 test_control_return(1);
796 }
797
798 /* Register all the USB host controllers available in this system */
799 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
800 if (status != UX_SUCCESS)
801 {
802
803 printf(" ERROR #4\n");
804 test_control_return(1);
805 }
806
807 /* Create the main host simulation thread. */
808 status = tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
809 stack_pointer, UX_DEMO_STACK_SIZE,
810 20, 20, 1, TX_AUTO_START);
811
812 /* Check for error. */
813 if (status != TX_SUCCESS)
814 {
815
816 printf(" ERROR #9\n");
817 test_control_return(1);
818 }
819
820 /* Create the main slave simulation thread. */
821 status = tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
822 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
823 20, 20, 1, TX_AUTO_START);
824
825 /* Check for error. */
826 if (status != TX_SUCCESS)
827 {
828
829 printf(" ERROR #10\n");
830 test_control_return(1);
831 }
832 }
833
tx_test_thread_host_simulation_entry(ULONG arg)834 void tx_test_thread_host_simulation_entry(ULONG arg)
835 {
836
837 UINT status;
838 ULONG test_n;
839 ULONG mem_free;
840
841 stepinfo("\n");
842
843 /* Find the cdc_acm class and wait for the link to be up. */
844 status = test_class_cdc_acm_get();
845 if (status != UX_SUCCESS)
846 {
847
848 /* DPUMP basic test error. */
849 printf("ERROR #11: class not found\n");
850 test_control_return(1);
851 }
852 if (!cdc_acm_host_control && !cdc_acm_host_data)
853 {
854
855 printf("ERROR #12: instance not detected\n");
856 test_control_return(1);
857 }
858 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
859
860 /* Test disconnect. */
861 stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
862 ux_test_dcd_sim_slave_disconnect();
863 ux_test_hcd_sim_host_disconnect();
864 if (cdc_acm_host_control || cdc_acm_host_data)
865 {
866
867 printf("ERROR #13: instance not removed when disconnect");
868 test_control_return(1);
869 }
870 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
871
872 /* Reset testing counts. */
873 stepinfo(">>>>>>>>>>>>>>>> Test connect & connection resource\n");
874 ux_test_utility_sim_mutex_create_count_reset();
875 ux_test_utility_sim_sem_create_count_reset();
876 ux_test_utility_sim_sem_get_count_reset();
877 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
878 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
879 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
880 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
881 tx_thread_sleep(100);
882 /* Log create counts when SetConfigure for further tests. */
883 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
884 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
885 rsc_enum_sem_get_count = rsc_sem_get_on_set_cfg;
886 rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
887 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
888
889 /* Reset enum counter */
890 enum_counter = 0;
891
892 stepinfo(">>>>>>>>>>>>>>>> Test disconnect on reset\n");
893 ux_test_hcd_sim_host_disconnect();
894 ux_test_hcd_sim_host_set_actions(disconnect_on_reset);
895 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
896 if (cdc_acm_host_control || cdc_acm_host_data)
897 {
898
899 printf("ERROR #13: instance installed when disconnect on reset");
900 test_control_return(1);
901 }
902 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
903 #if UX_MAX_DEVICES > 1
904 /* Enumeration should be processed */
905 if (enum_counter == 0)
906 {
907
908 printf("ERROR #%d: enum entry not invoked\n", __LINE__);
909 test_control_return(1);
910 }
911 #endif
912 stepinfo(">>>>>>>>>>>>>>>> Test EP0 fail\n");
913 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
914 ux_test_hcd_sim_host_disconnect();
915 ux_test_hcd_sim_host_set_actions(endpoint0_create_fail);
916 error_counter = 0;
917 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
918 if (error_counter)
919 {
920
921 /* DPUMP basic test error. */
922 printf("ERROR #14: detect EP transfer when EP0 creation fail\n");
923 test_control_return(1);
924 }
925 if (cdc_acm_host_control || cdc_acm_host_data)
926 {
927
928 printf("ERROR #15: instance installed when EP0 creation fail\n");
929 test_control_return(1);
930 }
931 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
932
933 stepinfo(">>>>>>>>>>>>>>>> Test disconnect on SetAddress\n");
934 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
935 ux_test_hcd_sim_host_disconnect();
936 ux_test_hcd_sim_host_set_actions(disconnect_on_SetAddress);
937 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
938 if (cdc_acm_host_control)
939 {
940
941 printf("ERROR #14: detect device when disconnect on SetAddress\n");
942 test_control_return(1);
943 }
944 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
945
946 stepinfo(">>>>>>>>>>>>>>>> Test disconnect on GetDeviceDescriptor\n");
947 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
948 ux_test_hcd_sim_host_disconnect();
949 ux_test_hcd_sim_host_set_actions(disconnect_on_GetDevDescr);
950 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
951 if (cdc_acm_host_control)
952 {
953
954 printf("ERROR #15: detect device when disconnect on GetDeviceDescriptor\n");
955 test_control_return(1);
956 }
957 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
958
959 stepinfo(">>>>>>>>>>>>>>>> Test disconnect on GetConfigureDescriptor\n");
960 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
961 ux_test_hcd_sim_host_disconnect();
962 ux_test_hcd_sim_host_set_actions(disconnect_on_GetCfgDescr);
963 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
964 if (cdc_acm_host_control)
965 {
966
967 printf("ERROR #16: detect device when disconnect on GetConfigureDescriptor\n");
968 test_control_return(1);
969 }
970 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
971
972 stepinfo(">>>>>>>>>>>>>>>> Test disconnect on SetConfigure\n");
973 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
974 ux_test_hcd_sim_host_disconnect();
975 ux_test_hcd_sim_host_set_actions(disconnect_on_SetCfg);
976 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
977 if (cdc_acm_host_control)
978 {
979
980 printf("ERROR #17: detect device when disconnect on SetConfigure\n");
981 test_control_return(1);
982 }
983 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
984
985 stepinfo(">>>>>>>>>>>>>>>> Normal replace descriptor test\n");
986 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
987 ux_test_hcd_sim_host_disconnect();
988 ux_test_hcd_sim_host_set_actions(normal_enum_replace);
989 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
990 tx_thread_sleep(100);
991 if (!cdc_acm_host_control)
992 {
993
994 printf("ERROR #18: no device detected when replacing DevDescr and CfgDescr\n");
995 test_control_return(1);
996 }
997 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
998
999 /* Swap bulk IN/OUT endpoint position.
1000 Simulate detach and attach for HS enumeration,
1001 and test possible mutex creation error handlings.
1002 */
1003 if (rsc_enum_mutex_usage) stepinfo(">>>>>>>>>>>>>>>> Mutex errors enumeration test\n");
1004 for (test_n = 0; test_n < rsc_enum_mutex_usage; test_n ++)
1005 {
1006
1007 stepinfo("%ld / %ld\n", test_n, rsc_enum_mutex_usage - 1);
1008
1009 /* Disconnect. */
1010 ux_test_dcd_sim_slave_disconnect();
1011 ux_test_hcd_sim_host_disconnect();
1012
1013 /* Swap EP address. */
1014 test_swap_framework_bulk_ep_descriptors();
1015
1016 /* Generate error while the test_n and after mutex are requested */
1017 ux_test_utility_sim_mutex_error_generation_start(test_n);
1018
1019 /* Count SetConfigure */
1020 set_cfg_counter = 0;
1021 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1022
1023 /* Connect. */
1024 ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
1025 ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
1026
1027 if (set_cfg_counter)
1028 {
1029
1030 printf("ERROR #19.%ld: device detected when there is mutex error\n", test_n);
1031 test_control_return(1);
1032 }
1033 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1034 }
1035 ux_test_utility_sim_mutex_error_generation_stop();
1036 if (rsc_enum_mutex_usage) stepinfo("\n");
1037
1038 /* Simulate detach and attach for FS enumeration,
1039 and test possible semaphore creation error handlings.
1040 Note CDC ACM has two semaphore for bulk endpoints, not tested here.
1041 */
1042 if (rsc_enum_sem_usage) stepinfo(">>>>>>>>>>>>>>>> Semaphore errors enumeration test\n");
1043 for (test_n = 0; test_n < rsc_enum_sem_usage; test_n ++)
1044 {
1045
1046 stepinfo("%2ld / %2ld\n", test_n, rsc_enum_sem_usage - 1);
1047
1048 /* Disconnect. */
1049 ux_test_dcd_sim_slave_disconnect();
1050 ux_test_hcd_sim_host_disconnect();
1051
1052 /* Generate error while the test_n and after semaphore are requested */
1053 ux_test_utility_sim_sem_error_generation_start(test_n);
1054
1055 /* Count SetConfigure */
1056 set_cfg_counter = 0;
1057 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1058
1059 /* Connect. */
1060 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1061 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1062
1063 /* Check error */
1064 if (set_cfg_counter)
1065 {
1066
1067 printf("ERROR #21.%ld: device detected when there is semaphore error\n", test_n);
1068 test_control_return(1);
1069 }
1070 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1071 }
1072 ux_test_utility_sim_sem_error_generation_stop();
1073 if (rsc_enum_sem_usage) stepinfo("\n");
1074
1075 /* Simulate detach and attach for FS enumeration,
1076 and test possible semaphore get error handlings.
1077 */
1078 if (rsc_enum_sem_get_count) stepinfo(">>>>>>>>>>>>>>>> Semaphore GET errors enumeration test\n");
1079 for (test_n = 0; test_n < rsc_enum_sem_get_count; test_n ++)
1080 {
1081
1082 stepinfo("%2ld / %2ld\n", test_n, rsc_enum_sem_get_count - 1);
1083
1084 /* Disconnect. */
1085 ux_test_dcd_sim_slave_disconnect();
1086 ux_test_hcd_sim_host_disconnect();
1087
1088 /* Generate error while the test_n and after semaphore are requested */
1089 ux_test_utility_sim_sem_get_error_generation_start(test_n);
1090
1091 /* Count SetConfigure */
1092 set_cfg_counter = 0;
1093 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1094
1095 /* Connect. */
1096 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1097 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1098
1099 if (set_cfg_counter)
1100 {
1101
1102 printf("ERROR #24.%ld: device detected when there is semaphore GET error\n", test_n);
1103 test_control_return(1);
1104 }
1105 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1106 }
1107 ux_test_utility_sim_sem_get_error_generation_stop();
1108 if (rsc_enum_sem_usage) stepinfo("\n");
1109
1110 /* Finally disconnect the device. */
1111 ux_device_stack_disconnect();
1112
1113 /* And deinitialize the class. */
1114 status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
1115
1116 /* Deinitialize the device side of usbx. */
1117 _ux_device_stack_uninitialize();
1118
1119 /* And finally the usbx system resources. */
1120 _ux_system_uninitialize();
1121
1122 /* Successful test. */
1123 printf("SUCCESS!\n");
1124 test_control_return(0);
1125
1126 }
1127
tx_test_thread_slave_simulation_entry(ULONG arg)1128 void tx_test_thread_slave_simulation_entry(ULONG arg)
1129 {
1130
1131 while(1)
1132 {
1133
1134 /* Sleep so ThreadX on Win32 will delete this thread. */
1135 tx_thread_sleep(10);
1136 }
1137 }
1138