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