1 /* This test is designed to test the simple video 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 #include "ux_hcd_sim_host.h"
9
10 #include "fx_api.h"
11
12 #include "ux_device_class_video.h"
13 #include "ux_device_stack.h"
14
15 #include "ux_host_class_video.h"
16 #include "ux_host_class_dummy.h"
17
18 #include "ux_test_dcd_sim_slave.h"
19 #include "ux_test_hcd_sim_host.h"
20 #include "ux_test_utility_sim.h"
21
22
23 /* Define constants. */
24
25 #define UX_DEMO_REQUEST_MAX_LENGTH \
26 ((UX_HCD_SIM_HOST_MAX_PAYLOAD) > (UX_SLAVE_REQUEST_DATA_MAX_LENGTH) ? \
27 (UX_HCD_SIM_HOST_MAX_PAYLOAD) : (UX_SLAVE_REQUEST_DATA_MAX_LENGTH))
28
29 #define UX_DEMO_DEBUG_SIZE (4096*8)
30 #define UX_DEMO_STACK_SIZE 1024
31 #define UX_DEMO_BUFFER_SIZE (UX_DEMO_REQUEST_MAX_LENGTH + 1)
32 #define UX_DEMO_MEMORY_SIZE (128*1024)
33 #define UX_DEMO_ENDPOINT_SIZE 480
34
35 #define UX_TEST_LOG_SIZE (64)
36
37
38 /* Define local/extern function prototypes. */
39 static void test_thread_entry(ULONG);
40 static TX_THREAD tx_test_thread_host_simulation;
41 static TX_THREAD tx_test_thread_slave_simulation;
42 static void tx_test_thread_host_simulation_entry(ULONG);
43 static void tx_test_thread_slave_simulation_entry(ULONG);
44
45
46 /* Define global data structures. */
47 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
48
49 static UX_HOST_CLASS_DUMMY *dummy_control;
50 static UX_HOST_CLASS_DUMMY *dummy_tx;
51 static UX_HOST_CLASS_DUMMY *dummy_rx;
52
53 static UX_DEVICE_CLASS_VIDEO *device_video;
54 static UX_DEVICE_CLASS_VIDEO_STREAM *device_video_tx_stream;
55 static UX_DEVICE_CLASS_VIDEO_STREAM *device_video_rx_stream;
56 static UX_DEVICE_CLASS_VIDEO_PARAMETER device_video_parameter;
57 static UX_DEVICE_CLASS_VIDEO_STREAM_PARAMETER device_video_stream_parameter[2];
58
59 static UX_SLAVE_TRANSFER *device_video_tx_transfer;
60 static UX_SLAVE_TRANSFER *device_video_rx_transfer;
61
62 static UX_HOST_CLASS_VIDEO *video;
63
64 static ULONG error_counter;
65
66 static ULONG set_cfg_counter;
67
68 static ULONG rsc_mem_free_on_set_cfg;
69 static ULONG rsc_sem_on_set_cfg;
70 static ULONG rsc_sem_get_on_set_cfg;
71 static ULONG rsc_mutex_on_set_cfg;
72
73 static ULONG rsc_enum_sem_usage;
74 static ULONG rsc_enum_sem_get_count;
75 static ULONG rsc_enum_mutex_usage;
76 static ULONG rsc_enum_mem_usage;
77
78 static ULONG rsc_video_sem_usage;
79 static ULONG rsc_video_sem_get_count;
80 static ULONG rsc_video_mutex_usage;
81 static ULONG rsc_video_mem_usage;
82
83 static ULONG interaction_count;
84
85 static UCHAR error_callback_ignore = UX_TRUE;
86 static ULONG error_callback_counter;
87
88 static struct BUFFER_LOG_STRUCT {
89 ULONG length;
90 UCHAR data[256];
91 } buffer_log[UX_TEST_LOG_SIZE];
92 static ULONG buffer_log_count = 0;
93 #define SAVE_BUFFER_LOG(buf,siz) do { \
94 if (buffer_log_count < UX_TEST_LOG_SIZE) { \
95 ULONG __local_size__ = ((siz) > 256) ? 256 : (siz); \
96 buffer_log[buffer_log_count].length = (siz); \
97 _ux_utility_memory_copy(buffer_log[buffer_log_count].data, (buf), __local_size__); \
98 } \
99 buffer_log_count ++; \
100 } while(0)
101
102 static ULONG test_tx_ack_count = 0xFFFFFFFF;
103 static ULONG test_tx_ins_count = 0;
104 static ULONG test_tx_ins_way = 0;
105
106 static struct CALLBACK_INVOKE_LOG_STRUCT {
107 VOID *func;
108 VOID *param1;
109 VOID *param2;
110 VOID *param3;
111 } callback_invoke_log[UX_TEST_LOG_SIZE];
112 static ULONG callback_invoke_count = 0;
113
114 #define SAVE_CALLBACK_INVOKE_LOG(f,p1,p2,p3) do { \
115 if (callback_invoke_count < UX_TEST_LOG_SIZE) { \
116 callback_invoke_log[callback_invoke_count].func = (VOID *)(f); \
117 callback_invoke_log[callback_invoke_count].param1 = (VOID *)(p1); \
118 callback_invoke_log[callback_invoke_count].param2 = (VOID *)(p2); \
119 callback_invoke_log[callback_invoke_count].param3 = (VOID *)(p3); \
120 callback_invoke_count++; \
121 } \
122 } while(0)
123 #define RESET_CALLBACK_INVOKE_LOG() do { \
124 callback_invoke_count = 0; \
125 } while(0)
126
127 /* Define device framework. */
128
129 #define W(d) UX_DW0(d), UX_DW1(d)
130 #define DW(d) UX_DW0(d), UX_DW1(d), UX_DW2(d), UX_DW3(d)
131
132 #define _DEVICE_DESCRIPTOR() \
133 /* --------------------------------------- Device Descriptor */ \
134 /* 0 bLength, bDescriptorType */ 18, 0x01, \
135 /* 2 bcdUSB */ UX_DW0(0x200),UX_DW1(0x200), \
136 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00, \
137 /* 7 bMaxPacketSize0 */ 0x08, \
138 /* 8 idVendor, idProduct */ 0x84, 0x84, 0x01, 0x00, \
139 /* 12 bcdDevice */ UX_DW0(0x100),UX_DW1(0x100), \
140 /* 14 iManufacturer, iProduct, iSerialNumber */ 0, 0, 0, \
141 /* 17 bNumConfigurations */ 1,
142
143 #define _DEVICE_QUALIFIER_DESCRIPTOR() \
144 /* ----------------------------- Device Qualifier Descriptor */ \
145 /* 0 bLength, bDescriptorType */ 10, 0x06, \
146 /* 2 bcdUSB */ UX_DW0(0x200),UX_DW1(0x200), \
147 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00, \
148 /* 7 bMaxPacketSize0 */ 8, \
149 /* 8 bNumConfigurations */ 1, \
150 /* 9 bReserved */ 0,
151
152 #define _CONFIGURE_DESCRIPTOR(total_len,n_ifc,cfg_v) \
153 /* -------------------------------- Configuration Descriptor */ \
154 /* 0 bLength, bDescriptorType */ 9, 0x02, \
155 /* 2 wTotalLength */ UX_DW0(total_len),UX_DW1(total_len),\
156 /* 4 bNumInterfaces, bConfigurationValue */ (n_ifc), (cfg_v), \
157 /* 6 iConfiguration */ 0, \
158 /* 7 bmAttributes, bMaxPower */ 0x80, 50,
159
160 #define _IAD_DESCRIPTOR(ifc_0,ifc_cnt,cls,sub,protocol) \
161 /* ------------------------ Interface Association Descriptor */ \
162 /* 0 bLength, bDescriptorType */ 8, 0x0B, \
163 /* 2 bFirstInterface, bInterfaceCount */ (ifc_0), (ifc_cnt), \
164 /* 4 bFunctionClass, bFunctionSubClass, bFunctionProtocol */ (cls), (sub), (protocol), \
165 /* 7 iFunction */ 0,
166
167 #define _INTERFACE_DESCRIPTOR(ifc,alt,n_ep,cls,sub,protocol) \
168 /* ------------------------------------ Interface Descriptor */ \
169 /* 0 bLength, bDescriptorType */ 9, 0x04, \
170 /* 2 bInterfaceNumber, bAlternateSetting */ (ifc), (alt), \
171 /* 4 bNumEndpoints */ (n_ep), \
172 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ (cls), (sub), (protocol), \
173 /* 8 iInterface */ 0,
174
175 #define _ENDPOINT_DESCRIPTOR(addr,attr,pkt_siz,interval) \
176 /* ------------------------------------- Endpoint Descriptor */ \
177 /* 0 bLength, bDescriptorType */ 7, 0x05, \
178 /* 2 bEndpointAddress, bmAttributes */ (addr), (attr), \
179 /* 4 wMaxPacketSize, bInterval */ UX_DW0(pkt_siz),UX_DW1(pkt_siz),(interval),
180
181 #define _VC_DESCRIPTORS_LEN (14+17+9+17+9)
182 #define _VC_DESCRIPTORS() \
183 /*--------------------------- Class VC Interface Descriptor (VC_HEADER). */ \
184 14, 0x24, 0x01, W(0x150), \
185 W(_VC_DESCRIPTORS_LEN), /* wTotalLength. */ \
186 DW(6000000), /* dwClockFrequency. */ \
187 2, /* bInCollection. */ \
188 1, 2, /* BaInterfaceNr(2). */ \
189 /*--------------------------- Input Terminal (VC_INPUT_TERMINAL, Camera) */ \
190 17, 0x24, 0x02, \
191 0x01, /* bTerminalID, ITT_CAMERA */ \
192 W(0x201), /* wTerminalType */ \
193 0x00, 0x00, W(0), W(0), W(0), \
194 0x02, W(0), /* bControlSize, bmControls */ \
195 /*---------------------------- Output Terminal (VC_OUTPUT_TERMINAL, USB) */ \
196 9, 0x24, 0x03, \
197 0x02, /* bTerminalID */ \
198 W(0x0101), /* wTerminalType, TT_STREAMING */ \
199 0x00, 0x01/* bSourceID */, 0x00, \
200 /*--------------------------- Input Terminal (VC_INPUT_TERMINAL, USB) */ \
201 17, 0x24, 0x02, \
202 0x03, /* bTerminalID */ \
203 W(0x101), /* wTerminalType, TT_STREAMING */ \
204 0x00, 0x00, W(0), W(0), W(0), \
205 0x02, W(0), /* bControlSize, bmControls */ \
206 /*---------------------------- Output Terminal (VC_OUTPUT_TERMINAL, DISPLAY) */ \
207 9, 0x24, 0x03, \
208 0x04, /* bTerminalID */ \
209 W(0x0301), /* wTerminalType, OTT_DISPLAY */ \
210 0x00, 0x03/* bSourceID */, 0x00,
211
212 #if 0
213 /*--------------------------------- Processing Unit (VC_PROCESSING_UNIT) */ \
214 12, 0x24, 0x05, \
215 , /* bUnitID */ \
216 , /* bSourceID */ \
217 W(0), \
218 3 /* bControlSize */, 0, 0, 0 /*bmControls */, \
219 0x00, 0x00, \
220 /*--------------------------------- Processing Unit (VC_PROCESSING_UNIT) */ \
221 12, 0x24, 0x05, \
222 , /* bUnitID */ \
223 , /* bSourceID */ \
224 W(0), \
225 3 /* bControlSize */, 0, 0, 0 /*bmControls */, \
226 0x00, 0x00, \
227
228 #endif
229
230 #define _VS_IN_DESCRIPTORS_LEN (14+11+38)
231 #define _VS_IN_DESCRIPTORS() \
232 /*------------------------- Class VS Header Descriptor (VS_INPUT_HEADER) */ \
233 14, 0x24, 0x01, \
234 0X01, /* bNumFormats */ \
235 W(_VS_IN_DESCRIPTORS_LEN), /* wTotalLength */ \
236 0x81, /* bEndpointAddress */ \
237 0x00, \
238 0x02, /* bTerminalLink */ \
239 0x00, /* bStillCaptureMethod */ \
240 0x00, 0x00, /* bTriggerSupport, bTriggerUsage */ \
241 0x01, 0x00, /* bControlSize, bmaControls */ \
242 /*------------------------------- VS Format Descriptor (VS_FORMAT_MJPEG) */ \
243 11, 0x24, 0x06, \
244 0x01, /* bFormatIndex */ \
245 0x01, /* bNumFrameDescriptors */ \
246 0x01, /* bmFlags */ \
247 0x01, /* bDefaultFrameIndex */ \
248 0x00, 0x00, 0x00, 0x00, \
249 /*--------------------------------- VS Frame Descriptor (VS_FRAME_MJPEG) */ \
250 38, 0x24, 0x07, \
251 0x01, /* bFrameIndex */ \
252 0x03, /* bmCapabilities */ \
253 W(176), W(144), /* wWidth, wHeight */ \
254 DW(912384), DW(912384), /* dwMinBitRate, dwMaxBitRate */ \
255 DW(38016), /* dwMaxVideoFrameBufSize */ \
256 DW(666666), /* dwDefaultFrameInterval */ \
257 0x00, /* bFrameIntervalType */ \
258 DW(666666), DW(666666), DW(0), /* dwMinFrameInterval, dwMaxFrameInterval, dwFrameIntervalStep */
259
260 #define _VS_OUT_DESCRIPTORS_LEN (11+11+38)
261 #define _VS_OUT_DESCRIPTORS() \
262 /*------------------------- Class VS Header Descriptor (VS_OUTPUT_HEADER) */ \
263 11, 0x24, 0x02, \
264 0x01, /* bNumFormats */ \
265 W(_VS_OUT_DESCRIPTORS_LEN), /* wTotalLength */ \
266 0x02, /* bEndpointAddress */ \
267 0x00, \
268 0x03, /* bTerminalLink */ \
269 0x01, 0x00, /* bControlSize, bmaControls */ \
270 /*------------------------------- VS Format Descriptor (VS_FORMAT_MJPEG) */ \
271 11, 0x24, 0x06, \
272 0x01, /* bFormatIndex */ \
273 0x01, /* bNumFrameDescriptors */ \
274 0x01, /* bmFlags */ \
275 0x01, /* bDefaultFrameIndex */ \
276 0x00, 0x00, 0x00, 0x00, \
277 /*--------------------------------- VS Frame Descriptor (VS_FRAME_MJPEG) */ \
278 38, 0x24, 0x07, \
279 0x01, /* bFrameIndex */ \
280 0x03, /* bmCapabilities */ \
281 W(176), W(144), /* wWidth, wHeight */ \
282 DW(912384), DW(912384), /* dwMinBitRate, dwMaxBitRate */ \
283 DW(38016), /* dwMaxVideoFrameBufSize */ \
284 DW(666666), /* dwDefaultFrameInterval */ \
285 0x00, /* bFrameIntervalType */ \
286 DW(666666), DW(666666), DW(0), /* dwMinFrameInterval, dwMaxFrameInterval, dwFrameIntervalStep */
287
288
289 #define _CONFIGURE_DESCRIPTORS_LEN (9+ 8+ 9+_VC_DESCRIPTORS_LEN+ 9+_VS_IN_DESCRIPTORS_LEN+9+7+ 9+_VS_OUT_DESCRIPTORS_LEN+9+7)
290
291 static unsigned char device_framework_full_speed[] = {
292 _DEVICE_DESCRIPTOR()
293 _CONFIGURE_DESCRIPTOR(_CONFIGURE_DESCRIPTORS_LEN,3,1)
294 _IAD_DESCRIPTOR(0,3,0x0E,0x03,0x00)
295
296 _INTERFACE_DESCRIPTOR(0,0,0,0x0E,0x01,0x01)
297 _VC_DESCRIPTORS()
298
299 _INTERFACE_DESCRIPTOR(1,0,0,0x0E,0x02,0x00)
300 _VS_IN_DESCRIPTORS()
301 _INTERFACE_DESCRIPTOR(1,1,1,0x0E,0x02,0x00)
302 _ENDPOINT_DESCRIPTOR(0x81,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
303
304 _INTERFACE_DESCRIPTOR(2,0,0,0x0E,0x02,0x00)
305 _VS_OUT_DESCRIPTORS()
306 _INTERFACE_DESCRIPTOR(2,1,1,0x0E,0x02,0x00)
307 _ENDPOINT_DESCRIPTOR(0x02,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
308 };
309 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
310
311 static unsigned char device_framework_high_speed[] = {
312 _DEVICE_DESCRIPTOR()
313 _DEVICE_QUALIFIER_DESCRIPTOR()
314 _CONFIGURE_DESCRIPTOR(_CONFIGURE_DESCRIPTORS_LEN,3,1)
315 _IAD_DESCRIPTOR(0,3,0x0E,0x03,0x00)
316
317 _INTERFACE_DESCRIPTOR(0,0,0,0x0E,0x01,0x01)
318 _VC_DESCRIPTORS()
319
320 _INTERFACE_DESCRIPTOR(1,0,0,0x0E,0x02,0x00)
321 _VS_IN_DESCRIPTORS()
322 _INTERFACE_DESCRIPTOR(1,1,1,0x0E,0x02,0x00)
323 _ENDPOINT_DESCRIPTOR(0x81,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
324
325 _INTERFACE_DESCRIPTOR(2,0,0,0x0E,0x02,0x00)
326 _VS_OUT_DESCRIPTORS()
327 _INTERFACE_DESCRIPTOR(2,1,1,0x0E,0x02,0x00)
328 _ENDPOINT_DESCRIPTOR(0x02,0x05,UX_DEMO_ENDPOINT_SIZE,0x01)
329 };
330 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
331
332 static unsigned char string_framework[] = {
333
334 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
335 0x09, 0x04, 0x01, 0x0c,
336 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
337 0x6f, 0x67, 0x69, 0x63,
338
339 /* Product string descriptor : Index 2 - "EL Composite device" */
340 0x09, 0x04, 0x02, 0x13,
341 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
342 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
343 0x69, 0x63, 0x65,
344
345 /* Serial Number string descriptor : Index 3 - "0001" */
346 0x09, 0x04, 0x03, 0x04,
347 0x30, 0x30, 0x30, 0x31
348 };
349 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
350
351
352 /* Multiple languages are supported on the device, to add
353 a language besides English, the Unicode language code must
354 be appended to the language_id_framework array and the length
355 adjusted accordingly. */
356 static unsigned char language_id_framework[] = {
357
358 /* English. */
359 0x09, 0x04
360 };
361 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
362
363 /* Setup requests */
364
365 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
366 static UX_TEST_SETUP _GetCfgDescr = UX_TEST_SETUP_GetCfgDescr;
367 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
368 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
369 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
370
371 /* Interaction define */
372
373 #ifndef ux_device_class_video_payload_write
ux_device_class_video_payload_write(UX_DEVICE_CLASS_VIDEO_STREAM * stream,UCHAR * payload,ULONG length)374 static UINT ux_device_class_video_payload_write(UX_DEVICE_CLASS_VIDEO_STREAM *stream, UCHAR *payload, ULONG length)
375 {
376
377 UX_SLAVE_ENDPOINT *endpoint;
378 UX_SLAVE_DEVICE *device;
379 UCHAR *next_payload_buffer;
380 ULONG payload_buffer_size;
381
382
383 /* Get the pointer to the device. */
384 device = &_ux_system_slave -> ux_system_slave_device;
385
386 /* As long as the device is in the CONFIGURED state. */
387 if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
388 {
389
390 /* Cannot proceed with command, the interface is down. */
391 return(UX_CONFIGURATION_HANDLE_UNKNOWN);
392 }
393
394 /* Check if endpoint is available. */
395 endpoint = stream -> ux_device_class_video_stream_endpoint;
396 if (endpoint == UX_NULL)
397 return(UX_ERROR);
398
399 /* Check if endpoint direction is OK (IN). */
400 if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT)
401 return(UX_ERROR);
402
403 /* Check payload length. */
404 payload_buffer_size = stream -> ux_device_class_video_stream_payload_buffer_size;
405 if ((payload_buffer_size - 4) < length)
406 return(UX_ERROR);
407
408 /* Check overflow!! */
409 if (stream -> ux_device_class_video_stream_access_pos == stream -> ux_device_class_video_stream_transfer_pos &&
410 stream -> ux_device_class_video_stream_access_pos -> ux_device_class_video_payload_length != 0)
411 return(UX_BUFFER_OVERFLOW);
412
413 /* Calculate next payload buffer. */
414 next_payload_buffer = (UCHAR *)stream -> ux_device_class_video_stream_access_pos;
415 next_payload_buffer += payload_buffer_size;
416 if (next_payload_buffer >= stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
417 next_payload_buffer = stream -> ux_device_class_video_stream_buffer;
418
419 /* Copy payload. */
420 _ux_utility_memory_copy(stream -> ux_device_class_video_stream_access_pos -> ux_device_class_video_payload_data, payload, length); /* Use case of memcpy is verified. */
421 stream -> ux_device_class_video_stream_access_pos -> ux_device_class_video_payload_length = length;
422
423 /* Move payload position. */
424 stream -> ux_device_class_video_stream_access_pos = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)next_payload_buffer;
425
426 return(UX_SUCCESS);
427 }
428 #endif
429
430 /* Hooks define */
431
ux_device_class_video_tx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)432 static VOID ux_device_class_video_tx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
433 {
434
435 UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *p = (UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *)params;
436 UX_SLAVE_TRANSFER *transfer = (UX_SLAVE_TRANSFER *)p -> parameter;
437 UCHAR tmp[32] = {'i','n','s','e','r','t','A',0};
438
439
440 (void)params;
441 // printf("%s:%d tTX\n", UX_TEST_FILE, __LINE__);
442
443 /* Acknowledge payload sent. */
444 if (test_tx_ack_count)
445 {
446 SAVE_BUFFER_LOG(transfer -> ux_slave_transfer_request_data_pointer, transfer -> ux_slave_transfer_request_requested_length);
447 transfer -> ux_slave_transfer_request_actual_length = transfer -> ux_slave_transfer_request_requested_length;
448 transfer -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
449 ux_test_dcd_sim_slave_transfer_done(transfer, UX_SUCCESS);
450 }
451 if (test_tx_ack_count != 0xFFFFFFFF && test_tx_ack_count > 0)
452 test_tx_ack_count --;
453
454 /* Insert payloads when sent. */
455 if (test_tx_ins_count)
456 {
457 tmp[6] = (test_tx_ins_count % 26) + 'A';
458 if (test_tx_ins_way == 0)
459 ux_device_class_video_payload_write(device_video_tx_stream, tmp, 32);
460 else
461 {
462
463 UCHAR *payload;
464 ULONG payload_length;
465
466
467 ux_device_class_video_write_payload_get(device_video_tx_stream, &payload, &payload_length);
468 _ux_utility_memory_copy(payload, tmp, 32);
469 ux_device_class_video_write_payload_commit(device_video_tx_stream, 32);
470 }
471 }
472 if (test_tx_ins_count != 0xFFFFFFFF && test_tx_ins_count > 0)
473 test_tx_ins_count --;
474 }
475
ux_device_class_video_rx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)476 static VOID ux_device_class_video_rx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
477 {
478
479 UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *p = (UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *)params;
480 UX_SLAVE_TRANSFER *transfer = (UX_SLAVE_TRANSFER *)p -> parameter;
481
482
483 (void)action;
484 (void)params;
485 (void)p;
486 (void)transfer;
487 // printf("tRX\n");
488 device_video_rx_transfer = transfer;
489 }
device_video_rx_simulate_one_payload(UCHAR * payload,ULONG payload_length)490 static VOID device_video_rx_simulate_one_payload(UCHAR *payload, ULONG payload_length)
491 {
492 UX_TEST_ASSERT(device_video_rx_transfer);
493 if (payload_length)
494 {
495 _ux_utility_memory_copy(device_video_rx_transfer->ux_slave_transfer_request_data_pointer, payload, payload_length);
496 device_video_rx_transfer->ux_slave_transfer_request_actual_length = payload_length;
497 device_video_rx_transfer->ux_slave_transfer_request_completion_code = UX_SUCCESS;
498 }
499 ux_test_dcd_sim_slave_transfer_done(device_video_rx_transfer, UX_SUCCESS);
500 _ux_utility_thread_sleep(1);
501 }
502
503 static UX_TEST_ACTION ux_device_class_video_transfer_hook[] =
504 {
505 {
506 .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
507 .function = UX_DCD_TRANSFER_REQUEST,
508 .action_func = ux_device_class_video_tx_hook,
509 .req_setup = UX_NULL,
510 .req_action = UX_TEST_MATCH_EP,
511 .req_ep_address = 0x81,
512 .do_after = UX_FALSE,
513 .no_return = UX_FALSE,
514 },
515 {
516 .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
517 .function = UX_DCD_TRANSFER_REQUEST,
518 .action_func = ux_device_class_video_rx_hook,
519 .req_setup = UX_NULL,
520 .req_action = UX_TEST_MATCH_EP,
521 .req_ep_address = 0x02,
522 .do_after = UX_FALSE,
523 .no_return = UX_FALSE,
524 },
525 { 0 },
526 };
527
528 /* Define the ISR dispatch. */
529
530 extern VOID (*test_isr_dispatch)(void);
531
532
533 /* Prototype for test control return. */
534
535 void test_control_return(UINT status);
536
error_callback(UINT system_level,UINT system_context,UINT error_code)537 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
538 {
539
540 error_callback_counter ++;
541 // printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
542
543 if (!error_callback_ignore)
544 {
545 {
546 /* Failed test. */
547 test_control_return(1);
548 }
549 }
550 }
551
sleep_break_on_error(VOID)552 static UINT sleep_break_on_error(VOID)
553 {
554
555 if (error_callback_counter >= 3)
556 return error_callback_counter;
557
558 return UX_SUCCESS;
559 }
560
561 /* Define the ISR dispatch routine. */
562
test_isr(void)563 static void test_isr(void)
564 {
565
566 /* For further expansion of interrupt-level testing. */
567 }
568
device_video_activate(VOID * video_instance)569 static VOID device_video_activate(VOID *video_instance)
570 {
571 device_video = (UX_DEVICE_CLASS_VIDEO *)video_instance;
572 ux_device_class_video_stream_get(device_video, 0, &device_video_tx_stream);
573 ux_device_class_video_stream_get(device_video, 1, &device_video_rx_stream);
574 // printf("sVID:%p,%p,%p\n", video_instance, device_video_tx_stream, device_video_rx_stream);
575 }
device_video_deactivate(VOID * video_instance)576 static VOID device_video_deactivate(VOID *video_instance)
577 {
578 if ((VOID *)device_video == video_instance)
579 {
580 device_video = UX_NULL;
581 device_video_tx_stream = UX_NULL;
582 device_video_rx_stream = UX_NULL;
583 }
584 }
device_video_tx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG alt)585 static VOID device_video_tx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG alt)
586 {
587 SAVE_CALLBACK_INVOKE_LOG(device_video_tx_stream_change, video, (ALIGN_TYPE)alt, 0);
588 }
device_video_rx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG alt)589 static VOID device_video_rx_stream_change(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG alt)
590 {
591 SAVE_CALLBACK_INVOKE_LOG(device_video_rx_stream_change, video, (ALIGN_TYPE)alt, 0);
592
593 device_video_rx_transfer = UX_NULL;
594 }
device_video_vc_control_process(UX_DEVICE_CLASS_VIDEO * video,UX_SLAVE_TRANSFER * transfer)595 static UINT device_video_vc_control_process(UX_DEVICE_CLASS_VIDEO *video, UX_SLAVE_TRANSFER *transfer)
596 {
597 SAVE_CALLBACK_INVOKE_LOG(device_video_vc_control_process, video, transfer, 0);
598 return(UX_ERROR);
599 }
device_video_vs_control_process(UX_DEVICE_CLASS_VIDEO_STREAM * video,UX_SLAVE_TRANSFER * transfer)600 static UINT device_video_vs_control_process(UX_DEVICE_CLASS_VIDEO_STREAM *video, UX_SLAVE_TRANSFER *transfer)
601 {
602 SAVE_CALLBACK_INVOKE_LOG(device_video_vs_control_process, video, transfer, 0);
603 return(UX_ERROR);
604 }
device_video_tx_done(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG length)605 static VOID device_video_tx_done(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG length)
606 {
607 SAVE_CALLBACK_INVOKE_LOG(device_video_tx_done, video, (ALIGN_TYPE)length, 0);
608 }
device_video_rx_done(UX_DEVICE_CLASS_VIDEO_STREAM * video,ULONG length)609 static VOID device_video_rx_done(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG length)
610 {
611 SAVE_CALLBACK_INVOKE_LOG(device_video_rx_done, video, (ALIGN_TYPE)length, 0);
612 }
613
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)614 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
615 {
616
617 UX_HOST_CLASS_DUMMY *dummy = (UX_HOST_CLASS_DUMMY *) inst;
618
619
620 switch(event)
621 {
622
623 case UX_DEVICE_INSERTION:
624
625 // printf("hINS:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
626 switch(dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber)
627 {
628 case 0: dummy_control = dummy; break;
629 case 1: dummy_rx = dummy; break;
630 case 2: dummy_tx = dummy; break;
631 }
632 break;
633
634 case UX_DEVICE_REMOVAL:
635
636 // printf("hRMV:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
637 switch(dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber)
638 {
639 case 0: dummy_control = UX_NULL; break;
640 case 1: dummy_rx = UX_NULL; break;
641 case 2: dummy_tx = UX_NULL; break;
642 }
643 break;
644
645 default:
646 break;
647 }
648 return 0;
649 }
650
651
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)652 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
653 {
654
655 set_cfg_counter ++;
656
657 rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
658 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
659 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
660 }
661
662
663 /* Define what the initial system looks like. */
664
665 #ifdef CTEST
test_application_define(void * first_unused_memory)666 void test_application_define(void *first_unused_memory)
667 #else
668 void usbx_ux_device_video_basic_test_application_define(void *first_unused_memory)
669 #endif
670 {
671
672 UINT status;
673 CHAR * stack_pointer;
674 CHAR * memory_pointer;
675
676
677 /* Inform user. */
678 printf("Running Video Device Basic Functionality Test....................... ");
679
680 #if !UX_TEST_MULTI_IFC_ON || !UX_TEST_MULTI_ALT_ON || !UX_TEST_MULTI_CLS_ON || \
681 (_CONFIGURE_DESCRIPTORS_LEN > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)
682 #warning Tests skipped due to compile option!
683 printf("SKIP SUCCESS!\n");
684 test_control_return(0);
685 return;
686 #endif
687
688 stepinfo("\n");
689
690 /* Reset testing counts. */
691 ux_test_utility_sim_mutex_create_count_reset();
692 ux_test_utility_sim_sem_create_count_reset();
693 ux_test_utility_sim_sem_get_count_reset();
694 /* Reset error generations */
695 ux_test_utility_sim_sem_error_generation_stop();
696 ux_test_utility_sim_mutex_error_generation_stop();
697 ux_test_utility_sim_sem_get_error_generation_stop();
698
699 /* Initialize the free memory pointer */
700 stack_pointer = (CHAR *) usbx_memory;
701 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
702
703 /* Initialize USBX Memory */
704 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
705 UX_TEST_CHECK_SUCCESS(status);
706
707 /* Register the error callback. */
708 _ux_utility_error_callback_register(error_callback);
709
710 /* The code below is required for installing the host portion of USBX */
711 status = ux_host_stack_initialize(test_host_change_function);
712 UX_TEST_CHECK_SUCCESS(status);
713
714 /* Register Audio class. */
715 status = ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_entry);
716 UX_TEST_CHECK_SUCCESS(status);
717
718 /* The code below is required for installing the device portion of USBX. No call back for
719 device status change in this example. */
720 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
721 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
722 string_framework, STRING_FRAMEWORK_LENGTH,
723 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
724 UX_TEST_CHECK_SUCCESS(status);
725
726 /* Set the parameters for callback when insertion/extraction of a Video device, with IAD. */
727 #if defined(UX_DEVICE_STANDALONE)
728 device_video_stream_parameter[0].ux_device_class_video_stream_parameter_task_function = ux_device_class_video_write_task_function;
729 #else
730 device_video_stream_parameter[0].ux_device_class_video_stream_parameter_thread_entry = ux_device_class_video_write_thread_entry;
731 #endif
732 device_video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_change = device_video_tx_stream_change;
733 device_video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_payload_done = device_video_tx_done;
734 device_video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_request = device_video_vs_control_process;
735 device_video_stream_parameter[0].ux_device_class_video_stream_parameter_max_payload_buffer_size = UX_DEMO_ENDPOINT_SIZE;
736 device_video_stream_parameter[0].ux_device_class_video_stream_parameter_max_payload_buffer_nb = 8;
737 #if defined(UX_DEVICE_STANDALONE)
738 device_video_stream_parameter[1].ux_device_class_video_stream_parameter_task_function = ux_device_class_video_read_task_function;
739 #else
740 device_video_stream_parameter[1].ux_device_class_video_stream_parameter_thread_entry = ux_device_class_video_read_thread_entry;
741 #endif
742 device_video_stream_parameter[1].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_change = device_video_rx_stream_change;
743 device_video_stream_parameter[1].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_payload_done = device_video_rx_done;
744 device_video_stream_parameter[1].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_request = device_video_vs_control_process;
745 device_video_stream_parameter[1].ux_device_class_video_stream_parameter_max_payload_buffer_size = UX_DEMO_ENDPOINT_SIZE;
746 device_video_stream_parameter[1].ux_device_class_video_stream_parameter_max_payload_buffer_nb = 8;
747 device_video_parameter.ux_device_class_video_parameter_streams = device_video_stream_parameter;
748 device_video_parameter.ux_device_class_video_parameter_streams_nb = 2;
749 device_video_parameter.ux_device_class_video_parameter_callbacks.ux_slave_class_video_instance_activate = device_video_activate;
750 device_video_parameter.ux_device_class_video_parameter_callbacks.ux_slave_class_video_instance_deactivate = device_video_deactivate;
751 device_video_parameter.ux_device_class_video_parameter_callbacks.ux_device_class_video_request = device_video_vc_control_process;
752 device_video_parameter.ux_device_class_video_parameter_callbacks.ux_device_class_video_arg = UX_NULL;
753
754 #if 0
755 printf("Memory requirement UX_DEVICE_CLASS_:\n");
756 printf(" per _VIDEO: %d bytes\n", sizeof(UX_DEVICE_CLASS_VIDEO));
757 printf(" per _VIDEO_STREAM: %d bytes\n", sizeof(UX_DEVICE_CLASS_VIDEO_STREAM));
758 printf(" per _VIDEO_CONTROL: %d bytes\n", sizeof(UX_DEVICE_CLASS_VIDEO_CONTROL));
759 printf("Dynamic memory allocation:\n");
760 temp = (device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_size+8) *
761 device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_nb;
762 printf(" per _payload_buffer_size: (%ld + 8) * %ld = %ld\n",
763 device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_size,
764 device_video_tx_stream_parameter.ux_device_class_video_stream_parameter_max_payload_buffer_nb,
765 temp);
766 temp += sizeof(UX_DEVICE_CLASS_VIDEO_STREAM);
767 printf(" per _stream: _VIDEO_STREAM + _payload_buffer_size = %ld\n", temp);
768 temp += sizeof(UX_DEVICE_CLASS_VIDEO);
769 temp *= 2;
770 printf(" per _video: (_VIDEO + _stream * 1 + _CONTROL * 0) * 2 = %ld\n", temp);
771 #endif
772
773 /* Initialize the device Audio class. This class owns interfaces starting with 1, 2. */
774 status = ux_device_stack_class_register(_ux_system_device_class_video_name, ux_device_class_video_entry,
775 1, 0, &device_video_parameter);
776 UX_TEST_CHECK_SUCCESS(status);
777
778 /* Initialize the simulated device controller. */
779 status = _ux_test_dcd_sim_slave_initialize();
780 UX_TEST_CHECK_SUCCESS(status);
781
782 /* Register all the USB host controllers available in this system */
783 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
784 UX_TEST_CHECK_SUCCESS(status);
785
786 /* Create the main host simulation thread. */
787 status = tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
788 stack_pointer, UX_DEMO_STACK_SIZE,
789 20, 20, 1, TX_AUTO_START);
790 UX_TEST_CHECK_SUCCESS(status);
791
792 /* Create the main slave simulation thread. */
793 status = tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
794 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
795 20, 20, 1, TX_AUTO_START);
796 UX_TEST_CHECK_SUCCESS(status);
797 }
798
test_wait_until_expected(VOID ** ptr,ULONG loop,VOID * expected)799 static UINT test_wait_until_expected(VOID **ptr, ULONG loop, VOID *expected)
800 {
801 while(loop)
802 {
803 _ux_utility_delay_ms(10);
804 if (*ptr == expected)
805 return UX_SUCCESS;
806 }
807 return UX_ERROR;
808 }
test_wait_until_not_expected(VOID ** ptr,ULONG loop,VOID * expected)809 static UINT test_wait_until_not_expected(VOID **ptr, ULONG loop, VOID *expected)
810 {
811 while(loop)
812 {
813 _ux_utility_delay_ms(10);
814 if (*ptr != expected)
815 return UX_SUCCESS;
816 }
817 return UX_ERROR;
818 }
819 #define test_wait_until_not_null(ptr, loop) test_wait_until_not_expected(ptr, loop, UX_NULL)
820 #define test_wait_until_null(ptr, loop) test_wait_until_expected(ptr, loop, UX_NULL)
821
tx_test_thread_host_simulation_entry(ULONG arg)822 void tx_test_thread_host_simulation_entry(ULONG arg)
823 {
824
825 UINT status;
826 ULONG test_n;
827 // ULONG mem_free;
828 UX_DEVICE *device;
829 UX_CONFIGURATION *configuration;
830 UX_INTERFACE *interface;
831 UX_INTERFACE *interface_inst[3][2];
832 // UX_ENDPOINT *control_endpoint;
833 // UX_TRANSFER *transfer_request;
834 UCHAR test_cmp[32];
835 ULONG temp;
836 UCHAR *temp_buf;
837
838
839 /* Test connect. */
840 status = test_wait_until_not_null((void**)&dummy_control, 100);
841 status |= test_wait_until_not_null((void**)&dummy_tx, 100);
842 status |= test_wait_until_not_null((void**)&dummy_rx, 100);
843 status |= test_wait_until_not_null((void**)&device_video, 100);
844 status |= test_wait_until_not_null((void**)&device_video_rx_stream, 100);
845 status |= test_wait_until_not_null((void**)&device_video_tx_stream, 100);
846 UX_TEST_CHECK_SUCCESS(status);
847
848 // /* Test disconnect. */
849 // ux_test_dcd_sim_slave_disconnect();
850 // ux_test_hcd_sim_host_disconnect();
851
852 // /* Reset testing counts. */
853 // ux_test_utility_sim_mutex_create_count_reset();
854 // ux_test_utility_sim_sem_create_count_reset();
855 // ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
856 // /* Save free memory usage. */
857 // mem_free = _ux_system->ux_system_regular_memory_pool_free;
858 // ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
859 // ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
860 // tx_thread_sleep(100);
861 // /* Log create counts for further tests. */
862 // rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
863 // rsc_enum_sem_usage = rsc_sem_on_set_cfg;
864 // rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
865 // /* Log create counts when instances active for further tests. */
866 // rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
867 // rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
868 // rsc_cdc_mem_usage = rsc_mem_free_on_set_cfg - _ux_system->ux_system_regular_memory_pool_free;
869 // stepinfo("mem free: %ld\n", _ux_system->ux_system_regular_memory_pool_free);
870
871 /* Validate configuration descriptors. */
872 /* ... */
873
874 /* Get testing instances. */
875
876 status = ux_host_stack_device_get(0, &device);
877 UX_TEST_CHECK_SUCCESS(status);
878
879 // control_endpoint = &device->ux_device_control_endpoint;
880 // transfer_request = &control_endpoint->ux_endpoint_transfer_request;
881
882 status = ux_host_stack_device_configuration_get(device, 0, &configuration);
883 UX_TEST_CHECK_SUCCESS(status);
884
885 interface = configuration -> ux_configuration_first_interface;
886 while(interface)
887 {
888 // printf("Interface: %ld.%ld\n", interface -> ux_interface_descriptor.bInterfaceNumber, interface -> ux_interface_descriptor.bAlternateSetting);
889 interface_inst[interface -> ux_interface_descriptor.bInterfaceNumber][interface -> ux_interface_descriptor.bAlternateSetting] = interface;
890 interface = interface -> ux_interface_next_interface;
891 }
892
893 /* Test interface change. */
894 /* Reset log. */
895 RESET_CALLBACK_INVOKE_LOG();
896 status = ux_host_stack_interface_setting_select(interface_inst[1][1]);
897 status |= ux_host_stack_interface_setting_select(interface_inst[1][0]);
898 status |= ux_host_stack_interface_setting_select(interface_inst[1][1]);
899
900 UX_TEST_CHECK_SUCCESS(status);
901 UX_TEST_ASSERT(callback_invoke_count == 3);
902 UX_TEST_ASSERT(callback_invoke_log[0].func == device_video_tx_stream_change);
903 UX_TEST_ASSERT(callback_invoke_log[0].param1 == device_video_tx_stream);
904 UX_TEST_ASSERT(callback_invoke_log[0].param2 == (VOID*)1);
905 UX_TEST_ASSERT(callback_invoke_log[1].func == device_video_tx_stream_change);
906 UX_TEST_ASSERT(callback_invoke_log[1].param1 == device_video_tx_stream);
907 UX_TEST_ASSERT(callback_invoke_log[1].param2 == 0);
908
909 RESET_CALLBACK_INVOKE_LOG();
910 status = ux_host_stack_interface_setting_select(interface_inst[2][1]);
911 status |= ux_host_stack_interface_setting_select(interface_inst[2][0]);
912 status |= ux_host_stack_interface_setting_select(interface_inst[2][1]);
913
914 UX_TEST_CHECK_SUCCESS(status);
915 UX_TEST_ASSERT(callback_invoke_count == 3);
916 UX_TEST_ASSERT(callback_invoke_log[0].func == device_video_rx_stream_change);
917 UX_TEST_ASSERT(callback_invoke_log[0].param1 == device_video_rx_stream);
918 UX_TEST_ASSERT(callback_invoke_log[0].param2 == (VOID*)1);
919 UX_TEST_ASSERT(callback_invoke_log[1].func == device_video_rx_stream_change);
920 UX_TEST_ASSERT(callback_invoke_log[1].param1 == device_video_rx_stream);
921 UX_TEST_ASSERT(callback_invoke_log[1].param2 == 0);
922
923 /* Test data streaming. */
924
925 /* Wrong interface! */
926 status = ux_device_class_video_transmission_start(device_video_rx_stream);
927 status |= ux_device_class_video_reception_start(device_video_tx_stream);
928 UX_TEST_CHECK_NOT_SUCCESS(status);
929
930 ux_test_link_hooks_from_array(ux_device_class_video_transfer_hook);
931
932 /* ------------------ Write test. */
933
934 status = ux_device_class_video_payload_write(device_video_tx_stream, "test0", 16);
935 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test1", 16);
936 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test2", 16);
937 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test3", 16);
938 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test4", 16);
939 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test5", 16);
940 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test6", 16);
941 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test7", 16);
942 UX_TEST_CHECK_SUCCESS(status);
943
944 error_callback_counter = 0;
945 status = ux_device_class_video_payload_write(device_video_tx_stream, "test8", 16);
946 UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, status);
947
948 /*
949 Keep sending until under-run.
950 No buffer appended while running.
951 */
952
953 buffer_log_count = 0;
954 test_tx_ack_count = 10;
955 status = ux_device_class_video_transmission_start(device_video_tx_stream);
956 UX_TEST_CHECK_SUCCESS(status);
957
958 /* Delay to let thread runs. */
959 _ux_utility_delay_ms(100);
960
961 /* Prepare data for checking. */
962 _ux_utility_memory_set(test_cmp, 0, 16);
963 _ux_utility_memory_copy(test_cmp, "test", 4);
964
965 /* 8 frame should be available. */
966 for (test_n = 0; test_n < 8; test_n ++)
967 {
968 // printf("%ld: %ld: %s\n", test_n, buffer_log[test_n].length, buffer_log[test_n].data);
969 test_cmp[4] = (UCHAR)(test_n + '0');
970
971 UX_TEST_ASSERT(buffer_log[test_n].length == 16);
972
973 status = _ux_utility_memory_compare(buffer_log[test_n].data, test_cmp, 6);
974 UX_TEST_CHECK_SUCCESS(status);
975 }
976 /* Then under-run, 0 length packets. */
977 for(;test_n < buffer_log_count; test_n ++)
978 {
979 // printf("%ld: %ld\n", test_n, buffer_log[test_n].length);
980 UX_TEST_ASSERT(buffer_log[test_n].length == 0);
981 }
982
983 /*
984 Keep sending until under-run.
985 Specific number of buffer appended while running.
986 */
987
988 for (test_tx_ins_way = 0; test_tx_ins_way < 2; test_tx_ins_way ++)
989 {
990
991 /* Switch interface to clean up status. */
992 status = ux_host_stack_interface_setting_select(interface_inst[1][0]);
993 status |= ux_host_stack_interface_setting_select(interface_inst[1][1]);
994
995 status = ux_device_class_video_payload_write(device_video_tx_stream, "test0", 20);
996 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test1", 20);
997 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test2", 20);
998 status |= ux_device_class_video_payload_write(device_video_tx_stream, "test3", 20);
999 UX_TEST_CHECK_SUCCESS(status);
1000
1001 test_tx_ins_count = 10;
1002 test_tx_ack_count = 20;
1003 buffer_log_count = 0;
1004 status = ux_device_class_video_transmission_start(device_video_tx_stream);
1005 UX_TEST_CHECK_SUCCESS(status);
1006
1007 /* Delay to let thread runs. */
1008 _ux_utility_delay_ms(300);
1009
1010 /* Prepare data for checking. */
1011 _ux_utility_memory_set(test_cmp, 0, 32);
1012
1013 /* 4 frame should be available. */
1014 _ux_utility_memory_copy(test_cmp, "test", 4);
1015 for (test_n = 0; test_n < 4; test_n ++)
1016 {
1017 // printf("%ld: %ld: %s\n", test_n, buffer_log[test_n].length, buffer_log[test_n].data);
1018 test_cmp[4] = (UCHAR)(test_n + '0');
1019
1020 UX_TEST_ASSERT(buffer_log[test_n].length == 20);
1021
1022 status = _ux_utility_memory_compare(buffer_log[test_n].data, test_cmp, 6);
1023 UX_TEST_CHECK_SUCCESS(status);
1024 }
1025 /* 10 more frame should be available. */
1026 _ux_utility_memory_copy(test_cmp, "insert", 6);
1027 for (; test_n < 14; test_n ++)
1028 {
1029 // printf("%ld: %ld: %s\n", test_n, buffer_log[test_n].length, buffer_log[test_n].data);
1030 test_cmp[6] = (UCHAR)(((10 - (test_n - 4)) % 26) + 'A');
1031
1032 UX_TEST_ASSERT(buffer_log[test_n].length == 32);
1033
1034 status = _ux_utility_memory_compare(buffer_log[test_n].data, test_cmp, 8);
1035 UX_TEST_CHECK_SUCCESS(status);
1036 }
1037 /* Then under-run, 0 length packets. */
1038 for(;test_n < buffer_log_count; test_n ++)
1039 {
1040 // printf("%ld: %ld\n", test_n, buffer_log[test_n].length);
1041 UX_TEST_ASSERT(buffer_log[test_n].length == 0);
1042 }
1043 }
1044
1045 UX_TEST_ASSERT(device_video_tx_stream->ux_device_class_video_stream_transfer_pos == device_video_tx_stream->ux_device_class_video_stream_access_pos);
1046
1047
1048 /* ------------------ Read test. */
1049
1050 UX_TEST_ASSERT(device_video_rx_transfer == UX_NULL);
1051
1052 temp = 0;
1053 status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1054 UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, status);
1055
1056 status = ux_device_class_video_reception_start(device_video_rx_stream);
1057 UX_TEST_CHECK_SUCCESS(status);
1058 _ux_utility_thread_sleep(1);
1059
1060 UX_TEST_ASSERT(device_video_rx_transfer != UX_NULL);
1061
1062 status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1063 UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, status);
1064
1065 RESET_CALLBACK_INVOKE_LOG();
1066
1067 device_video_rx_simulate_one_payload("012345", 6);
1068 status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1069 UX_TEST_CHECK_SUCCESS(status);
1070 for (test_n = 0; test_n < 6; test_n ++)
1071 {
1072 UX_TEST_ASSERT(temp_buf[test_n] == (test_n + '0'));
1073 }
1074 ux_device_class_video_read_payload_free(device_video_rx_stream);
1075
1076 device_video_rx_simulate_one_payload("012345", 6);
1077 device_video_rx_simulate_one_payload("67", 2);
1078 device_video_rx_simulate_one_payload("89", 2);
1079
1080 status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1081 UX_TEST_CHECK_SUCCESS(status);
1082 UX_TEST_ASSERT(temp == 6);
1083 for (test_n = 0; test_n < 6; test_n ++)
1084 {
1085 UX_TEST_ASSERT(temp_buf[test_n] == (test_n + '0'));
1086 }
1087 ux_device_class_video_read_payload_free(device_video_rx_stream);
1088 status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1089 UX_TEST_CHECK_SUCCESS(status);
1090 UX_TEST_ASSERT(temp == 2);
1091 for (; test_n < 8; test_n ++)
1092 {
1093 UX_TEST_ASSERT(temp_buf[test_n-6] == (test_n + '0'));
1094 }
1095 ux_device_class_video_read_payload_free(device_video_rx_stream);
1096 status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1097 UX_TEST_CHECK_SUCCESS(status);
1098 UX_TEST_ASSERT(temp == 2);
1099 for (; test_n < 10; test_n ++)
1100 {
1101 UX_TEST_ASSERT(temp_buf[test_n-8] == (test_n + '0'));
1102 }
1103 ux_device_class_video_read_payload_free(device_video_rx_stream);
1104
1105 UX_TEST_ASSERT(callback_invoke_count == 4);
1106 UX_TEST_ASSERT(callback_invoke_log[0].func == device_video_rx_done);
1107 UX_TEST_ASSERT(callback_invoke_log[0].param1 == device_video_rx_stream);
1108 UX_TEST_ASSERT(callback_invoke_log[1].func == device_video_rx_done);
1109 UX_TEST_ASSERT(callback_invoke_log[1].param1 == device_video_rx_stream);
1110 UX_TEST_ASSERT(callback_invoke_log[2].func == device_video_rx_done);
1111 UX_TEST_ASSERT(callback_invoke_log[2].param1 == device_video_rx_stream);
1112 UX_TEST_ASSERT(callback_invoke_log[3].func == device_video_rx_done);
1113 UX_TEST_ASSERT(callback_invoke_log[3].param1 == device_video_rx_stream);
1114
1115 RESET_CALLBACK_INVOKE_LOG();
1116 error_callback_counter = 0;
1117 for (test_n = 0; test_n < 10; test_n ++)
1118 {
1119 test_cmp[0] = (UCHAR)(test_n + '0');
1120 device_video_rx_simulate_one_payload(test_cmp, 1);
1121 }
1122
1123 UX_TEST_ASSERT(callback_invoke_count == 10);
1124 UX_TEST_ASSERT(error_callback_counter == 3);
1125 for (test_n = 0; test_n < 7; test_n ++)
1126 {
1127 status = ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp);
1128 UX_TEST_CHECK_SUCCESS(status);
1129 UX_TEST_ASSERT(temp == 1);
1130 UX_TEST_ASSERT(temp_buf[0] == (test_n + '0'));
1131 ux_device_class_video_read_payload_free(device_video_rx_stream);
1132 }
1133 UX_TEST_CHECK_SUCCESS(ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp));
1134 UX_TEST_ASSERT(temp == 1);
1135 UX_TEST_ASSERT(temp_buf[0] == '9');
1136 ux_device_class_video_read_payload_free(device_video_rx_stream);
1137 UX_TEST_CHECK_CODE(UX_BUFFER_OVERFLOW, ux_device_class_video_read_payload_get(device_video_rx_stream, &temp_buf, &temp));
1138
1139
1140 /* Wait pending threads. */
1141 _ux_utility_thread_sleep(1);
1142
1143 /* Finally disconnect the device. */
1144 ux_device_stack_disconnect();
1145
1146 /* And deinitialize the class. */
1147 ux_device_stack_class_unregister(_ux_system_device_class_video_name, ux_device_class_video_entry);
1148
1149 /* Deinitialize the device side of usbx. */
1150 _ux_device_stack_uninitialize();
1151
1152 /* And finally the usbx system resources. */
1153 _ux_system_uninitialize();
1154
1155 /* Successful test. */
1156 printf("SUCCESS!\n");
1157 test_control_return(0);
1158
1159 }
1160
1161
1162
tx_test_thread_slave_simulation_entry(ULONG arg)1163 void tx_test_thread_slave_simulation_entry(ULONG arg)
1164 {
1165 while(1)
1166 {
1167
1168 #if defined(UX_DEVICE_STANDALONE)
1169
1170 /* Standalone background task. */
1171 ux_system_tasks_run();
1172 #else
1173
1174 /* Sleep so ThreadX on Win32 will delete this thread. */
1175 tx_thread_sleep(10);
1176 #endif
1177 }
1178 }
1179