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