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 #include "ux_hcd_sim_host.h"
9
10 #include "fx_api.h"
11
12 #include "ux_device_class_audio.h"
13 #include "ux_device_class_audio10.h"
14 #include "ux_device_stack.h"
15
16 #include "ux_host_class_audio.h"
17 #include "ux_host_class_dummy.h"
18
19 #include "ux_test_dcd_sim_slave.h"
20 #include "ux_test_hcd_sim_host.h"
21 #include "ux_test_utility_sim.h"
22
23
24 /* Define constants. */
25
26 #define UX_DEMO_REQUEST_MAX_LENGTH \
27 ((UX_HCD_SIM_HOST_MAX_PAYLOAD) > (UX_SLAVE_REQUEST_DATA_MAX_LENGTH) ? \
28 (UX_HCD_SIM_HOST_MAX_PAYLOAD) : (UX_SLAVE_REQUEST_DATA_MAX_LENGTH))
29
30 #define UX_DEMO_DEBUG_SIZE (4096*8)
31 #define UX_DEMO_STACK_SIZE 1024
32 #define UX_DEMO_BUFFER_SIZE (UX_DEMO_REQUEST_MAX_LENGTH + 1)
33 #define UX_DEMO_MEMORY_SIZE (128*1024)
34
35 #define UX_TEST_LOG_SIZE (64)
36
37 #define UX_TEST_STATUS_QUEUE_MAX_SIZE 8
38
39
40 /* Define local/extern function prototypes. */
41 static void test_thread_entry(ULONG);
42 static TX_THREAD tx_test_thread_host_simulation;
43 static TX_THREAD tx_test_thread_slave_simulation;
44 static void tx_test_thread_host_simulation_entry(ULONG);
45 static void tx_test_thread_slave_simulation_entry(ULONG);
46
47
48 /* Define global data structures. */
49 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
50 static UCHAR buffer[64];
51
52 static UX_HOST_CLASS_DUMMY *dummy_control;
53 static UX_HOST_CLASS_DUMMY *dummy_tx;
54 static UX_HOST_CLASS_DUMMY *dummy_rx;
55
56 static UX_DEVICE_CLASS_AUDIO *slave_audio;
57 static UX_DEVICE_CLASS_AUDIO_PARAMETER slave_audio_parameter;
58 static UX_DEVICE_CLASS_AUDIO_STREAM_PARAMETER slave_audio_stream_parameter[2];
59
60 static UX_DEVICE_CLASS_AUDIO_STREAM *slave_audio_tx_stream;
61
62 static UX_DEVICE_CLASS_AUDIO_STREAM *slave_audio_rx_stream;
63 static UX_SLAVE_TRANSFER *slave_audio_rx_transfer;
64
65 static UX_HOST_CLASS_AUDIO *audio;
66
67 static UX_DEVICE_CLASS_AUDIO10_CONTROL g_slave_audio10_control[2];
68
69 static ULONG error_counter;
70
71 static ULONG set_cfg_counter;
72
73 static ULONG rsc_mem_free_on_set_cfg;
74 static ULONG rsc_sem_on_set_cfg;
75 static ULONG rsc_sem_get_on_set_cfg;
76 static ULONG rsc_mutex_on_set_cfg;
77
78 static ULONG rsc_enum_sem_usage;
79 static ULONG rsc_enum_sem_get_count;
80 static ULONG rsc_enum_mutex_usage;
81 static ULONG rsc_enum_mem_usage;
82
83 static ULONG rsc_audio_sem_usage;
84 static ULONG rsc_audio_sem_get_count;
85 static ULONG rsc_audio_mutex_usage;
86 static ULONG rsc_audio_mem_usage;
87
88 static ULONG interaction_count;
89
90 static UCHAR error_callback_ignore = UX_TRUE;
91 static ULONG error_callback_counter;
92
93 static struct BUFFER_LOG_STRUCT {
94 ULONG length;
95 UCHAR data[256];
96 } buffer_log[UX_TEST_LOG_SIZE];
97 static ULONG buffer_log_count = 0;
98 #define SAVE_BUFFER_LOG(buf,siz) do { \
99 if (buffer_log_count < UX_TEST_LOG_SIZE) { \
100 ULONG __local_size__ = ((siz) > 256) ? 256 : (siz); \
101 buffer_log[buffer_log_count].length = (siz); \
102 _ux_utility_memory_copy(buffer_log[buffer_log_count].data, (buf), __local_size__); \
103 } \
104 buffer_log_count ++; \
105 } while(0)
106
107 static ULONG test_tx_ack_count = 0xFFFFFFFF;
108 static ULONG test_tx_ins_count = 0;
109 static ULONG test_tx_ins_way = 0;
110
111 static struct CALLBACK_INVOKE_LOG_STRUCT {
112 VOID *func;
113 VOID *param1;
114 VOID *param2;
115 VOID *param3;
116 } callback_invoke_log[UX_TEST_LOG_SIZE];
117 static ULONG callback_invoke_count = 0;
118
119 #define SAVE_CALLBACK_INVOKE_LOG(f,p1,p2,p3) do { \
120 if (callback_invoke_count < UX_TEST_LOG_SIZE) { \
121 callback_invoke_log[callback_invoke_count].func = (VOID *)(f); \
122 callback_invoke_log[callback_invoke_count].param1 = (VOID *)(p1); \
123 callback_invoke_log[callback_invoke_count].param2 = (VOID *)(p2); \
124 callback_invoke_log[callback_invoke_count].param3 = (VOID *)(p3); \
125 callback_invoke_count++; \
126 } \
127 } while(0)
128 #define RESET_CALLBACK_INVOKE_LOG() do { \
129 callback_invoke_count = 0; \
130 } while(0)
131
132 /* Define device framework. */
133
134 #define D3(d) ((UCHAR)((d) >> 24))
135 #define D2(d) ((UCHAR)((d) >> 16))
136 #define D1(d) ((UCHAR)((d) >> 8))
137 #define D0(d) ((UCHAR)((d) >> 0))
138
139 static unsigned char device_framework_full_speed[] = {
140
141 /* --------------------------------------- Device Descriptor */
142 /* 0 bLength, bDescriptorType */ 18, 0x01,
143 /* 2 bcdUSB */ D0(0x200),D1(0x200),
144 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00,
145 /* 7 bMaxPacketSize0 */ 0x08,
146 /* 8 idVendor, idProduct */ 0x84, 0x84, 0x01, 0x00,
147 /* 12 bcdDevice */ D0(0x100),D1(0x100),
148 /* 14 iManufacturer, iProduct, iSerialNumber */ 0, 0, 0,
149 /* 17 bNumConfigurations */ 1,
150
151 /* -------------------------------- Configuration Descriptor *//* 9+8+88+52*2=209 */
152 /* 0 bLength, bDescriptorType */ 9, 0x02,
153 /* 2 wTotalLength */ D0(209),D1(209),
154 /* 4 bNumInterfaces, bConfigurationValue */ 3, 1,
155 /* 6 iConfiguration */ 0,
156 /* 7 bmAttributes, bMaxPower */ 0x80, 50,
157
158 /* ------------------------ Interface Association Descriptor */
159 /* 0 bLength, bDescriptorType */ 8, 0x0B,
160 /* 2 bFirstInterface, bInterfaceCount */ 0, 3,
161 /* 4 bFunctionClass, bFunctionSubClass, bFunctionProtocol */ 0x01, 0x01, 0x00,
162 /* 7 iFunction */ 0,
163
164 /* ------------------------------------ Interface Descriptor *//* 0 Control (9+72+7=88) */
165 /* 0 bLength, bDescriptorType */ 9, 0x04,
166 /* 2 bInterfaceNumber, bAlternateSetting */ 0, 0,
167 /* 4 bNumEndpoints */ 1,
168 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x01, 0x00,
169 /* 8 iInterface */ 0,
170 /* ---------------- Audio 1.0 AC Interface Header Descriptor *//* (10+12*2+10*2+9*2=72) */
171 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 10, 0x24, 0x01,
172 /* 3 bcdADC */ 0x00, 0x01,
173 /* 5 wTotalLength, bInCollection */ D0(72),D1(72), 2,
174 /* 8 baInterfaceNr(1) ... baInterfaceNr(n) */ 1, 2,
175 /* ------------------- Audio 1.0 AC Input Terminal Descriptor */
176 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x02,
177 /* 3 bTerminalID, wTerminalType */ 0x01, D0(0x0201),D1(0x0201),
178 /* 6 bAssocTerminal, */ 0x00,
179 /* 7 bNrChannels, wChannelConfig */ 0x02, D0(0),D1(0),
180 /* 10 iChannelNames, iTerminal */ 0, 0,
181 /* --------------------- Audio 1.0 AC Feature Unit Descriptor */
182 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 10, 0x24, 0x06,
183 /* 3 bUnitID, bSourceID */ 0x02, 0x01,
184 /* 5 bControlSize */ 1,
185 /* 6 bmaControls(0) ... bmaControls(...) ... */ 0x00, 0x00, 0x00,
186 /* . iFeature */ 0,
187 /* ------------------ Audio 1.0 AC Output Terminal Descriptor */
188 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 9, 0x24, 0x03,
189 /* 3 bTerminalID, wTerminalType */ 0x03, D0(0x0101),D1(0x0101),
190 /* 6 bAssocTerminal, bSourceID */ 0x00, 0x02,
191 /* 8 iTerminal */ 0,
192 /* ------------------- Audio 1.0 AC Input Terminal Descriptor */
193 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x02,
194 /* 3 bTerminalID, wTerminalType */ 0x04, D0(0x0101),D1(0x0101),
195 /* 6 bAssocTerminal, */ 0x00,
196 /* 7 bNrChannels, wChannelConfig */ 0x02, D0(0),D1(0),
197 /* 10 iChannelNames, iTerminal */ 0, 0,
198 /* --------------------- Audio 1.0 AC Feature Unit Descriptor */
199 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 10, 0x24, 0x06,
200 /* 3 bUnitID, bSourceID */ 0x05, 0x04,
201 /* 5 bControlSize */ 1,
202 /* 6 bmaControls(0) ... bmaControls(...) ... */ 0x00, 0x00, 0x00,
203 /* . iFeature */ 0,
204 /* ------------------ Audio 1.0 AC Output Terminal Descriptor */
205 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 9, 0x24, 0x03,
206 /* 3 bTerminalID, wTerminalType */ 0x06, D0(0x0301),D1(0x0301),
207 /* 6 bAssocTerminal, bSourceID */ 0x00, 0x05,
208 /* 8 iTerminal */ 0,
209 /* --------------- Audio 1.0 AC Interrupt Endpoint Descriptor */
210 /* 0 bLength, bDescriptorType */ 7, 0x05,
211 /* 2 bEndpointAddress, bmAttributes */ 0x83, 0x03,
212 /* 4 wMaxPacketSize, bInterval */ D0(8),D1(8), 1,
213
214 /* ------------------------------------ Interface Descriptor *//* 1 Stream IN (9+9+7+11+9+7=52) */
215 /* 0 bLength, bDescriptorType */ 9, 0x04,
216 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 0,
217 /* 4 bNumEndpoints */ 0,
218 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
219 /* 8 iInterface */ 0,
220 /* ------------------------------------ Interface Descriptor */
221 /* 0 bLength, bDescriptorType */ 9, 0x04,
222 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 1,
223 /* 4 bNumEndpoints */ 1,
224 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
225 /* 8 iInterface */ 0,
226 /* ------------------------ Audio 1.0 AS Interface Descriptor */
227 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x24, 0x01,
228 /* 3 bTerminalLink */ 0x03,
229 /* 4 bDelay, wFormatTag */ 0x00, D0(0x0001),D1(0x0001),
230 /* -------------------------- Audio AS Format Type Descriptor */
231 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 11, 0x24, 0x02,
232 /* 3 bFormatType, bNrChannels, bSubframeSize, bBitResolution */ 0x01, 0x02, 0x02, 16,
233 /* 7 bSamFreqType (n), tSamFreq[1] ... tSamFreq[n] */ 1, D0(48000),D1(48000),D2(48000),
234 /* --------------------- Audio 1.0 AS ISO Endpoint Descriptor */
235 /* 0 bLength, bDescriptorType */ 9, 0x05,
236 /* 2 bEndpointAddress, bmAttributes */ 0x81, 0x01,
237 /* 4 wMaxPacketSize, bInterval, bRefresh, bSynchAddress */ D0(256),D1(256), 1, 0, 0,
238 /* ---------- Audio 1.0 AS ISO Audio Data Endpoint Descriptor */
239 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x25, 0x01,
240 /* 3 bmAttributes */ 0x00,
241 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
242
243 /* ------------------------------------ Interface Descriptor *//* 2 Stream OUT (9+9+7+11+9+7=52) */
244 /* 0 bLength, bDescriptorType */ 9, 0x04,
245 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 0,
246 /* 4 bNumEndpoints */ 0,
247 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
248 /* 8 iInterface */ 0,
249 /* ------------------------------------ Interface Descriptor */
250 /* 0 bLength, bDescriptorType */ 9, 0x04,
251 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 1,
252 /* 4 bNumEndpoints */ 1,
253 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
254 /* 8 iInterface */ 0,
255 /* ------------------------ Audio 1.0 AS Interface Descriptor */
256 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x24, 0x01,
257 /* 3 bTerminalLink */ 0x04,
258 /* 4 bDelay, wFormatTag */ 0x00, D0(0x0001),D1(0x0001),
259 /* -------------------------- Audio AS Format Type Descriptor */
260 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 11, 0x24, 0x02,
261 /* 3 bFormatType, bNrChannels, bSubframeSize, bBitResolution */ 0x01, 0x02, 0x02, 16,
262 /* 7 bSamFreqType (n), tSamFreq[1] ... tSamFreq[n] */ 1, D0(48000),D1(48000),D2(48000),
263 /* --------------------- Audio 1.0 AS ISO Endpoint Descriptor */
264 /* 0 bLength, bDescriptorType */ 9, 0x05,
265 /* 2 bEndpointAddress, bmAttributes */ 0x02, 0x01,
266 /* 4 wMaxPacketSize, bInterval, bRefresh, bSynchAddress */ D0(256),D1(256), 1, 0, 0,
267 /* ---------- Audio 1.0 AS ISO Audio Data Endpoint Descriptor */
268 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x25, 0x01,
269 /* 3 bmAttributes */ 0x00,
270 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
271 };
272 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
273
274 static unsigned char device_framework_high_speed[] = {
275 /* --------------------------------------- Device Descriptor */
276 /* 0 bLength, bDescriptorType */ 18, 0x01,
277 /* 2 bcdUSB */ D0(0x200),D1(0x200),
278 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00,
279 /* 7 bMaxPacketSize0 */ 8,
280 /* 8 idVendor, idProduct */ 0x84, 0x84, 0x01, 0x00,
281 /* 12 bcdDevice */ D0(0x100),D1(0x100),
282 /* 14 iManufacturer, iProduct, iSerialNumber */ 0, 0, 0,
283 /* 17 bNumConfigurations */ 1,
284
285 /* ----------------------------- Device Qualifier Descriptor */
286 /* 0 bLength, bDescriptorType */ 10, 0x06,
287 /* 2 bcdUSB */ D0(0x200),D1(0x200),
288 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00,
289 /* 7 bMaxPacketSize0 */ 8,
290 /* 8 bNumConfigurations */ 1,
291 /* 9 bReserved */ 0,
292
293 /* -------------------------------- Configuration Descriptor *//* 9+8+88+52*2=209 */
294 /* 0 bLength, bDescriptorType */ 9, 0x02,
295 /* 2 wTotalLength */ D0(209),D1(209),
296 /* 4 bNumInterfaces, bConfigurationValue */ 3, 1,
297 /* 6 iConfiguration */ 0,
298 /* 7 bmAttributes, bMaxPower */ 0x80, 50,
299
300 /* ------------------------ Interface Association Descriptor */
301 /* 0 bLength, bDescriptorType */ 8, 0x0B,
302 /* 2 bFirstInterface, bInterfaceCount */ 0, 3,
303 /* 4 bFunctionClass, bFunctionSubClass, bFunctionProtocol */ 0x01, 0x01, 0x00,
304 /* 7 iFunction */ 0,
305
306 /* ------------------------------------ Interface Descriptor *//* 0 Control (9+72+7=88) */
307 /* 0 bLength, bDescriptorType */ 9, 0x04,
308 /* 2 bInterfaceNumber, bAlternateSetting */ 0, 0,
309 /* 4 bNumEndpoints */ 1,
310 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x01, 0x00,
311 /* 8 iInterface */ 0,
312 /* ---------------- Audio 1.0 AC Interface Header Descriptor *//* (10+12*2+10*2+9*2=72) */
313 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 10, 0x24, 0x01,
314 /* 3 bcdADC */ 0x00, 0x01,
315 /* 5 wTotalLength, bInCollection */ D0(72),D1(72), 2,
316 /* 8 baInterfaceNr(1) ... baInterfaceNr(n) */ 1, 2,
317 /* ------------------- Audio 1.0 AC Input Terminal Descriptor */
318 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x02,
319 /* 3 bTerminalID, wTerminalType */ 0x01, D0(0x0201),D1(0x0201),
320 /* 6 bAssocTerminal, */ 0x00,
321 /* 7 bNrChannels, wChannelConfig */ 0x02, D0(0),D1(0),
322 /* 10 iChannelNames, iTerminal */ 0, 0,
323 /* --------------------- Audio 1.0 AC Feature Unit Descriptor */
324 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 10, 0x24, 0x06,
325 /* 3 bUnitID, bSourceID */ 0x02, 0x01,
326 /* 5 bControlSize */ 1,
327 /* 6 bmaControls(0) ... bmaControls(...) ... */ 0x00, 0x00, 0x00,
328 /* . iFeature */ 0,
329 /* ------------------ Audio 1.0 AC Output Terminal Descriptor */
330 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 9, 0x24, 0x03,
331 /* 3 bTerminalID, wTerminalType */ 0x03, D0(0x0101),D1(0x0101),
332 /* 6 bAssocTerminal, bSourceID */ 0x00, 0x02,
333 /* 8 iTerminal */ 0,
334 /* ------------------- Audio 1.0 AC Input Terminal Descriptor */
335 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x02,
336 /* 3 bTerminalID, wTerminalType */ 0x04, D0(0x0101),D1(0x0101),
337 /* 6 bAssocTerminal, */ 0x00,
338 /* 7 bNrChannels, wChannelConfig */ 0x02, D0(0),D1(0),
339 /* 10 iChannelNames, iTerminal */ 0, 0,
340 /* --------------------- Audio 1.0 AC Feature Unit Descriptor */
341 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 10, 0x24, 0x06,
342 /* 3 bUnitID, bSourceID */ 0x05, 0x04,
343 /* 5 bControlSize */ 1,
344 /* 6 bmaControls(0) ... bmaControls(...) ... */ 0x00, 0x00, 0x00,
345 /* . iFeature */ 0,
346 /* ------------------ Audio 1.0 AC Output Terminal Descriptor */
347 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 9, 0x24, 0x03,
348 /* 3 bTerminalID, wTerminalType */ 0x06, D0(0x0301),D1(0x0301),
349 /* 6 bAssocTerminal, bSourceID */ 0x00, 0x05,
350 /* 8 iTerminal */ 0,
351 /* --------------- Audio 1.0 AC Interrupt Endpoint Descriptor */
352 /* 0 bLength, bDescriptorType */ 7, 0x05,
353 /* 2 bEndpointAddress, bmAttributes */ 0x83, 0x03,
354 /* 4 wMaxPacketSize, bInterval */ D0(8),D1(8), 1,
355
356 /* ------------------------------------ Interface Descriptor *//* 1 Stream IN (9+9+7+11+9+7=52) */
357 /* 0 bLength, bDescriptorType */ 9, 0x04,
358 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 0,
359 /* 4 bNumEndpoints */ 0,
360 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
361 /* 8 iInterface */ 0,
362 /* ------------------------------------ Interface Descriptor */
363 /* 0 bLength, bDescriptorType */ 9, 0x04,
364 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 1,
365 /* 4 bNumEndpoints */ 1,
366 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
367 /* 8 iInterface */ 0,
368 /* ------------------------ Audio 1.0 AS Interface Descriptor */
369 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x24, 0x01,
370 /* 3 bTerminalLink */ 0x03,
371 /* 4 bDelay, wFormatTag */ 0x00, D0(0x0001),D1(0x0001),
372 /* -------------------------- Audio AS Format Type Descriptor */
373 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 11, 0x24, 0x02,
374 /* 3 bFormatType, bNrChannels, bSubframeSize, bBitResolution */ 0x01, 0x02, 0x02, 16,
375 /* 7 bSamFreqType (n), tSamFreq[1] ... tSamFreq[n] */ 1, D0(48000),D1(48000),D2(48000),
376 /* --------------------- Audio 1.0 AS ISO Endpoint Descriptor */
377 /* 0 bLength, bDescriptorType */ 9, 0x05,
378 /* 2 bEndpointAddress, bmAttributes */ 0x81, 0x01,
379 /* 4 wMaxPacketSize, bInterval, bRefresh, bSynchAddress */ D0(256),D1(256), 4, 0, 0,
380 /* ---------- Audio 1.0 AS ISO Audio Data Endpoint Descriptor */
381 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x25, 0x01,
382 /* 3 bmAttributes */ 0x00,
383 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
384
385 /* ------------------------------------ Interface Descriptor *//* 2 Stream OUT (9+9+7+11+9+7=52) */
386 /* 0 bLength, bDescriptorType */ 9, 0x04,
387 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 0,
388 /* 4 bNumEndpoints */ 0,
389 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
390 /* 8 iInterface */ 0,
391 /* ------------------------------------ Interface Descriptor */
392 /* 0 bLength, bDescriptorType */ 9, 0x04,
393 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 1,
394 /* 4 bNumEndpoints */ 1,
395 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x00,
396 /* 8 iInterface */ 0,
397 /* ------------------------ Audio 1.0 AS Interface Descriptor */
398 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x24, 0x01,
399 /* 3 bTerminalLink */ 0x04,
400 /* 4 bDelay, wFormatTag */ 0x00, D0(0x0001),D1(0x0001),
401 /* -------------------------- Audio AS Format Type Descriptor */
402 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 11, 0x24, 0x02,
403 /* 3 bFormatType, bNrChannels, bSubframeSize, bBitResolution */ 0x01, 0x02, 0x02, 16,
404 /* 7 bSamFreqType (n), tSamFreq[1] ... tSamFreq[n] */ 1, D0(48000),D1(48000),D2(48000),
405 /* --------------------- Audio 1.0 AS ISO Endpoint Descriptor */
406 /* 0 bLength, bDescriptorType */ 9, 0x05,
407 /* 2 bEndpointAddress, bmAttributes */ 0x02, 0x01,
408 /* 4 wMaxPacketSize, bInterval, bRefresh, bSynchAddress */ D0(256),D1(256), 4, 0, 0,
409 /* ---------- Audio 1.0 AS ISO Audio Data Endpoint Descriptor */
410 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x25, 0x01,
411 /* 3 bmAttributes */ 0x00,
412 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
413 };
414 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
415
416 static unsigned char string_framework[] = {
417
418 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
419 0x09, 0x04, 0x01, 0x0c,
420 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
421 0x6f, 0x67, 0x69, 0x63,
422
423 /* Product string descriptor : Index 2 - "EL Composite device" */
424 0x09, 0x04, 0x02, 0x13,
425 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
426 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
427 0x69, 0x63, 0x65,
428
429 /* Serial Number string descriptor : Index 3 - "0001" */
430 0x09, 0x04, 0x03, 0x04,
431 0x30, 0x30, 0x30, 0x31
432 };
433 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
434
435
436 /* Multiple languages are supported on the device, to add
437 a language besides English, the Unicode language code must
438 be appended to the language_id_framework array and the length
439 adjusted accordingly. */
440 static unsigned char language_id_framework[] = {
441
442 /* English. */
443 0x09, 0x04
444 };
445 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
446
447 /* Setup requests */
448
449 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
450 static UX_TEST_SETUP _GetCfgDescr = UX_TEST_SETUP_GetCfgDescr;
451 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
452 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
453 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
454
455 /* Interaction define */
456
457 /* Hooks define */
458
ux_device_class_audio_tx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)459 static VOID ux_device_class_audio_tx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
460 {
461
462 UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *p = (UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *)params;
463 UX_SLAVE_TRANSFER *transfer = (UX_SLAVE_TRANSFER *)p -> parameter;
464 UCHAR tmp[32] = {'i','n','s','e','r','t','A',0};
465
466
467 (void)params;
468 // printf("tTX\n");
469
470 /* Acknowledge frame sent. */
471 if (test_tx_ack_count)
472 {
473 SAVE_BUFFER_LOG(transfer -> ux_slave_transfer_request_data_pointer, transfer -> ux_slave_transfer_request_requested_length);
474 transfer -> ux_slave_transfer_request_actual_length = transfer -> ux_slave_transfer_request_requested_length;
475 transfer -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
476 ux_test_dcd_sim_slave_transfer_done(transfer, UX_SUCCESS);
477 }
478 if (test_tx_ack_count != 0xFFFFFFFF && test_tx_ack_count > 0)
479 test_tx_ack_count --;
480
481 /* Insert frames when sent. */
482 if (test_tx_ins_count)
483 {
484 tmp[6] = (test_tx_ins_count % 26) + 'A';
485 if (test_tx_ins_way == 0)
486 ux_device_class_audio_frame_write(slave_audio_tx_stream, tmp, 32);
487 else
488 {
489
490 UCHAR *frame;
491 ULONG frame_length;
492
493
494 ux_device_class_audio_write_frame_get(slave_audio_tx_stream, &frame, &frame_length);
495 _ux_utility_memory_copy(frame, tmp, 32);
496 ux_device_class_audio_write_frame_commit(slave_audio_tx_stream, 32);
497 }
498 }
499 if (test_tx_ins_count != 0xFFFFFFFF && test_tx_ins_count > 0)
500 test_tx_ins_count --;
501 }
502
ux_device_class_audio_rx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)503 static VOID ux_device_class_audio_rx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
504 {
505
506 UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *p = (UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *)params;
507 UX_SLAVE_TRANSFER *transfer = (UX_SLAVE_TRANSFER *)p -> parameter;
508
509
510 (void)action;
511 (void)params;
512 (void)p;
513 (void)transfer;
514 // printf("tRX\n");
515 slave_audio_rx_transfer = transfer;
516 }
slave_audio_rx_simulate_one_frame(UCHAR * frame,ULONG frame_length)517 static VOID slave_audio_rx_simulate_one_frame(UCHAR *frame, ULONG frame_length)
518 {
519 UX_TEST_ASSERT(slave_audio_rx_transfer);
520 if (frame_length)
521 {
522 _ux_utility_memory_copy(slave_audio_rx_transfer->ux_slave_transfer_request_data_pointer, frame, frame_length);
523 slave_audio_rx_transfer->ux_slave_transfer_request_actual_length = frame_length;
524 slave_audio_rx_transfer->ux_slave_transfer_request_completion_code = UX_SUCCESS;
525 }
526 ux_test_dcd_sim_slave_transfer_done(slave_audio_rx_transfer, UX_SUCCESS);
527 _ux_utility_thread_sleep(1);
528 }
529
530 static UX_TEST_ACTION ux_device_class_audio_transfer_hook[] =
531 {
532 {
533 .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
534 .function = UX_DCD_TRANSFER_REQUEST,
535 .action_func = ux_device_class_audio_tx_hook,
536 .req_setup = UX_NULL,
537 .req_action = UX_TEST_MATCH_EP,
538 .req_ep_address = 0x81,
539 .do_after = UX_FALSE,
540 .no_return = UX_FALSE,
541 },
542 {
543 .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
544 .function = UX_DCD_TRANSFER_REQUEST,
545 .action_func = ux_device_class_audio_rx_hook,
546 .req_setup = UX_NULL,
547 .req_action = UX_TEST_MATCH_EP,
548 .req_ep_address = 0x02,
549 .do_after = UX_FALSE,
550 .no_return = UX_FALSE,
551 },
552 { 0 },
553 };
554
555 /* Define the ISR dispatch. */
556
557 extern VOID (*test_isr_dispatch)(void);
558
559
560 /* Prototype for test control return. */
561
562 void test_control_return(UINT status);
563
error_callback(UINT system_level,UINT system_context,UINT error_code)564 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
565 {
566
567 error_callback_counter ++;
568 // printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
569
570 if (!error_callback_ignore)
571 {
572 {
573 /* Failed test. */
574 test_control_return(1);
575 }
576 }
577 }
578
sleep_break_on_error(VOID)579 static UINT sleep_break_on_error(VOID)
580 {
581
582 if (error_callback_counter >= 3)
583 return error_callback_counter;
584
585 return UX_SUCCESS;
586 }
587
588 /* Define the ISR dispatch routine. */
589
test_isr(void)590 static void test_isr(void)
591 {
592
593 /* For further expansion of interrupt-level testing. */
594 }
595
slave_audio_activate(VOID * audio_instance)596 static VOID slave_audio_activate(VOID *audio_instance)
597 {
598 slave_audio = (UX_DEVICE_CLASS_AUDIO *)audio_instance;
599 ux_device_class_audio_stream_get(slave_audio, 0, &slave_audio_tx_stream);
600 ux_device_class_audio_stream_get(slave_audio, 1, &slave_audio_rx_stream);
601 // printf("sAUD:%p;%p,%p\n", audio_instance, slave_audio_tx_stream, slave_audio_rx_stream);
602 }
slave_audio_deactivate(VOID * audio_instance)603 static VOID slave_audio_deactivate(VOID *audio_instance)
604 {
605 if ((VOID *)slave_audio == audio_instance)
606 {
607 slave_audio = UX_NULL;
608 slave_audio_tx_stream = UX_NULL;
609 slave_audio_rx_stream = UX_NULL;
610 }
611 }
slave_audio_feature_change(struct UX_DEVICE_CLASS_AUDIO_STRUCT * audio,VOID * ext,ULONG selector)612 static VOID slave_audio_feature_change(struct UX_DEVICE_CLASS_AUDIO_STRUCT *audio, VOID *ext, ULONG selector)
613 {
614 SAVE_CALLBACK_INVOKE_LOG(slave_audio_feature_change, audio, ext, (ALIGN_TYPE)selector);
615 }
slave_audio_tx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG alt)616 static VOID slave_audio_tx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG alt)
617 {
618 SAVE_CALLBACK_INVOKE_LOG(slave_audio_tx_stream_change, audio, (ALIGN_TYPE)alt, 0);
619 }
slave_audio_rx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG alt)620 static VOID slave_audio_rx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG alt)
621 {
622 SAVE_CALLBACK_INVOKE_LOG(slave_audio_rx_stream_change, audio, (ALIGN_TYPE)alt, 0);
623
624 slave_audio_rx_transfer = UX_NULL;
625 }
slave_audio_control_process(UX_DEVICE_CLASS_AUDIO * audio,UX_SLAVE_TRANSFER * transfer)626 static UINT slave_audio_control_process(UX_DEVICE_CLASS_AUDIO *audio, UX_SLAVE_TRANSFER *transfer)
627 {
628
629 UINT status;
630 UX_DEVICE_CLASS_AUDIO10_CONTROL_GROUP group =
631 {2, g_slave_audio10_control};
632
633
634 SAVE_CALLBACK_INVOKE_LOG(slave_audio_control_process, audio, transfer, 0);
635
636 status = ux_device_class_audio10_control_process(audio, transfer, &group);
637 if (status == UX_SUCCESS)
638 {
639 if (g_slave_audio10_control[0].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED)
640 {
641 /* Mute change! */
642 }
643 if (g_slave_audio10_control[0].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_VOLUME_CHANGED)
644 {
645 /* Volume change! */
646 }
647 if (g_slave_audio10_control[1].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED)
648 {
649 /* Mute change! */
650 }
651 if (g_slave_audio10_control[1].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_VOLUME_CHANGED)
652 {
653 /* Volume change! */
654 }
655 }
656 return(status);
657 }
slave_audio_tx_done(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG length)658 static VOID slave_audio_tx_done(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG length)
659 {
660 SAVE_CALLBACK_INVOKE_LOG(slave_audio_tx_done, audio, (ALIGN_TYPE)length, 0);
661 }
slave_audio_rx_done(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG length)662 static VOID slave_audio_rx_done(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG length)
663 {
664 SAVE_CALLBACK_INVOKE_LOG(slave_audio_rx_done, audio, (ALIGN_TYPE)length, 0);
665 }
666
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)667 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
668 {
669
670 UX_HOST_CLASS_DUMMY *dummy = (UX_HOST_CLASS_DUMMY *) inst;
671
672
673 switch(event)
674 {
675
676 case UX_DEVICE_INSERTION:
677
678 // printf("hINS:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
679 switch(dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber)
680 {
681 case 0: dummy_control = dummy; break;
682 case 1: dummy_rx = dummy; break;
683 case 2: dummy_tx = dummy; break;
684 }
685 break;
686
687 case UX_DEVICE_REMOVAL:
688
689 // printf("hRMV:%p,%p:%ld\n", cls, inst, dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber);
690 switch(dummy -> ux_host_class_dummy_interface -> ux_interface_descriptor.bInterfaceNumber)
691 {
692 case 0: dummy_control = UX_NULL; break;
693 case 1: dummy_rx = UX_NULL; break;
694 case 2: dummy_tx = UX_NULL; break;
695 }
696 break;
697
698 default:
699 break;
700 }
701 return 0;
702 }
703
704
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)705 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
706 {
707
708 set_cfg_counter ++;
709
710 rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
711 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
712 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
713 }
714
715
716 /* Define what the initial system looks like. */
717
718 #ifdef CTEST
test_application_define(void * first_unused_memory)719 void test_application_define(void *first_unused_memory)
720 #else
721 void usbx_audio10_iad_device_control_test_application_define(void *first_unused_memory)
722 #endif
723 {
724
725 UINT status;
726 CHAR * stack_pointer;
727 CHAR * memory_pointer;
728
729
730 /* Inform user. */
731 printf("Running Audio 1.0 IAD Device Interrupt Functionality Test........... ");
732 stepinfo("\n");
733
734 /* Reset testing counts. */
735 ux_test_utility_sim_mutex_create_count_reset();
736 ux_test_utility_sim_sem_create_count_reset();
737 ux_test_utility_sim_sem_get_count_reset();
738 /* Reset error generations */
739 ux_test_utility_sim_sem_error_generation_stop();
740 ux_test_utility_sim_mutex_error_generation_stop();
741 ux_test_utility_sim_sem_get_error_generation_stop();
742
743 /* Initialize the free memory pointer */
744 stack_pointer = (CHAR *) usbx_memory;
745 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
746
747 /* Initialize USBX Memory */
748 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
749 UX_TEST_CHECK_SUCCESS(status);
750
751 /* Register the error callback. */
752 _ux_utility_error_callback_register(error_callback);
753
754 /* The code below is required for installing the host portion of USBX */
755 status = ux_host_stack_initialize(test_host_change_function);
756 UX_TEST_CHECK_SUCCESS(status);
757
758 /* Register Audio class. */
759 status = ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_entry);
760 UX_TEST_CHECK_SUCCESS(status);
761
762 /* The code below is required for installing the device portion of USBX. No call back for
763 device status change in this example. */
764 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
765 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
766 string_framework, STRING_FRAMEWORK_LENGTH,
767 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
768 UX_TEST_CHECK_SUCCESS(status);
769
770 /* Set the parameters for callback when insertion/extraction of a Audio 1.0 device, with IAD. */
771 ux_utility_memory_set(&slave_audio_parameter, 0, sizeof(slave_audio_parameter));
772 ux_utility_memory_set(slave_audio_stream_parameter, 0, sizeof(slave_audio_stream_parameter));
773 #if !defined(UX_DEVICE_STANDALONE)
774 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_thread_entry = ux_device_class_audio_write_thread_entry;
775 #else
776 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_task_function = _ux_device_class_audio_write_task_function;
777 #endif
778 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_change = slave_audio_tx_stream_change;
779 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_frame_done = slave_audio_tx_done;
780 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_max_frame_buffer_size = 256;
781 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_max_frame_buffer_nb = 8;
782
783 #if !defined(UX_DEVICE_STANDALONE)
784 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_thread_entry = ux_device_class_audio_read_thread_entry;
785 #else
786 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_task_function = _ux_device_class_audio_read_task_function;
787 #endif
788 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_change = slave_audio_rx_stream_change;
789 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_frame_done = slave_audio_rx_done;
790 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_max_frame_buffer_size = 256;
791 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_max_frame_buffer_nb = 8;
792 slave_audio_parameter.ux_device_class_audio_parameter_streams = slave_audio_stream_parameter;
793 slave_audio_parameter.ux_device_class_audio_parameter_streams_nb = 2;
794
795 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_slave_class_audio_instance_activate = slave_audio_activate;
796 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_slave_class_audio_instance_deactivate = slave_audio_deactivate;
797 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_device_class_audio_control_process = slave_audio_control_process;
798 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_device_class_audio_arg = UX_NULL;
799
800 #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
801 slave_audio_parameter.ux_device_class_audio_parameter_status_size = 2; /* UAC 1.0. */
802 slave_audio_parameter.ux_device_class_audio_parameter_status_queue_size = UX_TEST_STATUS_QUEUE_MAX_SIZE; /* Queue 8 interrupts. */
803 #endif
804
805 g_slave_audio10_control[0].ux_device_class_audio10_control_fu_id = 2;
806 g_slave_audio10_control[0].ux_device_class_audio10_control_mute[0] = 0;
807 g_slave_audio10_control[0].ux_device_class_audio10_control_volume[0] = 0;
808 g_slave_audio10_control[1].ux_device_class_audio10_control_fu_id = 5;
809 g_slave_audio10_control[1].ux_device_class_audio10_control_mute[0] = 0;
810 g_slave_audio10_control[1].ux_device_class_audio10_control_volume[0] = 0;
811
812 /* Initialize the device Audio class. This class owns interfaces starting with 0, 1, 2. */
813 status = ux_device_stack_class_register(_ux_system_slave_class_audio_name, ux_device_class_audio_entry,
814 1, 0, &slave_audio_parameter);
815 UX_TEST_CHECK_SUCCESS(status);
816
817 /* Initialize the simulated device controller. */
818 status = _ux_test_dcd_sim_slave_initialize();
819 UX_TEST_CHECK_SUCCESS(status);
820
821 /* Register all the USB host controllers available in this system */
822 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
823 UX_TEST_CHECK_SUCCESS(status);
824
825 /* Create the main host simulation thread. */
826 status = tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
827 stack_pointer, UX_DEMO_STACK_SIZE,
828 20, 20, 1, TX_AUTO_START);
829 UX_TEST_CHECK_SUCCESS(status);
830
831 /* Create the main slave simulation thread. */
832 status = tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
833 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
834 20, 20, 1, TX_AUTO_START);
835 UX_TEST_CHECK_SUCCESS(status);
836 }
837
test_wait_until_expected(VOID ** ptr,ULONG loop,VOID * expected)838 static UINT test_wait_until_expected(VOID **ptr, ULONG loop, VOID *expected)
839 {
840 while(loop)
841 {
842 _ux_utility_delay_ms(10);
843 if (*ptr == expected)
844 return UX_SUCCESS;
845 }
846 return UX_ERROR;
847 }
test_wait_until_not_expected(VOID ** ptr,ULONG loop,VOID * expected)848 static UINT test_wait_until_not_expected(VOID **ptr, ULONG loop, VOID *expected)
849 {
850 while(loop)
851 {
852 _ux_utility_delay_ms(10);
853 if (*ptr != expected)
854 return UX_SUCCESS;
855 }
856 return UX_ERROR;
857 }
858 #define test_wait_until_not_null(ptr, loop) test_wait_until_not_expected(ptr, loop, UX_NULL)
859 #define test_wait_until_null(ptr, loop) test_wait_until_expected(ptr, loop, UX_NULL)
860
861 #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
_test_device_uac_interrupts(ULONG queue_size)862 static void _test_device_uac_interrupts(ULONG queue_size)
863 {
864 ULONG i, actual;
865 UINT status;
866 UCHAR status_word[2];
867 UCHAR host_status[2];
868 stepinfo("== Device UAC status queue size %ld\n", queue_size);
869 /* Setup queue size. */
870 slave_audio->ux_device_class_audio_status_queue_bytes = queue_size * slave_audio->ux_device_class_audio_status_size;
871 slave_audio->ux_device_class_audio_status_head = slave_audio->ux_device_class_audio_status_queue;
872 slave_audio->ux_device_class_audio_status_tail = slave_audio->ux_device_class_audio_status_queue;
873
874 /* Fill status up to size. */
875 for (i = 0; i < queue_size; i ++)
876 {
877 status_word[0] = i;
878 status_word[1] = i;
879 status = ux_device_class_audio_interrupt_send(slave_audio, status_word);
880 UX_TEST_CHECK_SUCCESS(status);
881 }
882 /* Fill one duplicate status, success. */
883 status_word[0] = 0;
884 status_word[1] = 0;
885 status = ux_device_class_audio_interrupt_send(slave_audio, status_word);
886 UX_TEST_CHECK_SUCCESS(status);
887 /* Fill one more status, fail. */
888 status_word[0] = i;
889 status_word[1] = i;
890 status = ux_device_class_audio_interrupt_send(slave_audio, status_word);
891 UX_TEST_CHECK_CODE(UX_BUSY, status);
892 /* Read status on host side up to size. */
893 _ux_host_class_dummy_set_timeout(dummy_control, 0x83, 0, 10);
894 for (i = 0; i < queue_size; i ++)
895 {
896 status = _ux_host_class_dummy_transfer(dummy_control, 0x83, 0, host_status, 2, &actual);
897 UX_TEST_CHECK_SUCCESS(status);
898 UX_TEST_ASSERT(actual == 2);
899 UX_TEST_ASSERT(host_status[0] == i);
900 UX_TEST_ASSERT(host_status[1] == i);
901 }
902 /* Read one more status, fail. */
903 status = _ux_host_class_dummy_transfer(dummy_control, 0x83, 0, host_status, 2, &actual);
904 UX_TEST_CHECK_NOT_SUCCESS(status);
905 /* Fill status and read status 2*queue_size times, success. */
906 for (i = 0; i < (queue_size * 2); i ++)
907 {
908 status_word[0] = i;
909 status_word[1] = i;
910 status = ux_device_class_audio_interrupt_send(slave_audio, status_word);
911 UX_TEST_CHECK_SUCCESS(status);
912
913 status = _ux_host_class_dummy_transfer(dummy_control, 0x83, 0, host_status, 2, &actual);
914 UX_TEST_CHECK_SUCCESS(status);
915 UX_TEST_ASSERT(actual == 2);
916 UX_TEST_ASSERT(host_status[0] == i);
917 UX_TEST_ASSERT(host_status[1] == i);
918 }
919 /* The status queue is NULL. */
920 UX_TEST_ASSERT((slave_audio->ux_device_class_audio_status_head == slave_audio->ux_device_class_audio_status_tail) &&
921 (slave_audio->ux_device_class_audio_status_queued == 0));
922 }
923 #endif
924
tx_test_thread_host_simulation_entry(ULONG arg)925 void tx_test_thread_host_simulation_entry(ULONG arg)
926 {
927
928 UINT status;
929 ULONG test_n;
930 UX_DEVICE *device;
931 UX_CONFIGURATION *configuration;
932 UX_INTERFACE *interface;
933 UX_INTERFACE *interface_inst[3][2];
934 UX_ENDPOINT *control_endpoint;
935 UX_TRANSFER *transfer_request;
936 UCHAR test_tmp[32];
937
938
939 /* Test connect. */
940 status = test_wait_until_not_null((void**)&dummy_control, 100);
941 status |= test_wait_until_not_null((void**)&dummy_tx, 100);
942 status |= test_wait_until_not_null((void**)&dummy_rx, 100);
943 status |= test_wait_until_not_null((void**)&slave_audio_tx_stream, 100);
944 status |= test_wait_until_not_null((void**)&slave_audio_rx_stream, 100);
945 UX_TEST_CHECK_SUCCESS(status);
946
947 /* Validate configuration descriptors. */
948 /* ... */
949
950 /* Get testing instances. */
951
952 status = ux_host_stack_device_get(0, &device);
953 UX_TEST_CHECK_SUCCESS(status);
954
955 control_endpoint = &device->ux_device_control_endpoint;
956 transfer_request = &control_endpoint->ux_endpoint_transfer_request;
957
958 status = ux_host_stack_device_configuration_get(device, 0, &configuration);
959 UX_TEST_CHECK_SUCCESS(status);
960
961 interface = configuration -> ux_configuration_first_interface;
962 while(interface)
963 {
964 // printf("Interface: %ld.%ld\n", interface -> ux_interface_descriptor.bInterfaceNumber, interface -> ux_interface_descriptor.bAlternateSetting);
965 interface_inst[interface -> ux_interface_descriptor.bInterfaceNumber][interface -> ux_interface_descriptor.bAlternateSetting] = interface;
966 interface = interface -> ux_interface_next_interface;
967 }
968
969 /**************************************************************************/
970
971 /* Control requests test. */
972
973 transfer_request -> ux_transfer_request_data_pointer = buffer;
974
975 test_tmp[0] = 2;
976 test_tmp[1] = 5;
977
978 for (test_n = 0; test_n < 2; test_n ++)
979 {
980 transfer_request -> ux_transfer_request_function = UX_DEVICE_CLASS_AUDIO10_SET_CUR;
981 transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
982
983 /* Issue SetFeatureMute(test_tmp[test_n], 0). */
984 transfer_request -> ux_transfer_request_requested_length = 1;
985 transfer_request -> ux_transfer_request_index = (test_tmp[test_n] << 8) | 1;
986 transfer_request -> ux_transfer_request_value = (UX_DEVICE_CLASS_AUDIO10_FU_MUTE_CONTROL << 8) | 0;
987 buffer[0] = 0;
988 status = ux_host_stack_transfer_request(transfer_request);
989 UX_TEST_CHECK_SUCCESS(status);
990 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_changed == 0);
991
992 /* Issue SetFeatureMute(test_tmp[test_n], 1). */
993 buffer[0] = 1;
994 status = ux_host_stack_transfer_request(transfer_request);
995 UX_TEST_CHECK_SUCCESS(status);
996 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED);
997 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_mute[0] == 1);
998
999 /* Issue SetFeatureMute(test_tmp[test_n], 0). */
1000 buffer[0] = 0;
1001 status = ux_host_stack_transfer_request(transfer_request);
1002 UX_TEST_CHECK_SUCCESS(status);
1003 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED);
1004 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_mute[0] == 0);
1005
1006 /* Issue SetFeatureMute(test_tmp[test_n], 1). */
1007 buffer[0] = 1;
1008 status = ux_host_stack_transfer_request(transfer_request);
1009 UX_TEST_CHECK_SUCCESS(status);
1010 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_MUTE_CHANGED);
1011 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_mute[0] == 1);
1012
1013 /* Issue SetFeatureVolume(test_tmp[test_n], 0x0003). */
1014 transfer_request -> ux_transfer_request_requested_length = 2;
1015 transfer_request -> ux_transfer_request_index = (test_tmp[test_n] << 8) | 1;
1016 transfer_request -> ux_transfer_request_value = (UX_DEVICE_CLASS_AUDIO10_FU_VOLUME_CONTROL << 8) | 0;
1017 buffer[0] = 3; buffer[1] = 0;
1018 status = ux_host_stack_transfer_request(transfer_request);
1019 UX_TEST_CHECK_SUCCESS(status);
1020 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_VOLUME_CHANGED);
1021 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_volume[0] == 0x0003);
1022
1023 /* Issue SetFeatureVolume(test_tmp[test_n], 0x0103). */
1024 buffer[1] = 1;
1025 status = ux_host_stack_transfer_request(transfer_request);
1026 UX_TEST_CHECK_SUCCESS(status);
1027 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_changed == UX_DEVICE_CLASS_AUDIO10_CONTROL_VOLUME_CHANGED);
1028 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_volume[0] == 0x0103);
1029
1030 /* Issue SetFeatureVolume(test_tmp[test_n], 0x0103). */
1031 status = ux_host_stack_transfer_request(transfer_request);
1032 UX_TEST_CHECK_SUCCESS(status);
1033 UX_TEST_ASSERT(g_slave_audio10_control[test_n].ux_device_class_audio10_control_changed == 0);
1034
1035 /* Issue GetFeatureMute(test_tmp[test_n]). */
1036 transfer_request -> ux_transfer_request_function = UX_DEVICE_CLASS_AUDIO10_GET_CUR;
1037 transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE;
1038
1039 transfer_request -> ux_transfer_request_requested_length = 1;
1040 transfer_request -> ux_transfer_request_index = (test_tmp[test_n] << 8) | 1;
1041 transfer_request -> ux_transfer_request_value = (UX_DEVICE_CLASS_AUDIO10_FU_MUTE_CONTROL << 8) | 0;
1042 status = ux_host_stack_transfer_request(transfer_request);
1043 UX_TEST_CHECK_SUCCESS(status);
1044 UX_TEST_ASSERT(transfer_request -> ux_transfer_request_actual_length == 1);
1045 UX_TEST_ASSERT(buffer[0] == 1);
1046
1047 /* Issue GetFeatureMute(test_tmp[test_n]). */
1048 transfer_request -> ux_transfer_request_requested_length = 2;
1049 transfer_request -> ux_transfer_request_index = (test_tmp[test_n] << 8) | 1;
1050 transfer_request -> ux_transfer_request_value = (UX_DEVICE_CLASS_AUDIO10_FU_VOLUME_CONTROL << 8) | 0;
1051 status = ux_host_stack_transfer_request(transfer_request);
1052 UX_TEST_CHECK_SUCCESS(status);
1053 UX_TEST_ASSERT(transfer_request -> ux_transfer_request_actual_length == 2);
1054 UX_TEST_ASSERT(buffer[0] == 3);
1055 UX_TEST_ASSERT(buffer[1] == 1);
1056 }
1057
1058 /**************************************************************************/
1059
1060 /* Interrupt test. */
1061 #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
1062 for (test_n = 1; test_n <= UX_TEST_STATUS_QUEUE_MAX_SIZE; test_n <<= 1)
1063 _test_device_uac_interrupts(test_n);
1064 #endif
1065
1066 /* Wait pending threads. */
1067 _ux_utility_thread_sleep(1);
1068
1069 /* Finally disconnect the device. */
1070 ux_device_stack_disconnect();
1071
1072 /* And deinitialize the class. */
1073 ux_device_stack_class_unregister(_ux_system_slave_class_audio_name, ux_device_class_audio_entry);
1074
1075 /* Deinitialize the device side of usbx. */
1076 _ux_device_stack_uninitialize();
1077
1078 /* And finally the usbx system resources. */
1079 _ux_system_uninitialize();
1080
1081 /* Successful test. */
1082 printf("SUCCESS!\n");
1083 test_control_return(0);
1084
1085 }
1086
1087
1088
tx_test_thread_slave_simulation_entry(ULONG arg)1089 void tx_test_thread_slave_simulation_entry(ULONG arg)
1090 {
1091 while(1)
1092 {
1093
1094 #if defined(UX_DEVICE_STANDALONE)
1095
1096 /* Standalone background task. */
1097 ux_system_tasks_run();
1098 #else
1099 /* Sleep so ThreadX on Win32 will delete this thread. */
1100 tx_thread_sleep(10);
1101 #endif
1102 }
1103 }
1104