1 /* This test is designed to test the ux_host_stack_device_configuration_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_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
133                                     ULONG requested_length, ULONG *actual_length);
134 UINT                       _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
135                                     ULONG requested_length, ULONG *actual_length);
136 
137 static TX_THREAD           ux_test_thread_host_simulation;
138 static TX_THREAD           ux_test_thread_slave_simulation;
139 static void                ux_test_thread_host_simulation_entry(ULONG);
140 static void                ux_test_thread_slave_simulation_entry(ULONG);
141 
142 
143 /* Define the ISR dispatch.  */
144 
145 extern VOID    (*test_isr_dispatch)(void);
146 
147 
148 /* Prototype for test control return.  */
149 
150 void  test_control_return(UINT status);
151 
152 
153 /* Define the ISR dispatch routine.  */
154 
test_isr(void)155 static void    test_isr(void)
156 {
157 
158     /* For further expansion of interrupt-level testing.  */
159 }
160 
161 
error_callback(UINT system_level,UINT system_context,UINT error_code)162 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
163 {
164     if (error_code != UX_CONFIGURATION_HANDLE_UNKNOWN)
165     {
166         /* Failed test.  */
167         printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
168         test_control_return(1);
169     }
170 }
171 
172 /* Define what the initial system looks like.  */
173 
174 #ifdef CTEST
test_application_define(void * first_unused_memory)175 void test_application_define(void *first_unused_memory)
176 #else
177 void    usbx_ux_host_stack_device_configuration_get_test_application_define(void *first_unused_memory)
178 #endif
179 {
180 
181 UINT status;
182 CHAR                            *stack_pointer;
183 CHAR                            *memory_pointer;
184 UX_SLAVE_CLASS_DPUMP_PARAMETER  parameter;
185 
186 
187     /* Inform user.  */
188     printf("Running ux_host_stack_device_configuration_get Test................. ");
189 
190     /* Initialize the free memory pointer.  */
191     stack_pointer = (CHAR *) first_unused_memory;
192     memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
193 
194     /* Initialize USBX Memory.  */
195     status =  ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
196 
197     /* Check for error.  */
198     if (status != UX_SUCCESS)
199     {
200 
201         printf("ERROR #1\n");
202         test_control_return(1);
203     }
204 
205     /* Register the error callback. */
206     _ux_utility_error_callback_register(error_callback);
207 
208     /* The code below is required for installing the host portion of USBX.  */
209     status =  ux_host_stack_initialize(UX_NULL);
210 
211     /* Check for error.  */
212     if (status != UX_SUCCESS)
213     {
214 
215         printf("ERROR #2\n");
216         test_control_return(1);
217     }
218 
219     /* Register all the host class drivers for this USBX implementation.  */
220     status =  ux_host_stack_class_register(_ux_system_host_class_dpump_name, ux_host_class_dpump_entry);
221 
222     /* Check for error.  */
223     if (status != UX_SUCCESS)
224     {
225 
226         printf("ERROR #3\n");
227         test_control_return(1);
228     }
229 
230     /* The code below is required for installing the device portion of USBX */
231     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
232                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
233                                        string_framework, STRING_FRAMEWORK_LENGTH,
234                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
235 
236     /* Check for error.  */
237     if (status != UX_SUCCESS)
238     {
239 
240         printf("ERROR #5\n");
241         test_control_return(1);
242     }
243 
244     /* Set the parameters for callback when insertion/extraction of a Data Pump device.  */
245     parameter.ux_slave_class_dpump_instance_activate   =  ux_test_instance_activate;
246     parameter.ux_slave_class_dpump_instance_deactivate =  ux_test_instance_deactivate;
247 
248     /* Initialize the device dpump class. The class is connected with interface 0 */
249     status =  ux_device_stack_class_register(_ux_system_slave_class_dpump_name, _ux_device_class_dpump_entry,
250                                                1, 0, &parameter);
251 
252     /* Check for error.  */
253     if (status != UX_SUCCESS)
254     {
255 
256         printf("ERROR #6\n");
257         test_control_return(1);
258     }
259 
260     /* Initialize the simulated device controller.  */
261     status =  _ux_dcd_sim_slave_initialize();
262 
263     /* Check for error.  */
264     if (status != UX_SUCCESS)
265     {
266 
267         printf("ERROR #7\n");
268         test_control_return(1);
269     }
270 
271     /* Register all the USB host controllers available in this system */
272     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
273 
274     /* Check for error.  */
275     if (status != UX_SUCCESS)
276     {
277 
278         printf("ERROR #4\n");
279         test_control_return(1);
280     }
281 
282     /* Create the main host simulation thread.  */
283     status =  tx_thread_create(&ux_test_thread_host_simulation, "test host simulation", ux_test_thread_host_simulation_entry, 0,
284             stack_pointer, UX_TEST_STACK_SIZE,
285             20, 20, 1, TX_AUTO_START);
286 
287     /* Check for error.  */
288     if (status != TX_SUCCESS)
289     {
290 
291         printf("ERROR #8\n");
292         test_control_return(1);
293     }
294 }
295 
296 
ux_test_thread_host_simulation_entry(ULONG arg)297 static void  ux_test_thread_host_simulation_entry(ULONG arg)
298 {
299 
300 UINT                status;
301 UX_HOST_CLASS       *class;
302 UX_CONFIGURATION    *test_configuration;
303 
304     /* Find the main data pump container.  */
305     status =  ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class);
306 
307     /* Check for error.  */
308     if (status != UX_SUCCESS)
309     {
310 
311         /* DPUMP basic test error.  */
312         printf("ERROR #10\n");
313         test_control_return(1);
314     }
315 
316     /* We get the first instance of the data pump device.  */
317     do
318     {
319 
320         status =  ux_host_stack_class_instance_get(class, 0, (VOID **) &dpump);
321         tx_thread_relinquish();
322     } while (status != UX_SUCCESS);
323 
324     /* We still need to wait for the data pump status to be live.  */
325     while (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE)
326     {
327 
328         tx_thread_relinquish();
329     }
330 
331     /* At this point, the data pump class has been found.  Now call _ux_host_stack_device_configuration_get
332        with invalid configuration index.  */
333 
334     status = _ux_host_stack_device_configuration_get(dpump->ux_host_class_dpump_device, 1, &test_configuration);
335     if (status != UX_CONFIGURATION_HANDLE_UNKNOWN)
336     {
337 
338         /* ux_host_stack_device_get test error.  */
339         error_counter++;
340     }
341 
342     /* Sleep for a tick to make sure everything is complete.  */
343     tx_thread_sleep(1);
344 
345     /* Check for errors from other threads.  */
346     if (error_counter)
347     {
348 
349         /* Test error.  */
350         printf("ERROR #14\n");
351         test_control_return(1);
352     }
353     else
354     {
355 
356         /* Successful test.  */
357         printf("SUCCESS!\n");
358         test_control_return(0);
359     }
360 }
361 
ux_test_instance_activate(VOID * dpump_instance)362 static VOID  ux_test_instance_activate(VOID *dpump_instance)
363 {
364 
365     /* Save the DPUMP instance.  */
366     dpump_slave = (UX_SLAVE_CLASS_DPUMP *) dpump_instance;
367 }
368 
ux_test_instance_deactivate(VOID * dpump_instance)369 static VOID  ux_test_instance_deactivate(VOID *dpump_instance)
370 {
371 
372     /* Reset the DPUMP instance.  */
373     dpump_slave = UX_NULL;
374 }
375 
376