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 
16 #include "ux_test_dcd_sim_slave.h"
17 #include "ux_test_hcd_sim_host.h"
18 #include "ux_test_utility_sim.h"
19 
20 #include "ux_host_stack.h"
21 
22 /* Define constants.  */
23 #define                             UX_DEMO_DEBUG_SIZE  (4096*8)
24 #define                             UX_DEMO_STACK_SIZE  1024
25 #define                             UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
26 #define                             UX_DEMO_XMIT_BUFFER_SIZE 512
27 #define                             UX_DEMO_RECEPTION_BUFFER_SIZE 512
28 #define                             UX_DEMO_FILE_BUFFER_SIZE 512
29 #define                             UX_DEMO_RECEPTION_BLOCK_SIZE 64
30 #define                             UX_DEMO_MEMORY_SIZE     (64*1024)
31 #define                             UX_DEMO_FILE_SIZE       (128 * 1024)
32 #define                             UX_RAM_DISK_MEMORY      (256 * 1024)
33 
34 #define     LSB(x) ( (x) & 0x00ff)
35 #define     MSB(x) (((x) & 0xff00) >> 8)
36 
37 /* Configuration descriptor 9 bytes */
38 #define CFG_DESC(wTotalLength, bNumInterfaces, bmAttributes, bConfigurationValue)\
39     /* Configuration 1 descriptor 9 bytes */\
40     0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
41     (bNumInterfaces), (bConfigurationValue), 0x00,\
42     (bmAttributes), 0x00,
43 #define CFG_DESC_LEN 9
44 
45 #define IAD_DESC(bIfc) \
46     /* Interface association descriptor. 8 bytes.  */\
47     0x08, 0x0b, (bIfc), 0x02, 0x02, 0x02, 0x00, 0x00,
48 #define IAD_DESC_LEN 8
49 
50 #define CDC_IFC_DESC_ALL(bIfc, bIntIn, bBulkIn, bBulkOut)\
51     /* Communication Class Interface Descriptor Requirement. 9 bytes.   */\
52     0x09, 0x04, (bIfc), 0x00, 0x01, 0x02, 0x02, 0x01, 0x00,\
53     /* Header Functional Descriptor 5 bytes */\
54     0x05, 0x24, 0x00, 0x10, 0x01,\
55     /* ACM Functional Descriptor 4 bytes */\
56     0x04, 0x24, 0x02, 0x0f,\
57     /* Union Functional Descriptor 5 bytes */\
58     0x05, 0x24, 0x06, (bIfc), (bIfc + 1),\
59     /* Call Management Functional Descriptor 5 bytes */\
60     0x05, 0x24, 0x01, 0x03, (bIfc + 1),\
61     /* Endpoint interrupt in descriptor 7 bytes */\
62     0x07, 0x05, (bIntIn), 0x03, 0x40, 0x00, 0x10,\
63     /* Data Class Interface Descriptor Requirement 9 bytes */\
64     0x09, 0x04, (bIfc + 1), 0x00, 0x02, 0x0A, 0x00, 0x00, 0x00,\
65     /* Endpoint bulk in descriptor 7 bytes */\
66     0x07, 0x05, (bBulkIn), 0x02, 0x40, 0x00, 0x01,\
67     /* Endpoint bulk out descriptor 7 bytes */\
68     0x07, 0x05, (bBulkOut), 0x02, 0x40, 0x00, 0x01,
69 #define CDC_IFC_DESC_ALL_LEN (9+5+4+5+5+7+ 9+7+7)
70 
71 /* Define local/extern function prototypes.  */
72 static VOID                                test_thread_entry(ULONG);
73 static TX_THREAD                           tx_test_thread_host_simulation;
74 static TX_THREAD                           tx_test_thread_slave_simulation;
75 static VOID                                tx_test_thread_host_simulation_entry(ULONG);
76 static VOID                                tx_test_thread_slave_simulation_entry(ULONG);
77 static VOID                                test_cdc_instance_activate(VOID  *cdc_instance);
78 static VOID                                test_cdc_instance_deactivate(VOID *cdc_instance);
79 static VOID                                test_cdc_instance_parameter_change(VOID *cdc_instance);
80 
81 /* Define global data structures.  */
82 static UCHAR                               usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
83 static UX_HOST_CLASS                       *class_driver;
84 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_control;
85 static UX_HOST_CLASS_CDC_ACM               *cdc_acm_host_data;
86 
87 static UX_SLAVE_CLASS_CDC_ACM              *cdc_acm_slave;
88 static UCHAR                               cdc_acm_slave_change;
89 static UX_SLAVE_CLASS_CDC_ACM_PARAMETER    parameter;
90 
91 static ULONG                               error_counter;
92 
93 static ULONG                               error_callback_counter;
94 static UCHAR                               error_callback_ignore;
95 
96 static ULONG                               call_counter;
97 
98 static UCHAR                               buffer[UX_DEMO_BUFFER_SIZE];
99 
100 /* Define device framework.  */
101 
102 static unsigned char device_framework_full_speed[] = {
103 
104     /* Device descriptor     18 bytes
105        0x02 bDeviceClass:    CDC class code
106        0x00 bDeviceSubclass: CDC class sub code
107        0x00 bDeviceProtocol: CDC Device protocol
108 
109        idVendor & idProduct - http://www.linux-usb.org/usb.ids
110     */
111     0x12, 0x01, 0x10, 0x01,
112     0xEF, 0x02, 0x01,
113     0x08,
114     0x84, 0x84, 0x00, 0x00,
115     0x00, 0x01,
116     0x01, 0x02, 03,
117     0x01, /* bNumConfigurations */
118 
119     /* Configuration 1 descriptor 9 bytes, total 75 bytes */
120     CFG_DESC(CFG_DESC_LEN + IAD_DESC_LEN + CDC_IFC_DESC_ALL_LEN, 2, 0x40, 1)
121     /* IAD 8 bytes */
122     IAD_DESC(0)
123     /* CDC_ACM interfaces */
124     CDC_IFC_DESC_ALL(0, 0x83, 0x81, 0x02)
125 };
126 #define             DEVICE_FRAMEWORK_LENGTH_FULL_SPEED      sizeof(device_framework_full_speed)
127 
128 static unsigned char device_framework_high_speed[] = {
129 
130     /* Device descriptor     18 bytes
131        0x02 bDeviceClass:    CDC class code
132        0x00 bDeviceSubclass: CDC class sub code
133        0x00 bDeviceProtocol: CDC Device protocol
134 
135        idVendor & idProduct - http://www.linux-usb.org/usb.ids
136     */
137     0x12, 0x01, 0x00, 0x02,
138     0xEF, 0x02, 0x01,
139     0x40,
140     0x84, 0x84, 0x00, 0x00,
141     0x00, 0x01,
142     0x01, 0x02, 03,
143     0x01, /* bNumConfigurations */
144 
145     /* Device qualifier descriptor 10 bytes */
146     0x0a, 0x06, 0x00, 0x02,
147     0x02, 0x00, 0x00,
148     0x40,
149     0x01,
150     0x00,
151 
152     /* Configuration 1 descriptor 9 bytes, total 75-8=67 bytes */
153     CFG_DESC(CFG_DESC_LEN + CDC_IFC_DESC_ALL_LEN, 2, 0x60, 1)
154     CDC_IFC_DESC_ALL(0, 0x83, 0x81, 0x02)
155 };
156 #define             DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED      sizeof(device_framework_high_speed)
157 
158 static unsigned char string_framework[] = {
159 
160     /* Manufacturer string descriptor : Index 1 - "Express Logic" */
161     0x09, 0x04, 0x01, 0x0c,
162     0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
163     0x6f, 0x67, 0x69, 0x63,
164 
165     /* Product string descriptor : Index 2 - "EL Composite device" */
166     0x09, 0x04, 0x02, 0x13,
167     0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
168     0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
169     0x69, 0x63, 0x65,
170 
171     /* Serial Number string descriptor : Index 3 - "0001" */
172     0x09, 0x04, 0x03, 0x04,
173     0x30, 0x30, 0x30, 0x31
174 };
175 #define             STRING_FRAMEWORK_LENGTH                 sizeof(string_framework)
176 
177 /* Multiple languages are supported on the device, to add
178     a language besides english, the unicode language code must
179     be appended to the language_id_framework array and the length
180     adjusted accordingly. */
181 static unsigned char language_id_framework[] = {
182 
183     /* English. */
184     0x09, 0x04
185 };
186 #define             LANGUAGE_ID_FRAMEWORK_LENGTH            sizeof(language_id_framework)
187 
188 /* Define the ISR dispatch.  */
189 
190 extern VOID    (*test_isr_dispatch)(void);
191 
192 
193 /* Prototype for test control return.  */
194 
195 void  test_control_return(UINT status);
196 
197 
198 /* Define the ISR dispatch routine.  */
199 
test_isr(void)200 static void    test_isr(void)
201 {
202 
203     /* For further expansion of interrupt-level testing.  */
204 }
205 
206 /* DCD simulator. */
207 
UX_DCD_CHANGE_STATE_is_called(UX_TEST_ACTION * action,VOID * _params)208 static VOID UX_DCD_CHANGE_STATE_is_called(UX_TEST_ACTION *action, VOID *_params)
209 {
210     call_counter ++;
211 }
212 
213 static UX_TEST_DCD_SIM_ACTION monitor_UX_DCD_CHANGE_STATE[] = {
214 /* function, request to match,
215    port action, port status,
216    request action, request EP, request data, request actual length, request status,
217    status, additional callback,
218    no_return */
219 {   UX_DCD_CHANGE_STATE, NULL,
220         UX_FALSE, 0,
221         0, 0, UX_NULL, 0, 0,
222         UX_SUCCESS, UX_DCD_CHANGE_STATE_is_called},
223 {   0   }
224 };
225 
break_on_cdc_acm_all_ready(VOID)226 static UINT break_on_cdc_acm_all_ready(VOID)
227 {
228 UINT                                 status;
229 UINT                                 i;
230 UX_HOST_CLASS                       *class;
231 UX_HOST_CLASS_CDC_ACM               *cdc_acm;
232 
233     /* Find the main cdc_acm container */
234     status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
235     if (status != UX_SUCCESS)
236         /* Do not break. */
237         return 0;
238 
239     /* Find class instances. */
240     for (i = 0; i < 2; i ++)
241     {
242         status = ux_host_stack_class_instance_get(class, i, (void **) &cdc_acm);
243         if (status != UX_SUCCESS)
244             /* Do not break. */
245             return 0;
246 
247         switch(cdc_acm->ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass)
248         {
249 
250         case UX_HOST_CLASS_CDC_CONTROL_CLASS:
251             cdc_acm_host_control = cdc_acm;
252             break;
253 
254         case UX_HOST_CLASS_CDC_DATA_CLASS:
255             cdc_acm_host_data = cdc_acm;
256             break;
257 
258         default:
259             break;
260         }
261     }
262 
263     if (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL)
264         /* Do not break. */
265         return 0;
266 
267     if (cdc_acm_host_control->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
268         /* Do not break. */
269         return 0;
270 
271     if (cdc_acm_host_data->ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
272         /* Do not break. */
273         return 0;
274 
275     if (cdc_acm_slave == UX_NULL)
276         /* Do not break. */
277         return 0;
278 
279     /* All found, break. */
280     return 1;
281 }
282 
break_on_removal(VOID)283 static UINT break_on_removal(VOID)
284 {
285 
286 UINT                     status;
287 UX_DEVICE               *device;
288 
289     status = ux_host_stack_device_get(0, &device);
290     if (status == UX_SUCCESS)
291         /* Do not break. */
292         return UX_SUCCESS;
293 
294     cdc_acm_host_data = UX_NULL;
295     cdc_acm_host_control = UX_NULL;
296 
297     return 1;
298 }
299 
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)300 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
301 {
302 
303 UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
304 
305     switch(event)
306     {
307 
308         case UX_DEVICE_INSERTION:
309 
310             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
311                 cdc_acm_host_control = cdc_acm;
312             else
313                 cdc_acm_host_data = cdc_acm;
314             break;
315 
316         case UX_DEVICE_REMOVAL:
317 
318             if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
319                 cdc_acm_host_control = UX_NULL;
320             else
321                 cdc_acm_host_data = UX_NULL;
322             break;
323 
324         default:
325             break;
326     }
327     return 0;
328 }
329 
test_cdc_instance_activate(VOID * cdc_instance)330 static VOID    test_cdc_instance_activate(VOID *cdc_instance)
331 {
332 
333     /* Save the CDC instance.  */
334     cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
335 }
test_cdc_instance_deactivate(VOID * cdc_instance)336 static VOID    test_cdc_instance_deactivate(VOID *cdc_instance)
337 {
338 
339     /* Reset the CDC instance.  */
340     cdc_acm_slave = UX_NULL;
341 }
342 
test_cdc_instance_parameter_change(VOID * cdc_instance)343 static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
344 {
345 
346     /* Set CDC parameter change flag. */
347     cdc_acm_slave_change = UX_TRUE;
348 }
349 
test_ux_error_callback(UINT system_level,UINT system_context,UINT error_code)350 static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
351 {
352     error_callback_counter ++;
353 
354     if (!error_callback_ignore)
355     {
356         {
357             /* Failed test.  */
358             printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
359             // test_control_return(1);
360         }
361     }
362 }
363 
364 /* Define what the initial system looks like.  */
365 
366 #ifdef CTEST
test_application_define(void * first_unused_memory)367 void test_application_define(void *first_unused_memory)
368 #else
369 void usbx_ux_device_stack_remote_wakeup_test_application_define(void *first_unused_memory)
370 #endif
371 {
372 
373 UINT                    status;
374 CHAR *                  stack_pointer;
375 CHAR *                  memory_pointer;
376 
377     printf("Running ux_device_stack_ Remote Wakeup Test......................... ");
378 
379     /* Initialize the free memory pointer */
380     stack_pointer = (CHAR *) usbx_memory;
381     memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
382 
383     /* Initialize USBX Memory */
384     status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
385     /* Check for error.  */
386     if (status != UX_SUCCESS)
387     {
388 
389         printf("ERROR #%d\n", __LINE__);
390         test_control_return(1);
391     }
392 
393     /* Register the error callback. */
394     _ux_utility_error_callback_register(test_ux_error_callback);
395 
396     /* The code below is required for installing the host portion of USBX */
397     status =  ux_host_stack_initialize(UX_NULL);
398     if (status != UX_SUCCESS)
399     {
400 
401         printf("ERROR #%d\n", __LINE__);
402         test_control_return(1);
403     }
404 
405     /* Register CDC ACM class */
406     status =  ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
407     if (status != UX_SUCCESS)
408     {
409 
410         printf("ERROR #%d\n", __LINE__);
411         test_control_return(1);
412     }
413 
414     /* The code below is required for installing the device portion of USBX. No call back for
415        device status change in this example. */
416     status =  ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
417                                        device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
418                                        string_framework, STRING_FRAMEWORK_LENGTH,
419                                        language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
420     if(status!=UX_SUCCESS)
421     {
422 
423         printf("ERROR #%d\n", __LINE__);
424         test_control_return(1);
425     }
426 
427     /* Set the parameters for callback when insertion/extraction of a CDC device.  */
428     parameter.ux_slave_class_cdc_acm_instance_activate   =  test_cdc_instance_activate;
429     parameter.ux_slave_class_cdc_acm_instance_deactivate =  test_cdc_instance_deactivate;
430     parameter.ux_slave_class_cdc_acm_parameter_change    =  test_cdc_instance_parameter_change;
431 
432     /* Initialize the device cdc class. This class owns both interfaces starting with 0. */
433     status  =  ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
434                                              1,0,  &parameter);
435     status |= ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
436                                              2,0,  &parameter);
437     status |= ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
438                                              3,0,  &parameter);
439 #if UX_MAX_SLAVE_CLASS_DRIVER > 1
440     if(status!=UX_SUCCESS)
441     {
442 
443         printf("ERROR #%d\n", __LINE__);
444         test_control_return(1);
445     }
446 #endif
447 
448     /* Initialize the simulated device controller.  */
449     status =  _ux_test_dcd_sim_slave_initialize();
450 
451     /* Check for error.  */
452     if (status != TX_SUCCESS)
453     {
454 
455         printf("ERROR #%d\n", __LINE__);
456         test_control_return(1);
457     }
458 
459     /* Register HCD for test */
460     status =  ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
461     if (status != UX_SUCCESS)
462     {
463 
464         printf("ERROR #%d\n", __LINE__);
465         test_control_return(1);
466     }
467 
468     /* Create the main host simulation thread.  */
469     status =  tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
470             stack_pointer, UX_DEMO_STACK_SIZE,
471             20, 20, 1, TX_AUTO_START);
472 
473     /* Check for error.  */
474     if (status != TX_SUCCESS)
475     {
476 
477         printf("ERROR #%d\n", __LINE__);
478         test_control_return(1);
479     }
480 
481     /* Create the main slave simulation  thread.  */
482     status =  tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
483             stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
484             20, 20, 1, TX_AUTO_START);
485 
486     /* Check for error.  */
487     if (status != TX_SUCCESS)
488     {
489 
490         printf("ERROR #%d\n", __LINE__);
491         test_control_return(1);
492     }
493 }
494 
tx_test_thread_host_simulation_entry(ULONG arg)495 void  tx_test_thread_host_simulation_entry(ULONG arg)
496 {
497 
498 UINT                                                status;
499 UX_DEVICE                                          *device;
500 UX_ENDPOINT                                        *control_endpoint;
501 UX_TRANSFER                                        *transfer_request;
502 
503     stepinfo("\n");
504 
505     /* Test connect. */
506     stepinfo(">>>>>>>>>>>>>>>> Test connect (FS)\n");
507     ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
508     ux_test_breakable_sleep(100, break_on_cdc_acm_all_ready);
509     if (!(cdc_acm_host_control && cdc_acm_host_data && cdc_acm_slave))
510     {
511 
512         printf("ERROR #%d: connect fail\n", __LINE__);
513         test_control_return(1);
514     }
515 
516     /* Get device instance. */
517     status = ux_host_stack_device_get(0, &device);
518     if (status != UX_SUCCESS)
519     {
520 
521         printf("ERROR #%d: device_get fail\n", __LINE__);
522         test_control_return(1);
523     }
524     control_endpoint = &device->ux_device_control_endpoint;
525     transfer_request = &control_endpoint->ux_endpoint_transfer_request;
526 
527     /* Build transfer request. */
528     transfer_request -> ux_transfer_request_data_pointer =      buffer;
529     transfer_request -> ux_transfer_request_index =             0;
530 
531     error_callback_ignore = UX_TRUE;
532 
533     stepinfo(">>>>>>>>>>>>>>>> GetDeviceStatus(), no error\n");
534 
535     transfer_request -> ux_transfer_request_function =          UX_GET_STATUS;
536     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
537     transfer_request -> ux_transfer_request_value =             0;
538     transfer_request -> ux_transfer_request_requested_length =  2;
539     status = ux_host_stack_transfer_request(transfer_request);
540     if (status != UX_SUCCESS)
541     {
542 
543         printf("ERROR #%d: GetDeviceStatus() code 0x%x\n", __LINE__, status);
544         error_counter ++;
545     }
546 
547     stepinfo(">>>>>>>>>>>>>>>> SetDeviceFeature(DEVICE_REMOTE_WAKEUP), error\n");
548 
549     transfer_request -> ux_transfer_request_function =          UX_SET_FEATURE;
550     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
551     transfer_request -> ux_transfer_request_value =             1;
552     transfer_request -> ux_transfer_request_requested_length =  0;
553     status = ux_host_stack_transfer_request(transfer_request);
554     if (status == UX_SUCCESS)
555     {
556 
557         printf("ERROR #%d: SetDeviceFeature(DEVICE_REMOTE_WAKEUP) code 0x%x\n", __LINE__, status);
558         error_counter ++;
559     }
560 
561     stepinfo(">>>>>>>>>>>>>>>> ClearDeviceFeature(DEVICE_REMOTE_WAKEUP), error\n");
562 
563     transfer_request -> ux_transfer_request_function =          UX_CLEAR_FEATURE;
564     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
565     transfer_request -> ux_transfer_request_value =             1;
566     status = ux_host_stack_transfer_request(transfer_request);
567     if (status == UX_SUCCESS)
568     {
569 
570         printf("ERROR #%d: ClearDeviceFeature(DEVICE_REMOTE_WAKEUP) code 0x%x\n", __LINE__, status);
571         error_counter ++;
572     }
573 
574     stepinfo(">>>>>>>>>>>>>>>> Test connect (HS)\n");
575 
576     ux_test_hcd_sim_host_disconnect();
577     ux_test_dcd_sim_slave_disconnect();
578     ux_test_breakable_sleep(100, break_on_removal);
579 
580     ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
581     ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
582     ux_test_breakable_sleep(100, break_on_cdc_acm_all_ready);
583 
584     if (!(cdc_acm_host_control && cdc_acm_host_data && cdc_acm_slave))
585     {
586 
587         printf("ERROR #%d: connect fail\n", __LINE__);
588         test_control_return(1);
589     }
590 
591     /* Get device instance. */
592     status = ux_host_stack_device_get(0, &device);
593     if (status != UX_SUCCESS)
594     {
595 
596         printf("ERROR #%d: device_get fail\n", __LINE__);
597         test_control_return(1);
598     }
599     control_endpoint = &device->ux_device_control_endpoint;
600     transfer_request = &control_endpoint->ux_endpoint_transfer_request;
601 
602     /* Build transfer request. */
603     transfer_request -> ux_transfer_request_data_pointer =      buffer;
604     transfer_request -> ux_transfer_request_index =             0;
605 
606     stepinfo(">>>>>>>>>>>>>>>> SetDeviceFeature(DEVICE_REMOTE_WAKEUP), OK\n");
607 
608     transfer_request -> ux_transfer_request_function =          UX_SET_FEATURE;
609     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
610     transfer_request -> ux_transfer_request_value =             1;
611     transfer_request -> ux_transfer_request_requested_length =  0;
612     status = ux_host_stack_transfer_request(transfer_request);
613     if (status != UX_SUCCESS)
614     {
615 
616         printf("ERROR #%d: SetDeviceFeature(DEVICE_REMOTE_WAKEUP) code 0x%x\n", __LINE__, status);
617         error_counter ++;
618     }
619 
620     stepinfo(">>>>>>>>>>>>>>>> GetDeviceStatus(), 0x02 - remote wakeup enabled\n");
621 
622     transfer_request -> ux_transfer_request_function =          UX_GET_STATUS;
623     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
624     transfer_request -> ux_transfer_request_value =             0;
625     transfer_request -> ux_transfer_request_requested_length =  2;
626     status = ux_host_stack_transfer_request(transfer_request);
627     if (status != UX_SUCCESS)
628     {
629 
630         printf("ERROR #%d: GetDeviceStatus() code 0x%x\n", __LINE__, status);
631         error_counter ++;
632     }
633     if ((buffer[0] & 0x02u) == 0)
634     {
635 
636         printf("ERROR #%d: remote wakeup disabled\n", __LINE__);
637         error_counter ++;
638     }
639 
640     stepinfo(">>>>>>>>>>>>>>>> _ux_device_stack_host_wakeup(), UX_DCD_CHANGE_STATE called, OK\n");
641 
642     call_counter = 0;
643     ux_test_dcd_sim_slave_set_actions(monitor_UX_DCD_CHANGE_STATE);
644     status = _ux_device_stack_host_wakeup();
645     if (call_counter == 0)
646     {
647 
648         printf("ERROR #%d: UX_DCD_CHANGE_STATE not called\n", __LINE__);
649         error_counter ++;
650     }
651 
652     stepinfo(">>>>>>>>>>>>>>>> ClearDeviceFeature(DEVICE_REMOTE_WAKEUP), OK\n");
653 
654     transfer_request -> ux_transfer_request_function =          UX_CLEAR_FEATURE;
655     transfer_request -> ux_transfer_request_type =              UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
656     transfer_request -> ux_transfer_request_value =             1;
657     transfer_request -> ux_transfer_request_requested_length =  0;
658     status = ux_host_stack_transfer_request(transfer_request);
659     if (status != UX_SUCCESS)
660     {
661 
662         printf("ERROR #%d: ClearDeviceFeature(DEVICE_REMOTE_WAKEUP) code 0x%x\n", __LINE__, status);
663         error_counter ++;
664     }
665 
666     stepinfo(">>>>>>>>>>>>>>>> GetDeviceStatus(), 0x02 - remote wakeup disabled\n");
667 
668     transfer_request -> ux_transfer_request_function =          UX_GET_STATUS;
669     transfer_request -> ux_transfer_request_type =              UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
670     transfer_request -> ux_transfer_request_value =             0;
671     transfer_request -> ux_transfer_request_requested_length =  2;
672     status = ux_host_stack_transfer_request(transfer_request);
673     if (status != UX_SUCCESS)
674     {
675 
676         printf("ERROR #%d: GetDeviceStatus() code 0x%x\n", __LINE__, status);
677         error_counter ++;
678     }
679     if ((buffer[0] & 0x02u) != 0)
680     {
681 
682         printf("ERROR #%d: remote wakeup enabled\n", __LINE__);
683         error_counter ++;
684     }
685 
686     stepinfo(">>>>>>>>>>>>>>>> _ux_device_stack_host_wakeup(), UX_DCD_CHANGE_STATE not called, fail\n");
687 
688     call_counter = 0;
689     ux_test_dcd_sim_slave_set_actions(monitor_UX_DCD_CHANGE_STATE);
690     status = _ux_device_stack_host_wakeup();
691     if (status == 0)
692     {
693 
694         printf("ERROR #%d: expect fail\n", __LINE__);
695         error_counter ++;
696     }
697     if (call_counter > 0)
698     {
699 
700         printf("ERROR #%d: UX_DCD_CHANGE_STATE called\n", __LINE__);
701         error_counter ++;
702     }
703 
704     error_callback_ignore = UX_FALSE;
705 
706     stepinfo(">>>>>>>>>>>>>>>> Deinitialize\n");
707 
708     /* Deinitialize the class.  */
709     status =  ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
710 
711     /* Deinitialize the device side of usbx.  */
712     _ux_device_stack_uninitialize();
713 
714     /* And finally the usbx system resources.  */
715     _ux_system_uninitialize();
716 
717     stepinfo(">>>>>>>>>>>>>>>> Dump results\n");
718 
719     if (error_counter > 0)
720     {
721 
722         /* Test error.  */
723         printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
724         test_control_return(1);
725     }
726 
727     /* Successful test.  */
728     printf("SUCCESS!\n");
729     test_control_return(0);
730 }
731 
tx_test_thread_slave_simulation_entry(ULONG arg)732 void  tx_test_thread_slave_simulation_entry(ULONG arg)
733 {
734 
735     while(1)
736     {
737 
738         /* Sleep so ThreadX on Win32 will delete this thread. */
739         ux_utility_delay_ms(100);
740     }
741 }
742