1 /* This test is designed to test the simple dpump host/device class operation. */
2
3 #include <stdio.h>
4 #include "tx_api.h"
5 #include "ux_api.h"
6 #include "ux_system.h"
7 #include "ux_utility.h"
8
9 #include "fx_api.h"
10
11 #include "ux_device_class_cdc_acm.h"
12 #include "ux_device_stack.h"
13 #include "ux_host_class_cdc_acm.h"
14
15 #include "ux_test_dcd_sim_slave.h"
16 #include "ux_test_hcd_sim_host.h"
17 #include "ux_test_utility_sim.h"
18
19 #if 0 /* TODO: Enable/disable stepinfo */
20 #define stepinfo printf
21 #else
22 #define stepinfo(...)
23 #endif
24
25 /* Define constants. */
26 #define UX_DEMO_DEBUG_SIZE (4096*8)
27 #define UX_DEMO_STACK_SIZE 1024
28 #define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_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 (64*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_cdc_instance_activate(VOID *cdc_instance);
44 static VOID test_cdc_instance_deactivate(VOID *cdc_instance);
45 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance);
46
47 static VOID ux_test_hcd_entry_should_not_be_called(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter);
48 static VOID ux_test_hcd_entry_disconnect(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter);
49 static VOID ux_test_hcd_entry_set_cfg(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter);
50
51 /* Define global data structures. */
52 UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
53 UX_HOST_CLASS *class_driver;
54 UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
55 UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
56 ULONG command_received_count;
57 UCHAR cdc_acm_reception_buffer[UX_DEMO_RECEPTION_BUFFER_SIZE];
58 UCHAR cdc_acm_xmit_buffer[UX_DEMO_XMIT_BUFFER_SIZE];
59 UX_HOST_CLASS_CDC_ACM_RECEPTION cdc_acm_reception;
60 UCHAR *global_reception_buffer;
61 ULONG global_reception_size;
62
63 UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
64 UCHAR cdc_acm_slave_change;
65 UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
66 UCHAR buffer[UX_DEMO_BUFFER_SIZE];
67 ULONG echo_mode;
68
69 ULONG error_counter;
70
71 ULONG set_cfg_counter;
72
73 ULONG rsc_mem_free_on_set_cfg;
74 ULONG rsc_sem_on_set_cfg;
75 ULONG rsc_sem_get_on_set_cfg;
76 ULONG rsc_mutex_on_set_cfg;
77
78 ULONG rsc_enum_sem_usage;
79 ULONG rsc_enum_sem_get_count;
80 ULONG rsc_enum_mutex_usage;
81 ULONG rsc_enum_mem_usage;
82
83 /* Define device framework. */
84
85 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 93
86 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 103
87 #define STRING_FRAMEWORK_LENGTH 47
88 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
89
90 static unsigned char device_framework_full_speed[] = {
91
92 /* Device descriptor 18 bytes
93 0x02 bDeviceClass: CDC class code
94 0x00 bDeviceSubclass: CDC class sub code
95 0x00 bDeviceProtocol: CDC Device protocol
96
97 idVendor & idProduct - http://www.linux-usb.org/usb.ids
98 */
99 0x12, 0x01, 0x10, 0x01,
100 0xEF, 0x02, 0x01,
101 0x08,
102 0x84, 0x84, 0x00, 0x00,
103 0x00, 0x01,
104 0x01, 0x02, 03,
105 0x01,
106
107 /* Configuration 1 descriptor 9 bytes */
108 0x09, 0x02, 0x4b, 0x00,
109 0x02, 0x01, 0x00,
110 0x40, 0x00,
111
112 /* Interface association descriptor. 8 bytes. */
113 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
114
115 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
116 0x09, 0x04, 0x00,
117 0x00,
118 0x01,
119 0x02, 0x02, 0x01,
120 0x00,
121
122 /* Header Functional Descriptor 5 bytes */
123 0x05, 0x24, 0x00,
124 0x10, 0x01,
125
126 /* ACM Functional Descriptor 4 bytes */
127 0x04, 0x24, 0x02,
128 0x0f,
129
130 /* Union Functional Descriptor 5 bytes */
131 0x05, 0x24, 0x06,
132 0x00, /* Master interface */
133 0x01, /* Slave interface */
134
135 /* Call Management Functional Descriptor 5 bytes */
136 0x05, 0x24, 0x01,
137 0x03,
138 0x01, /* Data interface */
139
140 /* Endpoint 0x83 descriptor 7 bytes */
141 0x07, 0x05, 0x83,
142 0x03,
143 0x08, 0x00,
144 0xFF,
145
146 /* Data Class Interface Descriptor Requirement 9 bytes */
147 0x09, 0x04, 0x01,
148 0x00,
149 0x02,
150 0x0A, 0x00, 0x00,
151 0x00,
152
153 /* Endpoint 0x81 descriptor 7 bytes */
154 0x07, 0x05, 0x81, /* @ 93 - 14 + 2 = 81 */
155 0x02,
156 0x40, 0x00,
157 0x00,
158
159 /* Endpoint 0x02 descriptor 7 bytes */
160 0x07, 0x05, 0x02, /* @ 93 - 7 + 2 = 88 */
161 0x02,
162 0x40, 0x00,
163 0x00,
164
165 };
166
167 #define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
168 #define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
169
170 static unsigned char device_framework_high_speed[] = {
171
172 /* Device descriptor
173 0x02 bDeviceClass: CDC class code
174 0x00 bDeviceSubclass: CDC class sub code
175 0x00 bDeviceProtocol: CDC Device protocol
176
177 idVendor & idProduct - http://www.linux-usb.org/usb.ids
178 */
179 0x12, 0x01, 0x00, 0x02,
180 0xEF, 0x02, 0x01,
181 0x40,
182 0x84, 0x84, 0x00, 0x00,
183 0x00, 0x01,
184 0x01, 0x02, 03,
185 0x01,
186
187 /* Device qualifier descriptor */
188 0x0a, 0x06, 0x00, 0x02,
189 0x02, 0x00, 0x00,
190 0x40,
191 0x01,
192 0x00,
193
194 /* Configuration 1 descriptor */
195 0x09, 0x02, 0x4b, 0x00,
196 0x02, 0x01, 0x00,
197 0x40, 0x00,
198
199 /* Interface association descriptor. */
200 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
201
202 /* Communication Class Interface Descriptor Requirement */
203 0x09, 0x04, 0x00,
204 0x00,
205 0x01,
206 0x02, 0x02, 0x01,
207 0x00,
208
209 /* Header Functional Descriptor */
210 0x05, 0x24, 0x00,
211 0x10, 0x01,
212
213 /* ACM Functional Descriptor */
214 0x04, 0x24, 0x02,
215 0x0f,
216
217 /* Union Functional Descriptor */
218 0x05, 0x24, 0x06,
219 0x00,
220 0x01,
221
222 /* Call Management Functional Descriptor */
223 0x05, 0x24, 0x01,
224 0x00,
225 0x01,
226
227 /* Endpoint 0x83 descriptor */
228 0x07, 0x05, 0x83,
229 0x03,
230 0x08, 0x00,
231 0xFF,
232
233 /* Data Class Interface Descriptor Requirement */
234 0x09, 0x04, 0x01,
235 0x00,
236 0x02,
237 0x0A, 0x00, 0x00,
238 0x00,
239
240 /* Endpoint 0x81 descriptor */
241 0x07, 0x05, 0x81, /* @ 103 - 14 + 2 = 91 */
242 0x02,
243 0x40, 0x00,
244 0x00,
245
246 /* Endpoint 0x02 descriptor */
247 0x07, 0x05, 0x02, /* @ 103 - 7 + 2 = 98 */
248 0x02,
249 0x40, 0x00,
250 0x00,
251
252 };
253
254 #define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
255 #define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
256
257 static unsigned char string_framework[] = {
258
259 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
260 0x09, 0x04, 0x01, 0x0c,
261 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
262 0x6f, 0x67, 0x69, 0x63,
263
264 /* Product string descriptor : Index 2 - "EL Composite device" */
265 0x09, 0x04, 0x02, 0x13,
266 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
267 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
268 0x69, 0x63, 0x65,
269
270 /* Serial Number string descriptor : Index 3 - "0001" */
271 0x09, 0x04, 0x03, 0x04,
272 0x30, 0x30, 0x30, 0x31
273 };
274
275
276 /* Multiple languages are supported on the device, to add
277 a language besides english, the unicode language code must
278 be appended to the language_id_framework array and the length
279 adjusted accordingly. */
280 static unsigned char language_id_framework[] = {
281
282 /* English. */
283 0x09, 0x04
284 };
285
286 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
287 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
288 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
289 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
290
291 /* Test interactions */
292
293 /* Disconnect on RESET:
294 * Host still create the EP0 and expects first SETUP request failure.
295 */
296
297 static UX_TEST_HCD_SIM_ACTION disconnect_on_reset[] = {
298 /* function, request to match,
299 port action, port status,
300 request action, request EP, request data, request actual length, request status,
301 status, additional callback,
302 no_return */
303 { UX_HCD_RESET_PORT, NULL,
304 UX_TRUE , UX_TEST_PORT_STATUS_DISC,
305 0 , 0, UX_NULL, 0, 0,
306 UX_SUCCESS, ux_test_hcd_entry_disconnect},
307 #if 0
308 { UX_HCD_CREATE_ENDPOINT, NULL,
309 UX_FALSE, 0,
310 0 , 0, UX_NULL, 0, 0,
311 UX_ERROR , ux_test_hcd_entry_should_not_be_called},
312 #endif
313 { UX_HCD_TRANSFER_REQUEST, NULL,
314 UX_FALSE, 0,
315 0 , 0, UX_NULL, 0, 0,
316 UX_ERROR , UX_NULL}, /* Request just fail on disconnect */
317 { UX_HCD_TRANSFER_REQUEST, NULL,
318 UX_FALSE, 0,
319 0 , 0, UX_NULL, 0, 0,
320 UX_ERROR , UX_NULL},
321 { UX_HCD_TRANSFER_REQUEST, NULL,
322 UX_FALSE, 0,
323 0 , 0, UX_NULL, 0, 0,
324 UX_ERROR , UX_NULL},
325 { 0 }
326 };
327
328 static UX_TEST_HCD_SIM_ACTION endpoint0_create_fail[] = {
329 /* function, request to match,
330 port action, port status,
331 request action, request EP, request data, request actual length, request status,
332 status, additional callback,
333 no_return */
334 { UX_HCD_CREATE_ENDPOINT, NULL,
335 UX_FALSE, 0,
336 0 , 0, UX_NULL, 0, 0,
337 UX_ERROR},
338 { UX_HCD_CREATE_ENDPOINT, NULL,
339 UX_FALSE, 0,
340 0 , 0, UX_NULL, 0, 0,
341 UX_ERROR},
342 { UX_HCD_CREATE_ENDPOINT, NULL,
343 UX_FALSE, 0,
344 0 , 0, UX_NULL, 0, 0,
345 UX_ERROR},
346 { UX_HCD_TRANSFER_REQUEST, NULL,
347 UX_FALSE, 0,
348 0 , 0, UX_NULL, 0, 0,
349 UX_ERROR , ux_test_hcd_entry_should_not_be_called},
350 { 0 }
351 };
352
353 static UX_TEST_HCD_SIM_ACTION disconnect_on_SetAddress[] = {
354 /* function, request to match,
355 port action, port status,
356 request action, request EP, request data, request actual length, request status,
357 status, additional callback,
358 no_return */
359 { UX_HCD_TRANSFER_REQUEST, &_SetAddress,
360 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
361 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
362 UX_ERROR},
363 { UX_HCD_TRANSFER_REQUEST, &_SetAddress,
364 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
365 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
366 UX_ERROR},
367 { UX_HCD_TRANSFER_REQUEST, &_SetAddress,
368 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
369 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
370 UX_ERROR},
371 { 0 }
372 };
373
374 static UX_TEST_HCD_SIM_ACTION disconnect_on_GetDevDescr[] = {
375 /* function, request to match,
376 port action, port status,
377 request action, request EP, request data, request actual length, request status,
378 status, additional callback,
379 no_return */
380 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
381 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
382 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
383 UX_ERROR},
384 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
385 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
386 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
387 UX_ERROR},
388 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
389 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
390 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
391 0, UX_NULL,
392 UX_TRUE},
393 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
394 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
395 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
396 UX_ERROR},
397 { 0 }
398 };
399
400 static UX_TEST_HCD_SIM_ACTION disconnect_on_GetCfgDescr[] = {
401 /* function, request to match,
402 port action, port status,
403 request action, request EP, request data, request actual length, request status,
404 status, additional callback,
405 no_return */
406 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
407 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
408 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
409 UX_ERROR}, /* First try */
410 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
411 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
412 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
413 UX_ERROR}, /* Second try */
414 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
415 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
416 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
417 UX_SUCCESS, UX_NULL,
418 UX_TRUE}, /* Last try first run */
419 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
420 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
421 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, 0,
422 UX_ERROR},
423 { 0 }
424 };
425
426 static UX_TEST_HCD_SIM_ACTION disconnect_on_SetCfg[] = {
427 /* function, request to match,
428 port action, port status,
429 request action, request EP, request data, request actual length, request status,
430 status, additional callback,
431 no_return */
432 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
433 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
434 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
435 UX_ERROR}, /* First try */
436 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
437 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
438 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
439 UX_ERROR}, /* Second try */
440 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
441 UX_TRUE, UX_TEST_PORT_STATUS_DISC,
442 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
443 UX_ERROR}, /* Last try */
444 { 0 }
445 };
446
447 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
448 /* function, request to match,
449 port action, port status,
450 request action, request EP, request data, request actual length, request status,
451 status, additional callback,
452 no_return */
453 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
454 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
455 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
456 UX_SUCCESS, ux_test_hcd_entry_set_cfg,
457 UX_TRUE}, /* Invoke callback & continue */
458 { 0 }
459 };
460
461 static UX_TEST_HCD_SIM_ACTION normal_enum_replace[] = {
462 /* function, request to match,
463 port action, port status,
464 request action, request EP, request data, request actual length, request status,
465 status, additional callback,
466 no_return */
467 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
468 UX_FALSE, 0,
469 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 8, 0,
470 UX_SUCCESS, UX_NULL},
471 { UX_HCD_TRANSFER_REQUEST, &_GetDeviceDescriptor,
472 UX_FALSE, 0,
473 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 0, 18, 0,
474 UX_SUCCESS, UX_NULL},
475 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
476 UX_FALSE, 0,
477 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, UX_CONFIGURATION_DESCRIPTOR_LENGTH, 0,
478 UX_SUCCESS, UX_NULL},
479 { UX_HCD_TRANSFER_REQUEST, &_GetConfigDescriptor,
480 UX_FALSE, 0,
481 UX_TEST_SIM_REQ_ANSWER | UX_TEST_SETUP_MATCH_REQ_V, 0, device_framework_full_speed + 18, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 18, 0,
482 UX_SUCCESS, UX_NULL},
483 { 0 }
484 }
485 ;
486
487 /* Define the ISR dispatch. */
488
489 extern VOID (*test_isr_dispatch)(void);
490
491
492 /* Prototype for test control return. */
493
494 void test_control_return(UINT status);
495
496
497 /* Define the ISR dispatch routine. */
498
test_isr(void)499 static void test_isr(void)
500 {
501
502 /* For further expansion of interrupt-level testing. */
503 }
504
505
test_class_cdc_acm_get(void)506 static UINT test_class_cdc_acm_get(void)
507 {
508
509 UINT status;
510 UX_HOST_CLASS *class;
511 UX_HOST_CLASS_CDC_ACM *cdc_acm_host;
512
513
514 /* Find the main cdc_acm container */
515 status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
516 if (status != UX_SUCCESS)
517 return(status);
518
519 /* We get the first instance of the cdc_acm device */
520 do
521 {
522
523 status = ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
524 tx_thread_sleep(10);
525 } while (status != UX_SUCCESS);
526
527 /* We still need to wait for the cdc_acm status to be live */
528 while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
529 tx_thread_sleep(10);
530
531 /* Isolate both the control and data interfaces. */
532 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
533 {
534 /* This is the data interface. */
535 cdc_acm_host_data = cdc_acm_host;
536
537 /* In that case, the second one should be the control interface. */
538 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
539
540 /* Check error. */
541 if (status != UX_SUCCESS)
542 return(status);
543
544 /* Check for the control interfaces. */
545 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
546 {
547
548 /* This is the control interface. */
549 cdc_acm_host_control = cdc_acm_host;
550
551 return(UX_SUCCESS);
552
553 }
554 }
555 else
556 {
557 /* Check for the control interfaces. */
558 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
559 {
560
561 /* This is the control interface. */
562 cdc_acm_host_control = cdc_acm_host;
563
564 /* In that case, the second one should be the data interface. */
565 status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
566
567 /* Check error. */
568 if (status != UX_SUCCESS)
569 return(status);
570
571 /* Check for the data interface. */
572 if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
573 {
574
575 /* This is the data interface. */
576 cdc_acm_host_data = cdc_acm_host;
577
578 return(UX_SUCCESS);
579
580 }
581 }
582 }
583
584 /* Return ERROR. */
585 return(UX_ERROR);
586 }
587
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)588 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
589 {
590
591 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
592
593 switch(event)
594 {
595
596 case UX_DEVICE_INSERTION:
597
598 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
599 cdc_acm_host_control = cdc_acm;
600 else
601 cdc_acm_host_data = cdc_acm;
602 break;
603
604 case UX_DEVICE_REMOVAL:
605
606 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
607 cdc_acm_host_control = UX_NULL;
608 else
609 cdc_acm_host_data = UX_NULL;
610 break;
611
612 default:
613 break;
614 }
615 return 0;
616 }
617
test_cdc_instance_activate(VOID * cdc_instance)618 static VOID test_cdc_instance_activate(VOID *cdc_instance)
619 {
620
621 /* Save the CDC instance. */
622 cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
623 }
test_cdc_instance_deactivate(VOID * cdc_instance)624 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
625 {
626
627 /* Reset the CDC instance. */
628 cdc_acm_slave = UX_NULL;
629 }
630
test_cdc_instance_parameter_change(VOID * cdc_instance)631 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
632 {
633
634 /* Set CDC parameter change flag. */
635 cdc_acm_slave_change = UX_TRUE;
636 }
637
test_swap_framework_bulk_ep_descriptors(VOID)638 static VOID test_swap_framework_bulk_ep_descriptors(VOID)
639 {
640 UCHAR tmp;
641
642 tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
643 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
644 device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
645
646 tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
647 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
648 device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
649 }
650
651
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)652 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
653 {
654 }
655
ux_test_hcd_entry_should_not_be_called(UX_HCD * hcd,UX_TEST_HCD_SIM_ACTION * action,VOID * parameter)656 static VOID ux_test_hcd_entry_should_not_be_called(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter)
657 {
658
659 error_counter ++;
660 }
661
ux_test_hcd_entry_disconnect(UX_HCD * hcd,UX_TEST_HCD_SIM_ACTION * action,VOID * parameter)662 static VOID ux_test_hcd_entry_disconnect(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter)
663 {
664
665 ux_test_dcd_sim_slave_disconnect();
666 }
667
ux_test_hcd_entry_set_cfg(UX_HCD * hcd,UX_TEST_HCD_SIM_ACTION * action,VOID * parameter)668 static VOID ux_test_hcd_entry_set_cfg(UX_HCD *hcd, UX_TEST_HCD_SIM_ACTION *action, VOID *parameter)
669 {
670
671 set_cfg_counter ++;
672
673 rsc_mem_free_on_set_cfg = _ux_system->ux_system_regular_memory_pool_free;
674 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
675 rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
676 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
677 }
678
679 /* Define what the initial system looks like. */
680
681 #ifdef CTEST
test_application_define(void * first_unused_memory)682 void test_application_define(void *first_unused_memory)
683 #else
684 void usbx_host_basic_memory_test_application_define(void *first_unused_memory)
685 #endif
686 {
687
688 UINT status;
689 CHAR * stack_pointer;
690 CHAR * memory_pointer;
691 ULONG test_n;
692
693 printf("Running Host Basic Memory Test............................ ");
694
695 /* Reset testing counts. */
696 ux_test_utility_sim_mutex_create_count_reset();
697 ux_test_utility_sim_sem_create_count_reset();
698 ux_test_utility_sim_sem_get_count_reset();
699
700 /* Initialize the free memory pointer */
701 stack_pointer = (CHAR *) usbx_memory;
702 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
703
704 /* Initialize USBX Memory */
705 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
706
707 /* Check for error. */
708 if (status != UX_SUCCESS)
709 {
710
711 printf(" ERROR #1\n");
712 test_control_return(1);
713 }
714
715 /* Register the error callback. */
716 _ux_utility_error_callback_register(test_ux_error_callback);
717
718 /* The code below is required for installing the host portion of USBX */
719 status = ux_host_stack_initialize(test_host_change_function);
720 if (status != UX_SUCCESS)
721 {
722
723 printf(" ERROR #2\n");
724 test_control_return(1);
725 }
726
727 /* Register CDC-ACM class. */
728 status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
729 if (status != UX_SUCCESS)
730 {
731
732 printf(" ERROR #3\n");
733 test_control_return(1);
734 }
735
736 /* Register all the USB host controllers available in this system */
737 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
738 if (status != UX_SUCCESS)
739 {
740
741 printf(" ERROR #4\n");
742 test_control_return(1);
743 }
744
745 /* The code below is required for installing the device portion of USBX. No call back for
746 device status change in this example. */
747 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
748 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
749 string_framework, STRING_FRAMEWORK_LENGTH,
750 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
751 if(status!=UX_SUCCESS)
752 {
753
754 printf(" ERROR #5\n");
755 test_control_return(1);
756 }
757
758 /* Set the parameters for callback when insertion/extraction of a CDC device. */
759 parameter.ux_slave_class_cdc_acm_instance_activate = test_cdc_instance_activate;
760 parameter.ux_slave_class_cdc_acm_instance_deactivate = test_cdc_instance_deactivate;
761 parameter.ux_slave_class_cdc_acm_parameter_change = test_cdc_instance_parameter_change;
762
763 /* Mutex will be created on initialize to protect CDC Bulk IN/OUT */
764 for (test_n = 0; test_n < 2; test_n ++)
765 {
766 ux_test_utility_sim_mutex_error_generation_start(test_n);
767 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
768 1,0, ¶meter);
769 /* Mutex error should be reported */
770 if(status != UX_MUTEX_ERROR)
771 {
772
773 printf(" ERROR #6.%ld\n", test_n);
774 test_control_return(1);
775 }
776 }
777 ux_test_utility_sim_mutex_error_generation_stop();
778
779 /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
780 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
781 1,0, ¶meter);
782
783 if(status!=UX_SUCCESS)
784 {
785
786 printf(" ERROR #7\n");
787 test_control_return(1);
788 }
789
790 /* Initialize the simulated device controller. */
791 status = _ux_dcd_sim_slave_initialize();
792
793 /* Check for error. */
794 if (status != TX_SUCCESS)
795 {
796
797 printf(" ERROR #8\n");
798 test_control_return(1);
799 }
800
801 /* Create the main host simulation thread. */
802 status = tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
803 stack_pointer, UX_DEMO_STACK_SIZE,
804 20, 20, 1, TX_AUTO_START);
805
806 /* Check for error. */
807 if (status != TX_SUCCESS)
808 {
809
810 printf(" ERROR #9\n");
811 test_control_return(1);
812 }
813
814 /* Create the main slave simulation thread. */
815 status = tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
816 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
817 20, 20, 1, TX_AUTO_START);
818
819 /* Check for error. */
820 if (status != TX_SUCCESS)
821 {
822
823 printf(" ERROR #10\n");
824 test_control_return(1);
825 }
826 }
827
tx_test_thread_host_simulation_entry(ULONG arg)828 void tx_test_thread_host_simulation_entry(ULONG arg)
829 {
830
831 UINT status;
832 ULONG actual_length;
833 ULONG test_n;
834 ULONG mem_free;
835
836 stepinfo("\n");
837
838 /* Find the cdc_acm class and wait for the link to be up. */
839 status = test_class_cdc_acm_get();
840 if (status != UX_SUCCESS)
841 {
842
843 /* DPUMP basic test error. */
844 printf("ERROR #11: class not found\n");
845 test_control_return(1);
846 }
847 if (!cdc_acm_host_control && !cdc_acm_host_data)
848 {
849
850 printf("ERROR #12: instance not detected\n");
851 test_control_return(1);
852 }
853 stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
854
855 /* Test disconnect. */
856 stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
857 ux_test_dcd_sim_slave_disconnect();
858 ux_test_hcd_sim_host_disconnect();
859 if (cdc_acm_host_control || cdc_acm_host_data)
860 {
861
862 printf("ERROR #13: instance not removed when disconnect");
863 test_control_return(1);
864 }
865 stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
866
867 /* Reset testing counts. */
868 stepinfo(">>>>>>>>>>>>>>>> Test connect & connection resource\n");
869 ux_test_utility_sim_mutex_create_count_reset();
870 ux_test_utility_sim_sem_create_count_reset();
871 ux_test_utility_sim_sem_get_count_reset();
872 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
873 mem_free = _ux_system->ux_system_regular_memory_pool_free;
874 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
875 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
876 tx_thread_sleep(100);
877 /* Log create counts when SetConfigure for further tests. */
878 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
879 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
880 rsc_enum_sem_get_count = rsc_sem_get_on_set_cfg;
881 rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
882 stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
883
884 /* Simulate detach and attach for FS enumeration,
885 and test possible memory allocation error handlings.
886 */
887 if (rsc_enum_mem_usage) stepinfo(">>>>>>>>>>>>>>>> Memory errors enumeration test\n");
888 mem_free = _ux_system->ux_system_regular_memory_pool_free;
889 for (test_n = 8; test_n <= rsc_enum_mem_usage; test_n += 8)
890 {
891
892 stepinfo("%4ld / %4ld\n", test_n, rsc_enum_mem_usage);
893
894 /* Check memory level */
895 if (mem_free != _ux_system->ux_system_regular_memory_pool_free)
896 {
897
898 printf("ERROR #14.%ld: Memory level different after re-enumerations\n", test_n);
899 test_control_return(1);
900 }
901
902 /* Disconnect. */
903 ux_test_dcd_sim_slave_disconnect();
904 ux_test_hcd_sim_host_disconnect();
905
906 /* Update memory free level (disconnect) */
907 mem_free = _ux_system->ux_system_regular_memory_pool_free;
908
909 /* Set memory free level */
910 ux_test_utility_sim_mem_allocate_until(test_n);
911
912 /* Count SetConfigure */
913 set_cfg_counter = 0;
914 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
915
916 /* Connect. */
917 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
918 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
919
920 /* Free memory */
921 ux_test_utility_sim_mem_free_all();
922
923 /* Check error */
924 if (set_cfg_counter)
925 {
926
927 printf("ERROR #15.%ld: device detected when there is memory error\n", test_n);
928 test_control_return(1);
929 }
930 stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
931 }
932 if (rsc_enum_mem_usage) stepinfo("\n");
933
934 /* Finally disconnect the device. */
935 ux_device_stack_disconnect();
936
937 /* And deinitialize the class. */
938 status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
939
940 /* Deinitialize the device side of usbx. */
941 _ux_device_stack_uninitialize();
942
943 /* And finally the usbx system resources. */
944 _ux_system_uninitialize();
945
946 /* Successful test. */
947 printf("SUCCESS!\n");
948 test_control_return(0);
949
950 }
951
tx_test_thread_slave_simulation_entry(ULONG arg)952 void tx_test_thread_slave_simulation_entry(ULONG arg)
953 {
954
955 UINT status;
956 ULONG requested_length;
957 ULONG actual_length;
958 UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARAMETER line_coding;
959 UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER line_state;
960 UX_SLAVE_CLASS_COMMAND class_command;
961
962 UCHAR data_bit[16];
963 VOID* tmp_alloc;
964 ULONG tmp_alloc_len;
965
966 while(1)
967 {
968
969 /* Sleep so ThreadX on Win32 will delete this thread. */
970 tx_thread_sleep(10);
971 }
972 }
973