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