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