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