1 /* This test is designed to test the simple dpump host/device class operation. */
2
3 #include <stdio.h>
4
5 #include "tx_api.h"
6
7 #include "ux_api.h"
8 #include "ux_system.h"
9 #include "ux_utility.h"
10
11 #include "ux_host_class_dpump.h"
12 #include "ux_device_class_dpump.h"
13
14 #include "ux_test.h"
15
16
17 /* Define USBX demo constants. */
18
19 #define UX_DEMO_STACK_SIZE 4096
20 #define UX_DEMO_BUFFER_SIZE 2048
21 #define UX_DEMO_RUN 1
22 #define UX_DEMO_MEMORY_SIZE (64*1024)
23
24
25 /* Define the counters used in the demo application... */
26
27 static ULONG thread_0_counter;
28 static ULONG thread_1_counter;
29 static int error_counter = 0;
30
31
32 /* Define USBX demo global variables. */
33
34 static unsigned char host_out_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
35 static unsigned char host_in_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
36 static unsigned char slave_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
37
38 static UX_HOST_CLASS *class_driver;
39 static UX_HOST_CLASS_DPUMP *dpump;
40 static UX_SLAVE_CLASS_DPUMP *dpump_slave;
41
42 static UINT ignore_error = UX_FALSE;
43
44 #define BYTE0(x) (((x) ) & 0xFF)
45 #define BYTE1(x) (((x) >> 8) & 0xFF)
46
47 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
48 static UCHAR device_framework_full_speed[] = {
49
50 /* Device descriptor */
51 0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
52 0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00,
54 0x02, /* bNumConfigurations */
55
56 /* Configuration descriptor */
57 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
58 0x32,
59
60 /* Interface descriptor */
61 0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
62 0x00,
63
64 /* Endpoint descriptor (Bulk Out) */
65 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
66
67 /* Endpoint descriptor (Bulk In) */
68 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00,
69
70 /* Configuration descriptor */
71 0x09, 0x02,
72 0x09, 0x00, /* wTotalLength */
73 0x00, /* bNumInterfaces */
74 0x02, /* bConfigurationValue */
75 0x00, 0xc0, 0x32,
76 };
77
78 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
79 static UCHAR device_framework_high_speed[] = {
80
81 /* Device descriptor */
82 0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
83 0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
84 0x03,
85 0x02, /* bNumConfigurations */
86
87 /* Device qualifier descriptor */
88 0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
89 0x01, 0x00,
90
91 /* Configuration descriptor */
92 0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
93 0x32,
94
95 /* Interface descriptor */
96 0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
97 0x00,
98
99 /* Endpoint descriptor (Bulk Out) */
100 0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
101
102 /* Endpoint descriptor (Bulk In) */
103 0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00,
104
105 /* Configuration descriptor */
106 0x09, 0x02,
107 0x09, 0x00, /* wTotalLength */
108 0x00, /* bNumInterfaces */
109 0x02, /* bConfigurationValue */
110 0x00, 0xc0, 0x32,
111 };
112
113 /* String Device Framework :
114 Byte 0 and 1 : Word containing the language ID : 0x0904 for US
115 Byte 2 : Byte containing the index of the descriptor
116 Byte 3 : Byte containing the length of the descriptor string
117 */
118
119 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
120 static UCHAR string_framework[] = {
121
122 /* Manufacturer string descriptor : Index 1 */
123 0x09, 0x04, 0x01, 0x0c,
124 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
125 0x6f, 0x67, 0x69, 0x63,
126
127 /* Product string descriptor : Index 2 */
128 0x09, 0x04, 0x02, 0x0c,
129 0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
130 0x44, 0x65, 0x6d, 0x6f,
131
132 /* Serial Number string descriptor : Index 3 */
133 0x09, 0x04, 0x03, 0x04,
134 0x30, 0x30, 0x30, 0x31
135 };
136
137 /* Multiple languages are supported on the device, to add
138 a language besides English, the unicode language code must
139 be appended to the language_id_framework array and the length
140 adjusted accordingly. */
141 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
142 static UCHAR language_id_framework[] = {
143
144 /* English. */
145 0x09, 0x04
146 };
147
148
149 /* Define prototypes for external Host Controller's (HCDs), classes and clients. */
150
151 static VOID tx_demo_instance_activate(VOID *dpump_instance);
152 static VOID tx_demo_instance_deactivate(VOID *dpump_instance);
153
154 UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
155 UINT ux_hcd_sim_initialize(UX_HCD *hcd);
156
157 static TX_THREAD tx_demo_thread_host_simulation;
158 static TX_THREAD tx_demo_thread_slave_simulation;
159 static void tx_demo_thread_host_simulation_entry(ULONG);
160 static void tx_demo_thread_slave_simulation_entry(ULONG);
161
162
163 /* Define the ISR dispatch. */
164
165 extern VOID (*test_isr_dispatch)(void);
166
167
168 /* Prototype for test control return. */
169
170 void test_control_return(UINT status);
171
172
173 /* Define the ISR dispatch routine. */
174
test_isr(void)175 static void test_isr(void)
176 {
177
178 /* For further expansion of interrupt-level testing. */
179 }
180
181
error_callback(UINT system_level,UINT system_context,UINT error_code)182 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
183 {
184 if (!ignore_error)
185 {
186 /* Failed test. */
187 printf("Error #%d, system_level: %d, system_context: %d, code: %x(%d)\n",
188 __LINE__, system_level, system_context, error_code, error_code);
189 test_control_return(1);
190 }
191 }
192
193 /* Define what the initial system looks like. */
194
195 #ifdef CTEST
test_application_define(void * first_unused_memory)196 void test_application_define(void *first_unused_memory)
197 #else
198 void usbx_ux_host_stack_device_configuration_activate_test_application_define(void *first_unused_memory)
199 #endif
200 {
201
202 UINT status;
203 CHAR *stack_pointer;
204 CHAR *memory_pointer;
205 UX_SLAVE_CLASS_DPUMP_PARAMETER parameter;
206
207
208 printf("Running ux_host_stack_device_configuration_(de)activate Test........ ");
209 stepinfo("\n");
210
211 /* Initialize the free memory pointer. */
212 stack_pointer = (CHAR *) first_unused_memory;
213 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
214
215 /* Initialize USBX Memory. */
216 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
217
218 /* Check for error. */
219 if (status != UX_SUCCESS)
220 {
221 printf("ERROR #%d:0x%x\n", __LINE__, status);
222 test_control_return(1);
223 }
224
225 /* Register the error callback. */
226 _ux_utility_error_callback_register(error_callback);
227
228 /* The code below is required for installing the host portion of USBX. */
229 status = ux_host_stack_initialize(UX_NULL);
230
231 /* Check for error. */
232 if (status != UX_SUCCESS)
233 {
234 printf("ERROR #%d:0x%x\n", __LINE__, status);
235 test_control_return(1);
236 }
237
238 /* Register all the host class drivers for this USBX implementation. */
239 status = ux_host_stack_class_register(_ux_system_host_class_dpump_name, ux_host_class_dpump_entry);
240
241 /* Check for error. */
242 if (status != UX_SUCCESS)
243 {
244 printf("ERROR #%d:0x%x\n", __LINE__, status);
245 test_control_return(1);
246 }
247
248 /* The code below is required for installing the device portion of USBX */
249 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
250 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
251 string_framework, STRING_FRAMEWORK_LENGTH,
252 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
253
254 /* Check for error. */
255 if (status != UX_SUCCESS)
256 {
257 printf("ERROR #%d:0x%x\n", __LINE__, status);
258 test_control_return(1);
259 }
260
261 /* Set the parameters for callback when insertion/extraction of a Data Pump device. */
262 parameter.ux_slave_class_dpump_instance_activate = tx_demo_instance_activate;
263 parameter.ux_slave_class_dpump_instance_deactivate = tx_demo_instance_deactivate;
264
265 /* Initialize the device dpump class. The class is connected with interface 0 */
266 status = ux_device_stack_class_register(_ux_system_slave_class_dpump_name, _ux_device_class_dpump_entry,
267 1, 0, ¶meter);
268
269 /* Check for error. */
270 if (status != UX_SUCCESS)
271 {
272 printf("ERROR #%d:0x%x\n", __LINE__, status);
273 test_control_return(1);
274 }
275
276 /* Initialize the simulated device controller. */
277 status = _ux_dcd_sim_slave_initialize();
278
279 /* Check for error. */
280 if (status != UX_SUCCESS)
281 {
282 printf("ERROR #%d:0x%x\n", __LINE__, status);
283 test_control_return(1);
284 }
285
286 /* Register all the USB host controllers available in this system */
287 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
288
289 /* Check for error. */
290 if (status != UX_SUCCESS)
291 {
292 printf("ERROR #%d:0x%x\n", __LINE__, status);
293 test_control_return(1);
294 }
295
296 /* Create the main host simulation thread. */
297 status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
298 stack_pointer, UX_DEMO_STACK_SIZE,
299 20, 20, 1, TX_AUTO_START);
300
301 /* Check for error. */
302 if (status != TX_SUCCESS)
303 {
304 printf("ERROR #%d:0x%x\n", __LINE__, status);
305 test_control_return(1);
306 }
307
308 /* Create the main demo thread. */
309 status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
310 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
311 20, 20, 1, TX_AUTO_START);
312
313 /* Check for error. */
314 if (status != TX_SUCCESS)
315 {
316 printf("ERROR #%d:0x%x\n", __LINE__, status);
317 test_control_return(1);
318 }
319 }
320
tx_demo_dpump_get(void)321 static UINT tx_demo_dpump_get(void)
322 {
323 UINT status;
324 UX_HOST_CLASS *class_inst;
325 status = ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class_inst);
326 if (status != UX_SUCCESS)
327 return(UX_ERROR);
328 status = ux_host_stack_class_instance_get(class_inst, 0, (VOID **) &dpump);
329 if (status != UX_SUCCESS)
330 return(UX_ERROR);
331 if (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE)
332 return(UX_ERROR);
333 return(UX_SUCCESS);
334 }
335
tx_demo_thread_host_simulation_entry(ULONG arg)336 static void tx_demo_thread_host_simulation_entry(ULONG arg)
337 {
338
339 UINT status;
340 INT i;
341 UX_DEVICE *device;
342 UX_CONFIGURATION *configuration;
343 ULONG temp;
344
345 /* Wait until dpump is ready. */
346 for (i = 0; i < 100; i ++)
347 {
348 if (tx_demo_dpump_get() == UX_SUCCESS && dpump_slave != UX_NULL)
349 break;
350 tx_thread_sleep(UX_MS_TO_TICK_NON_ZERO(10));
351 }
352 if (dpump == UX_NULL || dpump_slave == UX_NULL)
353 {
354 printf("ERROR #%d\n", __LINE__);
355 test_control_return(1);
356 }
357 device = dpump -> ux_host_class_dpump_device;
358 configuration = device -> ux_device_first_configuration;
359
360 /* >>>>> Test configuration deactivate. */
361
362 ignore_error = UX_TRUE;
363
364 /* >>>>> ux_host_stack_device_configuration_deactivate: invalid device. */
365 temp = device -> ux_device_handle;
366 device -> ux_device_handle = 0;
367 status = ux_host_stack_device_configuration_deactivate(device);
368 if (status != UX_DEVICE_HANDLE_UNKNOWN)
369 {
370 printf("ERROR #%d:0x%x\n", __LINE__, status);
371 test_control_return(1);
372 }
373 device -> ux_device_handle = temp;
374
375 /* >>>>> ux_host_stack_device_configuration_deactivate: invalid device semaphore. */
376 _ux_utility_semaphore_delete(&device -> ux_device_protection_semaphore);
377 status = ux_host_stack_device_configuration_deactivate(device);
378 if (status != UX_SEMAPHORE_ERROR)
379 {
380 printf("ERROR #%d:0x%x\n", __LINE__, status);
381 test_control_return(1);
382 }
383 _ux_utility_semaphore_create(&device -> ux_device_protection_semaphore, "ux_device_protection_semaphore", 1);
384
385 ignore_error = UX_FALSE;
386
387 /* >>>>> ux_host_stack_device_configuration_deactivate: OK. */
388 status = ux_host_stack_device_configuration_deactivate(device);
389 if (status != UX_SUCCESS)
390 {
391 printf("ERROR #%d:0x%x\n", __LINE__, status);
392 test_control_return(1);
393 }
394 UX_TEST_ASSERT(dpump_slave == UX_NULL);
395
396 /* >>>>> ux_host_stack_device_configuration_deactivate: Already done, OK. */
397 status = ux_host_stack_device_configuration_deactivate(device);
398 if (status != UX_SUCCESS)
399 {
400 printf("ERROR #%d:0x%x\n", __LINE__, status);
401 test_control_return(1);
402 }
403
404 ignore_error = UX_TRUE;
405
406 /* >>>>> ux_host_stack_device_configuration_activate: invalid configuration handle. */
407 temp = configuration -> ux_configuration_handle;
408 configuration -> ux_configuration_handle = 0;
409 status = ux_host_stack_device_configuration_activate(configuration);
410 if (status != UX_CONFIGURATION_HANDLE_UNKNOWN)
411 {
412 printf("ERROR #%d:0x%x\n", __LINE__, status);
413 test_control_return(1);
414 }
415 configuration -> ux_configuration_handle = temp;
416
417 /* >>>>> ux_host_stack_device_configuration_activate: invalid device semaphore. */
418 _ux_utility_semaphore_delete(&device -> ux_device_protection_semaphore);
419 status = ux_host_stack_device_configuration_activate(configuration);
420 if (status != UX_SEMAPHORE_ERROR)
421 {
422 printf("ERROR #%d:0x%x\n", __LINE__, status);
423 test_control_return(1);
424 }
425 _ux_utility_semaphore_create(&device -> ux_device_protection_semaphore, "ux_device_protection_semaphore", 1);
426
427 ignore_error = UX_FALSE;
428
429 /* >>>>> ux_host_stack_device_configuration_activate: OK. */
430 status = ux_host_stack_device_configuration_activate(configuration);
431 if (status != UX_SUCCESS)
432 {
433 printf("ERROR #%d:0x%x\n", __LINE__, status);
434 test_control_return(1);
435 }
436 UX_TEST_ASSERT(dpump_slave != UX_NULL);
437
438 /* >>>>> ux_host_stack_device_configuration_activate: Already done, OK. */
439 status = ux_host_stack_device_configuration_activate(configuration);
440 if (status != UX_SUCCESS)
441 {
442 printf("ERROR #%d:0x%x\n", __LINE__, status);
443 test_control_return(1);
444 }
445
446 /* >>>>> ux_host_stack_device_configuration_activate: Activate another, FAIL. */
447 status = ux_host_stack_device_configuration_activate(configuration -> ux_configuration_next_configuration);
448 if (status != UX_ALREADY_ACTIVATED)
449 {
450 printf("ERROR #%d:0x%x\n", __LINE__, status);
451 test_control_return(1);
452 }
453
454 /* Sleep for a tick to make sure everything is complete. */
455 tx_thread_sleep(1);
456
457 /* Check for errors from other threads. */
458 if (error_counter)
459 {
460
461 /* DPUMP error. */
462 printf("ERROR %d\n", error_counter);
463 test_control_return(1);
464 }
465 else
466 {
467
468 /* Successful test. */
469 printf("SUCCESS!\n");
470 test_control_return(0);
471 }
472 }
473
474
tx_demo_thread_slave_simulation_entry(ULONG arg)475 static void tx_demo_thread_slave_simulation_entry(ULONG arg)
476 {
477 }
478
tx_demo_instance_activate(VOID * dpump_instance)479 static VOID tx_demo_instance_activate(VOID *dpump_instance)
480 {
481
482 /* Save the DPUMP instance. */
483 dpump_slave = (UX_SLAVE_CLASS_DPUMP *) dpump_instance;
484 }
485
tx_demo_instance_deactivate(VOID * dpump_instance)486 static VOID tx_demo_instance_deactivate(VOID *dpump_instance)
487 {
488
489 /* Reset the DPUMP instance. */
490 dpump_slave = UX_NULL;
491 }
492
493