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 "ux_host_class_dpump.h"
10 #include "ux_device_class_dpump.h"
11
12 #include "ux_host_stack.h"
13
14 #include "ux_test_hcd_sim_host.h"
15 #include "ux_test_dcd_sim_slave.h"
16 #include "ux_test_utility_sim.h"
17
18 /* Define USBX demo constants. */
19
20 #define UX_DEMO_STACK_SIZE 4096
21 #define UX_DEMO_BUFFER_SIZE 2048
22 #define UX_DEMO_RUN 1
23 #define UX_DEMO_MEMORY_SIZE (64*1024)
24
25
26 /* Define the counters used in the demo application... */
27
28 static ULONG test_error_cases = UX_FALSE;
29 static ULONG test_error_counter = 0;
30
31 static ULONG thread_0_counter;
32 static ULONG thread_1_counter;
33 static ULONG error_counter;
34
35 /* Define USBX demo global variables. */
36
37 static UX_HOST_CLASS *class_driver;
38 static UX_HOST_CLASS_DPUMP *dpump;
39 static UX_SLAVE_CLASS_DPUMP *dpump_slave;
40
41
42 static UCHAR device_framework_full_speed[] = {
43
44 /* Device descriptor */
45 0x12, 0x01, 0x10, 0x01,
46 0x00, 0x00, 0x00, /* bDeviceClass, bDeviceSubClass, bDeviceProtocol */
47 0x08, /* bMaxPacketSize0 */
48 0xec, 0x08, 0x10, 0x00, /* idVendor, idProduct */
49 0x00, 0x00,
50 0x00, 0x00, 0x00,
51 0x01, /* bNumConfigurations */
52
53 /* Configuration descriptor */
54 0x09, 0x02,
55 0x20 + 5, 0x00, /* wTotalLength */
56 0x01, 0x01, /* bNumInterfaces, bConfigurationValue */
57 0x00,
58 0xc0, 0x32, /* bmAttributes, bMaxPower */
59
60 /* OTG Descriptor. */
61 0x05, 0x09, 0x03, 0x02, 0x00,
62
63 /* Interface descriptor */
64 0x09, 0x04,
65 0x00, 0x00, 0x02, /* bInterfaceNumber, bAlternateSetting, bNumEndpoints */
66 0x99, 0x99, 0x99, /* bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */
67 0x00,
68
69 /* Endpoint descriptor (Bulk Out) */
70 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
71
72 /* Endpoint descriptor (Bulk In) */
73 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00
74 };
75 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
76
77
78 static UCHAR device_framework_high_speed[] = {
79
80 /* Device descriptor */
81 0x12, 0x01, 0x00, 0x02,
82 0x00, 0x00, 0x00, /* bDeviceClass, bDeviceSubClass, bDeviceProtocol */
83 0x40, /* bMaxPacketSize0 */
84 0x0a, 0x07, /* idVendor */
85 0x25, 0x40, /* idProduct */
86 0x01, 0x00,
87 0x01, 0x02, 0x03,
88 0x01, /* bNumConfigurations */
89
90 /* Device qualifier descriptor */
91 0x0a, 0x06, 0x00, 0x02,
92 0x00, 0x00, 0x00, /* bDeviceClass, bDeviceSubClass, bDeviceProtocol */
93 0x40, /* bMaxPacketSize0 */
94 0x01, /* bNumConfigurations */
95 0x00,
96
97 /* Configuration descriptor */
98 0x09, 0x02, 0x20 + 5, 0x00, 0x01, 0x01, 0x00, 0xc0,
99 0x32,
100
101 /* OTG Descriptor. */
102 0x05, 0x09, 0x03, 0x02, 0x00,
103
104 /* Interface descriptor */
105 0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
106 0x00,
107
108 /* Endpoint descriptor (Bulk Out) */
109 0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
110
111 /* Endpoint descriptor (Bulk In) */
112 0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00
113 };
114 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
115
116 /* String Device Framework :
117 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
118 Byte 2 : Byte containing the index of the descriptor
119 Byte 3 : Byte containing the length of the descriptor string
120 */
121 static UCHAR string_framework[] = {
122
123 /* Manufacturer string descriptor : Index 1 */
124 0x09, 0x04, 0x01, 0x0c,
125 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
126 0x6f, 0x67, 0x69, 0x63,
127
128 /* Product string descriptor : Index 2 */
129 0x09, 0x04, 0x02, 0x0c,
130 0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
131 0x44, 0x65, 0x6d, 0x6f,
132
133 /* Serial Number string descriptor : Index 3 */
134 0x09, 0x04, 0x03, 0x04,
135 0x30, 0x30, 0x30, 0x31
136 };
137 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
138
139 /* Multiple languages are supported on the device, to add
140 a language besides English, the unicode language code must
141 be appended to the language_id_framework array and the length
142 adjusted accordingly. */
143 static UCHAR language_id_framework[] = {
144
145 /* English. */
146 0x09, 0x04
147 };
148 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
149
150 /* Define prototypes for external Host Controller's (HCDs), classes and clients. */
151
152 static VOID tx_test_instance_activate(VOID *dpump_instance);
153 static VOID tx_test_instance_deactivate(VOID *dpump_instance);
154
155 UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
156 UINT ux_hcd_sim_initialize(UX_HCD *hcd);
157 UINT _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
158 ULONG requested_length, ULONG *actual_length);
159 UINT _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
160 ULONG requested_length, ULONG *actual_length);
161
162 static TX_THREAD tx_test_thread_host_simulation;
163 static TX_THREAD tx_test_thread_slave_simulation;
164 static void tx_test_thread_host_simulation_entry(ULONG);
165 static void tx_test_thread_slave_simulation_entry(ULONG);
166
167 static VOID ux_test_hcd_entry_invoked(UX_TEST_ACTION *action, VOID *params);
168
169 /* Define the ISR dispatch. */
170
171 extern VOID (*test_isr_dispatch)(void);
172
173
174 /* Prototype for test control return. */
175
176 void test_control_return(UINT status);
177
178 /* Simulation */
179
180 static UX_TEST_SETUP _b_hnp_support = {0x00,0x03,UX_OTG_FEATURE_A_HNP_SUPPORT,0x0000};
181
182 static UX_TEST_HCD_SIM_ACTION b_hnp_support_request_err[] = {
183 /* function, request to match,
184 port action, port status,
185 request action, request EP, request data, request actual length, request status,
186 status, additional callback,
187 no_return */
188 { UX_HCD_TRANSFER_REQUEST, &_b_hnp_support,
189 UX_FALSE, 0,
190 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, UX_ERROR,
191 UX_ERROR, ux_test_hcd_entry_invoked},
192 { UX_HCD_TRANSFER_REQUEST, &_b_hnp_support,
193 UX_FALSE, 0,
194 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, UX_ERROR,
195 UX_ERROR, ux_test_hcd_entry_invoked},
196 { UX_HCD_TRANSFER_REQUEST, &_b_hnp_support,
197 UX_FALSE, 0,
198 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, UX_ERROR,
199 UX_ERROR, ux_test_hcd_entry_invoked},
200 { 0 }
201 };
202
203 static UX_TEST_HCD_SIM_ACTION b_hnp_support_request_ok[] = {
204 /* function, request to match,
205 port action, port status,
206 request action, request EP, request data, request actual length, request status,
207 status, additional callback,
208 no_return */
209 { UX_HCD_TRANSFER_REQUEST, &_b_hnp_support,
210 UX_FALSE, 0,
211 UX_TEST_SETUP_MATCH_REQ_V, 0, UX_NULL, 0, UX_SUCCESS,
212 UX_SUCCESS, ux_test_hcd_entry_invoked},
213 { 0 }
214 };
215
216 /* Define the ISR dispatch routine. */
217
test_isr(void)218 static void test_isr(void)
219 {
220
221 /* For further expansion of interrupt-level testing. */
222 }
223
224
error_callback(UINT system_level,UINT system_context,UINT error_code)225 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
226 {
227
228 test_error_counter ++;
229
230 /* Failed test. */
231 if (!test_error_cases)
232 {
233
234 printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
235 test_control_return(1);
236 }
237 }
238
239 /* Define what the initial system looks like. */
240
241 #ifdef CTEST
test_application_define(void * first_unused_memory)242 void test_application_define(void *first_unused_memory)
243 #else
244 void usbx_ux_host_stack_configuration_set_test_application_define(void *first_unused_memory)
245 #endif
246 {
247
248 UINT status;
249 CHAR *stack_pointer;
250 CHAR *memory_pointer;
251 UX_SLAVE_CLASS_DPUMP_PARAMETER parameter;
252
253
254 /* Initialize the free memory pointer. */
255 stack_pointer = (CHAR *) first_unused_memory;
256 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
257
258 /* Initialize USBX Memory. */
259 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
260
261 /* Check for error. */
262 if (status != UX_SUCCESS)
263 {
264
265 printf("Running ux_host_stack_configuration_set Test........................ ERROR #1\n");
266 test_control_return(1);
267 }
268
269 /* Register the error callback. */
270 _ux_utility_error_callback_register(error_callback);
271
272 /* The code below is required for installing the host portion of USBX. */
273 status = ux_host_stack_initialize(UX_NULL);
274
275 /* Check for error. */
276 if (status != UX_SUCCESS)
277 {
278
279 printf("Running ux_host_stack_configuration_set Test........................ ERROR #2\n");
280 test_control_return(1);
281 }
282
283 /* Register all the host class drivers for this USBX implementation. */
284 status = ux_host_stack_class_register(_ux_system_host_class_dpump_name, _ux_host_class_dpump_entry);
285
286 /* Check for error. */
287 if (status != UX_SUCCESS)
288 {
289
290 printf("Running ux_host_stack_configuration_set Test........................ ERROR #3\n");
291 test_control_return(1);
292 }
293
294 /* The code below is required for installing the device portion of USBX */
295 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
296 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
297 string_framework, STRING_FRAMEWORK_LENGTH,
298 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
299
300 /* Check for error. */
301 if (status != UX_SUCCESS)
302 {
303
304 printf("Running ux_host_stack_configuration_set Test........................ ERROR #5\n");
305 test_control_return(1);
306 }
307
308 /* Set the parameters for callback when insertion/extraction of a Data Pump device. */
309 parameter.ux_slave_class_dpump_instance_activate = tx_test_instance_activate;
310 parameter.ux_slave_class_dpump_instance_deactivate = tx_test_instance_deactivate;
311
312 /* Initialize the device dpump class. The class is connected with interface 0 */
313 status = ux_device_stack_class_register(_ux_system_slave_class_dpump_name, _ux_device_class_dpump_entry,
314 1, 0, ¶meter);
315
316 /* Check for error. */
317 if (status != UX_SUCCESS)
318 {
319
320 printf("Running ux_host_stack_configuration_set Test........................ ERROR #6\n");
321 test_control_return(1);
322 }
323
324 /* Initialize the simulated device controller. */
325 status = _ux_test_dcd_sim_slave_initialize();
326
327 /* Check for error. */
328 if (status != UX_SUCCESS)
329 {
330
331 printf("Running ux_host_stack_configuration_set Test........................ ERROR #7\n");
332 test_control_return(1);
333 }
334
335 /* Register all the USB host controllers available in this system */
336 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
337
338 /* Check for error. */
339 if (status != UX_SUCCESS)
340 {
341
342 printf("Running ux_host_stack_configuration_set Test........................ ERROR #4\n");
343 test_control_return(1);
344 }
345
346 /* Create the main host simulation thread. */
347 status = tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
348 stack_pointer, UX_DEMO_STACK_SIZE,
349 20, 20, 1, TX_AUTO_START);
350
351 /* Check for error. */
352 if (status != TX_SUCCESS)
353 {
354
355 printf("Running ux_host_stack_configuration_set Test........................ ERROR #8\n");
356 test_control_return(1);
357 }
358
359 /* Create the main demo thread. */
360 status = tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
361 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
362 20, 20, 1, TX_AUTO_START);
363
364 /* Check for error. */
365 if (status != TX_SUCCESS)
366 {
367
368 printf("Running ux_host_stack_configuration_set Test........................ ERROR #9\n");
369 test_control_return(1);
370 }
371 }
372
373
tx_test_thread_host_simulation_entry(ULONG arg)374 static void tx_test_thread_host_simulation_entry(ULONG arg)
375 {
376
377 UINT status;
378 UX_DEVICE *device;
379 UX_CONFIGURATION *configuration;
380 UX_HCD *hcd;
381
382 /* Inform user. */
383 printf("Running ux_host_stack_configuration_set Test........................ ");
384
385 /* Wait for enumeration. */
386 ux_test_wait_for_enum_thread_completion();
387
388 /* Disconnect. */
389 ux_test_hcd_sim_host_disconnect();
390
391 /* Wait for disconnect. */
392 ux_test_wait_for_enum_thread_completion();
393
394 /* Simulate OTG HNP Support on HCD. */
395 hcd = &_ux_system_host -> ux_system_host_hcd_array[0];
396 #ifdef UX_OTG_SUPPORT
397 hcd -> ux_hcd_otg_capabilities = UX_HCD_OTG_CAPABLE;
398 #endif
399 test_error_counter = 0;
400 ux_test_hcd_sim_host_set_actions(b_hnp_support_request_err);
401
402 /* Connect, with OTG descriptor. */
403 ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
404
405 /* Check device connection. */
406 status = ux_host_stack_device_get(0, &device);
407 if (status != UX_SUCCESS)
408 {
409
410 printf("ERROR #%d: fail to get device instance\n", __LINE__);
411 test_control_return(1);
412 }
413
414 /* Get configuration. */
415 status = ux_host_stack_device_configuration_get(device, 0, &configuration);
416 if (status != UX_SUCCESS)
417 {
418
419 printf("ERROR #%d: fail to get device configuration\n", __LINE__);
420 test_control_return(1);
421 }
422
423 #ifdef UX_OTG_SUPPORT
424 if (test_error_counter == 0)
425 {
426
427 printf("ERROR #%d: Expect a_hnp_support request\n", __LINE__);
428 error_counter ++;
429 }
430 if (configuration->ux_configuration_otg_capabilities)
431 {
432
433 printf("ERROR #%d: Expect no OTG since a_hnp_support request fail\n", __LINE__);
434 error_counter ++;
435 }
436
437 /* SetConfiguration but device connected to hub. */
438 configuration->ux_configuration_otg_capabilities |= UX_OTG_HNP_SUPPORT;
439 configuration->ux_configuration_device->ux_device_parent = device;
440 status = _ux_host_stack_configuration_set(configuration);
441 if (status != UX_SUCCESS)
442 {
443 printf("ERROR #%d: fail to set configuration (no SNP request)\n", __LINE__);
444 error_counter ++;
445 }
446 configuration->ux_configuration_device->ux_device_parent = UX_NULL;
447
448 /* Simulate OTG HNP Support on HCD. */
449 UX_DEVICE_HCD_GET(configuration->ux_configuration_device)->ux_hcd_otg_capabilities |= UX_HCD_OTG_CAPABLE;
450
451 test_error_counter = 0;
452 ux_test_hcd_sim_host_set_actions(b_hnp_support_request_ok);
453
454 status = _ux_host_stack_configuration_set(configuration);
455 if (status != UX_SUCCESS)
456 {
457 printf("ERROR #%d: fail to set configuration (no SNP request)\n", __LINE__);
458 error_counter ++;
459 }
460 if (test_error_counter == 0)
461 {
462
463 printf("ERROR #%d: Expect a_hnp_support request\n", __LINE__);
464 error_counter ++;
465 }
466 if (!configuration->ux_configuration_otg_capabilities)
467 {
468
469 printf("ERROR #%d: Expect OTG since a_hnp_support request pass\n", __LINE__);
470 error_counter ++;
471 }
472 #endif
473
474 /* Sleep for a tick to make sure everything is complete. */
475 tx_thread_sleep(1);
476
477 /* Check for errors from other threads. */
478 if (error_counter)
479 {
480
481 /* DPUMP error. */
482 printf("ERROR #14\n");
483 test_control_return(1);
484 }
485 else
486 {
487
488 /* Successful test. */
489 printf("SUCCESS!\n");
490 test_control_return(0);
491 }
492 }
493
494
tx_test_thread_slave_simulation_entry(ULONG arg)495 static void tx_test_thread_slave_simulation_entry(ULONG arg)
496 {
497
498 while(1)
499 {
500
501 /* Ensure the dpump class on the device is still alive. */
502 if (dpump_slave != UX_NULL)
503 {
504
505 /* Increment thread counter. */
506 thread_1_counter++;
507 }
508
509 /* Let other thread run. */
510 tx_thread_sleep(10);
511 }
512 }
513
tx_test_instance_activate(VOID * dpump_instance)514 static VOID tx_test_instance_activate(VOID *dpump_instance)
515 {
516
517 /* Save the DPUMP instance. */
518 dpump_slave = (UX_SLAVE_CLASS_DPUMP *) dpump_instance;
519 }
520
tx_test_instance_deactivate(VOID * dpump_instance)521 static VOID tx_test_instance_deactivate(VOID *dpump_instance)
522 {
523
524 /* Reset the DPUMP instance. */
525 dpump_slave = UX_NULL;
526 }
527
ux_test_hcd_entry_invoked(UX_TEST_ACTION * action,VOID * params)528 static VOID ux_test_hcd_entry_invoked(UX_TEST_ACTION *action, VOID *params)
529 {
530
531 test_error_counter ++;
532 }