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