1 /* This test is designed to test the ux_host_stack_device_get.  */
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 #include "ux_host_class_dpump.h"
9 #include "ux_device_class_dpump.h"
10 
11 
12 /* Define USBX test constants.  */
13 
14 #define UX_TEST_STACK_SIZE      4096
15 #define UX_TEST_BUFFER_SIZE     2048
16 #define UX_TEST_RUN             1
17 #define UX_TEST_MEMORY_SIZE     (64*1024)
18 
19 
20 /* Define the counters used in the test application...  */
21 
22 static ULONG                           thread_0_counter;
23 static ULONG                           thread_1_counter;
24 static ULONG                           error_counter;
25 
26 
27 /* Define USBX test global variables.  */
28 
29 static unsigned char                   host_out_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
30 static unsigned char                   host_in_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
31 static unsigned char                   slave_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
32 
33 static UX_HOST_CLASS                   *class_driver;
34 static UX_HOST_CLASS_DPUMP             *dpump;
35 static UX_SLAVE_CLASS_DPUMP            *dpump_slave;
36 
37 
38 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
39 static UCHAR device_framework_full_speed[] = {
40 
41     /* Device descriptor */
42         0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
43         0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
44         0x00, 0x01,
45 
46     /* Configuration descriptor */
47         0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
48         0x32,
49 
50     /* Interface descriptor */
51         0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
52         0x00,
53 
54     /* Endpoint descriptor (Bulk Out) */
55         0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
56 
57     /* Endpoint descriptor (Bulk In) */
58         0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00
59     };
60 
61 
62 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 60
63 static UCHAR device_framework_high_speed[] = {
64 
65     /* Device descriptor */
66         0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
67         0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
68         0x03, 0x01,
69 
70     /* Device qualifier descriptor */
71         0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
72         0x01, 0x00,
73 
74     /* Configuration descriptor */
75         0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
76         0x32,
77 
78     /* Interface descriptor */
79         0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
80         0x00,
81 
82     /* Endpoint descriptor (Bulk Out) */
83         0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
84 
85     /* Endpoint descriptor (Bulk In) */
86         0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00
87     };
88 
89     /* String Device Framework :
90      Byte 0 and 1 : Word containing the language ID : 0x0904 for US
91      Byte 2       : Byte containing the index of the descriptor
92      Byte 3       : Byte containing the length of the descriptor string
93     */
94 
95 #define STRING_FRAMEWORK_LENGTH 38
96 static UCHAR string_framework[] = {
97 
98     /* Manufacturer string descriptor : Index 1 */
99         0x09, 0x04, 0x01, 0x0c,
100         0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
101         0x6f, 0x67, 0x69, 0x63,
102 
103     /* Product string descriptor : Index 2 */
104         0x09, 0x04, 0x02, 0x0c,
105         0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
106         0x44, 0x65, 0x6d, 0x6f,
107 
108     /* Serial Number string descriptor : Index 3 */
109         0x09, 0x04, 0x03, 0x04,
110         0x30, 0x30, 0x30, 0x31
111     };
112 
113 
114     /* Multiple languages are supported on the device, to add
115        a language besides English, the unicode language code must
116        be appended to the language_id_framework array and the length
117        adjusted accordingly. */
118 #define LANGUAGE_ID_FRAMEWORK_LENGTH 2
119 static UCHAR language_id_framework[] = {
120 
121     /* English. */
122         0x09, 0x04
123     };
124 
125 
126 /* Define prototypes for external Host Controller's (HCDs), classes and clients.  */
127 
128 static VOID                ux_test_instance_activate(VOID  *dpump_instance);
129 static VOID                ux_test_instance_deactivate(VOID *dpump_instance);
130 
131 UINT                       _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
132 UINT                       ux_hcd_sim_initialize(UX_HCD *hcd);
133 UINT                       _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
134                                     ULONG requested_length, ULONG *actual_length);
135 UINT                       _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
136                                     ULONG requested_length, ULONG *actual_length);
137 
138 static TX_THREAD           ux_test_thread_host_simulation;
139 static TX_THREAD           ux_test_thread_slave_simulation;
140 static void                ux_test_thread_host_simulation_entry(ULONG);
141 static void                ux_test_thread_slave_simulation_entry(ULONG);
142 
143 
144 /* Define the ISR dispatch.  */
145 
146 extern VOID    (*test_isr_dispatch)(void);
147 
148 
149 /* Prototype for test control return.  */
150 
151 void  test_control_return(UINT status);
152 
153 
154 /* Define the ISR dispatch routine.  */
155 
test_isr(void)156 static void    test_isr(void)
157 {
158 
159     /* For further expansion of interrupt-level testing.  */
160 }
161 
162 
error_callback(UINT system_level,UINT system_context,UINT error_code)163 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
164 {
165     if (error_code != UX_DEVICE_HANDLE_UNKNOWN)
166     {
167         /* Failed test.  */
168         printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
169         test_control_return(1);
170     }
171 }
172 
173 /* Define what the initial system looks like.  */
174 
175 #ifdef CTEST
test_application_define(void * first_unused_memory)176 void test_application_define(void *first_unused_memory)
177 #else
178 void    usbx_ux_host_stack_device_get_test_application_define(void *first_unused_memory)
179 #endif
180 {
181 
182 UINT status;
183 CHAR                            *stack_pointer;
184 CHAR                            *memory_pointer;
185 UX_SLAVE_CLASS_DPUMP_PARAMETER  parameter;
186 
187 
188     /* Initialize the free memory pointer.  */
189     stack_pointer = (CHAR *) first_unused_memory;
190     memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
191 
192     /* Initialize USBX Memory.  */
193     status =  ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
194 
195     /* Check for error.  */
196     if (status != UX_SUCCESS)
197     {
198 
199         printf("Running ux_host_stack_device_get Test............................... ERROR #1\n");
200         test_control_return(1);
201     }
202 
203     /* Register the error callback. */
204     _ux_utility_error_callback_register(error_callback);
205 
206     /* The code below is required for installing the host portion of USBX.  */
207     status =  ux_host_stack_initialize(UX_NULL);
208 
209     /* Check for error.  */
210     if (status != UX_SUCCESS)
211     {
212 
213         printf("Running ux_host_stack_device_get Test............................... ERROR #2\n");
214         test_control_return(1);
215     }
216 
217     /* Register all the host class drivers for this USBX implementation.  */
218     status =  ux_host_stack_class_register(_ux_system_host_class_dpump_name, ux_host_class_dpump_entry);
219 
220     /* Check for error.  */
221     if (status != UX_SUCCESS)
222     {
223 
224         printf("Running ux_host_stack_device_get Test............................... ERROR #3\n");
225         test_control_return(1);
226     }
227 
228     /* The code below is required for installing the device portion of USBX */
229     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
230                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
231                                        string_framework, STRING_FRAMEWORK_LENGTH,
232                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
233 
234     /* Check for error.  */
235     if (status != UX_SUCCESS)
236     {
237 
238         printf("Running ux_host_stack_device_get Test............................... ERROR #5\n");
239         test_control_return(1);
240     }
241 
242     /* Set the parameters for callback when insertion/extraction of a Data Pump device.  */
243     parameter.ux_slave_class_dpump_instance_activate   =  ux_test_instance_activate;
244     parameter.ux_slave_class_dpump_instance_deactivate =  ux_test_instance_deactivate;
245 
246     /* Initialize the device dpump class. The class is connected with interface 0 */
247     status =  ux_device_stack_class_register(_ux_system_slave_class_dpump_name, _ux_device_class_dpump_entry,
248                                                1, 0, &parameter);
249 
250     /* Check for error.  */
251     if (status != UX_SUCCESS)
252     {
253 
254         printf("Running ux_host_stack_device_get Test............................... ERROR #6\n");
255         test_control_return(1);
256     }
257 
258     /* Initialize the simulated device controller.  */
259     status =  _ux_dcd_sim_slave_initialize();
260 
261     /* Check for error.  */
262     if (status != UX_SUCCESS)
263     {
264 
265         printf("Running ux_host_stack_device_get Test............................... ERROR #7\n");
266         test_control_return(1);
267     }
268 
269     /* Register all the USB host controllers available in this system */
270     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
271 
272     /* Check for error.  */
273     if (status != UX_SUCCESS)
274     {
275 
276         printf("Running ux_host_stack_device_get Test............................... ERROR #4\n");
277         test_control_return(1);
278     }
279 
280     /* Create the main host simulation thread.  */
281     status =  tx_thread_create(&ux_test_thread_host_simulation, "test host simulation", ux_test_thread_host_simulation_entry, 0,
282             stack_pointer, UX_TEST_STACK_SIZE,
283             20, 20, 1, TX_AUTO_START);
284 
285     /* Check for error.  */
286     if (status != TX_SUCCESS)
287     {
288 
289         printf("Running ux_host_stack_device_get Test............................... ERROR #8\n");
290         test_control_return(1);
291     }
292 }
293 
294 
ux_test_thread_host_simulation_entry(ULONG arg)295 static void  ux_test_thread_host_simulation_entry(ULONG arg)
296 {
297 
298 UINT            status;
299 UX_HOST_CLASS   *class;
300 UX_DEVICE       *test_device;
301 
302     /* Inform user.  */
303     printf("Running ux_host_stack_device_get Test............................... ");
304 
305     /* Find the main data pump container.  */
306     status =  ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class);
307 
308     /* Check for error.  */
309     if (status != UX_SUCCESS)
310     {
311 
312         /* DPUMP basic test error.  */
313         printf("ERROR #10\n");
314         test_control_return(1);
315     }
316 
317     /* We get the first instance of the data pump device.  */
318     do
319     {
320 
321         status =  ux_host_stack_class_instance_get(class, 0, (VOID **) &dpump);
322         tx_thread_relinquish();
323     } while (status != UX_SUCCESS);
324 
325     /* We still need to wait for the data pump status to be live.  */
326     while (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE)
327     {
328 
329         tx_thread_relinquish();
330     }
331 
332     /* At this point, the data pump class has been found.  Now get the first
333        device using ux_host_stack_device_get.  */
334     status = ux_host_stack_device_get(0, &test_device);
335     if (status != UX_SUCCESS)
336     {
337 
338         /* ux_host_stack_device_get test error.  */
339         error_counter++;
340     }
341 
342     /* Check if we get correct device.  */
343     if (test_device != dpump -> ux_host_class_dpump_device)
344     {
345 
346         /* ux_host_stack_device_get test error.  */
347         error_counter++;
348     }
349 
350     /* Call ux_host_stack_device_get with device index 1.  */
351     status = ux_host_stack_device_get(1, &test_device);
352     if (status != UX_DEVICE_HANDLE_UNKNOWN)
353     {
354 
355         /* ux_host_stack_device_get test error.  */
356         error_counter++;
357     }
358 
359     /* Call ux_host_stack_device_get with device index exceeding maximum.  */
360     status = ux_host_stack_device_get(100, &test_device);
361     if (status != UX_DEVICE_HANDLE_UNKNOWN)
362     {
363 
364         /* ux_host_stack_device_get test error.  */
365         error_counter++;
366     }
367 
368     /* Sleep for a tick to make sure everything is complete.  */
369     tx_thread_sleep(1);
370 
371     /* Check for errors from other threads.  */
372     if (error_counter)
373     {
374 
375         /* Test error.  */
376         printf("ERROR #14\n");
377         test_control_return(1);
378     }
379     else
380     {
381 
382         /* Successful test.  */
383         printf("SUCCESS!\n");
384         test_control_return(0);
385     }
386 }
387 
ux_test_instance_activate(VOID * dpump_instance)388 static VOID  ux_test_instance_activate(VOID *dpump_instance)
389 {
390 
391     /* Save the DPUMP instance.  */
392     dpump_slave = (UX_SLAVE_CLASS_DPUMP *) dpump_instance;
393 }
394 
ux_test_instance_deactivate(VOID * dpump_instance)395 static VOID  ux_test_instance_deactivate(VOID *dpump_instance)
396 {
397 
398     /* Reset the DPUMP instance.  */
399     dpump_slave = UX_NULL;
400 }
401 
402