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