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, &parameter);
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