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 #include "ux_hcd_sim_host.h"
9
10 #include "fx_api.h"
11
12 #include "ux_device_class_cdc_acm.h"
13 #include "ux_device_stack.h"
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 #define UX_DEMO_REQUEST_MAX_LENGTH \
21 ((UX_HCD_SIM_HOST_MAX_PAYLOAD) > (UX_SLAVE_REQUEST_DATA_MAX_LENGTH) ? \
22 (UX_HCD_SIM_HOST_MAX_PAYLOAD) : (UX_SLAVE_REQUEST_DATA_MAX_LENGTH))
23
24 /* Define constants. */
25 #define UX_CDC_ACM_CONNECTION_DELAY ((UX_RH_ENUMERATION_RETRY + 1)*UX_HOST_CLASS_CDC_ACM_DEVICE_INIT_DELAY)
26 #define UX_DEMO_DEBUG_SIZE (4096*8)
27 #define UX_DEMO_STACK_SIZE 1024
28 #define UX_DEMO_BUFFER_SIZE (UX_DEMO_REQUEST_MAX_LENGTH + 1)
29 #define UX_DEMO_XMIT_BUFFER_SIZE 512
30 #define UX_DEMO_RECEPTION_BUFFER_SIZE 512
31 #define UX_DEMO_FILE_BUFFER_SIZE 512
32 #define UX_DEMO_RECEPTION_BLOCK_SIZE 64
33 #define UX_DEMO_MEMORY_SIZE (128*1024)
34 #define UX_DEMO_FILE_SIZE (128 * 1024)
35 #define UX_RAM_DISK_MEMORY (256 * 1024)
36
37 /* Define local/extern function prototypes. */
38 static void test_thread_entry(ULONG);
39 static TX_THREAD tx_test_thread_host_simulation;
40 static TX_THREAD tx_test_thread_slave_simulation;
41 static void tx_test_thread_host_simulation_entry(ULONG);
42 static void tx_test_thread_slave_simulation_entry(ULONG);
43 static void test_thread_host_reception_callback(UX_HOST_CLASS_CDC_ACM *cdc_acm, UINT status, UCHAR *reception_buffer, ULONG reception_size);
44 static VOID demo_cdc_instance_activate(VOID *cdc_instance);
45 static VOID demo_cdc_instance_deactivate(VOID *cdc_instance);
46 static VOID demo_cdc_instance_parameter_change(VOID *cdc_instance);
47 static UINT test_usbx_simulator_cdc_acm_host_send_command(UCHAR *string, ULONG length, ULONG no_ack);
48 static UINT tx_test_thread_slave_simulation_response(UCHAR *string, ULONG length);
49
50 static UINT ux_test_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM *cdc_acm, ULONG command, ULONG value, UCHAR *data_buffer, ULONG data_length, ULONG *actual_length);
51
52 static VOID ux_test_host_class_cdc_acm_device_status_change_callback(struct UX_HOST_CLASS_CDC_ACM_STRUCT *cdc_acm,
53 ULONG notification_type, ULONG notification_value);
54
55 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
56 static VOID ux_test_hcd_entry_interaction_request_sem_put(UX_TEST_ACTION *action, VOID *params);
57 static VOID ux_test_hcd_entry_interaction_invoked(UX_TEST_ACTION *action, VOID *params);
58 static VOID ux_test_hcd_entry_interaction_wait_transfer_disconnection(UX_TEST_ACTION *action, VOID *params);
59
60 #define test_usbx_simulator_cdc_acm_host_send_at_command(s,l) test_usbx_simulator_cdc_acm_host_send_command(s,l,UX_FALSE)
61 #define test_usbx_simulator_cdc_acm_host_send_string(s,l) test_usbx_simulator_cdc_acm_host_send_command(s,l,UX_TRUE)
62
63 /* Define global data structures. */
64 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
65 static UX_HOST_CLASS *class_driver;
66 static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
67 static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
68 static ULONG notification_count;
69 static ULONG command_received_count;
70 static UCHAR cdc_acm_reception_buffer[UX_DEMO_RECEPTION_BUFFER_SIZE];
71 static UCHAR cdc_acm_xmit_buffer[UX_DEMO_XMIT_BUFFER_SIZE];
72 static UX_HOST_CLASS_CDC_ACM_RECEPTION cdc_acm_reception;
73 static UCHAR *global_reception_buffer;
74 static ULONG global_reception_size;
75 static UCHAR cdc_acm_reception_overflow = UX_FALSE;
76
77 static UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
78 static UCHAR cdc_acm_slave_change;
79 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
80 static UCHAR buffer[UX_DEMO_BUFFER_SIZE * 4]; /* Large enough to avoid memory access exception. */
81 static UCHAR cdc_acm_slave_bulk_read_write = UX_TRUE;
82
83 static ULONG error_counter;
84
85 static ULONG set_cfg_counter;
86
87 static ULONG rsc_mem_free_on_set_cfg;
88 static ULONG rsc_sem_on_set_cfg;
89 static ULONG rsc_sem_get_on_set_cfg;
90 static ULONG rsc_mutex_on_set_cfg;
91
92 static ULONG rsc_enum_sem_usage;
93 static ULONG rsc_enum_sem_get_count;
94 static ULONG rsc_enum_mutex_usage;
95 static ULONG rsc_enum_mem_usage;
96
97 static ULONG rsc_cdc_sem_usage;
98 static ULONG rsc_cdc_sem_get_count;
99 static ULONG rsc_cdc_mutex_usage;
100 static ULONG rsc_cdc_mem_usage;
101
102 static ULONG interaction_count;
103
104 static UCHAR error_callback_ignore = UX_TRUE;
105 static ULONG error_callback_counter;
106
107 static UCHAR _rsp_ok[UX_DEMO_BUFFER_SIZE] = {'O', 'K', '\r', '\n', '\0'};
108
109 /* Define device framework. */
110
111 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED (93 + 7)
112 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED (103 + 7)
113 #define STRING_FRAMEWORK_LENGTH 47
114 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
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,
132
133 /* Configuration 1 descriptor 9 bytes */
134 0x09, 0x02, 0x52, 0x00,
135 0x02, 0x01, 0x00,
136 0x40, 0x00,
137
138 /* Interface association descriptor. 8 bytes. */
139 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
140
141 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
142 0x09, 0x04, 0x00,
143 0x00,
144 0x02,
145 0x02, 0x02, 0x01,
146 0x00,
147
148 /* Header Functional Descriptor 5 bytes */
149 0x05, 0x24, 0x00,
150 0x10, 0x01,
151
152 /* ACM Functional Descriptor 4 bytes */
153 0x04, 0x24, 0x02,
154 0x0f,
155
156 /* Union Functional Descriptor 5 bytes */
157 0x05, 0x24, 0x06,
158 0x00, /* Master interface */
159 0x01, /* Slave interface */
160
161 /* Call Management Functional Descriptor 5 bytes */
162 0x05, 0x24, 0x01,
163 0x03,
164 0x01, /* Data interface */
165
166 /* Endpoint 0x04 descriptor 7 bytes */
167 0x07, 0x05, 0x04,
168 0x03,
169 0x08, 0x00,
170 15,
171
172 /* Endpoint 0x83 descriptor 7 bytes */
173 0x07, 0x05, 0x83,
174 0x03,
175 0x08, 0x00,
176 0xFF,
177
178 /* Data Class Interface Descriptor Requirement 9 bytes */
179 0x09, 0x04, 0x01,
180 0x00,
181 0x02,
182 0x0A, 0x00, 0x00,
183 0x00,
184
185 /* Endpoint 0x02 descriptor 7 bytes */
186 0x07, 0x05, 0x02, /* @ 93 - 14 + 2 = 81 */
187 0x02,
188 0x40, 0x00,
189 0x00,
190
191 /* Endpoint 0x81 descriptor 7 bytes */
192 0x07, 0x05, 0x81, /* @ 93 - 7 + 2 = 88 */
193 0x02,
194 0x40, 0x00,
195 0x00,
196
197 };
198
199 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
200 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
201
202 static unsigned char device_framework_high_speed[] = {
203
204 /* Device descriptor
205 0x02 bDeviceClass: CDC class code
206 0x00 bDeviceSubclass: CDC class sub code
207 0x00 bDeviceProtocol: CDC Device protocol
208
209 idVendor & idProduct - http://www.linux-usb.org/usb.ids
210 */
211 0x12, 0x01, 0x00, 0x02,
212 0xEF, 0x02, 0x01,
213 0x40,
214 0x84, 0x84, 0x00, 0x00,
215 0x00, 0x01,
216 0x01, 0x02, 03,
217 0x01,
218
219 /* Device qualifier descriptor */
220 0x0a, 0x06, 0x00, 0x02,
221 0x02, 0x00, 0x00,
222 0x40,
223 0x01,
224 0x00,
225
226 /* Configuration 1 descriptor */
227 0x09, 0x02, 0x52, 0x00,
228 0x02, 0x01, 0x00,
229 0x40, 0x00,
230
231 /* Interface association descriptor. */
232 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
233
234 /* Communication Class Interface Descriptor Requirement */
235 0x09, 0x04, 0x00,
236 0x00,
237 0x02,
238 0x02, 0x02, 0x01,
239 0x00,
240
241 /* Header Functional Descriptor */
242 0x05, 0x24, 0x00,
243 0x10, 0x01,
244
245 /* ACM Functional Descriptor */
246 0x04, 0x24, 0x02,
247 0x0f,
248
249 /* Union Functional Descriptor */
250 0x05, 0x24, 0x06,
251 0x00,
252 0x01,
253
254 /* Call Management Functional Descriptor */
255 0x05, 0x24, 0x01,
256 0x00,
257 0x01,
258
259 /* Endpoint 0x04 descriptor */
260 0x07, 0x05, 0x04,
261 0x03,
262 0x08, 0x00,
263 10,
264
265 /* Endpoint 0x83 descriptor */
266 0x07, 0x05, 0x83,
267 0x03,
268 0x08, 0x00,
269 10,
270
271 /* Data Class Interface Descriptor Requirement */
272 0x09, 0x04, 0x01,
273 0x00,
274 0x02,
275 0x0A, 0x00, 0x00,
276 0x00,
277
278 /* Endpoint 0x02 descriptor */
279 0x07, 0x05, 0x02, /* @ 103 - 14 + 2 = 91 */
280 0x02,
281 0x40, 0x00,
282 0x00,
283
284 /* Endpoint 0x81 descriptor */
285 0x07, 0x05, 0x81, /* @ 103 - 7 + 2 = 98 */
286 0x02,
287 0x40, 0x00,
288 0x00,
289
290 };
291
292 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
293 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
294
295 static unsigned char string_framework[] = {
296
297 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
298 0x09, 0x04, 0x01, 0x0c,
299 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
300 0x6f, 0x67, 0x69, 0x63,
301
302 /* Product string descriptor : Index 2 - "EL Composite device" */
303 0x09, 0x04, 0x02, 0x13,
304 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
305 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
306 0x69, 0x63, 0x65,
307
308 /* Serial Number string descriptor : Index 3 - "0001" */
309 0x09, 0x04, 0x03, 0x04,
310 0x30, 0x30, 0x30, 0x31
311 };
312
313
314 /* Multiple languages are supported on the device, to add
315 a language besides english, the unicode language code must
316 be appended to the language_id_framework array and the length
317 adjusted accordingly. */
318 static unsigned char language_id_framework[] = {
319
320 /* English. */
321 0x09, 0x04
322 };
323
324 #define DEVICE_FRAMEWORK1_LENGTH (18 +9 +8 +9+5+4+5+5+ 9+7+7) /* =86 */
325 #define DEVICE_FRAMEWORK1_CFG_TOTAL_LEN_POS (18+2)
326 #define DEVICE_FRAMEWORK1_IFC1_N_EPS_POS (86-7-7-9+4)
327 #define DEVICE_FRAMEWORK1_IFC1_EPA1_POS (86-7-7+2)
328 #define DEVICE_FRAMEWORK1_IFC1_EPA2_POS (86-7+2)
329
330 static unsigned char device_framework_no_interrupt_ep[] = {
331
332 /* Device descriptor 18 bytes
333 0x02 bDeviceClass: CDC class code
334 0x00 bDeviceSubclass: CDC class sub code
335 0x00 bDeviceProtocol: CDC Device protocol
336
337 idVendor & idProduct - http://www.linux-usb.org/usb.ids
338 */
339 0x12, 0x01, 0x10, 0x01,
340 0xEF, 0x02, 0x01,
341 0x08,
342 0x84, 0x84, 0x00, 0x00,
343 0x00, 0x01,
344 0x01, 0x02, 0x03,
345 0x01,
346
347 /* Configuration 1 descriptor 9 bytes */
348 0x09, 0x02, 0x44, 0x00, /* wTotalLength @ 21 */
349 0x02, 0x01, 0x00,
350 0x40, 0x00,
351
352 /* Interface association descriptor. 8 bytes. */
353 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
354
355 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
356 0x09, 0x04, 0x00,
357 0x00,
358 0x00,
359 0x02, 0x02, 0x01,
360 0x00,
361
362 /* Header Functional Descriptor 5 bytes */
363 0x05, 0x24, 0x00,
364 0x10, 0x01,
365
366 /* ACM Functional Descriptor 4 bytes */
367 0x04, 0x24, 0x02,
368 0x0f,
369
370 /* Union Functional Descriptor 5 bytes */
371 0x05, 0x24, 0x06,
372 0x00, /* Master interface */
373 0x01, /* Slave interface */
374
375 /* Call Management Functional Descriptor 5 bytes */
376 0x05, 0x24, 0x01,
377 0x03,
378 0x01, /* Data interface */
379
380 /* Data Class Interface Descriptor Requirement 9 bytes */
381 0x09, 0x04, 0x01,
382 0x00,
383 0x02, /* bNumEndpoints @ 86 - 14 - 9 + 4 = 67 */
384 0x0A, 0x00, 0x00,
385 0x00,
386
387 /* Endpoint 0x81 descriptor 7 bytes */
388 0x07, 0x05, 0x81, /* @ 86 - 14 + 2 = 73 */
389 0x02,
390 0x40, 0x00,
391 0x00,
392
393 /* Endpoint 0x02 descriptor 7 bytes */
394 0x07, 0x05, 0x02, /* @ 86 - 7 + 2 = 81 */
395 0x02,
396 0x40, 0x00,
397 0x00,
398
399 };
400
401 static unsigned char replaced_cfg_descriptor[] =
402 {
403 /* Configuration 1 descriptor 9 bytes */
404 0x09, 0x02, 0x52, 0x00,
405 0x02, 0x01, 0x00,
406 0x40, 0x00,
407
408 /* Interface association descriptor. 8 bytes. */
409 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
410
411 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
412 0x09, 0x04, 0x00,
413 0x00,
414 0x02,
415 0x02, 0x02, 0x01,
416 0x00,
417
418 /* Header Functional Descriptor 5 bytes */
419 0x05, 0x24, 0x00,
420 0x10, 0x01,
421
422 /* ACM Functional Descriptor 4 bytes */
423 0x04, 0x24, 0x02,
424 0x0f,
425
426 /* Union Functional Descriptor 5 bytes */
427 0x05, 0x24, 0x06,
428 0x00, /* Master interface */
429 0x01, /* Slave interface */
430
431 /* Call Management Functional Descriptor 5 bytes */
432 0x05, 0x24, 0x01,
433 0x03,
434 0x01, /* Data interface */
435
436 /* Endpoint 0x04 descriptor 7 bytes */
437 0x07, 0x05, 0x04,
438 0x03,
439 0x08, 0x00,
440 10,
441
442 /* Endpoint 0x83 descriptor 7 bytes */
443 0x07, 0x05, 0x83,
444 0x03,
445 0x08, 0x00,
446 10,
447
448 /* Data Class Interface Descriptor Requirement 9 bytes */
449 0x09, 0x04, 0x01,
450 0x00,
451 0x02,
452 0x0A, 0x00, 0x00,
453 0x00,
454
455 /* Endpoint 0x02 descriptor 7 bytes */
456 0x07, 0x05, 0x02, /* @ 93 - 14 + 2 = 81 */
457 0x02,
458 0x40, 0x00,
459 0x00,
460
461 /* Endpoint 0x81 descriptor 7 bytes */
462 0x07, 0x05, 0x81, /* @ 93 - 7 + 2 = 88 */
463 0x02,
464 0x40, 0x00,
465 0x00,
466 };
467
468 static unsigned char replaced_cfg_descriptor_no_bulk[] =
469 {
470 /* Configuration 1 descriptor */
471 0x09, 0x02, 0x52 - 7, 0x00,
472 0x02, 0x01, 0x00,
473 0x40, 0x00,
474
475 /* Interface association descriptor. */
476 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
477
478 /* Communication Class Interface Descriptor Requirement */
479 0x09, 0x04, 0x00,
480 0x00,
481 0x02,
482 0x02, 0x02, 0x01,
483 0x00,
484
485 /* Header Functional Descriptor */
486 0x05, 0x24, 0x00,
487 0x10, 0x01,
488
489 /* ACM Functional Descriptor */
490 0x04, 0x24, 0x02,
491 0x0f,
492
493 /* Union Functional Descriptor */
494 0x05, 0x24, 0x06,
495 0x00,
496 0x01,
497
498 /* Call Management Functional Descriptor */
499 0x05, 0x24, 0x01,
500 0x00,
501 0x01,
502
503 /* Endpoint 0x04 descriptor */
504 0x07, 0x05, 0x04,
505 0x03,
506 0x08, 0x00,
507 10,
508
509 /* Endpoint 0x83 descriptor */
510 0x07, 0x05, 0x83,
511 0x03,
512 0x08, 0x00,
513 10,
514
515 /* Data Class Interface Descriptor Requirement */
516 0x09, 0x04, 0x01,
517 0x00,
518 0x01,
519 0x0A, 0x00, 0x00,
520 0x00,
521
522 /* Endpoint 0x02 descriptor */
523 0x07, 0x05, 0x02, /* @ - 7 + 2 */
524 0x02,
525 0x40, 0x00,
526 0x00,
527
528 };
529
530 /* Setup requests */
531
532 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
533 static UX_TEST_SETUP _GetCfgDescr = UX_TEST_SETUP_GetCfgDescr;
534 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
535 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
536 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
537
538 /* Interaction define */
539
540 static UX_TEST_HCD_SIM_ACTION check_ignore_next_transfer_request[] = {
541 /* function, request to match,
542 port action, port status,
543 request action, request EP, request data, request actual length, request status,
544 status, additional callback,
545 no_return */
546 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
547 UX_FALSE, 0,
548 0, 0, UX_NULL, 0, 0,
549 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
550 { 0 }
551 };
552
553 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
554 /* function, request to match,
555 port action, port status,
556 request action, request EP, request data, request actual length, request status,
557 status, additional callback,
558 no_return */
559 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
560 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
561 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
562 UX_SUCCESS, ux_test_hcd_entry_set_cfg,
563 UX_TRUE}, /* Invoke callback & continue */
564 { 0 }
565 };
566
567 static UX_TEST_HCD_SIM_ACTION wait_disconn_on_transfer_0[] = {
568 /* function, request to match,
569 port action, port status,
570 request action, request EP, request data, request actual length, request status,
571 status, additional callback,
572 no_return */
573 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
574 UX_FALSE, 0,
575 0, 0, UX_NULL, 0, 0,
576 UX_ERROR, ux_test_hcd_entry_interaction_wait_transfer_disconnection},
577 { 0 }
578 };
579
580 static UX_TEST_HCD_SIM_ACTION error_on_transfer_0[] = {
581 /* function, request to match,
582 port action, port status,
583 request action, request EP, request data, request actual length, request status,
584 status, additional callback,
585 no_return */
586 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
587 UX_FALSE, 0,
588 UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, UX_ERROR,
589 UX_ERROR},
590 { 0 }
591 };
592
593 static UX_TEST_HCD_SIM_ACTION error_on_transfer_1[] = {
594 /* function, request to match,
595 port action, port status,
596 request action, request EP, request data, request actual length, request status,
597 status, additional callback,
598 no_return */
599 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
600 UX_FALSE, 0,
601 UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, ~0, 0,
602 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* All requested */
603 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
604 UX_FALSE, 0,
605 UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, UX_ERROR,
606 UX_ERROR, ux_test_hcd_entry_interaction_invoked}, /* Error */
607 { 0 }
608 };
609
610 static UX_TEST_HCD_SIM_ACTION good_on_transfer_1[] = {
611 /* function, request to match,
612 port action, port status,
613 request action, request EP, request data, request actual length, request status,
614 status, additional callback,
615 no_return */
616 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
617 UX_FALSE, 0,
618 UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, ~0, 0, /* Return all required */
619 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* All requested */
620 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
621 UX_FALSE, 0,
622 UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, 0, /* Return ZLP */
623 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* No Error */
624 { 0 }
625 };
626
627 static UX_TEST_HCD_SIM_ACTION good_on_transfer_0_ZLP[] = {
628 /* function, request to match,
629 port action, port status,
630 request action, request EP, request data, request actual length, request status,
631 status, additional callback,
632 no_return */
633 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
634 UX_FALSE, 0,
635 UX_TEST_SIM_REQ_ANSWER, 0, UX_NULL, 0, 0, /* Return ZLP */
636 UX_SUCCESS, ux_test_hcd_entry_interaction_request_sem_put}, /* No Error */
637 { 0 }
638 };
639
640 static UX_TEST_HCD_SIM_ACTION error_on_transfer_interruptEP[] = {
641 /* function, request to match,
642 port action, port status,
643 request action, request EP, request data, request actual length, request status,
644 status, additional callback,
645 no_return */
646 { UX_HCD_TRANSFER_REQUEST, UX_NULL,
647 UX_FALSE, 0,
648 UX_TEST_MATCH_EP, 0x83, UX_NULL, 0, 0,
649 UX_ERROR, ux_test_hcd_entry_interaction_invoked}, /* Error */
650 { 0 }
651 };
652
653 static UX_TEST_HCD_SIM_ACTION replaced_GetCfgDescr[] = {
654 /* function, request to match,
655 port action, port status,
656 request action, request EP, request data, request actual length, request status,
657 status, additional callback,
658 no_return */
659 { UX_HCD_TRANSFER_REQUEST, &_GetCfgDescr,
660 UX_FALSE, 0,
661 UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, replaced_cfg_descriptor, 9, 0,
662 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* Invoke callback & answer */
663 { UX_HCD_TRANSFER_REQUEST, &_GetCfgDescr,
664 UX_FALSE, 0,
665 UX_TEST_SETUP_MATCH_REQ | UX_TEST_SIM_REQ_ANSWER, 0, replaced_cfg_descriptor, sizeof(replaced_cfg_descriptor), 0,
666 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked}, /* Invoke callback & answer */
667 { 0 }
668 };
669
670 static UX_TEST_HCD_SIM_ACTION enum_replace_no_bulk[] = {
671 /* function, request to match,
672 port action, port status,
673 request action, request EP, request data, request actual length, request status,
674 status, additional callback,
675 no_return */
676 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
677 UX_FALSE, 0,
678 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
679 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
680 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
681 UX_FALSE, 0,
682 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
683 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
684
685 /* Note: Each enumeration does two GetConfigurations (the second one is in _ux_host_class_cdc_acm_capabilities_get.c) */
686
687 /* 1st. */
688 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
689 UX_FALSE, 0,
690 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
691 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
692 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
693 UX_FALSE, 0,
694 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
695 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
696 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
697 UX_FALSE, 0,
698 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
699 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
700 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
701 UX_FALSE, 0,
702 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
703 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
704
705 /* 2nd. */
706 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
707 UX_FALSE, 0,
708 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
709 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
710 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
711 UX_FALSE, 0,
712 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
713 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
714 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
715 UX_FALSE, 0,
716 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
717 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
718 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
719 UX_FALSE, 0,
720 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
721 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
722
723 /* 3rd. */
724 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
725 UX_FALSE, 0,
726 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
727 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
728 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
729 UX_FALSE, 0,
730 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
731 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
732 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
733 UX_FALSE, 0,
734 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
735 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
736 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
737 UX_FALSE, 0,
738 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, replaced_cfg_descriptor_no_bulk, sizeof(replaced_cfg_descriptor_no_bulk), 0,
739 UX_SUCCESS, ux_test_hcd_entry_interaction_invoked},
740 { 0 }
741 };
742
743 /* Define the ISR dispatch. */
744
745 extern VOID (*test_isr_dispatch)(void);
746
747
748 /* Prototype for test control return. */
749
750 void test_control_return(UINT status);
751
error_callback(UINT system_level,UINT system_context,UINT error_code)752 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
753 {
754
755 error_callback_counter ++;
756
757 if (!error_callback_ignore)
758 {
759 {
760 /* Failed test. */
761 printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
762 test_control_return(1);
763 }
764 }
765 }
766
sleep_break_on_error(VOID)767 static UINT sleep_break_on_error(VOID)
768 {
769
770 if (error_callback_counter >= 3)
771 return error_callback_counter;
772
773 return UX_SUCCESS;
774 }
775
776 /* Define the ISR dispatch routine. */
777
test_isr(void)778 static void test_isr(void)
779 {
780
781 /* For further expansion of interrupt-level testing. */
782 }
783
784
demo_class_cdc_acm_get(void)785 static UINT demo_class_cdc_acm_get(void)
786 {
787
788 UINT status;
789 UX_HOST_CLASS *class;
790 UX_HOST_CLASS_CDC_ACM *cdc_acm_host;
791
792
793 /* Find the main cdc_acm container */
794 status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
795 if (status != UX_SUCCESS)
796 return(status);
797
798 /* We get the first instance of the cdc_acm device */
799 do
800 {
801
802 status = ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
803 tx_thread_sleep(10);
804 } while (status != UX_SUCCESS);
805
806 /* We still need to wait for the cdc_acm status to be live */
807 while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
808 tx_thread_sleep(10);
809
810 /* Isolate both the control and data interfaces. */
811 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
812 {
813 /* This is the data interface. */
814 cdc_acm_host_data = cdc_acm_host;
815
816 /* In that case, the second one should be the control interface. */
817 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
818
819 /* Check error. */
820 if (status != UX_SUCCESS)
821 return(status);
822
823 /* Check for the control interfaces. */
824 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
825 {
826
827 /* This is the control interface. */
828 cdc_acm_host_control = cdc_acm_host;
829
830 return(UX_SUCCESS);
831
832 }
833 }
834 else
835 {
836 /* Check for the control interfaces. */
837 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
838 {
839
840 /* This is the control interface. */
841 cdc_acm_host_control = cdc_acm_host;
842
843 /* In that case, the second one should be the data interface. */
844 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
845
846 /* Check error. */
847 if (status != UX_SUCCESS)
848 return(status);
849
850 /* Check for the data interface. */
851 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
852 {
853
854 /* This is the data interface. */
855 cdc_acm_host_data = cdc_acm_host;
856
857 return(UX_SUCCESS);
858
859 }
860 }
861 }
862
863 /* Return ERROR. */
864 return(UX_ERROR);
865 }
866
demo_system_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)867 static UINT demo_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
868 {
869
870 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
871
872 switch(event)
873 {
874
875 case UX_DEVICE_INSERTION:
876
877 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
878 cdc_acm_host_control = cdc_acm;
879 else
880 cdc_acm_host_data = cdc_acm;
881 break;
882
883 case UX_DEVICE_REMOVAL:
884
885 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
886 cdc_acm_host_control = UX_NULL;
887 else
888 cdc_acm_host_data = UX_NULL;
889 break;
890
891 default:
892 break;
893 }
894 return 0;
895 }
896
demo_cdc_instance_activate(VOID * cdc_instance)897 static VOID demo_cdc_instance_activate(VOID *cdc_instance)
898 {
899
900 /* Save the CDC instance. */
901 cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
902 }
demo_cdc_instance_deactivate(VOID * cdc_instance)903 static VOID demo_cdc_instance_deactivate(VOID *cdc_instance)
904 {
905
906 /* Reset the CDC instance. */
907 cdc_acm_slave = UX_NULL;
908 }
909
demo_cdc_instance_parameter_change(VOID * cdc_instance)910 static VOID demo_cdc_instance_parameter_change(VOID *cdc_instance)
911 {
912
913 /* Set CDC parameter change flag. */
914 cdc_acm_slave_change = UX_TRUE;
915 }
916
test_swap_framework_bulk_ep_descriptors(VOID)917 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
918 {
919 UCHAR tmp;
920
921 tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
922 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
923 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
924
925 tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
926 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
927 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
928 }
929
test_slave_cdc_acm_transfer_disconnect(UX_SLAVE_CLASS_CDC_ACM * cdc_acm,ULONG ep_dir)930 static VOID test_slave_cdc_acm_transfer_disconnect(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, ULONG ep_dir)
931 {
932
933 UX_SLAVE_ENDPOINT *endpoint;
934 UX_SLAVE_DEVICE *device;
935 UX_SLAVE_INTERFACE *interface;
936 UX_SLAVE_TRANSFER *transfer_request;
937
938 /* Get the pointer to the device. */
939 device = &_ux_system_slave -> ux_system_slave_device;
940
941 /* This is the first time we are activated. We need the interface to the class. */
942 interface = cdc_acm -> ux_slave_class_cdc_acm_interface;
943
944 /* Locate the endpoints. */
945 endpoint = interface -> ux_slave_interface_first_endpoint;
946
947 /* Check the endpoint direction, if OUT we have the correct endpoint. */
948 if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != ep_dir)
949 {
950
951 /* So the next endpoint has to be the OUT endpoint. */
952 endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
953 }
954
955 /* All CDC reading are on the endpoint OUT, from the host. */
956 transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
957
958 /* Continue transfer. */
959 transfer_request -> ux_slave_transfer_request_actual_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
960
961 /* Change device state. */
962 device -> ux_slave_device_state = UX_DEVICE_ATTACHED;
963
964 /* Inform hcd. */
965 _ux_utility_semaphore_put(&transfer_request -> ux_slave_transfer_request_semaphore);
966
967 /* Wait a while for transfer request handling. */
968 tx_thread_sleep(50);
969
970 /* Change device state. */
971 device -> ux_slave_device_state = UX_DEVICE_CONFIGURED;
972 }
973
ux_test_hcd_entry_interaction_wait_transfer_disconnection(UX_TEST_ACTION * action,VOID * _params)974 static VOID ux_test_hcd_entry_interaction_wait_transfer_disconnection(UX_TEST_ACTION *action, VOID *_params)
975 {
976 UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS *params = _params;
977 UX_TRANSFER *transfer_request = (UX_TRANSFER *)params->parameter;
978 UX_ENDPOINT *endpoint;
979 UX_DEVICE *device;
980
981 endpoint = transfer_request -> ux_transfer_request_endpoint;
982 device = endpoint -> ux_endpoint_device;
983
984 while(device -> ux_device_state > UX_DEVICE_RESET)
985 tx_thread_sleep(10);
986 }
987
ux_test_hcd_entry_interaction_invoked(UX_TEST_ACTION * action,VOID * params)988 static VOID ux_test_hcd_entry_interaction_invoked(UX_TEST_ACTION *action, VOID *params)
989 {
990
991 interaction_count ++;
992 }
993
ux_test_hcd_entry_interaction_request_sem_put(UX_TEST_ACTION * action,VOID * params)994 static VOID ux_test_hcd_entry_interaction_request_sem_put(UX_TEST_ACTION *action, VOID *params)
995 {
996
997 interaction_count ++;
998
999 }
1000
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)1001 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
1002 {
1003
1004 set_cfg_counter ++;
1005
1006 rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1007 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
1008 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
1009 }
1010
1011 /* Define what the initial system looks like. */
1012
1013 #ifdef CTEST
test_application_define(void * first_unused_memory)1014 void test_application_define(void *first_unused_memory)
1015 #else
1016 void usbx_cdc_acm_basic_test_application_define(void *first_unused_memory)
1017 #endif
1018 {
1019
1020 UINT status;
1021 CHAR * stack_pointer;
1022 CHAR * memory_pointer;
1023 ULONG test_n;
1024
1025 /* Inform user. */
1026 printf("Running CDC ACM Basic Functionality Test............................ ");
1027
1028 /* Reset testing counts. */
1029 ux_test_utility_sim_mutex_create_count_reset();
1030 ux_test_utility_sim_sem_create_count_reset();
1031 ux_test_utility_sim_sem_get_count_reset();
1032 /* Reset error generations */
1033 ux_test_utility_sim_sem_error_generation_stop();
1034 ux_test_utility_sim_mutex_error_generation_stop();
1035 ux_test_utility_sim_sem_get_error_generation_stop();
1036
1037 /* Initialize the free memory pointer */
1038 stack_pointer = (CHAR *) usbx_memory;
1039 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
1040
1041 /* Initialize USBX Memory */
1042 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
1043
1044 /* Check for error. */
1045 if (status != UX_SUCCESS)
1046 {
1047
1048 printf("ERROR #1\n");
1049 test_control_return(1);
1050 }
1051
1052 /* Register the error callback. */
1053 _ux_utility_error_callback_register(error_callback);
1054
1055 /* The code below is required for installing the host portion of USBX */
1056 status = ux_host_stack_initialize(demo_system_host_change_function);
1057 if (status != UX_SUCCESS)
1058 {
1059
1060 printf("ERROR #2\n");
1061 test_control_return(1);
1062 }
1063
1064 /* Register CDC-ACM class. */
1065 status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
1066 if (status != UX_SUCCESS)
1067 {
1068
1069 printf("ERROR #3\n");
1070 test_control_return(1);
1071 }
1072
1073 /* The code below is required for installing the device portion of USBX. No call back for
1074 device status change in this example. */
1075 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
1076 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
1077 string_framework, STRING_FRAMEWORK_LENGTH,
1078 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
1079 if(status!=UX_SUCCESS)
1080 {
1081
1082 printf("ERROR #5\n");
1083 test_control_return(1);
1084 }
1085
1086 /* Set the parameters for callback when insertion/extraction of a CDC device. */
1087 parameter.ux_slave_class_cdc_acm_instance_activate = demo_cdc_instance_activate;
1088 parameter.ux_slave_class_cdc_acm_instance_deactivate = demo_cdc_instance_deactivate;
1089 parameter.ux_slave_class_cdc_acm_parameter_change = demo_cdc_instance_parameter_change;
1090
1091 /* Mutex will be created on initialize to protect CDC Bulk IN/OUT */
1092 for (test_n = 0; test_n < 2; test_n ++)
1093 {
1094 ux_test_utility_sim_mutex_error_generation_start(test_n);
1095 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
1096 1,0, ¶meter);
1097 /* Mutex error should be reported */
1098 if(status != UX_MUTEX_ERROR)
1099 {
1100
1101 printf("ERROR #46.%ld\n", test_n);
1102 test_control_return(1);
1103 }
1104 }
1105 ux_test_utility_sim_mutex_error_generation_stop();
1106
1107 /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
1108 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
1109 1,0, ¶meter);
1110
1111 if(status!=UX_SUCCESS)
1112 {
1113
1114 printf("ERROR #6\n");
1115 test_control_return(1);
1116 }
1117
1118 /* Initialize the simulated device controller. */
1119 status = _ux_dcd_sim_slave_initialize();
1120
1121 /* Check for error. */
1122 if (status != TX_SUCCESS)
1123 {
1124
1125 printf("ERROR #7\n");
1126 test_control_return(1);
1127 }
1128
1129 /* Register all the USB host controllers available in this system */
1130 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
1131 if (status != UX_SUCCESS)
1132 {
1133
1134 printf("ERROR #4\n");
1135 test_control_return(1);
1136 }
1137
1138 /* Create the main host simulation thread. */
1139 status = tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
1140 stack_pointer, UX_DEMO_STACK_SIZE,
1141 20, 20, 1, TX_AUTO_START);
1142
1143 /* Check for error. */
1144 if (status != TX_SUCCESS)
1145 {
1146
1147 printf("ERROR #8\n");
1148 test_control_return(1);
1149 }
1150
1151 /* Create the main slave simulation thread. */
1152 status = tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
1153 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
1154 20, 20, 1, TX_AUTO_START);
1155
1156 /* Check for error. */
1157 if (status != TX_SUCCESS)
1158 {
1159
1160 printf("ERROR #9\n");
1161 test_control_return(1);
1162 }
1163 }
1164
tx_test_thread_host_simulation_entry(ULONG arg)1165 void tx_test_thread_host_simulation_entry(ULONG arg)
1166 {
1167
1168 UINT status;
1169 UX_HOST_CLASS_CDC_ACM_LINE_CODING line_coding_host;
1170 UX_HOST_CLASS_CDC_ACM_LINE_STATE line_state_host;
1171 ULONG actual_length;
1172 UCHAR at_cmd[16];
1173 UX_SLAVE_CLASS_CDC_ACM * cdc_acm_slave_bak;
1174 UX_HOST_CLASS_CDC_ACM * cdc_acm_host_ctrl_bak;
1175 UX_HOST_CLASS_CDC_ACM * cdc_acm_host_data_bak;
1176 ULONG test_n;
1177 UX_HOST_CLASS_COMMAND command;
1178 UX_HOST_CLASS_COMMAND command1;
1179 ULONG mem_free;
1180
1181 stepinfo("\n");
1182
1183 /* Find the cdc_acm class and wait for the link to be up. */
1184 status = demo_class_cdc_acm_get();
1185 if (status != UX_SUCCESS)
1186 {
1187
1188 /* CDC ACM basic test error. */
1189 printf("ERROR #10\n");
1190 test_control_return(1);
1191 }
1192
1193 /* Reception parameter */
1194 cdc_acm_reception.ux_host_class_cdc_acm_reception_block_size = UX_DEMO_RECEPTION_BLOCK_SIZE;
1195 cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer = cdc_acm_reception_buffer;
1196 cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer_size = UX_DEMO_RECEPTION_BUFFER_SIZE;
1197 cdc_acm_reception.ux_host_class_cdc_acm_reception_callback = test_thread_host_reception_callback;
1198
1199 /* Save slave instance for later tests. */
1200 cdc_acm_slave_bak = cdc_acm_slave;
1201 /* Save host instances for later tests. */
1202 cdc_acm_host_ctrl_bak = cdc_acm_host_control;
1203 cdc_acm_host_data_bak = cdc_acm_host_data;
1204
1205 /* Test disconnect. */
1206 ux_test_dcd_sim_slave_disconnect();
1207 ux_test_hcd_sim_host_disconnect();
1208
1209 /* Test reception on instance inactive */
1210 stepinfo(">>>>>>>>>>>> Start reception when interface is inactive\n");
1211 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data_bak, &cdc_acm_reception);
1212 if (status == UX_SUCCESS)
1213 {
1214
1215 /* CDC ACM basic test error. */
1216 printf("ERROR #86: error must be reported when invoking reception while interface is not ready\n");
1217 test_control_return(1);
1218 }
1219
1220 /* Test stop reception on inactive interface */
1221 stepinfo(">>>>>>>>>>>> Stop reception when interface is inactive\n");
1222 status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data_bak, &cdc_acm_reception);
1223 if (status == UX_SUCCESS)
1224 {
1225
1226 /* CDC ACM basic test error. */
1227 printf("ERROR #91: error not reported when stop reception on inactive interface\n");
1228 test_control_return(1);
1229 }
1230
1231 /* Reset testing counts. */
1232 ux_test_utility_sim_mutex_create_count_reset();
1233 ux_test_utility_sim_sem_create_count_reset();
1234 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1235 /* Save free memory usage. */
1236 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1237 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1238 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1239 tx_thread_sleep(100);
1240 /* Log create counts for further tests. */
1241 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
1242 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
1243 rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
1244 /* Log create counts when instances active for further tests. */
1245 rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
1246 rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
1247 rsc_cdc_mem_usage = rsc_mem_free_on_set_cfg - _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1248 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1249
1250 /* Start the reception on control interface. */
1251 stepinfo(">>>>>>>>>>>> Start reception on control interface\n");
1252 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_control, &cdc_acm_reception);
1253 if (status == UX_SUCCESS)
1254 {
1255
1256 /* CDC ACM basic test error. */
1257 printf("ERROR #87: error must be reported when invoking reception on control interface\n");
1258 test_control_return(1);
1259 }
1260
1261 /* Start and stop immediately. */
1262 stepinfo(">>>>>>>>>>>> Start reception and stop it immediately\n");
1263 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1264 status |= ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
1265 if (status != UX_SUCCESS)
1266 {
1267
1268 /* CDC ACM basic test error. */
1269 printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1270 test_control_return(1);
1271 }
1272
1273 /* Transfer error. */
1274 stepinfo(">>>>>>>>>>>> Start reception request error\n");
1275 ux_test_hcd_sim_host_set_actions(error_on_transfer_0);
1276 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1277 if (status == UX_SUCCESS)
1278 {
1279
1280 /* CDC ACM basic test error. */
1281 printf("ERROR #88: error must be reported when transfer request error\n");
1282 test_control_return(1);
1283 }
1284
1285 /* Start the reception for test. */
1286 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1287 if (status != UX_SUCCESS)
1288 {
1289
1290 /* CDC ACM basic test error. */
1291 printf("ERROR #89: Start reception fail\n");
1292 test_control_return(1);
1293 }
1294
1295 /* Test stop reception on wrong interface */
1296 status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_control, &cdc_acm_reception);
1297 if (status == UX_SUCCESS)
1298 {
1299
1300 /* CDC ACM basic test error. */
1301 printf("ERROR #90: error not reported when stop reception on wrong interface\n");
1302 test_control_return(1);
1303 }
1304
1305 /* Stop reception for test */
1306 status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
1307 if (status != UX_SUCCESS)
1308 {
1309
1310 /* CDC ACM basic test error. */
1311 printf("ERROR #92: stop reception failed\n");
1312 test_control_return(1);
1313 }
1314
1315 /* Start the reception for cdc_acm. */
1316 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1317
1318 /* Get the current data rate. */
1319 stepinfo(">>>>>>>>>>>> ATB: get baud\n");
1320 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATB",3);
1321
1322 /* The device may be extracted after we start sending\receiving. */
1323 if (status != UX_SUCCESS)
1324 {
1325
1326 /* CDC ACM basic test error. */
1327 printf("ERROR #11\n");
1328 test_control_return(1);
1329 }
1330
1331 /* Get the current stop bit rate. */
1332 stepinfo(">>>>>>>>>>>> ATS: get stop bits\n");
1333 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATS",3);
1334
1335 /* The device may be extracted after we start sending\receiving. */
1336 if (status != UX_SUCCESS)
1337 {
1338
1339 /* CDC ACM basic test error. */
1340 printf("ERROR #12\n");
1341 test_control_return(1);
1342 }
1343
1344 /* Get the current parity rate. */
1345 stepinfo(">>>>>>>>>>>> ATP: get parity\n");
1346 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATP",3);
1347
1348 /* The device may be extracted after we start sending\receiving. */
1349 if (status != UX_SUCCESS)
1350 {
1351
1352 /* CDC ACM basic test error. */
1353 printf("ERROR #13\n");
1354 test_control_return(1);
1355 }
1356
1357 /* Get the current data bit rate. */
1358 stepinfo(">>>>>>>>>>>> ATD: data bits\n");
1359 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATD",3);
1360
1361 /* The device may be extracted after we start sending\receiving. */
1362 if (status != UX_SUCCESS)
1363 {
1364
1365 /* CDC ACM basic test error. */
1366 printf("ERROR #14\n");
1367 test_control_return(1);
1368 }
1369
1370 /* Get the current RTS state. */
1371 stepinfo(">>>>>>>>>>>> ATR: RTS\n");
1372 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATR",3);
1373
1374 /* The device may be extracted after we start sending\receiving. */
1375 if (status != UX_SUCCESS)
1376 {
1377
1378 /* CDC ACM basic test error. */
1379 printf("ERROR #15\n");
1380 test_control_return(1);
1381 }
1382
1383 /* Get the current DTR rate. */
1384 stepinfo(">>>>>>>>>>>> ATT: DTR\n");
1385 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATT",3);
1386
1387 /* The device may be extracted after we start sending\receiving. */
1388 if (status != UX_SUCCESS)
1389 {
1390
1391 /* CDC ACM basic test error. */
1392 printf("ERROR #16\n");
1393 test_control_return(1);
1394 }
1395
1396 /* Stop after receive. */
1397 stepinfo(">>>>>>>>>>>> Start reception and stop it immediately\n");
1398 status |= ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
1399 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1400 if (status != UX_SUCCESS)
1401 {
1402
1403 /* CDC ACM basic test error. */
1404 printf("ERROR #%d: code 0x%x\n", __LINE__, status);
1405 test_control_return(1);
1406 }
1407
1408 /* Read 64 bytes and next device side expect 64 byte */
1409 stepinfo(">>>>>>>>>>>> ATOP: 64/64\n");
1410 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATOP", 4);
1411 if (status != UX_SUCCESS)
1412 {
1413
1414 /* CDC ACM basic test error. */
1415 printf("ERROR #%d\n", __LINE__);
1416 test_control_return(1);
1417 }
1418
1419 /* Set the line coding. */
1420 stepinfo(">>>>>>>>>>>> ATL: Set LineCoding\n");
1421 at_cmd[0] = 'A';
1422 at_cmd[1] = 'T';
1423 at_cmd[2] = 'L';
1424 at_cmd[3] = 0x00;
1425 at_cmd[4] = 0xC2;
1426 at_cmd[5] = 0x01;
1427 at_cmd[6] = 0x00; /* 115200: 0x0001C200 */
1428 at_cmd[7] = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_STOP_BIT;
1429 at_cmd[8] = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARITY;
1430 at_cmd[9] = 7;
1431 status = test_usbx_simulator_cdc_acm_host_send_at_command(at_cmd,62);
1432
1433 /* The device may be extracted after we start sending\receiving. */
1434 if (status != UX_SUCCESS)
1435 {
1436
1437 /* CDC ACM basic test error. */
1438 printf("ERROR #33\n");
1439 test_control_return(1);
1440 }
1441
1442 /* Change the line coding values. */
1443 stepinfo(">>>>>>>>>>>> IOCTRL: SetLineCoding\n");
1444 line_coding_host.ux_host_class_cdc_acm_line_coding_dter = 9600;
1445 line_coding_host.ux_host_class_cdc_acm_line_coding_stop_bit = UX_HOST_CLASS_CDC_ACM_LINE_CODING_STOP_BIT_15;
1446 line_coding_host.ux_host_class_cdc_acm_line_coding_parity = UX_HOST_CLASS_CDC_ACM_LINE_CODING_PARITY_EVEN;
1447 line_coding_host.ux_host_class_cdc_acm_line_coding_data_bits = 5;
1448
1449 status = _ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING,
1450 &line_coding_host);
1451
1452 if (status != UX_SUCCESS)
1453 {
1454
1455 /* CDC ACM basic test error. */
1456 printf("ERROR #17\n");
1457 test_control_return(1);
1458 }
1459
1460 /* Slave should invoke parameter change callback */
1461 if (cdc_acm_slave_change != UX_TRUE)
1462 {
1463
1464 /* CDC ACM basic test error. */
1465 printf("ERROR #25\n");
1466 test_control_return(1);
1467 }
1468 /* Reset slave change flag */
1469 cdc_acm_slave_change = UX_FALSE;
1470
1471 /* Change the line state values. */
1472 stepinfo(">>>>>>>>>>>> IOCTRL: SetLineState\n");
1473 line_state_host.ux_host_class_cdc_acm_line_state_rts = 0;
1474 line_state_host.ux_host_class_cdc_acm_line_state_dtr = 0;
1475
1476 status = _ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_STATE,
1477 &line_state_host);
1478
1479 if (status != UX_SUCCESS)
1480 {
1481
1482 /* CDC ACM basic test error. */
1483 printf("ERROR #18\n");
1484 test_control_return(1);
1485 }
1486
1487 /* Slave should invoke parameter change callback */
1488 if (cdc_acm_slave_change != UX_TRUE)
1489 {
1490
1491 /* CDC ACM basic test error. */
1492 printf("ERROR #26\n");
1493 test_control_return(1);
1494 }
1495 /* Reset slave change flag */
1496 cdc_acm_slave_change = UX_FALSE;
1497
1498 /* Reobtain the cdc acm line values. */
1499 /* Get the current data rate. */
1500 stepinfo(">>>>>>>>>>>> ATB: baud rate\n");
1501 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATB",3);
1502
1503 /* The device may be extracted after we start sending\receiving. */
1504 if (status != UX_SUCCESS)
1505 {
1506
1507 /* CDC ACM basic test error. */
1508 printf("ERROR #19\n");
1509 test_control_return(1);
1510 }
1511
1512 /* Get the current stop bit rate. */
1513 stepinfo(">>>>>>>>>>>> ATS: stop bits\n");
1514 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATS",3);
1515
1516 /* The device may be extracted after we start sending\receiving. */
1517 if (status != UX_SUCCESS)
1518 {
1519
1520 /* CDC ACM basic test error. */
1521 printf("ERROR #20\n");
1522 test_control_return(1);
1523 }
1524
1525 /* Get the current parity rate. */
1526 stepinfo(">>>>>>>>>>>> ATP: parity\n");
1527 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATP",3);
1528
1529 /* The device may be extracted after we start sending\receiving. */
1530 if (status != UX_SUCCESS)
1531 {
1532
1533 /* CDC ACM basic test error. */
1534 printf("ERROR #21\n");
1535 test_control_return(1);
1536 }
1537
1538 /* Get the current data bit rate. */
1539 stepinfo(">>>>>>>>>>>> ATD: data bits\n");
1540 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATD",3);
1541
1542 /* The device may be extracted after we start sending\receiving. */
1543 if (status != UX_SUCCESS)
1544 {
1545
1546 /* CDC ACM basic test error. */
1547 printf("ERROR #22\n");
1548 test_control_return(1);
1549 }
1550
1551 /* Get the current RTS state. */
1552 stepinfo(">>>>>>>>>>>> ATR: RTS\n");
1553 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATR",3);
1554
1555 /* The device may be extracted after we start sending\receiving. */
1556 if (status != UX_SUCCESS)
1557 {
1558
1559 /* CDC ACM basic test error. */
1560 printf("ERROR #23\n");
1561 test_control_return(1);
1562 }
1563
1564 /* Test enumeration different descriptors */
1565
1566 /* Initialize to disconnect */
1567 ux_test_dcd_sim_slave_disconnect();
1568 ux_test_hcd_sim_host_disconnect();
1569
1570 /* Test enumeration no interrupt EP */
1571 stepinfo(">>>>>>>>>>>> Enumerate device wihtout interrupt EP\n");
1572 _ux_system_slave->ux_system_slave_device_framework_full_speed = device_framework_no_interrupt_ep;
1573 _ux_system_slave->ux_system_slave_device_framework_length_full_speed = sizeof(device_framework_no_interrupt_ep);
1574 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1575 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1576 ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1577 /* Instances should be ready */
1578 if (!cdc_acm_slave || !cdc_acm_host_control || !cdc_acm_host_data)
1579 {
1580
1581 printf("ERROR #57: instance should ready after reconnect without interrupt EP\n");
1582 test_control_return(1);
1583 }
1584 ux_test_dcd_sim_slave_disconnect();
1585 ux_test_hcd_sim_host_disconnect();
1586 /* Instances should be removed */
1587 if (cdc_acm_slave || cdc_acm_host_control || cdc_acm_host_data)
1588 {
1589
1590 printf("ERROR #60: instance should removed after disconnect without interrupt EP\n");
1591 test_control_return(1);
1592 }
1593
1594 stepinfo(">>>>>>>>>>>> Enumerate device wihtout one of bulk EP\n");
1595 /* Pause bulk read/write since there is no bulk EP. */
1596 cdc_acm_slave_bulk_read_write = UX_FALSE;
1597
1598 /* Test enumeration no bulk EP */
1599
1600 ux_test_hcd_sim_host_set_actions(enum_replace_no_bulk);
1601 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1602 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1603 ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1604 /* Data instances should not be ready */
1605 if (cdc_acm_host_data)
1606 {
1607
1608 printf("ERROR #58: instance should NOT ready after reconnect without one of bulk EP\n");
1609 test_control_return(1);
1610 }
1611 UX_TEST_ASSERT(ux_test_check_actions_empty());
1612
1613 ux_test_dcd_sim_slave_disconnect();
1614 ux_test_hcd_sim_host_disconnect();
1615 if (cdc_acm_slave || cdc_acm_host_control)
1616 {
1617
1618 printf("ERROR #61: instance should be removed after disconnect without one of bulk EP\n");
1619 test_control_return(1);
1620 }
1621
1622 replaced_cfg_descriptor_no_bulk[sizeof(replaced_cfg_descriptor_no_bulk) - 7 + 2] ^= 0x80;
1623 ux_test_hcd_sim_host_set_actions(enum_replace_no_bulk);
1624 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1625 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1626 ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1627 /* Data instances should not be ready */
1628 if (cdc_acm_host_data)
1629 {
1630
1631 printf("ERROR #59: instance should NOT ready after reconnect without one of bulk EP\n");
1632 test_control_return(1);
1633 }
1634
1635 /* Restore frameworks */
1636 ux_test_dcd_sim_slave_disconnect();
1637 ux_test_hcd_sim_host_disconnect();
1638 _ux_system_slave->ux_system_slave_device_framework_full_speed = device_framework_full_speed;
1639 _ux_system_slave->ux_system_slave_device_framework_length_full_speed = DEVICE_FRAMEWORK_LENGTH_FULL_SPEED;
1640 ux_test_hcd_sim_host_set_actions(UX_NULL);
1641 cdc_acm_slave_bulk_read_write = UX_TRUE;
1642
1643 /* Swap EP address for different EP sequence. */
1644 stepinfo(">>>>>>>>>>>> Enumerate device swap bulk EP addresses\n");
1645 ux_test_dcd_sim_slave_disconnect();
1646 ux_test_hcd_sim_host_disconnect();
1647 test_swap_framework_bulk_ep_descriptors();
1648 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1649 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1650 ux_utility_delay_ms(UX_CDC_ACM_CONNECTION_DELAY);
1651 /* Instances should be ready */
1652 if (!cdc_acm_slave || !cdc_acm_host_control || !cdc_acm_host_data)
1653 {
1654
1655 printf("ERROR #53: instance not ready after reconnect (%p,%p,%p)\n", cdc_acm_slave, cdc_acm_host_control, cdc_acm_host_data);
1656 test_control_return(1);
1657 }
1658
1659 if (cdc_acm_host_control->ux_host_class_cdc_acm_interrupt_endpoint)
1660 {
1661
1662 stepinfo(">>>>>>>>>>>> Notification reception test\n");
1663
1664 /* Set notification callback */
1665 status = _ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_NOTIFICATION_CALLBACK,
1666 (VOID*)ux_test_host_class_cdc_acm_device_status_change_callback);
1667 if (status != UX_SUCCESS)
1668 {
1669
1670 printf("ERROR #55: notification callback set fail\n");
1671 test_control_return(1);
1672 }
1673 interaction_count = 0;
1674 ux_test_hcd_sim_host_set_actions(check_ignore_next_transfer_request);
1675 /* Simulate notification! */
1676 cdc_acm_host_control->ux_host_class_cdc_acm_interrupt_endpoint->ux_endpoint_transfer_request.ux_transfer_request_completion_code = UX_SUCCESS;
1677 _ux_host_class_cdc_acm_transfer_request_completed(&cdc_acm_host_control->ux_host_class_cdc_acm_interrupt_endpoint->ux_endpoint_transfer_request);
1678 /* There should be call of transfer to re-start notification monitoring */
1679 if (interaction_count == 0)
1680 {
1681
1682 printf("ERROR #56: notification monitoring not reactivated\n");
1683 test_control_return(1);
1684 }
1685
1686 }
1687
1688 /* Start the reception for cdc_acm. */
1689 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1690 if (status != UX_SUCCESS)
1691 {
1692
1693 printf("ERROR #54: reception start error\n");
1694 test_control_return(1);
1695 }
1696
1697 /* Get the current DTR rate. */
1698 stepinfo(">>>>>>>>>>>> ATT: get DTR\n");
1699 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATT",3);
1700
1701 /* The device may be extracted after we start sending\receiving. */
1702 if (status != UX_SUCCESS)
1703 {
1704
1705 /* CDC ACM basic test error. */
1706 printf("ERROR #24\n");
1707 test_control_return(1);
1708 }
1709
1710 /* Try invalid command on IOCTL. */
1711 stepinfo(">>>>>>>>>>>> ATF: invalid device IOCTRL command\n");
1712 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATF",3);
1713
1714 /* The device may be extracted after we start sending\receiving. */
1715 if (status != UX_SUCCESS)
1716 {
1717
1718 /* CDC ACM basic test error. */
1719 printf("ERROR #36\n");
1720 test_control_return(1);
1721 }
1722
1723 /* Try slave ABORT command on IOCTL. */
1724 stepinfo(">>>>>>>>>>>> ATA: slave IOCTRL ABORT test\n");
1725 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATA",3);
1726
1727 /* The device may be extracted after we start sending\receiving. */
1728 if (status != UX_SUCCESS)
1729 {
1730
1731 /* CDC ACM basic test error. */
1732 printf("ERROR #37\n");
1733 test_control_return(1);
1734 }
1735
1736 /* Start reception again if it's aborted */
1737 ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1738 /* Read until there is no data from slave */
1739 do
1740 {
1741 status = command_received_count;
1742 tx_thread_sleep(20);
1743 } while(status != command_received_count);
1744
1745 /* Try overflow */
1746 stepinfo(">>>>>>>>>>>> Reception overflow test\n");
1747 cdc_acm_reception_overflow = UX_TRUE;
1748 /* Start writing long buffer in device side */
1749 test_usbx_simulator_cdc_acm_host_send_string("ATO\0", 4);
1750 /* Waiting overflow detection */
1751 status = 50;
1752 while(cdc_acm_reception_overflow && status --)
1753 {
1754 tx_thread_sleep(20);
1755 }
1756 if (cdc_acm_reception_overflow)
1757 {
1758
1759 printf("ERROR #93: Reception overflow not detected\n");
1760 cdc_acm_reception_overflow = UX_FALSE;
1761 test_control_return(1);
1762 }
1763 /* Continue reception */
1764 ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1765
1766 /* GetLineCoding with larger buffer size
1767 response should be OK with correct bytes */
1768 stepinfo(">>>>>>>>>>>> GetLineCoding with larger buffer than line coding data\n");
1769 status = ux_test_host_class_cdc_acm_command(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING,
1770 0, cdc_acm_reception_buffer, UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH + 1,
1771 &actual_length);
1772
1773 /* The device may be extracted after we start sending\receiving. */
1774 if (status != UX_SUCCESS)
1775 {
1776
1777 /* CDC ACM basic test error. */
1778 printf("ERROR #27\n");
1779 test_control_return(1);
1780 }
1781 /* Returned number of bytes should be correct */
1782 if (actual_length != UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH)
1783 {
1784
1785 /* CDC ACM basic test error. */
1786 printf("ERROR #28\n");
1787 test_control_return(1);
1788 }
1789
1790 /* Host command test */
1791
1792 /* Undefined command */
1793 stepinfo(">>>>>>>>>>>> Invalid command\n");
1794 status = _ux_host_class_cdc_acm_command(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING + 7,
1795 0, cdc_acm_reception_buffer, UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH + 1);
1796
1797 /* The device may be extracted after we start sending\receiving. */
1798 if (status == UX_SUCCESS)
1799 {
1800
1801 /* CDC ACM basic test error. */
1802 printf("ERROR #29\n");
1803 test_control_return(1);
1804 }
1805
1806 /* Semaphore protection error test */
1807 stepinfo(">>>>>>>>>>>> Semaphore get error on command\n");
1808 ux_test_utility_sim_sem_get_error_generation_start(0);
1809 status = _ux_host_class_cdc_acm_command(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING,
1810 0, cdc_acm_reception_buffer, UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH);
1811 if (status == UX_SUCCESS)
1812 {
1813
1814 printf("ERROR #64: no error reported on control semaphore error\n");
1815 test_control_return(1);
1816 }
1817 ux_test_utility_sim_sem_get_error_generation_stop();
1818
1819 /* Host entry test */
1820
1821 /* Invalid command */
1822 stepinfo(">>>>>>>>>>>> Host Entry - Invalid command\n");
1823 command.ux_host_class_command_request = 0xFF;
1824 status = ux_host_class_cdc_acm_entry(&command);
1825 if (status == UX_SUCCESS)
1826 {
1827
1828 printf("ERROR #62: no error report on invalid command entry\n");
1829 test_control_return(1);
1830 }
1831
1832 stepinfo(">>>>>>>>>>>> Host Entry - Query\n");
1833
1834 /* Query test - wrong class */
1835 command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY;
1836 command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP;
1837 command.ux_host_class_command_class = 0xFF;
1838 status = ux_host_class_cdc_acm_entry(&command);
1839 if (status == UX_SUCCESS)
1840 {
1841
1842 printf("ERROR #63: no error report when Query class wrong\n");
1843 test_control_return(1);
1844 }
1845
1846 /* Query test - CTRL & DLC */
1847 command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY;
1848 command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP;
1849 command.ux_host_class_command_class = UX_HOST_CLASS_CDC_CONTROL_CLASS;
1850 command.ux_host_class_command_subclass = UX_HOST_CLASS_CDC_DLC_SUBCLASS;
1851 command.ux_host_class_command_iad_class = 0;
1852 command.ux_host_class_command_iad_subclass = 0;
1853 status = ux_host_class_cdc_acm_entry(&command);
1854 if (status != UX_SUCCESS)
1855 {
1856
1857 printf("ERROR #64: error report when Query class OK\n");
1858 test_control_return(1);
1859 }
1860
1861 /* Query test - wrong IAD */
1862 command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_QUERY;
1863 command.ux_host_class_command_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP;
1864 command.ux_host_class_command_class = UX_HOST_CLASS_CDC_CONTROL_CLASS;
1865 command.ux_host_class_command_subclass = UX_HOST_CLASS_CDC_DLC_SUBCLASS;
1866 command.ux_host_class_command_iad_class = 0xFE;
1867 status = ux_host_class_cdc_acm_entry(&command);
1868 if (status == UX_SUCCESS)
1869 {
1870
1871 printf("ERROR #65: no error report when Query class IAD wrong");
1872 test_control_return(1);
1873 }
1874
1875 /* Host class deactivate & activate */
1876 stepinfo(">>>>>>>>>>>> Host CDC deactivate & activate\n");
1877 command.ux_host_class_command_container = cdc_acm_host_control->ux_host_class_cdc_acm_interface;
1878 command.ux_host_class_command_class_ptr = cdc_acm_host_control->ux_host_class_cdc_acm_class;
1879 command.ux_host_class_command_instance = cdc_acm_host_control;
1880 command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_DEACTIVATE;
1881
1882 command1.ux_host_class_command_container = cdc_acm_host_data->ux_host_class_cdc_acm_interface;
1883 command1.ux_host_class_command_class_ptr = cdc_acm_host_data->ux_host_class_cdc_acm_class;
1884 command1.ux_host_class_command_instance = cdc_acm_host_data;
1885 command1.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_DEACTIVATE;
1886
1887 ux_host_class_cdc_acm_entry(&command);
1888 /* Instance should be removed */
1889 if (cdc_acm_host_control)
1890 {
1891
1892 printf("ERROR #67: control instance not deactivate\n");
1893 test_control_return(1);
1894 }
1895
1896 ux_host_class_cdc_acm_entry(&command1);
1897 /* Instance should be removed */
1898 if (cdc_acm_host_data)
1899 {
1900
1901 printf("ERROR #67: control instance not deactivate\n");
1902 test_control_return(1);
1903 }
1904
1905 command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE;
1906 ux_host_class_cdc_acm_entry(&command);
1907 /* Instance should be back */
1908 if (!cdc_acm_host_control)
1909 {
1910
1911 printf("ERROR #68: control instance not activate\n");
1912 test_control_return(1);
1913 }
1914
1915 command1.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE;
1916 ux_host_class_cdc_acm_entry(&command1);
1917 /* Instance should be back */
1918 if (!cdc_acm_host_data)
1919 {
1920
1921 printf("ERROR #68: control instance not activate\n");
1922 test_control_return(1);
1923 }
1924
1925 /* Start the reception for cdc_acm. */
1926 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
1927 if (status != UX_SUCCESS)
1928 {
1929
1930 printf("ERROR #70: reception start error\n");
1931 test_control_return(1);
1932 }
1933
1934 /* Get the current stop bit rate. */
1935 stepinfo(">>>>>>>>>>>> ATS: stop bits\n");
1936 status = test_usbx_simulator_cdc_acm_host_send_at_command("ATS",3);
1937
1938 /* The device may be extracted after we start sending\receiving. */
1939 if (status != UX_SUCCESS)
1940 {
1941
1942 /* CDC ACM basic test error. */
1943 printf("ERROR #69\n");
1944 test_control_return(1);
1945 }
1946
1947 /* Sim: slave lost configure while reading pending. */
1948 stepinfo(">>>>>>>>>>>> Slave lost connection while reading\n");
1949 ux_utility_memory_set(cdc_acm_xmit_buffer, 0x00, 3);
1950 status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, 128, &actual_length);
1951 /* Simulate disconnect after first packet sent */
1952 test_slave_cdc_acm_transfer_disconnect(cdc_acm_slave_bak, UX_ENDPOINT_OUT);
1953 status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, 64, &actual_length);
1954 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1955 tx_thread_sleep(50);
1956
1957 /* Sim: slave lost configure while writing pending. */
1958 stepinfo(">>>>>>>>>>>> Slave lost connection while writing\n");
1959 status = test_usbx_simulator_cdc_acm_host_send_string("\0",1);
1960 status = test_usbx_simulator_cdc_acm_host_send_string("ATW",3);
1961 /* The device may be extracted after we start sending\receiving. */
1962 if (status != UX_SUCCESS)
1963 {
1964
1965 /* CDC ACM basic test error. */
1966 printf("ERROR #42\n");
1967 test_control_return(1);
1968 }
1969 tx_thread_sleep(20);
1970 test_slave_cdc_acm_transfer_disconnect(cdc_acm_slave_bak, UX_ENDPOINT_IN);
1971
1972 /* Now disconnect the device. */
1973 ux_test_dcd_sim_slave_disconnect();
1974
1975 /* Read/write through disconnected slave should return error */
1976 stepinfo(">>>>>>>>>>>> R/W on deactivated slave interface instance\n");
1977 /* Try read, error must be returned */
1978 status = ux_device_class_cdc_acm_read(cdc_acm_slave_bak, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
1979 if (status == UX_SUCCESS)
1980 {
1981
1982 /* CDC ACM basic test error. */
1983 printf("ERROR #40\n");
1984 test_control_return(1);
1985
1986 }
1987
1988 /* Try write, error must be returned */
1989 status = ux_device_class_cdc_acm_write(cdc_acm_slave_bak, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
1990 if (status == UX_SUCCESS)
1991 {
1992
1993 /* CDC ACM basic test error. */
1994 printf("ERROR #41\n");
1995 test_control_return(1);
1996
1997 }
1998
1999 stepinfo(">>>>>>>>>>>> R/W on invalid interface instance\n");
2000
2001 /* Try host read on control interface, error must be returned. */
2002 status = ux_host_class_cdc_acm_read(cdc_acm_host_control, buffer, 64, &actual_length);
2003 if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2004 {
2005
2006 /* CDC ACM basic test error. */
2007 printf("ERROR #47\n");
2008 test_control_return(1);
2009 }
2010
2011 /* Try host write, error must be returned. */
2012 status = ux_host_class_cdc_acm_write(cdc_acm_host_control, buffer, 64, &actual_length);
2013 if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2014 {
2015
2016 /* CDC ACM basic test error. */
2017 printf("ERROR #48\n");
2018 test_control_return(1);
2019 }
2020
2021 stepinfo(">>>>>>>>>>>> R/W on deactivated host interface instance\n");
2022
2023 ux_test_hcd_sim_host_disconnect();
2024 tx_thread_sleep(50);
2025
2026 /* Try host read on disconnected interface, error must be returned. */
2027 status = ux_host_class_cdc_acm_read(cdc_acm_host_data_bak, buffer, 64, &actual_length);
2028 if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2029 {
2030
2031 /* CDC ACM basic test error. */
2032 printf("ERROR #49\n");
2033 test_control_return(1);
2034 }
2035
2036 /* Try host write, error must be returned. */
2037 status = ux_host_class_cdc_acm_write(cdc_acm_host_data_bak, buffer, 64, &actual_length);
2038 if (status != UX_HOST_CLASS_INSTANCE_UNKNOWN)
2039 {
2040
2041 /* CDC ACM basic test error. */
2042 printf("ERROR #43\n");
2043 test_control_return(1);
2044 }
2045
2046 stepinfo(">>>>>>>>>>>> IOCTRL on deactivated host interface instance\n");
2047 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data_bak, 0, UX_NULL);
2048 if (status == UX_SUCCESS)
2049 {
2050
2051 printf("ERROR #73: IOCTRL on deactivated interface should report error\n");
2052 test_control_return(1);
2053 }
2054
2055 ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
2056 ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
2057 while(!cdc_acm_host_control || !cdc_acm_host_data)
2058 tx_thread_sleep(10);
2059
2060 /* Host IOCTRL tests */
2061
2062 /* Try invalid IOCTRL command */
2063 stepinfo(">>>>>>>>>>>> IOCTRL invalid command\n");
2064 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, 0xFF, UX_NULL);
2065 if (status != UX_FUNCTION_NOT_SUPPORTED)
2066 {
2067
2068 printf("ERROR #74: IOCTRL with invalid command should report UX_FUNCTION_NOT_SUPPORTED\n");
2069 test_control_return(1);
2070 }
2071
2072 /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS */
2073 stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS\n");
2074 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS, &test_n);
2075 if (status != UX_SUCCESS)
2076 {
2077
2078 printf("ERROR #75: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_DEVICE_STATUS should be OK\n");
2079 test_control_return(1);
2080 }
2081
2082 /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE */
2083 stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE\n");
2084 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE, UX_NULL);
2085 if (status != UX_SUCCESS)
2086 {
2087
2088 printf("ERROR #76: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_OUT_PIPE should be OK\n");
2089 test_control_return(1);
2090 }
2091
2092 /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE */
2093 stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE\n");
2094 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE, UX_NULL);
2095 if (status != UX_SUCCESS)
2096 {
2097
2098 printf("ERROR #77: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_ABORT_IN_PIPE should be OK\n");
2099 test_control_return(1);
2100 }
2101
2102 /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK */
2103 stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK\n");
2104 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_control, UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK, &test_n);
2105 /* Not supported by simulator */
2106 if (status == UX_SUCCESS)
2107 {
2108
2109 printf("ERROR #78: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SEND_BREAK should fail\n");
2110 test_control_return(1);
2111 }
2112
2113 /* Try IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET/SET_LINE_CODING */
2114 stepinfo(">>>>>>>>>>>> IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET/SET_LINE_CODING without enough memory\n");
2115
2116 /* Use out memories */
2117 ux_test_utility_sim_mem_allocate_until(UX_HOST_CLASS_CDC_ACM_LINE_CODING_LENGTH);
2118
2119 /* UX_HOST_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING */
2120 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &test_n);
2121 if (status != UX_MEMORY_INSUFFICIENT)
2122 {
2123
2124 printf("ERROR #80: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING should be fail if no memory\n");
2125 test_control_return(1);
2126 }
2127
2128 /* UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING */
2129 status = ux_host_class_cdc_acm_ioctl(cdc_acm_host_data, UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING, &line_coding_host);
2130 if (status != UX_MEMORY_INSUFFICIENT)
2131 {
2132
2133 printf("ERROR #81: IOCTRL UX_HOST_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING should be fail if no memory\n");
2134 test_control_return(1);
2135 }
2136
2137 /* Free memory */
2138 ux_test_utility_sim_mem_free_all();
2139
2140 /* Try host read/write with semaphore error. */
2141 stepinfo(">>>>>>>>>>>> R/W semaphore error\n");
2142
2143 /* Try host write, error must be returned. */
2144 ux_test_utility_sim_sem_get_error_exception_add(UX_NULL, UX_WAIT_FOREVER);
2145 ux_test_utility_sim_sem_get_error_generation_start(0);
2146
2147 /* Write small size */
2148 status = ux_host_class_cdc_acm_write(cdc_acm_host_data, buffer, 64, &actual_length);
2149 if (status == UX_SUCCESS)
2150 {
2151
2152 /* CDC ACM basic test error. */
2153 printf("ERROR #52: write semaphore error not reported\n");
2154 test_control_return(1);
2155 }
2156
2157 /* Read large size */
2158 status = ux_host_class_cdc_acm_read(cdc_acm_host_data, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2159 if (status == UX_SUCCESS)
2160 {
2161
2162 /* CDC ACM basic test error. */
2163 printf("ERROR #51: read semaphore error not reported\n");
2164 test_control_return(1);
2165 }
2166 ux_test_utility_sim_sem_get_error_generation_stop();
2167 ux_test_utility_sim_sem_get_error_exception_reset();
2168
2169 /* Try host read/write with transfer error. */
2170 stepinfo(">>>>>>>>>>>> R/W transfer error\n");
2171
2172 ux_test_hcd_sim_host_set_actions(error_on_transfer_0);
2173 status = ux_host_class_cdc_acm_write(cdc_acm_host_data, buffer, 64, &actual_length);
2174 if (status == UX_SUCCESS)
2175 {
2176
2177 /* CDC ACM basic test error. */
2178 printf("ERROR #82: write transfer request error not reported\n");
2179 test_control_return(1);
2180 }
2181
2182 /* Stop reception for test */
2183 status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
2184
2185 ux_test_hcd_sim_host_set_actions(error_on_transfer_0);
2186 /* Read large size */
2187 status = ux_host_class_cdc_acm_read(cdc_acm_host_data, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2188 if (status == UX_SUCCESS)
2189 {
2190
2191 /* CDC ACM basic test error. */
2192 printf("ERROR #83: read transfer request error not reported\n");
2193 test_control_return(1);
2194 }
2195
2196 /* Error on second transfer request */
2197 ux_test_hcd_sim_host_set_actions(error_on_transfer_1);
2198
2199 /* Put a semaphore for first transfer request. */
2200 _ux_utility_semaphore_put(&cdc_acm_host_data->ux_host_class_cdc_acm_bulk_in_endpoint->ux_endpoint_transfer_request.ux_transfer_request_semaphore);
2201
2202 /* Read large size */
2203 status = ux_host_class_cdc_acm_read(cdc_acm_host_data, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2204 if (status == UX_SUCCESS)
2205 {
2206
2207 /* CDC ACM basic test error. */
2208 printf("ERROR #84: read transfer request error not reported\n");
2209 test_control_return(1);
2210 }
2211 if (actual_length == 0)
2212 {
2213
2214 /* CDC ACM basic test error. */
2215 printf("ERROR #85: actual length should not be 0\n");
2216 test_control_return(1);
2217 }
2218
2219 /* Flush device. */
2220 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
2221 status = test_usbx_simulator_cdc_acm_host_send_string("ATO0",4);
2222 status = test_usbx_simulator_cdc_acm_host_send_string("ATO0",4);
2223 _tx_thread_sleep(10);
2224
2225 /* Stop reception for read test. */
2226 status = ux_host_class_cdc_acm_reception_stop(cdc_acm_host_data, &cdc_acm_reception);
2227
2228 stepinfo(">>>>>>>>>>>> Read transfer good\n");
2229
2230 /* ATO1: expect return OK */
2231 status = test_usbx_simulator_cdc_acm_host_send_string("ATO1",4);
2232
2233 /* Read, expect short package. */
2234 status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, 64, &actual_length);
2235 if (status != UX_SUCCESS)
2236 {
2237
2238 /* CDC ACM basic test error. */
2239 printf("ERROR #86: read transfer request error should not be reported\n");
2240 test_control_return(1);
2241 }
2242 if (actual_length != 2)
2243 {
2244
2245 /* CDC ACM basic test error. */
2246 printf("ERROR #87: actual length should be 2\n");
2247 test_control_return(1);
2248 }
2249
2250 /* ATO1: expect return OK */
2251 status = test_usbx_simulator_cdc_acm_host_send_string("ATO1",4);
2252
2253 /* Read, expect exact size. */
2254 status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, 2, &actual_length);
2255 if (status != UX_SUCCESS)
2256 {
2257
2258 /* CDC ACM basic test error. */
2259 printf("ERROR #86: read transfer request error should not be reported\n");
2260 test_control_return(1);
2261 }
2262 if (actual_length != 2)
2263 {
2264
2265 /* CDC ACM basic test error. */
2266 printf("ERROR #87: actual length should be 2\n");
2267 test_control_return(1);
2268 }
2269
2270 /* ATO0: expect ZLP */
2271 test_usbx_simulator_cdc_acm_host_send_string("ATO0",4);
2272 status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, 64, &actual_length);
2273 if (status != UX_SUCCESS)
2274 {
2275
2276 /* CDC ACM basic test error. */
2277 printf("ERROR #94: read transfer request error should not be reported\n");
2278 test_control_return(1);
2279 }
2280 if (actual_length != 0)
2281 {
2282
2283 /* CDC ACM basic test error. */
2284 printf("ERROR #95: actual length should be 0 but not %ld\n", actual_length);
2285 test_control_return(1);
2286 }
2287
2288 #if defined(UX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP)
2289 test_usbx_simulator_cdc_acm_host_send_string("ATO2",4);
2290 status = ux_host_class_cdc_acm_read(cdc_acm_host_data, cdc_acm_reception_buffer, UX_DEMO_RECEPTION_BUFFER_SIZE, &actual_length);
2291 if (status != UX_SUCCESS)
2292 {
2293
2294 /* CDC ACM basic test error. */
2295 printf("ERROR #%d: read transfer request error should not be reported\n", __LINE__);
2296 test_control_return(1);
2297 }
2298 if (actual_length != 64)
2299 {
2300
2301 /* CDC ACM basic test error. */
2302 printf("ERROR #%d: actual length should be 64 but not %ld\n", __LINE__, actual_length);
2303 test_control_return(1);
2304 }
2305 #endif
2306
2307 /* Start the reception for cdc_acm. */
2308 status = ux_host_class_cdc_acm_reception_start(cdc_acm_host_data, &cdc_acm_reception);
2309
2310 /* Swap bulk IN/OUT endpoint position.
2311 Simulate detach and attach for HS enumeration,
2312 and test possible mutex creation error handlings.
2313 */
2314 if (rsc_cdc_mutex_usage) stepinfo(">>>>>>>>>>>> Enumerate mutex error\n");
2315 for (test_n = 0; test_n < rsc_cdc_mutex_usage; test_n ++)
2316 {
2317
2318 stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mutex_usage - 1);
2319
2320 /* Disconnect. */
2321 ux_test_dcd_sim_slave_disconnect();
2322 ux_test_hcd_sim_host_disconnect();
2323
2324 /* Swap EP address. */
2325 test_swap_framework_bulk_ep_descriptors();
2326
2327 /* Generate error while the test_n and after mutex are requested */
2328 ux_test_utility_sim_mutex_error_generation_start(test_n + rsc_enum_mutex_usage);
2329
2330 /* Connect. */
2331 ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
2332 ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
2333 tx_thread_sleep(100);
2334
2335 if (cdc_acm_host_control && cdc_acm_host_data)
2336 {
2337
2338 printf("ERROR #97: at least one interface should fail\n");
2339 test_control_return(1);
2340 }
2341 }
2342 ux_test_utility_sim_mutex_error_generation_stop();
2343
2344 /* Simulate detach and attach for FS enumeration,
2345 and test possible semaphore creation error handlings.
2346 */
2347 ux_test_utility_sim_sem_get_error_exception_add(&_ux_system_host -> ux_system_host_hcd_semaphore, UX_WAIT_FOREVER);
2348 if (rsc_cdc_sem_usage) stepinfo(">>>>>>>>>>>> Enumerate semaphore error\n");
2349 for (test_n = 0; test_n < rsc_cdc_sem_usage; test_n ++)
2350 {
2351
2352 stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_sem_usage - 1);
2353
2354 /* Disconnect. */
2355 ux_test_dcd_sim_slave_disconnect();
2356 ux_test_hcd_sim_host_disconnect();
2357
2358 /* Generate error while the test_n and after semaphore are requested */
2359 ux_test_utility_sim_sem_error_generation_start(test_n + rsc_enum_sem_usage);
2360
2361 /* Connect. */
2362 error_callback_counter = 0;
2363 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
2364 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
2365 #if 0
2366 tx_thread_sleep(100);
2367 #else
2368 /* Wait until error detected. */
2369 ux_test_breakable_sleep(100, sleep_break_on_error);
2370 #endif
2371
2372 if (cdc_acm_host_control && cdc_acm_host_data)
2373 {
2374
2375 printf("ERROR #97: at least one interface should fail\n");
2376 test_control_return(1);
2377 }
2378 }
2379 ux_test_utility_sim_sem_error_generation_stop();
2380 ux_test_utility_sim_sem_get_error_exception_reset();
2381
2382 stepinfo(">>>>>>>>>>>> Enumerate interrupt EP transfer request error\n");
2383 /* Disconnect. */
2384 ux_test_dcd_sim_slave_disconnect();
2385 ux_test_hcd_sim_host_disconnect();
2386 /* Transfer error on interrupt IN 0x83 */
2387 ux_test_hcd_sim_host_set_actions(error_on_transfer_interruptEP);
2388 /* Connect. */
2389 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
2390 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
2391 tx_thread_sleep(100);
2392 if (cdc_acm_host_control)
2393 {
2394
2395 printf("ERROR #96: control interface should fail\n");
2396 test_control_return(1);
2397 }
2398
2399 stepinfo(">>>>>>>>>>>> Capabilities get\n");
2400
2401 /* Confirm connection */
2402 ux_test_dcd_sim_slave_disconnect();
2403 ux_test_hcd_sim_host_disconnect();
2404 ux_test_hcd_sim_host_set_actions(UX_NULL);
2405 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
2406 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
2407 test_n = 10;
2408 while(cdc_acm_host_control == UX_NULL && test_n --)
2409 tx_thread_sleep(10);
2410 if (cdc_acm_host_control == UX_NULL)
2411 {
2412
2413 printf("ERROR #99: CDC ACM control interface is not ready\n");
2414 test_control_return(1);
2415 }
2416
2417 /* Some of descriptor length is too small */
2418 replaced_cfg_descriptor[9+8+9+5] = 0;
2419 ux_test_hcd_sim_host_set_actions(replaced_GetCfgDescr);
2420 status = _ux_host_class_cdc_acm_capabilities_get(cdc_acm_host_control);
2421 if (status != UX_DESCRIPTOR_CORRUPTED)
2422 {
2423
2424 printf("ERROR #100: descriptor error should be reported\n");
2425 test_control_return(1);
2426 }
2427
2428 /* Some of descriptor length is too large */
2429 replaced_cfg_descriptor[9+8+9+5] = sizeof(replaced_cfg_descriptor);
2430 ux_test_hcd_sim_host_set_actions(replaced_GetCfgDescr);
2431 status = _ux_host_class_cdc_acm_capabilities_get(cdc_acm_host_control);
2432 if (status != UX_DESCRIPTOR_CORRUPTED)
2433 {
2434
2435 printf("ERROR #101: no descriptor error reported\n");
2436 test_control_return(1);
2437 }
2438
2439 /* Restore descriptor size */
2440 replaced_cfg_descriptor[9+8+9+5] = device_framework_full_speed[18 + 9+8+9+5];
2441 /* Set descriptor sub class to DLC */
2442 replaced_cfg_descriptor[9+8 + 6] = UX_HOST_CLASS_CDC_DLC_SUBCLASS;
2443 ux_test_hcd_sim_host_set_actions(replaced_GetCfgDescr);
2444 status = _ux_host_class_cdc_acm_capabilities_get(cdc_acm_host_control);
2445 if (status != UX_SUCCESS)
2446 {
2447
2448 printf("ERROR #102: no error expected\n");
2449 test_control_return(1);
2450 }
2451
2452 stepinfo(">>>>>>>>>>>> Deactivate while writing\n");
2453 test_usbx_simulator_cdc_acm_host_send_string("ATK",3); /* Disconnect after 10 tick */
2454 ux_test_hcd_sim_host_set_actions(wait_disconn_on_transfer_0);
2455 status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, 16384, &actual_length);
2456
2457 stepinfo(">>>>>>>>>>>> All Done\n");
2458
2459 /* Finally disconnect the device. */
2460 ux_device_stack_disconnect();
2461
2462 /* And deinitialize the class. */
2463 status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
2464
2465 /* Deinitialize the device side of usbx. */
2466 _ux_device_stack_uninitialize();
2467
2468 /* And finally the usbx system resources. */
2469 _ux_system_uninitialize();
2470
2471 /* Successful test. */
2472 printf("SUCCESS!\n");
2473 test_control_return(0);
2474
2475 }
2476
2477
test_usbx_simulator_cdc_acm_host_send_command(UCHAR * string,ULONG length,ULONG no_ack)2478 UINT test_usbx_simulator_cdc_acm_host_send_command(UCHAR *string, ULONG length, ULONG no_ack)
2479 {
2480
2481 UINT status;
2482 ULONG actual_length;
2483
2484 /* Perform a write to the modem to echo values. And wait for the answer. */
2485 ux_utility_memory_copy(cdc_acm_xmit_buffer, string,length);
2486 cdc_acm_xmit_buffer[length] = 0x0d;
2487 cdc_acm_xmit_buffer[length+1] = 0x0a;
2488
2489 /* Update the length. */
2490 length += 2;
2491
2492 /* Send the AT command. */
2493 status = ux_host_class_cdc_acm_write(cdc_acm_host_data, cdc_acm_xmit_buffer, length, &actual_length);
2494
2495 /* The device may be extracted after we start sending\receiving. */
2496 if (status != UX_SUCCESS)
2497 return(status);
2498
2499 /* Wait for the answer. */
2500 if (!no_ack)
2501 while(command_received_count == 0)
2502 tx_thread_sleep(10);
2503
2504 /* Reset receive count. */
2505 command_received_count = 0;
2506
2507 /* Return status. */
2508 return(status);
2509 }
2510
test_thread_host_reception_callback(UX_HOST_CLASS_CDC_ACM * cdc_acm,UINT status,UCHAR * reception_buffer,ULONG reception_size)2511 void test_thread_host_reception_callback(UX_HOST_CLASS_CDC_ACM *cdc_acm, UINT status, UCHAR *reception_buffer, ULONG reception_size)
2512 {
2513
2514 /* Incase target to test overflow case, buffers are not moved. */
2515 if (!cdc_acm_reception_overflow)
2516 {
2517 /* And move to the next reception buffer. Check if we are at the end of the application buffer. */
2518 if (cdc_acm_reception.ux_host_class_cdc_acm_reception_data_tail + cdc_acm_reception.ux_host_class_cdc_acm_reception_block_size >=
2519 cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer + cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer_size)
2520
2521 /* We are at the end of the buffer. Move back to the beginning. */
2522 cdc_acm_reception.ux_host_class_cdc_acm_reception_data_tail = cdc_acm_reception.ux_host_class_cdc_acm_reception_data_buffer;
2523
2524 else
2525
2526 /* Program the tail to be after the current buffer. */
2527 cdc_acm_reception.ux_host_class_cdc_acm_reception_data_tail += cdc_acm_reception.ux_host_class_cdc_acm_reception_block_size;
2528 }
2529 if (status == UX_BUFFER_OVERFLOW)
2530 cdc_acm_reception_overflow = UX_FALSE;
2531
2532 /* Keep the buffer pointer and length received. */
2533 global_reception_buffer = reception_buffer;
2534 global_reception_size = reception_size;
2535
2536 /* We have received a response. */
2537 command_received_count++;
2538
2539 return;
2540 }
2541
ux_test_host_class_cdc_acm_device_status_change_callback(struct UX_HOST_CLASS_CDC_ACM_STRUCT * cdc_acm,ULONG notification_type,ULONG notification_value)2542 static VOID ux_test_host_class_cdc_acm_device_status_change_callback(
2543 struct UX_HOST_CLASS_CDC_ACM_STRUCT *cdc_acm,
2544 ULONG notification_type,
2545 ULONG notification_value)
2546 {
2547
2548 /* We received a notification */
2549 notification_count ++;
2550 }
2551
2552
tx_test_thread_slave_simulation_entry(ULONG arg)2553 void tx_test_thread_slave_simulation_entry(ULONG arg)
2554 {
2555
2556 UINT status;
2557 ULONG requested_length;
2558 ULONG actual_length;
2559 UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER line_coding;
2560 UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER line_state;
2561 UX_SLAVE_CLASS_COMMAND class_command;
2562
2563 UCHAR data_bit[16];
2564
2565 ULONG read_size = 64;
2566 ULONG write_size;
2567
2568 /* The stack/class code always invoke ux_device_class_cdc_acm_entry correct.
2569 Do a command request error test here. */
2570 class_command.ux_slave_class_command_request = 0xFF;
2571 status = ux_device_class_cdc_acm_entry(&class_command);
2572 /* Error should be reported */
2573 if (status == UX_SUCCESS)
2574 {
2575
2576 /* CDC ACM basic test error. */
2577 printf("ERROR #30\n");
2578 test_control_return(1);
2579 }
2580
2581 /* On CDC ACM driver initialize, there is memory allocation for:
2582 - instance of the device cdc_acm class
2583 - mute for each of endpoint (EP IN and EP OUT)
2584 mute creation never fails so there is no tests.
2585 */
2586 /* Use out memories */
2587 ux_test_utility_sim_mem_allocate_until(sizeof(UX_SLAVE_CLASS_CDC_ACM));
2588
2589 /* Try initialize CDC ACM instance */
2590 class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_INITIALIZE;
2591 status = ux_device_class_cdc_acm_entry(&class_command);
2592 /* Error should be reported */
2593 if (status == UX_SUCCESS)
2594 {
2595
2596 /* CDC ACM basic test error. */
2597 printf("ERROR #32\n");
2598 test_control_return(1);
2599 }
2600
2601 /* Free memory after test */
2602 ux_test_utility_sim_mem_free_all();
2603
2604 while(1)
2605 {
2606
2607 /* Ensure the CDC class is mounted. */
2608 while(cdc_acm_slave != UX_NULL && cdc_acm_slave_bulk_read_write == UX_TRUE)
2609 {
2610
2611 /* Read from the CDC class. */
2612 status = ux_device_class_cdc_acm_read(cdc_acm_slave, buffer, read_size, &actual_length);
2613
2614 if (status != UX_SUCCESS)
2615 {
2616
2617 break;
2618 }
2619
2620 /* Change read size for different read cases */
2621 if (read_size <= 64)
2622 read_size = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
2623
2624 /* The actual length becomes the requested length. */
2625 requested_length = actual_length;
2626
2627 /* Check for AT command. */
2628 if (*buffer == 'A' && *(buffer + 1) == 'T')
2629 {
2630
2631 /* This is a AT command. Decode next byte. */
2632 switch (*(buffer + 2))
2633 {
2634 case 'K' : /* Break! */
2635
2636 tx_thread_sleep(10);
2637 ux_test_hcd_sim_host_disconnect();
2638 break;
2639
2640 case 'O' :
2641
2642 /* Start writing. */
2643 switch(*(buffer + 3))
2644 {
2645 case '0': /* ZLP */
2646 write_size = 0;
2647 break;
2648 case '1': /* Short packet of 2 */
2649 write_size = 2;
2650 break;
2651 case '2': /* Full packet of 64 */
2652 write_size = 64;
2653 break;
2654 case '3': /* Full packet of 512 */
2655 write_size = 512;
2656 break;
2657 case '4': /* Full packet of 4096 */
2658 write_size = 4096;
2659 break;
2660 case '5': /* Full packet of 8128 */
2661 write_size = 8128;
2662 break;
2663 case 'P': /* Full packet of 64 */
2664 write_size = 64;
2665 read_size = 64; /* Next read is 64 */
2666 break;
2667 default:
2668 write_size = UX_DEMO_BUFFER_SIZE * 4;
2669 break;
2670 }
2671
2672 status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, write_size, &actual_length);
2673 if (status == UX_TRANSFER_BUS_RESET)
2674 status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, write_size, &actual_length);
2675
2676 break;
2677
2678 case 'W' :
2679
2680 /* Start writing. */
2681 status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, UX_DEMO_BUFFER_SIZE, &actual_length);
2682 if (status == UX_SUCCESS)
2683 {
2684
2685 /* CDC ACM basic test error. */
2686 printf("ERROR #50\n");
2687 test_control_return(1);
2688 }
2689
2690 break;
2691
2692 case 'A' :
2693
2694 /* This is to try abort XMIT. Pending or next XMIT aborted. */
2695 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);
2696 /* Error should not be reported */
2697 if (status != UX_SUCCESS)
2698 {
2699
2700 /* CDC ACM basic test error. */
2701 printf("ERROR #35\n");
2702 test_control_return(1);
2703 }
2704
2705 /* This is to try abort RCV. */
2706 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);
2707 /* Error should not be reported */
2708 if (status != UX_SUCCESS)
2709 {
2710
2711 /* CDC ACM basic test error. */
2712 printf("ERROR #39\n");
2713 test_control_return(1);
2714 }
2715
2716 /* This is to try abort unknown. */
2717 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_ABORT_PIPE, (VOID*)0xFF);
2718 /* Error should be reported */
2719 if (status == UX_SUCCESS)
2720 {
2721
2722 /* CDC ACM basic test error. */
2723 printf("ERROR #47\n");
2724 test_control_return(1);
2725 }
2726
2727 status = tx_test_thread_slave_simulation_response(_rsp_ok, UX_DEMO_BUFFER_SIZE - 2);
2728 if (status != UX_SUCCESS)
2729 {
2730 /* Try again if it's aborted */
2731 status = tx_test_thread_slave_simulation_response(_rsp_ok, UX_DEMO_BUFFER_SIZE - 2);
2732 }
2733 if (status != UX_SUCCESS)
2734 {
2735
2736 /* CDC ACM basic test error. */
2737 printf("ERROR #44: response sent error %x\n", status);
2738 test_control_return(1);
2739 }
2740
2741 break;
2742
2743 case 'F' :
2744
2745 /* This is to try invalid IOCTRL code */
2746 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, 0xFF, 0);
2747
2748 /* Error should be reported */
2749 if (status == UX_SUCCESS)
2750 {
2751
2752 /* CDC ACM basic test error. */
2753 printf("ERROR #34\n");
2754 test_control_return(1);
2755 }
2756 /* Send response any case */
2757 status = tx_test_thread_slave_simulation_response("OK", 2);
2758 if (status == UX_TRANSFER_BUS_RESET)
2759 status = tx_test_thread_slave_simulation_response("OK", 2);
2760 /* Send ZLP */
2761 ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, 0, &actual_length);
2762 break;
2763
2764 case 'L' :
2765
2766 /* This is to set line coding. */
2767 line_coding.ux_slave_class_cdc_acm_parameter_baudrate = buffer[3] + (buffer[4] << 8) + (buffer[5] << 16) + (buffer[6] << 24);
2768 line_coding.ux_slave_class_cdc_acm_parameter_stop_bit = *(buffer + 7);
2769 line_coding.ux_slave_class_cdc_acm_parameter_parity = *(buffer + 8);
2770 line_coding.ux_slave_class_cdc_acm_parameter_data_bit = *(buffer + 9);
2771 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_SET_LINE_CODING, &line_coding);
2772
2773 if (status != UX_SUCCESS)
2774 {
2775
2776 /* CDC ACM basic test error. */
2777 printf("ERROR #38\n");
2778 test_control_return(1);
2779 }
2780 /* Send response any case */
2781 status = tx_test_thread_slave_simulation_response("OK", 2);
2782 break;
2783
2784 case 'B' :
2785
2786 /* This is to retrieve BAUD rate. */
2787 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2788
2789 /* Any error ? */
2790 if (status == UX_SUCCESS)
2791 {
2792 /* Decode BAUD rate. */
2793 switch (line_coding.ux_slave_class_cdc_acm_parameter_baudrate)
2794 {
2795
2796 case 300 :
2797 status = tx_test_thread_slave_simulation_response("300", 3);
2798 break;
2799
2800 case 1200 :
2801 status = tx_test_thread_slave_simulation_response("1200", 4);
2802 break;
2803
2804 case 2400 :
2805 status = tx_test_thread_slave_simulation_response("2400", 4);
2806 break;
2807
2808 case 4800 :
2809 status = tx_test_thread_slave_simulation_response("4800", 4);
2810 break;
2811
2812 case 9600 :
2813 status = tx_test_thread_slave_simulation_response("9600", 4);
2814 break;
2815
2816 case 14400 :
2817 status = tx_test_thread_slave_simulation_response("14400", 5);
2818 break;
2819
2820 case 19200 :
2821 status = tx_test_thread_slave_simulation_response("19200", 5);
2822 break;
2823
2824 case 28800 :
2825 status = tx_test_thread_slave_simulation_response("28800", 5);
2826 break;
2827
2828 case 38400 :
2829 status = tx_test_thread_slave_simulation_response("38400", 5);
2830 break;
2831
2832 case 57600 :
2833 status = tx_test_thread_slave_simulation_response("57600", 5);
2834 break;
2835
2836 case 115200 :
2837 status = tx_test_thread_slave_simulation_response("115200", 6);
2838 break;
2839
2840 case 230400 :
2841 status = tx_test_thread_slave_simulation_response("230400", 6);
2842 break;
2843 }
2844
2845 }
2846 break;
2847
2848
2849 case 'S' :
2850
2851 /* This is to retrieve stop bit rate. */
2852 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2853
2854 /* Any error ? */
2855 if (status == UX_SUCCESS)
2856 {
2857
2858 /* Decode stop bit. */
2859 switch (line_coding.ux_slave_class_cdc_acm_parameter_stop_bit)
2860 {
2861
2862 case 0 :
2863 status = tx_test_thread_slave_simulation_response("0 Stop bit", 10);
2864 break;
2865
2866 case 1 :
2867 status = tx_test_thread_slave_simulation_response("1.5 Stop bit", 12);
2868 break;
2869
2870 case 2 :
2871 status = tx_test_thread_slave_simulation_response("2 Stop bit", 10);
2872 break;
2873 }
2874 }
2875 break;
2876
2877
2878 case 'P' :
2879
2880 /* This is to retrieve parity rate. */
2881 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2882
2883 /* Any error ? */
2884 if (status == UX_SUCCESS)
2885 {
2886
2887 /* Decode Parity bit. */
2888 switch (line_coding.ux_slave_class_cdc_acm_parameter_parity)
2889 {
2890
2891 case 0 :
2892 status = tx_test_thread_slave_simulation_response("Parity none", 11);
2893 break;
2894
2895 case 1 :
2896 status = tx_test_thread_slave_simulation_response("Parity odd", 10);
2897 break;
2898
2899 case 2 :
2900 status = tx_test_thread_slave_simulation_response("Parity even", 11);
2901 break;
2902
2903 case 3 :
2904 status = tx_test_thread_slave_simulation_response("Parity mark", 11);
2905 break;
2906
2907 case 4 :
2908 status = tx_test_thread_slave_simulation_response("Parity space", 12);
2909 break;
2910
2911
2912 }
2913 }
2914 break;
2915
2916 case 'D' :
2917
2918 /* This is to retrieve Data Bit. */
2919 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_CODING, &line_coding);
2920
2921 /* Any error ? */
2922 if (status == UX_SUCCESS)
2923 {
2924 /* Copy generic string. */
2925 ux_utility_memory_copy(data_bit, "Data Bit x",10);
2926
2927 /* Put data bit value. */
2928 data_bit[9] = line_coding.ux_slave_class_cdc_acm_parameter_data_bit + '0';
2929
2930 /* Send data. */
2931 status = tx_test_thread_slave_simulation_response(data_bit, 10);
2932 }
2933 break;
2934
2935 case 'R' :
2936
2937 /* This is to retrieve RTS state. */
2938 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE, &line_state);
2939
2940 /* Any error ? */
2941 if (status == UX_SUCCESS)
2942 {
2943 /* Check state. */
2944 if (line_state.ux_slave_class_cdc_acm_parameter_rts == UX_TRUE)
2945
2946 /* State is ON. */
2947 status = tx_test_thread_slave_simulation_response("RTS ON", 6);
2948
2949 else
2950
2951 /* State is OFF. */
2952 status = tx_test_thread_slave_simulation_response("RTS OFF", 7);
2953
2954 }
2955 break;
2956
2957 case 'T' :
2958
2959 /* This is to retrieve DTR state. */
2960 status = _ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE, &line_state);
2961
2962 /* Any error ? */
2963 if (status == UX_SUCCESS)
2964 {
2965 /* Check state. */
2966 if (line_state.ux_slave_class_cdc_acm_parameter_dtr == UX_TRUE)
2967
2968 /* State is ON. */
2969 status = tx_test_thread_slave_simulation_response("DTR ON", 6);
2970
2971 else
2972
2973 /* State is OFF. */
2974 status = tx_test_thread_slave_simulation_response("DTR OFF", 7);
2975
2976 }
2977 break;
2978 }
2979 }
2980 else
2981 {
2982
2983 /* Not an AT command, just echo back. */
2984 /* Check the status. If OK, we will write to the CDC instance. */
2985 status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, requested_length, &actual_length);
2986
2987 /* Check for CR/LF. */
2988 if (buffer[requested_length - 1] == '\r')
2989 {
2990
2991 /* Copy LF value into user buffer. */
2992 ux_utility_memory_copy(buffer, "\n", 1);
2993
2994 /* And send it again. */
2995 status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, 1, &actual_length);
2996
2997 }
2998 }
2999 }
3000
3001 /* Sleep so ThreadX on Win32 will delete this thread. */
3002 tx_thread_sleep(10);
3003 }
3004 }
3005
tx_test_thread_slave_simulation_response(UCHAR * string,ULONG length)3006 UINT tx_test_thread_slave_simulation_response(UCHAR *string, ULONG length)
3007 {
3008
3009 UINT status;
3010 ULONG actual_length;
3011
3012 /* Perform a write to the modem to echo values. And wait for the answer. */
3013 ux_utility_memory_copy(buffer, string,length);
3014 buffer[length] = 0x0d;
3015 buffer[length+1] = 0x0a;
3016
3017 /* Update the length. */
3018 length += 2;
3019
3020 /* Check the status. If OK, we will write to the CDC instance. */
3021 status = ux_device_class_cdc_acm_write(cdc_acm_slave, buffer, length, &actual_length);
3022
3023 /* Return status. */
3024 return(status);
3025 }
3026
ux_test_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM * cdc_acm,ULONG command,ULONG value,UCHAR * data_buffer,ULONG data_length,ULONG * actual_length)3027 static UINT ux_test_host_class_cdc_acm_command(UX_HOST_CLASS_CDC_ACM *cdc_acm, ULONG command,
3028 ULONG value, UCHAR *data_buffer, ULONG data_length,
3029 ULONG *actual_length)
3030 {
3031
3032 UX_ENDPOINT *control_endpoint;
3033 UX_TRANSFER *transfer_request;
3034 UINT status;
3035 ULONG request_direction;
3036
3037 /* We need to get the default control endpoint transfer request pointer. */
3038 control_endpoint = &cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_control_endpoint;
3039 transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
3040 switch(command)
3041 {
3042 case UX_HOST_CLASS_CDC_ACM_REQ_GET_ENCAPSULATED_COMMAND:
3043 case UX_HOST_CLASS_CDC_ACM_REQ_GET_COMM_FEATURE:
3044 case UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING:
3045 case UX_HOST_CLASS_CDC_ACM_REQ_GET_RINGER_PARMS:
3046 case UX_HOST_CLASS_CDC_ACM_REQ_GET_OPERATION_PARMS:
3047 case UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_PARMS:
3048
3049 request_direction = UX_REQUEST_IN;
3050 break;
3051
3052 default:
3053
3054 request_direction = UX_REQUEST_OUT;
3055 }
3056
3057 /* Protect the control endpoint semaphore here. It will be unprotected in the
3058 transfer request function. */
3059 status = _ux_utility_semaphore_get(&cdc_acm -> ux_host_class_cdc_acm_device -> ux_device_protection_semaphore, UX_WAIT_FOREVER);
3060
3061 /* Check for status. */
3062 if (status != UX_SUCCESS)
3063
3064 /* Something went wrong. */
3065 return(status);
3066
3067 /* Create a transfer_request for the request. */
3068 transfer_request -> ux_transfer_request_data_pointer = data_buffer;
3069 transfer_request -> ux_transfer_request_requested_length = data_length;
3070 transfer_request -> ux_transfer_request_function = command;
3071 transfer_request -> ux_transfer_request_type = request_direction | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
3072 transfer_request -> ux_transfer_request_value = value;
3073 transfer_request -> ux_transfer_request_index = cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceNumber;
3074
3075 /* Send request to HCD layer. */
3076 status = ux_host_stack_transfer_request(transfer_request);
3077
3078 /* Fill actual length */
3079 if (actual_length) {
3080 *actual_length = transfer_request -> ux_transfer_request_actual_length;
3081 }
3082
3083 /* Return completion status. */
3084 return(status);
3085 }
3086
3087