1 /* This test is designed to test the simple dpump host/device class operation. */
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 #include "fx_api.h"
10
11 #include "ux_device_class_cdc_acm.h"
12 #include "ux_device_stack.h"
13
14 #include "ux_host_class_cdc_acm.h"
15 #include "ux_host_stack.h"
16
17 #include "ux_host_class_hid.h"
18 #include "ux_device_class_hid.h"
19
20 #include "ux_host_class_storage.h"
21 #include "ux_device_class_storage.h"
22
23 #include "ux_test_dcd_sim_slave.h"
24 #include "ux_test_hcd_sim_host.h"
25 #include "ux_test_utility_sim.h"
26
27 /* Define constants. */
28 #define UX_CDC_ACM_CONNECTION_DELAY ((UX_RH_ENUMERATION_RETRY + 1)*UX_HOST_CLASS_CDC_ACM_DEVICE_INIT_DELAY)
29 #define UX_DEMO_DEBUG_SIZE (4096*8)
30 #define UX_DEMO_STACK_SIZE 1024
31 #define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
32 #define UX_DEMO_XMIT_BUFFER_SIZE 512
33 #define UX_DEMO_RECEPTION_BUFFER_SIZE 512
34 #define UX_DEMO_FILE_BUFFER_SIZE 512
35 #define UX_DEMO_RECEPTION_BLOCK_SIZE 64
36 #define UX_DEMO_MEMORY_SIZE (96*1024)
37 #define UX_DEMO_FILE_SIZE (128 * 1024)
38 #define UX_RAM_DISK_MEMORY (256 * 1024)
39
40 #define UX_DEMO_VENDOR_REQUEST 0x54
41
42 /* Define local/extern function prototypes. */
43 static VOID test_thread_entry(ULONG);
44 static TX_THREAD tx_test_thread_simulation0;
45 static TX_THREAD tx_test_thread_simulation1;
46 static VOID tx_test_thread_simulation0_entry(ULONG);
47 static VOID tx_test_thread_simulation1_entry(ULONG);
48 static VOID test_cdc_instance_activate(VOID *cdc_instance);
49 static VOID test_cdc_instance_deactivate(VOID *cdc_instance);
50 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance);
51
52 static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
53 static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
54 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
55
56 static UINT test_ux_device_class_cdc_acm_entry(UX_SLAVE_CLASS_COMMAND *command);
57
58 static UINT test_ms_vendor_request(ULONG request, ULONG request_value, ULONG request_index, ULONG request_length,
59 UCHAR *transfer_request_buffer, ULONG *transfer_request_length);
60
61 static VOID ux_test_dcd_entry_is_called(UX_TEST_ACTION *action, VOID *params);
62
63 static UINT test_ux_device_class_cdc_acm_read_halt(UX_SLAVE_CLASS_CDC_ACM *cdc_acm);
64
65 static UINT test_ux_host_class_cdc_acm_write(UX_HOST_CLASS_CDC_ACM *cdc_acm, UCHAR *data_pointer,
66 ULONG requested_length, ULONG *actual_length);
67 static UINT test_ux_host_class_cdc_acm_write_halt_clear(UX_HOST_CLASS_CDC_ACM *cdc_acm);
68
69
70 /* Define global data structures. */
71 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
72 static UX_HOST_CLASS *class_driver;
73 static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
74 static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
75
76 static UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
77 static UCHAR cdc_acm_slave_change;
78 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
79 static UCHAR cdc_acm_slave_reading = UX_TRUE;
80
81 static UCHAR buffer[UX_DEMO_BUFFER_SIZE];
82
83 static ULONG error_counter;
84
85 static ULONG set_cfg_counter;
86
87 static ULONG rsc_mem_alloc_cnt_on_set_cfg;
88 static ULONG rsc_sem_on_set_cfg;
89 static ULONG rsc_sem_get_on_set_cfg;
90 static ULONG rsc_mutex_on_set_cfg;
91
92 static ULONG rsc_enum_mem_alloc_count;
93 static ULONG rsc_enum_sem_usage;
94 static ULONG rsc_enum_sem_get_count;
95 static ULONG rsc_enum_mutex_usage;
96
97 static UINT class_entry_rc = UX_SUCCESS;
98
99 static UINT vendor_req_rc = UX_SUCCESS;
100
101 static UX_SLAVE_CLASS_HID_PARAMETER hid_parameter;
102
103 /* HID mouse related descriptors */
104
105 static UCHAR hid_mouse_report[] = {
106
107 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
108 0x09, 0x02, // USAGE (Mouse)
109 0xa1, 0x01, // COLLECTION (Application)
110 0x09, 0x01, // USAGE (Pointer)
111 0xa1, 0x00, // COLLECTION (Physical)
112 0x05, 0x09, // USAGE_PAGE (Button)
113 0x19, 0x01, // USAGE_MINIMUM (Button 1)
114 0x29, 0x03, // USAGE_MAXIMUM (Button 3)
115 0x15, 0x00, // LOGICAL_MINIMUM (0)
116 0x25, 0x01, // LOGICAL_MAXIMUM (1)
117 0x95, 0x03, // REPORT_COUNT (3)
118 0x75, 0x01, // REPORT_SIZE (1)
119 0x81, 0x02, // INPUT (Data,Var,Abs)
120 0x95, 0x01, // REPORT_COUNT (1)
121 0x75, 0x05, // REPORT_SIZE (5)
122 0x81, 0x03, // INPUT (Cnst,Var,Abs)
123 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
124 0x09, 0x30, // USAGE (X)
125 0x09, 0x31, // USAGE (Y)
126 0x15, 0x81, // LOGICAL_MINIMUM (-127)
127 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
128 0x75, 0x08, // REPORT_SIZE (8)
129 0x95, 0x02, // REPORT_COUNT (2)
130 0x81, 0x06, // INPUT (Data,Var,Rel)
131 0x09, 0x38, // USAGE (Mouse Wheel)
132 0x15, 0x81, // LOGICAL_MINIMUM (-127)
133 0x25, 0x7f, // LOGICAL_MAXIMUM (127)
134 0x75, 0x08, // REPORT_SIZE (8)
135 0x95, 0x01, // REPORT_COUNT (1)
136 0x81, 0x06, // INPUT (Data,Var,Rel)
137 0xc0, // END_COLLECTION
138 0xc0 // END_COLLECTION
139 };
140 #define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
141
142 #define LSB(x) (x & 0x00ff)
143 #define MSB(x) ((x & 0xff00) >> 8)
144
145 /* HID Mouse interface descriptors 9+9+7=25 bytes */
146 #define HID_MOUSE_IFC_DESC_ALL(ifc, interrupt_epa) \
147 /* Interface descriptor */\
148 0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
149 /* HID descriptor */\
150 0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),\
151 MSB(HID_MOUSE_REPORT_LENGTH),\
152 /* Endpoint descriptor (Interrupt) */\
153 0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
154 #define HID_MOUSE_IFC_DESC_ALL_LEN 25
155
156 /* Storage related descriptors 9+7+7=23 bytes */
157 #define MS_IFC_DESC_ALL(ifc, bulk_in_epa, bulk_out_epa) \
158 /* Interface descriptor */\
159 0x09, 0x04, (ifc), 0x00, 0x03, 0x08, 0x06, 0x50, 0x00,\
160 /* Endpoint descriptor (Bulk In) */\
161 0x07, 0x05, (bulk_in_epa), 0x02, 0x40, 0x00, 0x00,\
162 /* Endpoint descriptor (Bulk Out) */\
163 0x07, 0x05, (bulk_out_epa), 0x02, 0x40, 0x00, 0x00,
164 #define MS_IFC_DESC_ALL_LEN 23
165
166 /* CDC IAD 8 bytes */
167 #define CDC_IAD_DESC(comm_ifc) \
168 /* Interface association descriptor. 8 bytes. */\
169 0x08, 0x0b, (comm_ifc), 0x02, 0x02, 0x02, 0x00, 0x00,
170 #define CDC_IAD_DESC_LEN 8
171
172 /* CDC Communication interface descriptors 9+5+4+5+5+7=35 bytes */
173 #define CDC_COMM_IFC_DESC_ALL(comm_ifc, data_ifc, interrupt_epa) \
174 /* Communication Class Interface Descriptor. 9 bytes. */\
175 0x09, 0x04, (comm_ifc), 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,\
176 /* Header Functional Descriptor 5 bytes */\
177 0x05, 0x24, 0x00, 0x10, 0x01,\
178 /* ACM Functional Descriptor 4 bytes */\
179 0x04, 0x24, 0x02, 0x0f,\
180 /* Union Functional Descriptor 5 bytes */\
181 0x05, 0x24, 0x06,\
182 (comm_ifc), /* Master interface */\
183 (data_ifc), /* Slave interface */\
184 /* Call Management Functional Descriptor 5 bytes */\
185 0x05, 0x24, 0x01, 0x03,\
186 (data_ifc), /* Data interface */\
187 /* Endpoint 0x83 descriptor 7 bytes */\
188 0x07, 0x05, (interrupt_epa),\
189 0x03,\
190 0x08, 0x00,\
191 15,
192 #define CDC_COMM_IFC_DESC_ALL_LEN 35
193
194 /* CDC Data interface descriptors 9+7+7=23 bytes */
195 #define CDC_DATA_IFC_DESC_ALL(ifc, bulk_in_epa, bulk_out_epa) \
196 /* Data Class Interface Descriptor Requirement 9 bytes */\
197 0x09, 0x04, (ifc),\
198 0x00, /* bAlternateSetting */\
199 0x02, /* bNumEndpoints */\
200 0x0A, 0x00, 0x00,\
201 0x00,\
202 /* Endpoint bulk IN descriptor 7 bytes */\
203 0x07, 0x05, (bulk_in_epa),\
204 0x02,\
205 0x40, 0x00,\
206 0x00,\
207 /* Endpoint bulk OUT descriptor 7 bytes */\
208 0x07, 0x05, (bulk_out_epa),\
209 0x02,\
210 0x40, 0x00,\
211 0x00,
212 #define CDC_DATA_IFC_DESC_ALL_LEN 23
213
214 /* Configuration descriptor 9 bytes */
215 #define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
216 /* Configuration 1 descriptor 9 bytes */\
217 0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
218 (bNumInterfaces), (bConfigurationValue), 0x00,\
219 0x40, 0x00,
220 #define CFG_DESC_LEN 9
221
222 /* Define device framework. */
223
224 static unsigned char device_framework_full_speed[] = {
225
226 /* Device descriptor 18 bytes
227 0x02 bDeviceClass: CDC class code
228 0x00 bDeviceSubclass: CDC class sub code
229 0x00 bDeviceProtocol: CDC Device protocol
230
231 idVendor & idProduct - http://www.linux-usb.org/usb.ids
232 */
233 0x12, 0x01, 0x10, 0x01,
234 0xEF, 0x02, 0x01,
235 0x08,
236 0x84, 0x84, 0x00, 0x00,
237 0x00, 0x01,
238 0x01, 0x02, 03,
239 0x01, /* bNumConfigurations */
240
241 /* Configuration 1 descriptor 9 bytes */
242 0x09, 0x02, 0x4b, 0x00,
243 0x02, 0x01, 0x00,
244 0xE0, 0x00,
245
246 /* Interface association descriptor. 8 bytes. */
247 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
248
249 /* Communication Class Interface Descriptor. 9 bytes. */
250 0x09, 0x04, 0x00,
251 0x00,
252 0x01,
253 0x02, 0x02, 0x01,
254 0x00,
255
256 /* Header Functional Descriptor 5 bytes */
257 0x05, 0x24, 0x00,
258 0x10, 0x01,
259
260 /* ACM Functional Descriptor 4 bytes */
261 0x04, 0x24, 0x02,
262 0x0f,
263
264 /* Union Functional Descriptor 5 bytes */
265 0x05, 0x24, 0x06,
266 0x00, /* Master interface */
267 0x01, /* Slave interface */
268
269 /* Call Management Functional Descriptor 5 bytes */
270 0x05, 0x24, 0x01,
271 0x03,
272 0x01, /* Data interface */
273
274 /* Endpoint 0x83 descriptor 7 bytes */
275 0x07, 0x05, 0x83,
276 0x03,
277 0x08, 0x00,
278 0xFF,
279
280 /* Data Class Interface Descriptor Requirement 9 bytes */
281 0x09, 0x04, 0x01,
282 0x00,
283 0x02,
284 0x0A, 0x00, 0x00,
285 0x00,
286
287 /* Endpoint 0x81 descriptor 7 bytes */
288 0x07, 0x05, 0x81,
289 0x02,
290 0x40, 0x00,
291 0x00,
292
293 /* Endpoint 0x02 descriptor 7 bytes */
294 0x07, 0x05, 0x02,
295 0x02,
296 0x40, 0x00,
297 0x00,
298
299 /* Configuration 2 descriptor 9 bytes */
300 0x09, 0x02, (0x4b + 28 + 46), 0x00,
301 0x02, 0x02, 0x00,
302 0x40, 0x00,
303
304 /* Interface association descriptor. 8 bytes. */
305 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
306
307 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
308 0x09, 0x04, 0x00,
309 0x00, /* bAlternateSetting */
310 0x00, /* bNumEndpoints */
311 0x02, 0x02, 0x01,
312 0x00,
313
314 /* Header Functional Descriptor 5 bytes */
315 0x05, 0x24, 0x00,
316 0x10, 0x01,
317
318 /* ACM Functional Descriptor 4 bytes */
319 0x04, 0x24, 0x02,
320 0x0f,
321
322 /* Union Functional Descriptor 5 bytes */
323 0x05, 0x24, 0x06,
324 0x00, /* Master interface */
325 0x01, /* Slave interface */
326
327 /* Call Management Functional Descriptor 5 bytes */
328 0x05, 0x24, 0x01,
329 0x03,
330 0x01, /* Data interface */
331
332 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
333 0x09, 0x04, 0x00,
334 0x01, /* bAlternateSetting */
335 0x01, /* bNumEndpoints */
336 0x02, 0x02, 0x01,
337 0x00,
338
339 /* Header Functional Descriptor 5 bytes */
340 0x05, 0x24, 0x00,
341 0x10, 0x01,
342
343 /* ACM Functional Descriptor 4 bytes */
344 0x04, 0x24, 0x02,
345 0x0f,
346
347 /* Union Functional Descriptor 5 bytes */
348 0x05, 0x24, 0x06,
349 0x00, /* Master interface */
350 0x01, /* Slave interface */
351
352 /* Call Management Functional Descriptor 5 bytes */
353 0x05, 0x24, 0x01,
354 0x03,
355 0x01, /* Data interface */
356
357 /* Endpoint 0x83 descriptor 7 bytes */
358 0x07, 0x05, 0x83,
359 0x03,
360 0x08, 0x00,
361 0xFF,
362
363 /* Data Class Interface Descriptor Requirement 9 bytes */
364 0x09, 0x04, 0x01,
365 0x00, /* bAlternateSetting */
366 0x00, /* bNumEndpoints */
367 0x0A, 0x00, 0x00,
368 0x00,
369
370 /* Data Class Interface Descriptor Requirement 9 bytes */
371 0x09, 0x04, 0x01,
372 0x01, /* bAlternateSetting */
373 0x02, /* bNumEndpoints */
374 0x0A, 0x00, 0x00,
375 0x00,
376
377 /* Endpoint 0x81 descriptor 7 bytes */
378 0x07, 0x05, 0x81,
379 0x02,
380 0x40, 0x00,
381 0x00,
382
383 /* Endpoint 0x02 descriptor 7 bytes */
384 0x07, 0x05, 0x02,
385 0x02,
386 0x40, 0x00,
387 0x00,
388
389 /* Data Class Interface Descriptor Requirement 9 bytes */
390 0x09, 0x04, 0x01,
391 0x02, /* bAlternateSetting */
392 0x04, /* bNumEndpoints */
393 0x0A, 0x00, 0x00,
394 0x00,
395
396 /* Endpoint 0x81 descriptor 7 bytes */
397 0x07, 0x05, 0x81,
398 0x02,
399 0x40, 0x00,
400 0x00,
401
402 /* Endpoint 0x02 descriptor 7 bytes */
403 0x07, 0x05, 0x02,
404 0x02,
405 0x40, 0x00,
406 0x00,
407
408 /* Endpoint 0x85 descriptor 7 bytes */
409 0x07, 0x05, 0x85,
410 0x02,
411 0x40, 0x00,
412 0x00,
413
414 /* Endpoint 0x04 descriptor 7 bytes */
415 0x07, 0x05, 0x04,
416 0x02,
417 0x40, 0x00,
418 0x00,
419
420 /* Configuration 3: CDC + CDC */
421 CFG_DESC(CFG_DESC_LEN+2*(CDC_IAD_DESC_LEN+CDC_COMM_IFC_DESC_ALL_LEN+CDC_DATA_IFC_DESC_ALL_LEN), 4, 3)
422 CDC_IAD_DESC(0)
423 CDC_COMM_IFC_DESC_ALL(0, 1, 0x83)
424 CDC_DATA_IFC_DESC_ALL(1, 0x81, 0x02)
425 CDC_IAD_DESC(2)
426 CDC_COMM_IFC_DESC_ALL(2, 3, 0x86)
427 CDC_DATA_IFC_DESC_ALL(3, 0x84, 0x05)
428
429 /* Configuration 4: HID + HID */
430 CFG_DESC(CFG_DESC_LEN+2*(HID_MOUSE_IFC_DESC_ALL_LEN), 2, 4)
431 HID_MOUSE_IFC_DESC_ALL(0, 0x81)
432 HID_MOUSE_IFC_DESC_ALL(1, 0x82)
433
434 };
435 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
436
437 static unsigned char device_framework_high_speed[] = {
438
439 /* Device descriptor
440 0x02 bDeviceClass: CDC class code
441 0x00 bDeviceSubclass: CDC class sub code
442 0x00 bDeviceProtocol: CDC Device protocol
443
444 idVendor & idProduct - http://www.linux-usb.org/usb.ids
445 */
446 0x12, 0x01, 0x00, 0x02,
447 0xEF, 0x02, 0x01,
448 0x40,
449 0x84, 0x84, 0x00, 0x00,
450 0x00, 0x01,
451 0x01, 0x02, 03,
452 0x01, /* bNumConfigurations */
453
454 /* Device qualifier descriptor */
455 0x0a, 0x06, 0x00, 0x02,
456 0x02, 0x00, 0x00,
457 0x40,
458 0x01,
459 0x00,
460
461 /* Configuration 1 descriptor */
462 0x09, 0x02, (0x4b+5), 0x00,
463 0x02, 0x01, 0x00,
464 0xE0, 0x00,
465
466 /* OTG Descriptor. */
467 0x05, 0x09, 0x03, 0x02, 0x00,
468
469 /* Interface association descriptor. */
470 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
471
472 /* Communication Class Interface Descriptor Requirement */
473 0x09, 0x04, 0x00,
474 0x00,
475 0x01,
476 0x02, 0x02, 0x01,
477 0x00,
478
479 /* Header Functional Descriptor */
480 0x05, 0x24, 0x00,
481 0x10, 0x01,
482
483 /* ACM Functional Descriptor */
484 0x04, 0x24, 0x02,
485 0x0f,
486
487 /* Union Functional Descriptor */
488 0x05, 0x24, 0x06,
489 0x00,
490 0x01,
491
492 /* Call Management Functional Descriptor */
493 0x05, 0x24, 0x01,
494 0x00,
495 0x01,
496
497 /* Endpoint 0x83 descriptor */
498 0x07, 0x05, 0x83,
499 0x03,
500 0x08, 0x00,
501 15,
502
503 /* Data Class Interface Descriptor Requirement */
504 0x09, 0x04, 0x01,
505 0x00,
506 0x02,
507 0x0A, 0x00, 0x00,
508 0x00,
509
510 /* Endpoint 0x81 descriptor */
511 0x07, 0x05, 0x81,
512 0x02,
513 0x40, 0x00,
514 0x00,
515
516 /* Endpoint 0x02 descriptor */
517 0x07, 0x05, 0x02,
518 0x02,
519 0x40, 0x00,
520 0x00,
521
522 /* Configuration 2 descriptor 9 bytes */
523 0x09, 0x02, (0x4b + 28 + 46), 0x00,
524 0x02, 0x02, 0x00,
525 0x40, 0x00,
526
527 /* Interface association descriptor. 8 bytes. */
528 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
529
530 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
531 0x09, 0x04, 0x00,
532 0x00, /* bAlternateSetting */
533 0x00, /* bNumEndpoints */
534 0x02, 0x02, 0x01,
535 0x00,
536
537 /* Header Functional Descriptor 5 bytes */
538 0x05, 0x24, 0x00,
539 0x10, 0x01,
540
541 /* ACM Functional Descriptor 4 bytes */
542 0x04, 0x24, 0x02,
543 0x0f,
544
545 /* Union Functional Descriptor 5 bytes */
546 0x05, 0x24, 0x06,
547 0x00, /* Master interface */
548 0x01, /* Slave interface */
549
550 /* Call Management Functional Descriptor 5 bytes */
551 0x05, 0x24, 0x01,
552 0x03,
553 0x01, /* Data interface */
554
555 /* Communication Class Interface Descriptor Requirement. 9 bytes. */
556 0x09, 0x04, 0x00,
557 0x01, /* bAlternateSetting */
558 0x01, /* bNumEndpoints */
559 0x02, 0x02, 0x01,
560 0x00,
561
562 /* Header Functional Descriptor 5 bytes */
563 0x05, 0x24, 0x00,
564 0x10, 0x01,
565
566 /* ACM Functional Descriptor 4 bytes */
567 0x04, 0x24, 0x02,
568 0x0f,
569
570 /* Union Functional Descriptor 5 bytes */
571 0x05, 0x24, 0x06,
572 0x00, /* Master interface */
573 0x01, /* Slave interface */
574
575 /* Call Management Functional Descriptor 5 bytes */
576 0x05, 0x24, 0x01,
577 0x03,
578 0x01, /* Data interface */
579
580 /* Endpoint 0x83 descriptor 7 bytes */
581 0x07, 0x05, 0x83,
582 0x03,
583 0x08, 0x00,
584 15,
585
586 /* Data Class Interface Descriptor Requirement 9 bytes */
587 0x09, 0x04, 0x01,
588 0x00,
589 0x00,
590 0x0A, 0x00, 0x00,
591 0x00,
592
593 /* Data Class Interface Descriptor Requirement 9 bytes */
594 0x09, 0x04, 0x01,
595 0x01,
596 0x02,
597 0x0A, 0x00, 0x00,
598 0x00,
599
600 /* Endpoint 0x81 descriptor 7 bytes */
601 0x07, 0x05, 0x81,
602 0x02,
603 0x40, 0x00,
604 0x00,
605
606 /* Endpoint 0x02 descriptor 7 bytes */
607 0x07, 0x05, 0x02,
608 0x02,
609 0x40, 0x00,
610 0x00,
611
612 /* Data Class Interface Descriptor Requirement 9 bytes */
613 0x09, 0x04, 0x01,
614 0x02, /* bAlternateSetting */
615 0x04, /* bNumEndpoints */
616 0x0A, 0x00, 0x00,
617 0x00,
618
619 /* Endpoint 0x81 descriptor 7 bytes */
620 0x07, 0x05, 0x81,
621 0x02,
622 0x40, 0x00,
623 0x00,
624
625 /* Endpoint 0x02 descriptor 7 bytes */
626 0x07, 0x05, 0x02,
627 0x02,
628 0x40, 0x00,
629 0x00,
630
631 /* Endpoint 0x85 descriptor 7 bytes */
632 0x07, 0x05, 0x85,
633 0x02,
634 0x40, 0x00,
635 0x00,
636
637 /* Endpoint 0x04 descriptor 7 bytes */
638 0x07, 0x05, 0x04,
639 0x02,
640 0x40, 0x00,
641 0x00,
642
643 /* Configuration 3: CDC + CDC */
644 CFG_DESC(CFG_DESC_LEN+2*(CDC_IAD_DESC_LEN+CDC_COMM_IFC_DESC_ALL_LEN+CDC_DATA_IFC_DESC_ALL_LEN), 4, 3)
645 CDC_IAD_DESC(0)
646 CDC_COMM_IFC_DESC_ALL(0, 1, 0x83)
647 CDC_DATA_IFC_DESC_ALL(1, 0x81, 0x02)
648 CDC_IAD_DESC(2)
649 CDC_COMM_IFC_DESC_ALL(2, 3, 0x86)
650 CDC_DATA_IFC_DESC_ALL(3, 0x84, 0x05)
651
652 /* Configuration 4: HID + HID */
653 CFG_DESC(CFG_DESC_LEN+2*(HID_MOUSE_IFC_DESC_ALL_LEN), 2, 4)
654 HID_MOUSE_IFC_DESC_ALL(0, 0x81)
655 HID_MOUSE_IFC_DESC_ALL(1, 0x82)
656
657 };
658 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
659
660
661 static unsigned char string_framework[] = {
662
663 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
664 0x09, 0x04, 0x01, 0x0c,
665 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
666 0x6f, 0x67, 0x69, 0x63,
667
668 /* Product string descriptor : Index 2 - "EL Composite device" */
669 0x09, 0x04, 0x02, 0x13,
670 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
671 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
672 0x69, 0x63, 0x65,
673
674 /* Serial Number string descriptor : Index 3 - "0001" */
675 0x09, 0x04, 0x03, 0x04,
676 0x30, 0x30, 0x30, 0x31,
677
678 /* Microsoft OS string descriptor : Index 0xEE. String is MSFT100.
679 The last byte is the vendor code used to filter Vendor specific commands.
680 The vendor commands will be executed in the class.
681 This code can be anything but must not be 0x66 or 0x67 which are PIMA class commands. */
682 0x00, 0x00, 0xEE, 0x08,
683 0x4D, 0x53, 0x46, 0x54,
684 0x31, 0x30, 0x30,
685 UX_DEMO_VENDOR_REQUEST
686 };
687 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
688
689 /* Multiple languages are supported on the device, to add
690 a language besides english, the unicode language code must
691 be appended to the language_id_framework array and the length
692 adjusted accordingly. */
693 static unsigned char language_id_framework[] = {
694
695 /* English. */
696 0x09, 0x04
697 };
698 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
699
700 /* Simulation actions. */
701
702 static UX_TEST_SIM_ENTRY_ACTION dcd_transfer_is_called[] = {
703 /* function, request to match,
704 port action, port status,
705 request action, request EP, request data, request actual length, request status,
706 status, additional callback,
707 no_return */
708 { UX_DCD_TRANSFER_REQUEST, NULL,
709 UX_FALSE, 0,
710 0 , 0, UX_NULL, 0, 0,
711 UX_ERROR , ux_test_dcd_entry_is_called},
712 { 0 }
713 };
714
715
716 /* Define the ISR dispatch. */
717
718 extern VOID (*test_isr_dispatch)(void);
719
720
721 /* Prototype for test control return. */
722
723 void test_control_return(UINT status);
724
725
726 /* Define the ISR dispatch routine. */
727
test_isr(void)728 static void test_isr(void)
729 {
730
731 /* For further expansion of interrupt-level testing. */
732 }
733
ux_test_dcd_entry_is_called(UX_TEST_ACTION * action,VOID * params)734 static VOID ux_test_dcd_entry_is_called(UX_TEST_ACTION *action, VOID *params)
735 {
736 error_counter ++;
737 }
738
test_ms_vendor_request(ULONG request,ULONG request_value,ULONG request_index,ULONG request_length,UCHAR * transfer_request_buffer,ULONG * transfer_request_length)739 static UINT test_ms_vendor_request(ULONG request, ULONG request_value, ULONG request_index, ULONG request_length,
740 UCHAR *transfer_request_buffer, ULONG *transfer_request_length)
741 {
742 return vendor_req_rc;
743 }
744
745
test_ux_device_class_cdc_acm_entry(UX_SLAVE_CLASS_COMMAND * command)746 static UINT test_ux_device_class_cdc_acm_entry(UX_SLAVE_CLASS_COMMAND *command)
747 {
748 if (class_entry_rc != UX_SUCCESS)
749 return class_entry_rc;
750
751 switch (command -> ux_slave_class_command_request)
752 {
753 case UX_SLAVE_CLASS_COMMAND_CHANGE:
754 return UX_SUCCESS;
755 default: break;
756 }
757 return _ux_device_class_cdc_acm_entry(command);
758 }
759
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)760 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
761 {
762
763 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
764
765 switch(event)
766 {
767
768 case UX_DEVICE_INSERTION:
769
770 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
771 cdc_acm_host_control = cdc_acm;
772 else
773 cdc_acm_host_data = cdc_acm;
774 break;
775
776 case UX_DEVICE_REMOVAL:
777
778 if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
779 cdc_acm_host_control = UX_NULL;
780 else
781 cdc_acm_host_data = UX_NULL;
782 break;
783
784 default:
785 break;
786 }
787 return 0;
788 }
789
test_cdc_instance_activate(VOID * cdc_instance)790 static VOID test_cdc_instance_activate(VOID *cdc_instance)
791 {
792
793 /* Save the CDC instance. */
794 cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
795 }
test_cdc_instance_deactivate(VOID * cdc_instance)796 static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
797 {
798
799 /* Reset the CDC instance. */
800 cdc_acm_slave = UX_NULL;
801 }
802
test_cdc_instance_parameter_change(VOID * cdc_instance)803 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
804 {
805
806 /* Set CDC parameter change flag. */
807 cdc_acm_slave_change = UX_TRUE;
808 }
809
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)810 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
811 {
812 }
813
ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION * action,VOID * params)814 static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params)
815 {
816
817 error_counter ++;
818 }
819
ux_test_hcd_entry_disconnect(UX_TEST_ACTION * action,VOID * params)820 static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params)
821 {
822
823 ux_test_dcd_sim_slave_disconnect();
824 }
825
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)826 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
827 {
828
829 set_cfg_counter ++;
830
831 rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
832
833 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
834 rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
835 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
836 }
837
test_ux_device_class_cdc_acm_read_halt(UX_SLAVE_CLASS_CDC_ACM * cdc_acm)838 static UINT test_ux_device_class_cdc_acm_read_halt(UX_SLAVE_CLASS_CDC_ACM *cdc_acm)
839 {
840 UX_SLAVE_ENDPOINT *endpoint;
841 UX_SLAVE_INTERFACE *interface;
842
843 /* This is the first time we are activated. We need the interface to the class. */
844 interface = cdc_acm -> ux_slave_class_cdc_acm_interface;
845
846 /* Locate the endpoints. */
847 endpoint = interface -> ux_slave_interface_first_endpoint;
848
849 /* Check the endpoint direction, if OUT we have the correct endpoint. */
850 if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_OUT)
851 {
852
853 /* So the next endpoint has to be the OUT endpoint. */
854 endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
855 }
856
857 return ux_device_stack_endpoint_stall(endpoint);
858 }
859
860 extern UINT _ux_host_stack_endpoint_reset(UX_ENDPOINT *endpoint);
test_ux_host_class_cdc_acm_write_halt_clear(UX_HOST_CLASS_CDC_ACM * cdc_acm)861 static UINT test_ux_host_class_cdc_acm_write_halt_clear(UX_HOST_CLASS_CDC_ACM *cdc_acm)
862 {
863 return _ux_host_stack_endpoint_reset(cdc_acm->ux_host_class_cdc_acm_bulk_out_endpoint);
864 }
865
test_ux_host_class_cdc_acm_write(UX_HOST_CLASS_CDC_ACM * cdc_acm,UCHAR * data_pointer,ULONG requested_length,ULONG * actual_length)866 static UINT test_ux_host_class_cdc_acm_write(UX_HOST_CLASS_CDC_ACM *cdc_acm, UCHAR *data_pointer,
867 ULONG requested_length, ULONG *actual_length)
868 {
869 UX_TRANSFER *transfer_request;
870 UINT status;
871 ULONG transfer_request_length;
872
873 /* Start by resetting the actual length of the transfer. */
874 *actual_length = 0;
875
876 /* Get the pointer to the bulk out endpoint transfer request. */
877 transfer_request = &cdc_acm -> ux_host_class_cdc_acm_bulk_out_endpoint -> ux_endpoint_transfer_request;
878
879 /* Program the maximum authorized length for this transfer_request. */
880 if (requested_length > transfer_request -> ux_transfer_request_maximum_length)
881 transfer_request_length = transfer_request -> ux_transfer_request_maximum_length;
882 else
883 transfer_request_length = requested_length;
884
885 /* Initialize the transfer_request. */
886 transfer_request -> ux_transfer_request_data_pointer = data_pointer;
887 transfer_request -> ux_transfer_request_requested_length = transfer_request_length;
888
889 /* Perform the transfer. */
890 status = ux_host_stack_transfer_request(transfer_request);
891
892 /* If the transfer is successful, we need to wait for the transfer request to be completed. */
893 if (status == UX_SUCCESS)
894 {
895
896 /* Wait for the completion of the transfer request. */
897 status = _ux_utility_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, UX_HOST_CLASS_CDC_ACM_CLASS_TRANSFER_TIMEOUT);
898
899 /* Update the length of the actual data transferred. We do this after the
900 abort of the transfer_request in case some data actually went out. */
901 *actual_length += transfer_request -> ux_transfer_request_actual_length;
902
903 /* If the semaphore did not succeed we probably have a time out. */
904 if (status != UX_SUCCESS)
905 {
906
907 /* All transfers pending need to abort. There may have been a partial transfer. */
908 ux_host_stack_transfer_request_abort(transfer_request);
909
910 /* Set the completion code. */
911 transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_TIMEOUT;
912
913 /* Error trap. */
914 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_TIMEOUT);
915
916 /* If trace is enabled, insert this event into the trace buffer. */
917 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_TIMEOUT, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
918
919 }
920
921 /* Report completion code. */
922 status = transfer_request -> ux_transfer_request_completion_code;
923 }
924
925 /* Return status. */
926 return(status);
927 }
928
929
930 /* Define what the initial system looks like. */
931
932 #ifdef CTEST
test_application_define(void * first_unused_memory)933 void test_application_define(void *first_unused_memory)
934 #else
935 void usbx_device_stack_standard_request_test_application_define(void *first_unused_memory)
936 #endif
937 {
938
939 UINT status;
940 CHAR * stack_pointer;
941 CHAR * memory_pointer;
942
943 printf("Running Host & Device Standard Request Test......................... ");
944
945 /* Reset testing counts. */
946 ux_test_utility_sim_mem_alloc_count_reset();
947 ux_test_utility_sim_mutex_create_count_reset();
948 ux_test_utility_sim_sem_create_count_reset();
949 ux_test_utility_sim_sem_get_count_reset();
950 /* Reset error generations */
951 ux_test_utility_sim_mem_alloc_error_generation_stop();
952 ux_test_utility_sim_sem_error_generation_stop();
953 ux_test_utility_sim_mutex_error_generation_stop();
954 ux_test_utility_sim_sem_get_error_generation_stop();
955
956 /* Initialize the free memory pointer */
957 stack_pointer = (CHAR *) usbx_memory;
958 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
959
960 /* Initialize USBX Memory */
961 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
962
963 /* Check for error. */
964 if (status != UX_SUCCESS)
965 {
966
967 printf(" ERROR #1\n");
968 test_control_return(1);
969 }
970
971 /* Register the error callback. */
972 _ux_utility_error_callback_register(test_ux_error_callback);
973
974 /* The code below is required for installing the device portion of USBX. No call back for
975 device status change in this example. */
976 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
977 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
978 string_framework, STRING_FRAMEWORK_LENGTH,
979 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
980 if(status!=UX_SUCCESS)
981 {
982
983 printf(" ERROR #5\n");
984 test_control_return(1);
985 }
986
987 /* Set the parameters for callback when insertion/extraction of a CDC device. */
988 parameter.ux_slave_class_cdc_acm_instance_activate = test_cdc_instance_activate;
989 parameter.ux_slave_class_cdc_acm_instance_deactivate = test_cdc_instance_deactivate;
990 parameter.ux_slave_class_cdc_acm_parameter_change = test_cdc_instance_parameter_change;
991
992 /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
993 status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, test_ux_device_class_cdc_acm_entry,
994 1,0, ¶meter);
995 status |= ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, test_ux_device_class_cdc_acm_entry,
996 1,2, ¶meter);
997 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
998 if(status!=UX_SUCCESS)
999 {
1000
1001 printf(" ERROR #7\n");
1002 test_control_return(1);
1003 }
1004 #endif
1005
1006 /* Initialize the hid class parameters. */
1007 hid_parameter.ux_device_class_hid_parameter_report_address = hid_mouse_report;
1008 hid_parameter.ux_device_class_hid_parameter_report_length = HID_MOUSE_REPORT_LENGTH;
1009 hid_parameter.ux_device_class_hid_parameter_callback = UX_NULL;
1010 hid_parameter.ux_slave_class_hid_instance_activate = UX_NULL;
1011
1012 /* Initilize the device hid class. The class is connected with interface 0 */
1013 status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
1014 4, 0, (VOID *)&hid_parameter);
1015 // status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
1016 // 4, 1, (VOID *)&hid_parameter);
1017 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
1018 if(status!=UX_SUCCESS)
1019 {
1020
1021 printf("Error on line %d, error code: %x\n", __LINE__, status);
1022 test_control_return(1);
1023 }
1024 #endif
1025
1026 /* MS extensions. */
1027 status = _ux_device_stack_microsoft_extension_register(UX_DEMO_VENDOR_REQUEST, test_ms_vendor_request);
1028
1029 if(status!=UX_SUCCESS)
1030 {
1031
1032 printf(" ERROR #%d\n", __LINE__);
1033 test_control_return(1);
1034 }
1035
1036 /* Initialize the simulated device controller. */
1037 status = _ux_test_dcd_sim_slave_initialize();
1038
1039 /* Check for error. */
1040 if (status != TX_SUCCESS)
1041 {
1042
1043 printf(" ERROR #8\n");
1044 test_control_return(1);
1045 }
1046
1047 /* The code below is required for installing the host portion of USBX */
1048 status = ux_host_stack_initialize(test_host_change_function);
1049 if (status != UX_SUCCESS)
1050 {
1051
1052 printf(" ERROR #2\n");
1053 test_control_return(1);
1054 }
1055
1056 /* Register CDC-ACM class. */
1057 status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
1058 if (status != UX_SUCCESS)
1059 {
1060
1061 printf(" ERROR #3\n");
1062 test_control_return(1);
1063 }
1064
1065 /* Register all the USB host controllers available in this system */
1066 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
1067 if (status != UX_SUCCESS)
1068 {
1069
1070 printf(" ERROR #4\n");
1071 test_control_return(1);
1072 }
1073
1074 /* Create the main host simulation thread. */
1075 status = tx_thread_create(&tx_test_thread_simulation0, "tx test simulation 0", tx_test_thread_simulation0_entry, 0,
1076 stack_pointer, UX_DEMO_STACK_SIZE,
1077 20, 20, 1, TX_AUTO_START);
1078
1079 /* Check for error. */
1080 if (status != TX_SUCCESS)
1081 {
1082
1083 printf(" ERROR #9\n");
1084 test_control_return(1);
1085 }
1086
1087 /* Create the main slave simulation thread. */
1088 status = tx_thread_create(&tx_test_thread_simulation1, "tx test simulation 1", tx_test_thread_simulation1_entry, 0,
1089 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
1090 20, 20, 1, TX_AUTO_START);
1091
1092 /* Check for error. */
1093 if (status != TX_SUCCESS)
1094 {
1095
1096 printf(" ERROR #10\n");
1097 test_control_return(1);
1098 }
1099 }
1100
tx_test_thread_simulation0_entry(ULONG arg)1101 void tx_test_thread_simulation0_entry(ULONG arg)
1102 {
1103 UINT status;
1104 ULONG actual_length;
1105 UX_DEVICE *device;
1106 UX_ENDPOINT *control_endpoint;
1107 UX_TRANSFER *transfer_request;
1108 UX_SLAVE_TRANSFER *slave_transfer_request;
1109
1110 stepinfo("\n");
1111
1112 /* Wait for first enumeration to complete. */
1113 stepinfo(">>>>>>>>>>>>>>>> Wait for first enumeration completion\n");
1114 while (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL || cdc_acm_slave == UX_NULL)
1115 tx_thread_sleep(10);
1116
1117 /* Wait for instances to be live. */
1118 tx_thread_sleep(10);
1119
1120 ux_test_dcd_sim_slave_disconnect();
1121 ux_test_hcd_sim_host_disconnect();
1122
1123 /* Test connect. Note that we must switch to high speed for tests. */
1124 stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
1125 ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
1126 ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
1127 tx_thread_sleep(UX_CDC_ACM_CONNECTION_DELAY);
1128 if (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL || cdc_acm_slave == UX_NULL)
1129 {
1130
1131 printf("ERROR #%d: connection not detected\n", __LINE__);
1132 test_control_return(1);
1133 }
1134
1135 status = ux_host_stack_device_get(0, &device);
1136 if (status != UX_SUCCESS)
1137 {
1138
1139 printf("ERROR #%d: device_get fail\n", __LINE__);
1140 test_control_return(1);
1141 }
1142 control_endpoint = &device->ux_device_control_endpoint;
1143 transfer_request = &control_endpoint->ux_endpoint_transfer_request;
1144
1145 slave_transfer_request = &_ux_system_slave->ux_system_slave_device.ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
1146
1147 /* Test bulk stall handling */
1148 stepinfo(">>>>>>>>>>>>>>>> Test Bulk OUT STALL\n");
1149 /* Start waiting stall on device side */
1150 status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TSTALL\n", 7, &actual_length);
1151 if (status != UX_SUCCESS)
1152 {
1153
1154 printf("ERROR #%d: Bulk OUT fail: %x\n", __LINE__, status);
1155 test_control_return(1);
1156 }
1157
1158 /* Check endpoint stalled */
1159 status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1160 if (status != UX_TRANSFER_STALLED)
1161 {
1162
1163 printf("ERROR #%d: Bulk OUT not stalled: %x\n", __LINE__, status);
1164 test_control_return(1);
1165 }
1166
1167 /* Clear halt */
1168 status = test_ux_host_class_cdc_acm_write_halt_clear(cdc_acm_host_data);
1169 if (status != UX_SUCCESS)
1170 {
1171
1172 printf("ERROR #%d: Stall clear fail: %x\n", __LINE__, status);
1173 test_control_return(1);
1174 }
1175
1176 /* Check endpoint good */
1177 status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1178 if (status != UX_SUCCESS)
1179 {
1180
1181 printf("ERROR #%d: Bulk OUT failed: %x\n", __LINE__, status);
1182 test_control_return(1);
1183 }
1184
1185 /* Test normal requests */
1186 stepinfo(">>>>>>>>>>>>>>>> Test GetDeviceDescriptor\n");
1187 transfer_request -> ux_transfer_request_data_pointer = buffer;
1188 transfer_request -> ux_transfer_request_requested_length = 64;
1189 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1190 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1191 transfer_request -> ux_transfer_request_value = UX_DEVICE_DESCRIPTOR_ITEM << 8;
1192 transfer_request -> ux_transfer_request_index = 0;
1193 status = ux_host_stack_transfer_request(transfer_request);
1194 if (status != UX_SUCCESS)
1195 {
1196
1197 printf("ERROR #%d: GetDeviceDescriptor(64) fail\n", __LINE__);
1198 test_control_return(1);
1199 }
1200 if (transfer_request->ux_transfer_request_actual_length != 18)
1201 {
1202
1203 printf("ERROR #%d: GetDeviceDescriptor(64) actual length is not 18\n", __LINE__);
1204 test_control_return(1);
1205 }
1206
1207 stepinfo(">>>>>>>>>>>>>>>> Test GetDeviceQualifierDescriptor\n");
1208 transfer_request -> ux_transfer_request_data_pointer = buffer;
1209 transfer_request -> ux_transfer_request_requested_length = 8;
1210 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1211 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1212 transfer_request -> ux_transfer_request_value = UX_DEVICE_QUALIFIER_DESCRIPTOR_ITEM << 8;
1213 transfer_request -> ux_transfer_request_index = 0;
1214 status = ux_host_stack_transfer_request(transfer_request);
1215 if (status != UX_SUCCESS)
1216 {
1217
1218 printf("ERROR #%d: GetDeviceQualifierDescriptor(8) fail\n", __LINE__);
1219 test_control_return(1);
1220 }
1221 if (transfer_request->ux_transfer_request_actual_length != 8)
1222 {
1223
1224 printf("ERROR #%d: GetDeviceQualifierDescriptor(8) actual length is not 8\n", __LINE__);
1225 test_control_return(1);
1226 }
1227
1228 transfer_request -> ux_transfer_request_requested_length = 64;
1229 status = ux_host_stack_transfer_request(transfer_request);
1230 if (status != UX_SUCCESS)
1231 {
1232
1233 printf("ERROR #%d: GetDeviceQualifierDescriptor(64) fail\n", __LINE__);
1234 test_control_return(1);
1235 }
1236 if (transfer_request->ux_transfer_request_actual_length != 10)
1237 {
1238
1239 printf("ERROR #%d: GetDeviceQualifierDescriptor(64) actual length is not 10\n", __LINE__);
1240 test_control_return(1);
1241 }
1242
1243 _ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed;
1244 _ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
1245
1246 status = ux_host_stack_transfer_request(transfer_request);
1247 if (status == UX_SUCCESS)
1248 {
1249
1250 printf("ERROR #%d: GetDeviceQualifierDescriptor(64) should fail\n", __LINE__);
1251 test_control_return(1);
1252 }
1253
1254 stepinfo(">>>>>>>>>>>>>>>> Test GetOTGDescriptor\n");
1255 transfer_request -> ux_transfer_request_data_pointer = buffer;
1256 transfer_request -> ux_transfer_request_requested_length = 64;
1257 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1258 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1259 transfer_request -> ux_transfer_request_value = UX_OTG_DESCRIPTOR_ITEM << 8;
1260 transfer_request -> ux_transfer_request_index = 0;
1261
1262 status = ux_host_stack_transfer_request(transfer_request);
1263 if (status == UX_SUCCESS)
1264 {
1265
1266 printf("ERROR #%d: GetOTGDescriptor(64) should fail\n", __LINE__);
1267 test_control_return(1);
1268 }
1269
1270 _ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_high_speed;
1271 _ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_high_speed;
1272 status = ux_host_stack_transfer_request(transfer_request);
1273 if (status != UX_SUCCESS)
1274 {
1275
1276 printf("ERROR #%d: GetOTGDescriptor(64) fail: %x\n", __LINE__, status);
1277 test_control_return(1);
1278 }
1279 if (transfer_request->ux_transfer_request_actual_length != 5)
1280 {
1281
1282 printf("ERROR #%d: GetOTGDescriptor(64) actual length is not 5\n", __LINE__);
1283 test_control_return(1);
1284 }
1285
1286 transfer_request -> ux_transfer_request_requested_length = 5;
1287 status = ux_host_stack_transfer_request(transfer_request);
1288 if (status != UX_SUCCESS)
1289 {
1290
1291 printf("ERROR #%d: GetOTGDescriptor(5) fail\n", __LINE__);
1292 test_control_return(1);
1293 }
1294 if (transfer_request->ux_transfer_request_actual_length != 5)
1295 {
1296
1297 printf("ERROR #%d: GetOTGDescriptor(5) actual length is not 5\n", __LINE__);
1298 test_control_return(1);
1299 }
1300
1301 stepinfo(">>>>>>>>>>>>>>>> Test GetOtherSpeedDescriptor\n");
1302 transfer_request -> ux_transfer_request_data_pointer = buffer;
1303 transfer_request -> ux_transfer_request_requested_length = 8;
1304 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1305 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1306 transfer_request -> ux_transfer_request_value = UX_OTHER_SPEED_DESCRIPTOR_ITEM << 8;
1307 transfer_request -> ux_transfer_request_index = 0;
1308 status = ux_host_stack_transfer_request(transfer_request);
1309 if (status != UX_SUCCESS)
1310 {
1311
1312 printf("ERROR #%d: GetOtherSpeedDescriptor(8) fail\n", __LINE__);
1313 test_control_return(1);
1314 }
1315
1316 transfer_request -> ux_transfer_request_requested_length = 256;
1317 status = ux_host_stack_transfer_request(transfer_request);
1318 if (status != UX_SUCCESS)
1319 {
1320
1321 printf("ERROR #%d: GetOtherSpeedDescriptor(256) fail\n", __LINE__);
1322 test_control_return(1);
1323 }
1324
1325 transfer_request -> ux_transfer_request_value = (UX_OTHER_SPEED_DESCRIPTOR_ITEM << 8) | 10;
1326 status = ux_host_stack_transfer_request(transfer_request);
1327 if (status == UX_SUCCESS)
1328 {
1329
1330 printf("ERROR #%d: GetOtherSpeedDescriptor(10, 256) must fail\n", __LINE__);
1331 test_control_return(1);
1332 }
1333
1334 stepinfo(">>>>>>>>>>>>>>>> Test GetConfigurationDescriptor\n");
1335 transfer_request -> ux_transfer_request_data_pointer = buffer;
1336 transfer_request -> ux_transfer_request_requested_length = 256;
1337 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1338 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1339 transfer_request -> ux_transfer_request_index = 0;
1340
1341 /* Get existing configuration */
1342 transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8;
1343 status = ux_host_stack_transfer_request(transfer_request);
1344 if (status != UX_SUCCESS)
1345 {
1346
1347 printf("ERROR #%d: GetConfigurationDescriptor(0, 256) fail\n", __LINE__);
1348 test_control_return(1);
1349 }
1350
1351 /* Get non-existing configuration */
1352 transfer_request -> ux_transfer_request_value = (UX_CONFIGURATION_DESCRIPTOR_ITEM << 8) | 10;
1353 status = ux_host_stack_transfer_request(transfer_request);
1354 if (status == UX_SUCCESS)
1355 {
1356
1357 printf("ERROR #%d: GetConfigurationDescriptor(10, 256) must fail\n", __LINE__);
1358 test_control_return(1);
1359 }
1360
1361 stepinfo(">>>>>>>>>>>>>>>> Test GetStringDescriptor\n");
1362 transfer_request -> ux_transfer_request_data_pointer = buffer;
1363 transfer_request -> ux_transfer_request_requested_length = 64;
1364 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1365 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1366
1367 /* Get LangID with big buffer */
1368 transfer_request -> ux_transfer_request_value = UX_STRING_DESCRIPTOR_ITEM << 8;
1369 transfer_request -> ux_transfer_request_index = 0;
1370 status = ux_host_stack_transfer_request(transfer_request);
1371 if (status != UX_SUCCESS)
1372 {
1373
1374 printf("ERROR #%d: GetStringDescriptor(0, 64) fail\n", __LINE__);
1375 test_control_return(1);
1376 }
1377
1378 /* Get LangID with exactly size */
1379 transfer_request -> ux_transfer_request_requested_length = 4;
1380 status = ux_host_stack_transfer_request(transfer_request);
1381 if (status != UX_SUCCESS)
1382 {
1383
1384 printf("ERROR #%d: GetStringDescriptor(0, 4) fail\n", __LINE__);
1385 test_control_return(1);
1386 }
1387
1388 /* Get String with small buffer */
1389 transfer_request -> ux_transfer_request_index = 0x0409;
1390 transfer_request -> ux_transfer_request_value = (UX_STRING_DESCRIPTOR_ITEM << 8) | 1;
1391 status = ux_host_stack_transfer_request(transfer_request);
1392 if (status != UX_SUCCESS)
1393 {
1394
1395 printf("ERROR #%d: GetStringDescriptor(1, 4) fail\n", __LINE__);
1396 test_control_return(1);
1397 }
1398
1399 /* Get String with large buffer */
1400 transfer_request -> ux_transfer_request_requested_length = 256;
1401 transfer_request -> ux_transfer_request_value = (UX_STRING_DESCRIPTOR_ITEM << 8) | 2;
1402 status = ux_host_stack_transfer_request(transfer_request);
1403 if (status != UX_SUCCESS)
1404 {
1405
1406 printf("ERROR #%d: GetStringDescriptor(2, 256) fail\n", __LINE__);
1407 test_control_return(1);
1408 }
1409
1410 /* Get String not existing */
1411 transfer_request -> ux_transfer_request_value = (UX_STRING_DESCRIPTOR_ITEM << 8) | 10;
1412 status = ux_host_stack_transfer_request(transfer_request);
1413 if (status == UX_SUCCESS)
1414 {
1415
1416 printf("ERROR #%d: GetStringDescriptor(10, 256) must fail\n", __LINE__);
1417 test_control_return(1);
1418 }
1419
1420 /* Get Manufacturer string descriptor. */
1421 transfer_request -> ux_transfer_request_data_pointer = buffer;
1422 transfer_request -> ux_transfer_request_requested_length = 0xff;
1423 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1424 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1425 transfer_request -> ux_transfer_request_value = (UX_STRING_DESCRIPTOR_ITEM << 8) | 0x01;
1426 status = ux_host_stack_transfer_request(transfer_request);
1427 if (status != UX_SUCCESS)
1428 {
1429
1430 printf("ERROR #%d: GetStringDescriptor(10, 256) must fail\n", __LINE__);
1431 test_control_return(1);
1432 }
1433
1434 UCHAR string_descriptor_manufacturer_length = *(string_framework + 3);
1435 UCHAR get_string_descriptor_manufacturer_expected[] = {
1436 /* bLength. '2 +' is for bLength and bDescriptorType, '0x0c' is the length of
1437 the string, and '*2' is because it's 16-bit unicode, where each character
1438 is 2 bytes, the LSB is the value, and MSB is 0 (for ascii anyways). */
1439 (UCHAR)(2 + string_descriptor_manufacturer_length*2),
1440
1441 /* bDescriptorType */
1442 0x03,
1443
1444 /* "Express Logic" in unicode. */
1445 0x45, 0x00,
1446 0x78, 0x00,
1447 0x70, 0x00,
1448 0x72, 0x00,
1449 0x65, 0x00,
1450 0x73, 0x00,
1451 0x20, 0x00,
1452 0x4c, 0x00,
1453 0x6f, 0x00,
1454 0x67, 0x00,
1455 0x69, 0x00,
1456 0x63, 0x00,
1457 };
1458
1459 /* Ensure the length is correct. */
1460 if (transfer_request->ux_transfer_request_actual_length != sizeof(get_string_descriptor_manufacturer_expected))
1461 {
1462
1463 printf("ERROR on line %d\n", __LINE__);
1464 test_control_return(1);
1465 }
1466
1467 /* Now check the contents. */
1468 if (_ux_utility_memory_compare(transfer_request->ux_transfer_request_data_pointer, get_string_descriptor_manufacturer_expected, sizeof(get_string_descriptor_manufacturer_expected)))
1469 {
1470
1471 printf("ERROR on line %d\n", __LINE__);
1472 test_control_return(1);
1473 }
1474
1475 stepinfo(">>>>>>>>>>>>>>>> Test GetDescriptor(unknown)\n");
1476 transfer_request -> ux_transfer_request_data_pointer = buffer;
1477 transfer_request -> ux_transfer_request_requested_length = 64;
1478 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1479 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1480
1481 /* Get unknown discriptor */
1482 transfer_request -> ux_transfer_request_value = 11 << 8;
1483 transfer_request -> ux_transfer_request_index = 0;
1484 status = ux_host_stack_transfer_request(transfer_request);
1485 if (status == UX_SUCCESS)
1486 {
1487
1488 printf("ERROR #%d: GetDescriptor(unknown) must fail\n", __LINE__);
1489 test_control_return(1);
1490 }
1491
1492 stepinfo(">>>>>>>>>>>>>>>> Test GetDescriptor(class)\n");
1493 transfer_request -> ux_transfer_request_data_pointer = buffer;
1494 transfer_request -> ux_transfer_request_requested_length = 64;
1495 transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
1496 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1497
1498 /* Get class discriptor */
1499 transfer_request -> ux_transfer_request_value = (11 + UX_REQUEST_TYPE_CLASS) << 8;
1500 transfer_request -> ux_transfer_request_index = 0;
1501 status = ux_host_stack_transfer_request(transfer_request);
1502 if (status == UX_SUCCESS)
1503 {
1504
1505 printf("ERROR #%d: GetDescriptor(class) must fail\n", __LINE__);
1506 test_control_return(1);
1507 }
1508
1509 stepinfo(">>>>>>>>>>>>>>>> Test SetFeature/ClearFeature/GetStatus\n");
1510
1511 transfer_request -> ux_transfer_request_requested_length = 0;
1512 transfer_request -> ux_transfer_request_data_pointer = buffer;
1513 transfer_request -> ux_transfer_request_function = UX_SET_FEATURE;
1514
1515 /* SetDeviceFeature */
1516 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1517 transfer_request -> ux_transfer_request_value = UX_REQUEST_FEATURE_DEVICE_REMOTE_WAKEUP;
1518 transfer_request -> ux_transfer_request_index = 0;
1519 status = ux_host_stack_transfer_request(transfer_request);
1520 if (status != UX_SUCCESS)
1521 {
1522
1523 printf("ERROR #%d: SetDeviceFeature fail\n", __LINE__);
1524 test_control_return(1);
1525 }
1526
1527 /* SetInterfaceFeature */
1528 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1529 status = ux_host_stack_transfer_request(transfer_request);
1530
1531 /* Normal write, should be good. */
1532 status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1533 if (status != UX_SUCCESS)
1534 {
1535
1536 printf("ERROR #%d: Bulk OUT status %x\n", __LINE__, status);
1537 test_control_return(1);
1538 }
1539
1540 stepinfo(">>>>>>>>>>>>>>>> Test SetEndpointFeature(0x81)\n");
1541
1542 /* SetEndpointFeature to existing endpoint */
1543 transfer_request -> ux_transfer_request_index = 0x02;
1544 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1545 status = ux_host_stack_transfer_request(transfer_request);
1546 if (status != UX_SUCCESS)
1547 {
1548
1549 printf("ERROR #%d: SetEndpointFeature(0x81) fail\n", __LINE__);
1550 test_control_return(1);
1551 }
1552
1553 stepinfo(">>>>>>>>>>>>>>>> Test SetEndpointFeature(0x82)\n");
1554
1555 /* SetEndpointFeature to not existing one */
1556 transfer_request -> ux_transfer_request_index = 0x82;
1557 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1558 status = ux_host_stack_transfer_request(transfer_request);
1559 if (status == UX_SUCCESS)
1560 {
1561
1562 printf("ERROR #%d: SetEndpointFeature(0x82) must fail\n", __LINE__);
1563 test_control_return(1);
1564 }
1565
1566 /* GetDeviceStatus */
1567 transfer_request -> ux_transfer_request_requested_length = 64;
1568 transfer_request -> ux_transfer_request_function = UX_GET_STATUS;
1569 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1570 transfer_request -> ux_transfer_request_index = 0;
1571 status = ux_host_stack_transfer_request(transfer_request);
1572 if (status != UX_SUCCESS)
1573 {
1574
1575 printf("ERROR #%d: GetDeviceStatus fail\n", __LINE__);
1576 test_control_return(1);
1577 }
1578
1579 /* GetDeviceOTGStatus */
1580 transfer_request -> ux_transfer_request_index = UX_OTG_STATUS_SELECTOR;
1581 status = ux_host_stack_transfer_request(transfer_request);
1582 if (status != UX_SUCCESS)
1583 {
1584
1585 printf("ERROR #%d: GetDeviceOTGStatus fail\n", __LINE__);
1586 test_control_return(1);
1587 }
1588
1589 /* GetInterfaceStatus may or may not implement */
1590 transfer_request -> ux_transfer_request_index = 0;
1591 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1592 status = ux_host_stack_transfer_request(transfer_request);
1593
1594 /* GetEndpointStatus for existing endpoint */
1595 transfer_request -> ux_transfer_request_index = 0x02;
1596 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1597 status = ux_host_stack_transfer_request(transfer_request);
1598 if (status != UX_SUCCESS)
1599 {
1600
1601 printf("ERROR #%d: GetEndpointStatus(0x02) fail\n", __LINE__);
1602 test_control_return(1);
1603 }
1604 if (buffer[0] != 1)
1605 {
1606
1607 printf("ERROR #%d: GetEndpointStatus(0x02) should halt\n", __LINE__);
1608 test_control_return(1);
1609
1610 }
1611
1612 /* Write, should return halt. */
1613 status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1614 if (status == UX_SUCCESS)
1615 {
1616
1617 printf("ERROR #%d: Bulk OUT status %x\n", __LINE__, status);
1618 test_control_return(1);
1619 }
1620
1621 stepinfo(">>>>>>>>>>>>>>>> Test ClearEndpointFeature(0x02)\n");
1622
1623 /* ClearEndpointFeature for existing endpoint */
1624 transfer_request -> ux_transfer_request_function = UX_CLEAR_FEATURE;
1625 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1626 transfer_request -> ux_transfer_request_index = 0x02;
1627 transfer_request -> ux_transfer_request_requested_length = 0;
1628 status = ux_host_stack_transfer_request(transfer_request);
1629 if (status != UX_SUCCESS)
1630 {
1631
1632 printf("ERROR #%d: ClearEndpointFeature(0x02) fail\n", __LINE__);
1633 test_control_return(1);
1634 }
1635
1636 /* GetEndpointStatus for existing endpoint to check if clear is done */
1637 transfer_request -> ux_transfer_request_function = UX_GET_STATUS;
1638 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1639 transfer_request -> ux_transfer_request_index = 0x02;
1640 transfer_request -> ux_transfer_request_requested_length = 2;
1641 status = ux_host_stack_transfer_request(transfer_request);
1642 if (status != UX_SUCCESS)
1643 {
1644
1645 printf("ERROR #%d: GetEndpointStatus(0x02) fail\n", __LINE__);
1646 test_control_return(1);
1647 }
1648 if (buffer[0] != 0)
1649 {
1650
1651 printf("ERROR #%d: GetEndpointStatus(0x02) should clear\n", __LINE__);
1652 test_control_return(1);
1653
1654 }
1655
1656 /* Write, should return OK. */
1657 status = test_ux_host_class_cdc_acm_write(cdc_acm_host_data, "TEST\n", 5, &actual_length);
1658 if (status != UX_SUCCESS)
1659 {
1660
1661 printf("ERROR #%d: Bulk OUT status %x\n", __LINE__, status);
1662 test_control_return(1);
1663 }
1664
1665 stepinfo(">>>>>>>>>>>>>>>> Test ClearEndpointFeature(0x05)\n");
1666
1667 /* ClearEndpointFeature on not existing endpoint */
1668 transfer_request -> ux_transfer_request_function = UX_CLEAR_FEATURE;
1669 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_ENDPOINT;
1670 transfer_request -> ux_transfer_request_index = 0x05;
1671 transfer_request -> ux_transfer_request_requested_length = 0;
1672 status = ux_host_stack_transfer_request(transfer_request);
1673 if (status == UX_SUCCESS)
1674 {
1675
1676 printf("ERROR #%d: GetEndpointStatus(0x05) must fail\n", __LINE__);
1677 test_control_return(1);
1678 }
1679
1680 /* ClearDeviceFeature */
1681 transfer_request -> ux_transfer_request_function = UX_CLEAR_FEATURE;
1682 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1683 transfer_request -> ux_transfer_request_index = 0;
1684 transfer_request -> ux_transfer_request_requested_length = 0;
1685 status = ux_host_stack_transfer_request(transfer_request);
1686 if (status != UX_SUCCESS)
1687 {
1688
1689 printf("ERROR #%d: ClearDeviceFeature() fail\n", __LINE__);
1690 test_control_return(1);
1691 }
1692
1693 stepinfo(">>>>>>>>>>>>>>>> Test ClearInterfaceFeature(0x00)\n");
1694
1695 /* ClearInterfaceFeature, may or may not implement */
1696 transfer_request -> ux_transfer_request_function = UX_CLEAR_FEATURE;
1697 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1698 transfer_request -> ux_transfer_request_index = 0;
1699 transfer_request -> ux_transfer_request_requested_length = 0;
1700 status = ux_host_stack_transfer_request(transfer_request);
1701
1702 stepinfo(">>>>>>>>>>>>>>>> Test GetConfiguration\n");
1703 transfer_request -> ux_transfer_request_data_pointer = buffer;
1704 transfer_request -> ux_transfer_request_requested_length = 1;
1705 transfer_request -> ux_transfer_request_function = UX_GET_CONFIGURATION;
1706 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1707 transfer_request -> ux_transfer_request_value = 0;
1708 transfer_request -> ux_transfer_request_index = 0;
1709 /* GetConfiguration should OK */
1710 status = ux_host_stack_transfer_request(transfer_request);
1711 if (status != UX_SUCCESS)
1712 {
1713
1714 printf("ERROR #%d: GetConfiguration fail\n", __LINE__);
1715 test_control_return(1);
1716 }
1717 if (buffer[0] != 1)
1718 {
1719
1720 printf("ERROR #%d: GetConfiguration should return 1\n", __LINE__);
1721 test_control_return(1);
1722 }
1723
1724 stepinfo(">>>>>>>>>>>>>>>> Test SetConfiguration\n");
1725 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
1726 transfer_request -> ux_transfer_request_requested_length = 0;
1727 transfer_request -> ux_transfer_request_function = UX_SET_CONFIGURATION;
1728 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1729 transfer_request -> ux_transfer_request_value = 1;
1730 transfer_request -> ux_transfer_request_index = 0;
1731 /* SetConfiguration should OK */
1732 status = ux_host_stack_transfer_request(transfer_request);
1733 if (status != UX_SUCCESS)
1734 {
1735
1736 printf("ERROR #%d: SetConfiguration fail\n", __LINE__);
1737 test_control_return(1);
1738 }
1739
1740 /* SetConfiguration to invalid should fail */
1741 transfer_request -> ux_transfer_request_value = 10;
1742 status = ux_host_stack_transfer_request(transfer_request);
1743 if (status == UX_SUCCESS)
1744 {
1745
1746 printf("ERROR #%d: SetConfiguration(10) must fail\n", __LINE__);
1747 test_control_return(1);
1748 }
1749
1750 /* SetConfiguration */
1751 transfer_request -> ux_transfer_request_value = 3;
1752 status = ux_host_stack_transfer_request(transfer_request);
1753 if (status != UX_SUCCESS)
1754 {
1755
1756 printf("ERROR #%d: SetConfiguration(3) must pass\n", __LINE__);
1757 test_control_return(1);
1758 }
1759
1760 /* SetConfiguration */
1761 transfer_request -> ux_transfer_request_value = 4;
1762 status = ux_host_stack_transfer_request(transfer_request);
1763 if (status != UX_SUCCESS)
1764 {
1765
1766 printf("ERROR #%d: SetConfiguration(4) must pass\n", __LINE__);
1767 test_control_return(1);
1768 }
1769
1770 /* Stop reading on device side */
1771 cdc_acm_slave_reading = UX_FALSE;
1772
1773 stepinfo(">>>>>>>>>>>>>>>> Test SetInterface/GetInterface\n");
1774 transfer_request -> ux_transfer_request_data_pointer = buffer;
1775 transfer_request -> ux_transfer_request_requested_length = 0;
1776
1777 /* Unonfiguration */
1778 transfer_request -> ux_transfer_request_function = UX_SET_CONFIGURATION;
1779 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1780 transfer_request -> ux_transfer_request_value = 0;
1781 status = ux_host_stack_transfer_request(transfer_request);
1782 if (status != UX_SUCCESS)
1783 {
1784
1785 printf("ERROR #%d: SetConfiguration(0) fail\n", __LINE__);
1786 test_control_return(1);
1787 }
1788
1789
1790 /* SetInterface must report error */
1791 transfer_request -> ux_transfer_request_function = UX_SET_INTERFACE;
1792 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1793 transfer_request -> ux_transfer_request_value = 0;
1794 transfer_request -> ux_transfer_request_index = 0;
1795 status = ux_host_stack_transfer_request(transfer_request);
1796 if (status == UX_SUCCESS)
1797 {
1798
1799 printf("ERROR #%d: SetInterface must fail when not configured\n", __LINE__);
1800 test_control_return(1);
1801 }
1802
1803 /* GetInterface must report error */
1804 transfer_request -> ux_transfer_request_requested_length = 1;
1805 transfer_request -> ux_transfer_request_function = UX_GET_INTERFACE;
1806 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1807 status = ux_host_stack_transfer_request(transfer_request);
1808 if (status == UX_SUCCESS)
1809 {
1810
1811 printf("ERROR #%d: GetInterface must fail when not configured\n", __LINE__);
1812 test_control_return(1);
1813 }
1814
1815 /* Back to normal configuration */
1816 transfer_request -> ux_transfer_request_requested_length = 0;
1817 transfer_request -> ux_transfer_request_function = UX_SET_CONFIGURATION;
1818 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1819 transfer_request -> ux_transfer_request_value = 1;
1820 status = ux_host_stack_transfer_request(transfer_request);
1821 if (status != UX_SUCCESS)
1822 {
1823
1824 printf("ERROR #%d: SetConfiguration(1) fail\n", __LINE__);
1825 test_control_return(1);
1826 }
1827
1828 transfer_request -> ux_transfer_request_function = UX_SET_INTERFACE;
1829 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1830
1831 /* Good interface */
1832 transfer_request -> ux_transfer_request_value = 0;
1833 transfer_request -> ux_transfer_request_index = 0;
1834 status = ux_host_stack_transfer_request(transfer_request);
1835 if (status != UX_SUCCESS)
1836 {
1837
1838 printf("ERROR #%d: SetInterface(0.0) should be OK\n", __LINE__);
1839 test_control_return(1);
1840 }
1841
1842 /* Get interface */
1843 transfer_request -> ux_transfer_request_requested_length = 1;
1844 transfer_request -> ux_transfer_request_function = UX_GET_INTERFACE;
1845 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1846 status = ux_host_stack_transfer_request(transfer_request);
1847 if (status != UX_SUCCESS)
1848 {
1849
1850 printf("ERROR #%d: GetInterface fail %x\n", __LINE__, status);
1851 test_control_return(1);
1852 }
1853 if (buffer[0] != 0)
1854 {
1855
1856 printf("ERROR #%d: GetInterface must return 0 but not %x\n", __LINE__, buffer[0]);
1857 test_control_return(1);
1858 }
1859
1860 /* Invalid interface */
1861 transfer_request -> ux_transfer_request_requested_length = 0;
1862 transfer_request -> ux_transfer_request_function = UX_SET_INTERFACE;
1863 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1864
1865 transfer_request -> ux_transfer_request_value = 0;
1866 transfer_request -> ux_transfer_request_index = 2;
1867 status = ux_host_stack_transfer_request(transfer_request);
1868 if (status == UX_SUCCESS)
1869 {
1870
1871 printf("ERROR #%d: SetInterface must fail\n", __LINE__);
1872 test_control_return(1);
1873 }
1874
1875 /* Invalid alternate setting */
1876 transfer_request -> ux_transfer_request_value = 2;
1877 transfer_request -> ux_transfer_request_index = 0;
1878 status = ux_host_stack_transfer_request(transfer_request);
1879 if (status == UX_SUCCESS)
1880 {
1881
1882 printf("ERROR #%d: SetInterface should fail\n", __LINE__);
1883 test_control_return(1);
1884 }
1885
1886 /* SetConfiguration(2) */
1887 transfer_request -> ux_transfer_request_requested_length = 0;
1888 transfer_request -> ux_transfer_request_function = UX_SET_CONFIGURATION;
1889 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1890 transfer_request -> ux_transfer_request_value = 2;
1891 status = ux_host_stack_transfer_request(transfer_request);
1892 if (status != UX_SUCCESS)
1893 {
1894
1895 printf("ERROR #%d: SetConfiguration(2) fail\n", __LINE__);
1896 test_control_return(1);
1897 }
1898
1899 /* SetInterface(2, 0, 1) */
1900 transfer_request -> ux_transfer_request_function = UX_SET_INTERFACE;
1901 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1902 transfer_request -> ux_transfer_request_value = 1;
1903 transfer_request -> ux_transfer_request_index = 0;
1904 status = ux_host_stack_transfer_request(transfer_request);
1905 if (status != UX_SUCCESS)
1906 {
1907
1908 printf("ERROR #%d: SetInterface(0,1) should be OK\n", __LINE__);
1909 test_control_return(1);
1910 }
1911
1912 /* GetInterface(2, 0) */
1913 transfer_request -> ux_transfer_request_requested_length = 1;
1914 transfer_request -> ux_transfer_request_function = UX_GET_INTERFACE;
1915 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1916 status = ux_host_stack_transfer_request(transfer_request);
1917 if (status != UX_SUCCESS)
1918 {
1919
1920 printf("ERROR #%d: GetInterface must be OK\n", __LINE__);
1921 test_control_return(1);
1922 }
1923 if (buffer[0] != 1)
1924 {
1925
1926 printf("ERROR #%d: GetInterface must return 1 but not %x\n", __LINE__, buffer[0]);
1927 test_control_return(1);
1928 }
1929
1930 /* GetInterface(2, 1) */
1931 transfer_request -> ux_transfer_request_index = 1;
1932 status = ux_host_stack_transfer_request(transfer_request);
1933 if (status != UX_SUCCESS)
1934 {
1935
1936 printf("ERROR #%d: GetInterface must be OK\n", __LINE__);
1937 test_control_return(1);
1938 }
1939 if (buffer[0] != 0)
1940 {
1941
1942 printf("ERROR #%d: GetInterface must return 0 but not %x\n", __LINE__, buffer[0]);
1943 test_control_return(1);
1944 }
1945
1946 /* SetInterface(1, 1), OK or STALL due to no class driver on device side. */
1947 transfer_request -> ux_transfer_request_function = UX_SET_INTERFACE;
1948 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
1949 transfer_request -> ux_transfer_request_value = 1;
1950 transfer_request -> ux_transfer_request_index = 1;
1951 status = ux_host_stack_transfer_request(transfer_request);
1952 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1953 {
1954
1955 printf("ERROR #%d: SetInterface(1,1) status %x\n", __LINE__, status);
1956 test_control_return(1);
1957 }
1958
1959 /* SetInterface(1, 2), OK or STALL due to no class driver on device side. */
1960 transfer_request -> ux_transfer_request_value = 2;
1961 transfer_request -> ux_transfer_request_index = 1;
1962 status = ux_host_stack_transfer_request(transfer_request);
1963 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1964 {
1965
1966 printf("ERROR #%d: SetInterface(1,2) status %x\n", __LINE__, status);
1967 test_control_return(1);
1968 }
1969
1970 /* SetInterface(1, 0), OK or STALL due to no class driver on device side. */
1971 transfer_request -> ux_transfer_request_value = 0;
1972 transfer_request -> ux_transfer_request_index = 1;
1973 status = ux_host_stack_transfer_request(transfer_request);
1974 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1975 {
1976
1977 printf("ERROR #%d: SetInterface(1,0) status %x\n", __LINE__, status);
1978 test_control_return(1);
1979 }
1980
1981 stepinfo(">>>>>>>>>>>>>>>> Test SetDescriptor\n");
1982 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
1983 transfer_request -> ux_transfer_request_requested_length = 0;
1984 transfer_request -> ux_transfer_request_function = UX_SET_DESCRIPTOR;
1985 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
1986 transfer_request -> ux_transfer_request_value = 0;
1987 transfer_request -> ux_transfer_request_index = 0;
1988 /* SetDescriptor should OK or STALL */
1989 status = ux_host_stack_transfer_request(transfer_request);
1990 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
1991 {
1992
1993 printf("ERROR #%d: SetDescriptor status %x\n", __LINE__, status);
1994 test_control_return(1);
1995 }
1996
1997 stepinfo(">>>>>>>>>>>>>>>> Test SyncFrame\n");
1998 transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
1999 transfer_request -> ux_transfer_request_requested_length = 0;
2000 transfer_request -> ux_transfer_request_function = UX_SYNCH_FRAME;
2001 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
2002 transfer_request -> ux_transfer_request_value = 0;
2003 transfer_request -> ux_transfer_request_index = 0;
2004 /* SyncFrame should OK or STALL */
2005 status = ux_host_stack_transfer_request(transfer_request);
2006 if (status != UX_SUCCESS && status != UX_TRANSFER_STALLED)
2007 {
2008
2009 printf("ERROR #%d: SyncFrame status %x\n", __LINE__, status);
2010 test_control_return(1);
2011 }
2012
2013 stepinfo(">>>>>>>>>>>>>>>> Test Unknown Request\n");
2014 /* Unknown request should STALL */
2015 transfer_request -> ux_transfer_request_function = 20;
2016 status = ux_host_stack_transfer_request(transfer_request);
2017 if (status != UX_TRANSFER_STALLED)
2018 {
2019
2020 printf("ERROR #%d: Unknown request status %x\n", __LINE__, status);
2021 test_control_return(1);
2022 }
2023
2024 stepinfo(">>>>>>>>>>>>>>>> Test Class Request\n");
2025 transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_CDC_ACM_REQ_GET_LINE_CODING;
2026 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_DEVICE;
2027 /* Check DCD transfer call */
2028 error_counter = 0;
2029 ux_test_dcd_sim_slave_set_actions(dcd_transfer_is_called);
2030 /* Process request */
2031 status = ux_host_stack_transfer_request(transfer_request);
2032 if (status != UX_SUCCESS)
2033 {
2034
2035 printf("ERROR #%d: Class request status %x\n", __LINE__, status);
2036 test_control_return(1);
2037 }
2038 if (error_counter == 0)
2039 {
2040
2041 printf("ERROR #%d: Class request no DCD transfer\n", __LINE__);
2042 test_control_return(1);
2043 }
2044
2045 class_entry_rc = UX_ERROR;
2046 status = ux_host_stack_transfer_request(transfer_request);
2047 if (status != UX_TRANSFER_STALLED)
2048 {
2049
2050 printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2051 test_control_return(1);
2052 }
2053
2054 stepinfo(">>>>>>>>>>>>>>>> Test Vendor Request\n");
2055 transfer_request -> ux_transfer_request_function = 0xEE;
2056 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
2057 status = ux_host_stack_transfer_request(transfer_request);
2058 if (status != UX_TRANSFER_STALLED)
2059 {
2060
2061 printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2062 test_control_return(1);
2063 }
2064
2065 stepinfo(">>>>>>>>>>>>>>>> Test MS Vendor Request\n");
2066 transfer_request -> ux_transfer_request_function = UX_DEMO_VENDOR_REQUEST;
2067
2068 vendor_req_rc = UX_ERROR;
2069 status = ux_host_stack_transfer_request(transfer_request);
2070 if (status != UX_TRANSFER_STALLED)
2071 {
2072
2073 printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2074 test_control_return(1);
2075 }
2076 vendor_req_rc = UX_SUCCESS;
2077
2078 status = ux_host_stack_transfer_request(transfer_request);
2079 if (status != UX_SUCCESS)
2080 {
2081
2082 printf("ERROR #%d: Vendor request status %x\n", __LINE__, status);
2083 test_control_return(1);
2084 }
2085
2086 stepinfo(">>>>>>>>>>>>>>>> ux_slave_transfer_request_status_phase_ignore\n");
2087 /* DCD should not been called */
2088 slave_transfer_request->ux_slave_transfer_request_status_phase_ignore = UX_TRUE;
2089 error_counter = 0;
2090 ux_test_dcd_sim_slave_set_actions(dcd_transfer_is_called);
2091 status = _ux_device_stack_transfer_request(slave_transfer_request, 18, 18);
2092 if (status != UX_SUCCESS)
2093 {
2094
2095 printf("ERROR #%d: Request not success: %x\n", __LINE__, status);
2096 test_control_return(1);
2097 }
2098 if (error_counter != 0)
2099 {
2100
2101 printf("ERROR #%d: Unexpected call\n", __LINE__);
2102 test_control_return(1);
2103 }
2104 slave_transfer_request->ux_slave_transfer_request_status_phase_ignore = UX_FALSE;
2105
2106
2107 /* Finally disconnect the device. */
2108 ux_device_stack_disconnect();
2109
2110 /* And deinitialize the class. */
2111 status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
2112
2113 /* Deinitialize the device side of usbx. */
2114 _ux_device_stack_uninitialize();
2115
2116 /* And finally the usbx system resources. */
2117 _ux_system_uninitialize();
2118
2119 /* Successful test. */
2120 printf("SUCCESS!\n");
2121 test_control_return(0);
2122
2123 }
2124
tx_test_thread_simulation1_entry(ULONG arg)2125 void tx_test_thread_simulation1_entry(ULONG arg)
2126 {
2127
2128 UINT status;
2129 ULONG actual_length;
2130
2131 while(1)
2132 {
2133 while(cdc_acm_slave != UX_NULL && cdc_acm_slave_reading)
2134 {
2135
2136 status = ux_device_class_cdc_acm_read(cdc_acm_slave, buffer, 64, &actual_length);
2137
2138 if (status == UX_SUCCESS && actual_length)
2139 {
2140
2141 if (ux_utility_memory_compare("TSTALL\n", buffer, 7) == UX_SUCCESS)
2142 {
2143
2144 status = test_ux_device_class_cdc_acm_read_halt(cdc_acm_slave);
2145 if (status != UX_SUCCESS)
2146 {
2147
2148 printf("ERROR #%d: set halt fail: %x\n", __LINE__, status);
2149 test_control_return(1);
2150 }
2151 }
2152 }
2153 }
2154
2155 /* Sleep so ThreadX on Win32 will delete this thread. */
2156 tx_thread_sleep(10);
2157 }
2158 }
2159