1 /* This test is designed to test the BOS.  */
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 
10 /* Define USBX test constants.  */
11 
12 #define UX_TEST_STACK_SIZE      4096
13 #define UX_TEST_BUFFER_SIZE     2048
14 #define UX_TEST_RUN             1
15 #define UX_TEST_MEMORY_SIZE     (64*1024)
16 
17 
18 /* Define the counters used in the test application...  */
19 
20 static ULONG                           thread_0_counter;
21 static ULONG                           thread_1_counter;
22 static ULONG                           error_counter;
23 
24 static UCHAR                           buffer[UX_TEST_BUFFER_SIZE];
25 
26 /* Define USBX test global variables.  */
27 
28 #define DW3(x)     (((x) >> 24) & 0xFFu)
29 #define DW2(x)     (((x) >> 16) & 0xFFu)
30 #define DW1(x)     (((x) >>  8) & 0xFFu)
31 #define DW0(x)     ( (x)        & 0xFFu)
32 #define W1(x)      (((x) >>  8) & 0xFFu)
33 #define W0(x)      ( (x)        & 0xFFu)
34 
35 #define _DEVICE_DESCRIPTOR \
36     /* Device descriptor.  */       \
37     18, UX_DEVICE_DESCRIPTOR_ITEM,  \
38     W0(0x201), W1(0x201),           \
39     UX_CLASS_BILLBOARD_CLASS,       \
40     UX_CLASS_BILLBOARD_SUBCLASS,    \
41     UX_CLASS_BILLBOARD_PROTOCOL,    \
42     64,                             \
43     W0(0xec08), W1(0xec08),         \
44     W0(0x0001), W1(0x0001),         \
45     W0(0x0001), W1(0x0001),         \
46     0, 0, 0,                        \
47     1
48 
49 #define _DEVICE_QUALIFIER_DESCRIPTOR \
50     /* Device Qualifier Descriptor.  */     \
51     10, UX_DEVICE_QUALIFIER_DESCRIPTOR_ITEM,\
52     W0(0x201), W1(0x201),                   \
53     UX_CLASS_BILLBOARD_CLASS,               \
54     UX_CLASS_BILLBOARD_SUBCLASS,            \
55     UX_CLASS_BILLBOARD_PROTOCOL,            \
56     8,                                      \
57     1,                                      \
58     0
59 
60 #define _CONFIGURATION_DESCRIPTOR \
61     /* Configuration Descriptor.  */    \
62     9, UX_CONFIGURATION_DESCRIPTOR_ITEM,\
63     W0(18), W1(18),                     \
64     1, 1,                               \
65     0, 0xc0, 0x32
66 
67 #define _INTERFACE_DESCRIPTOR \
68     /* Interface Descriptor.  */    \
69     9, UX_INTERFACE_DESCRIPTOR_ITEM,\
70     0, 0, 0,                        \
71     UX_CLASS_BILLBOARD_CLASS,       \
72     UX_CLASS_BILLBOARD_SUBCLASS,    \
73     UX_CLASS_BILLBOARD_PROTOCOL,    \
74     0
75 
76 #define _BOS_DESCRIPTORS_LENGTH (5+7+56+8+8+8)
77 #define _BOS_DESCRIPTORS \
78     /* BOS descriptor.  */                                      \
79     5, UX_BOS_DESCRIPTOR_ITEM,                                  \
80     W0(_BOS_DESCRIPTORS_LENGTH), W1(_BOS_DESCRIPTORS_LENGTH), 1,\
81     /* USB 2.0 Extension descriptor  */                                       \
82     7, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_USB_2_0_EXTENSION, \
83     DW0(0x00000002u), DW1(0x00000002u), DW2(0x00000002u), DW3(0x00000002u),   \
84     /* Billboard Capability Descriptor Example (44+3*4=56)  */\
85     56, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD, 0,   \
86     1, 0,                                                                   \
87     W0(0), W1(0),                                                           \
88     0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
89     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
90     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
91     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                         \
92     W0(0x0000), W0(0x0000),                                                 \
93     0x00, 0x00,                                                             \
94     W0(0x8087), W1(0x8087), 0x00, 0x00,                                     \
95     W0(0x8087), W1(0x8087), 0x01, 0x00,                                     \
96     W0(0xFF01), W1(0xFF01), 0x00, 0x00,                                     \
97     /* Billboard Alternate Mode Capability Descriptor Examples  */\
98     8, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD_EX,    \
99     0, DW0(0x00000010), DW1(0x00000010), DW2(0x00000010), DW3(0x00000010),  \
100     8, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD_EX,    \
101     1, DW0(0x00000002), DW1(0x00000002), DW2(0x00000002), DW3(0x00000002),  \
102     8, UX_DEVICE_CAPABILITY_DESCRIPTOR_ITEM, UX_CAPABILITY_BILLBOARD_EX,    \
103     2, DW0(0x000C00C5), DW1(0x000C00C5), DW2(0x000C00C5), DW3(0x000C00C5)
104 
105 
106 static UCHAR device_framework_full_speed[] = {
107 
108     _DEVICE_DESCRIPTOR,
109     _BOS_DESCRIPTORS,
110     _CONFIGURATION_DESCRIPTOR,
111     _INTERFACE_DESCRIPTOR,
112 };
113 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
114 
115 static UCHAR device_framework_high_speed[] = {
116 
117     _DEVICE_DESCRIPTOR,
118     _BOS_DESCRIPTORS,
119     _DEVICE_QUALIFIER_DESCRIPTOR,
120     _CONFIGURATION_DESCRIPTOR,
121     _INTERFACE_DESCRIPTOR,
122 };
123 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
124 
125 
126 /* String Device Framework :
127      Byte 0 and 1 : Word containing the language ID : 0x0904 for US
128      Byte 2       : Byte containing the index of the descriptor
129      Byte 3       : Byte containing the length of the descriptor string
130 */
131 static UCHAR string_framework[] = {
132 
133     /* Manufacturer string descriptor : Index 1 */
134         0x09, 0x04, 0x01, 0x0c,
135         0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
136         0x6f, 0x67, 0x69, 0x63,
137 
138     /* Product string descriptor : Index 2 */
139         0x09, 0x04, 0x02, 0x0c,
140         0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
141         0x44, 0x65, 0x6d, 0x6f,
142 
143     /* Serial Number string descriptor : Index 3 */
144         0x09, 0x04, 0x03, 0x04,
145         0x30, 0x30, 0x30, 0x31
146 };
147 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
148 
149 
150 /* Multiple languages are supported on the device, to add
151        a language besides English, the unicode language code must
152        be appended to the language_id_framework array and the length
153        adjusted accordingly. */
154 static UCHAR language_id_framework[] = {
155 
156     /* English. */
157         0x09, 0x04
158 };
159 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
160 
161 
162 /* Define prototypes for external Host Controller's (HCDs), classes and clients.  */
163 
164 static TX_THREAD           ux_test_thread_host_simulation;
165 static TX_THREAD           ux_test_thread_slave_simulation;
166 static void                ux_test_thread_host_simulation_entry(ULONG);
167 static void                ux_test_thread_slave_simulation_entry(ULONG);
168 
169 
170 /* Define the ISR dispatch.  */
171 
172 extern VOID    (*test_isr_dispatch)(void);
173 
174 
175 /* Prototype for test control return.  */
176 
177 void  test_control_return(UINT status);
178 
179 
180 /* Define the ISR dispatch routine.  */
181 
test_isr(void)182 static void    test_isr(void)
183 {
184 
185     /* For further expansion of interrupt-level testing.  */
186 }
187 
188 
error_callback(UINT system_level,UINT system_context,UINT error_code)189 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
190 {
191     if (error_code != UX_DEVICE_HANDLE_UNKNOWN &&
192         error_code != UX_DEVICE_ENUMERATION_FAILURE)
193     {
194         /* Failed test.  */
195         printf("Error #%d, system_level: %d, system_context: %d, error code: 0x%x\n", __LINE__, system_level, system_context, error_code);
196         test_control_return(1);
197     }
198 }
199 
200 /* Define what the initial system looks like.  */
201 
202 #ifdef CTEST
test_application_define(void * first_unused_memory)203 void test_application_define(void *first_unused_memory)
204 #else
205 void    usbx_ux_device_stack_bos_test_application_define(void *first_unused_memory)
206 #endif
207 {
208 
209 UINT status;
210 CHAR                            *stack_pointer;
211 CHAR                            *memory_pointer;
212 
213 
214     printf("Running ux_device_stack BOS Test....................................");
215 
216     /* Initialize the free memory pointer.  */
217     stack_pointer = (CHAR *) first_unused_memory;
218     memory_pointer = stack_pointer + (UX_TEST_STACK_SIZE * 2);
219 
220     /* Initialize USBX Memory.  */
221     status =  ux_system_initialize(memory_pointer, UX_TEST_MEMORY_SIZE, UX_NULL, 0);
222 
223     /* Check for error.  */
224     if (status != UX_SUCCESS)
225     {
226 
227         printf("ERROR #%d\n", __LINE__);
228         test_control_return(1);
229     }
230 
231     /* Register the error callback. */
232     _ux_utility_error_callback_register(error_callback);
233 
234     /* The code below is required for installing the host portion of USBX.  */
235     status =  ux_host_stack_initialize(UX_NULL);
236 
237     /* Check for error.  */
238     if (status != UX_SUCCESS)
239     {
240 
241         printf("ERROR #%d\n", __LINE__);
242         test_control_return(1);
243     }
244 
245     /* The code below is required for installing the device portion of USBX */
246     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
247                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
248                                        string_framework, STRING_FRAMEWORK_LENGTH,
249                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
250 
251     /* Check for error.  */
252     if (status != UX_SUCCESS)
253     {
254 
255         printf("ERROR #%d\n", __LINE__);
256         test_control_return(1);
257     }
258 
259     /* Initialize the simulated device controller.  */
260     status =  _ux_dcd_sim_slave_initialize();
261 
262     /* Check for error.  */
263     if (status != UX_SUCCESS)
264     {
265 
266         printf("ERROR #%d\n", __LINE__);
267         test_control_return(1);
268     }
269 
270     /* Register all the USB host controllers available in this system */
271     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
272 
273     /* Check for error.  */
274     if (status != UX_SUCCESS)
275     {
276 
277         printf("ERROR #%d\n", __LINE__);
278         test_control_return(1);
279     }
280 
281     /* Create the main host simulation thread.  */
282     status =  tx_thread_create(&ux_test_thread_host_simulation, "test host simulation", ux_test_thread_host_simulation_entry, 0,
283             stack_pointer, UX_TEST_STACK_SIZE,
284             20, 20, 1, TX_AUTO_START);
285 
286     /* Check for error.  */
287     if (status != TX_SUCCESS)
288     {
289 
290         printf("ERROR #%d\n", __LINE__);
291         test_control_return(1);
292     }
293 }
294 
295 
ux_test_thread_host_simulation_entry(ULONG arg)296 static void  ux_test_thread_host_simulation_entry(ULONG arg)
297 {
298 
299 UINT                    status;
300 INT                     i;
301 UX_DEVICE               *device;
302 UX_ENDPOINT             *control_endpoint;
303 UX_TRANSFER             *transfer_request;
304 
305 
306     /* Wait device connection.  */
307     for (i = 0; i < 10; i ++)
308     {
309         status = ux_host_stack_device_get(0, &device);
310         if (status == UX_SUCCESS)
311             break;
312         ux_utility_delay_ms(10);
313     }
314     if (status != UX_SUCCESS)
315     {
316         printf("ERROR #%d\n", __LINE__);
317         test_control_return(1);
318     }
319     control_endpoint = &device->ux_device_control_endpoint;
320     transfer_request = &control_endpoint->ux_endpoint_transfer_request;
321 
322     /* Wait until enumeration retries end.  */
323     ux_utility_delay_ms(1000);
324 
325     /* Test BOS request.  */
326     transfer_request -> ux_transfer_request_data_pointer =      buffer;
327     transfer_request -> ux_transfer_request_requested_length =  0xFF;
328     transfer_request -> ux_transfer_request_function =          UX_GET_DESCRIPTOR;
329     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
330     transfer_request -> ux_transfer_request_value =             UX_BOS_DESCRIPTOR_ITEM << 8;
331     transfer_request -> ux_transfer_request_index =             0;
332 
333     status = ux_host_stack_transfer_request(transfer_request);
334     if (status != UX_SUCCESS)
335     {
336 
337         printf("ERROR #%d: 0x%x\n", __LINE__, status);
338         error_counter ++;
339     }
340     if (transfer_request->ux_transfer_request_actual_length != _BOS_DESCRIPTORS_LENGTH)
341     {
342 
343         printf("ERROR #%d: 0x%x\n", __LINE__, status);
344         error_counter ++;
345     }
346 
347     /* Sleep for a tick to make sure everything is complete.  */
348     tx_thread_sleep(1);
349 
350     /* Check for errors from other threads.  */
351     if (error_counter)
352     {
353 
354         /* Test error.  */
355         printf("ERROR #%d\n", __LINE__);
356         test_control_return(1);
357     }
358     else
359     {
360 
361         /* Successful test.  */
362         printf("SUCCESS\n");
363         test_control_return(0);
364     }
365 }
366