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_audio20.h"
14 #include "ux_device_stack.h"
15
16 #include "ux_host_class_audio.h"
17 #include "ux_host_class_audio.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_FEEDBACK (\
31 defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT) && \
32 defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) && \
33 defined(UX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT))
34
35 #define UX_DEMO_DEBUG_SIZE (4096*8)
36 #define UX_DEMO_STACK_SIZE 1024
37 #define UX_DEMO_BUFFER_SIZE (UX_DEMO_REQUEST_MAX_LENGTH + 1)
38 #define UX_DEMO_MEMORY_SIZE (128*1024)
39
40 #define UX_TEST_LOG_SIZE (64)
41
42
43 /* Define local/extern function prototypes. */
44 static void test_thread_entry(ULONG);
45 static TX_THREAD tx_test_thread_host_simulation;
46 static TX_THREAD tx_test_thread_slave_simulation;
47 static void tx_test_thread_host_simulation_entry(ULONG);
48 static void tx_test_thread_slave_simulation_entry(ULONG);
49
50 static TX_EVENT_FLAGS_GROUP tx_test_events;
51
52 /* Define global data structures. */
53 static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
54 static UCHAR buffer[64];
55
56 static UX_HOST_CLASS_AUDIO *host_audio_tx;
57 static UX_HOST_CLASS_AUDIO *host_audio_rx;
58
59 static UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST audio_transfer1 = {0};
60 static UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST audio_transfer2 = {0};
61 UCHAR host_audio_buffer[2][1024 * 3];
62
63 static UX_DEVICE_CLASS_AUDIO *slave_audio;
64 static UX_DEVICE_CLASS_AUDIO_PARAMETER slave_audio_parameter;
65 static UX_DEVICE_CLASS_AUDIO_STREAM_PARAMETER slave_audio_stream_parameter[2];
66
67 static UX_DEVICE_CLASS_AUDIO_STREAM *slave_audio_tx_stream;
68
69 static UX_DEVICE_CLASS_AUDIO_STREAM *slave_audio_rx_stream;
70 static UX_SLAVE_TRANSFER *slave_audio_rx_transfer;
71
72 static UX_HOST_CLASS_AUDIO *audio;
73
74 static UX_DEVICE_CLASS_AUDIO20_CONTROL g_slave_audio20_control[2];
75
76 static ULONG error_counter;
77
78 static ULONG set_cfg_counter;
79
80 static ULONG rsc_mem_free_on_set_cfg;
81 static ULONG rsc_sem_on_set_cfg;
82 static ULONG rsc_sem_get_on_set_cfg;
83 static ULONG rsc_mutex_on_set_cfg;
84
85 static ULONG rsc_mem_alloc_cnt_on_set_cfg;
86 static ULONG rsc_enum_sem_usage;
87 static ULONG rsc_enum_sem_get_count;
88 static ULONG rsc_enum_mutex_usage;
89 static ULONG rsc_enum_mem_usage;
90 static ULONG rsc_enum_mem_alloc_count;
91
92 static ULONG rsc_audio_sem_usage;
93 static ULONG rsc_audio_sem_get_count;
94 static ULONG rsc_audio_mutex_usage;
95 static ULONG rsc_audio_mem_usage;
96 static ULONG rsc_audio_mem_alloc_count;
97
98 static ULONG interaction_count;
99
100 static UCHAR error_callback_ignore = UX_TRUE;
101 static ULONG error_callback_counter;
102
103 static struct BUFFER_LOG_STRUCT {
104 ULONG length;
105 UCHAR data[256];
106 } buffer_log[UX_TEST_LOG_SIZE];
107 static ULONG buffer_log_count = 0;
108 #define SAVE_BUFFER_LOG(buf,siz) do { \
109 if (buffer_log_count < UX_TEST_LOG_SIZE) { \
110 ULONG __local_size__ = ((siz) > 256) ? 256 : (siz); \
111 buffer_log[buffer_log_count].length = (siz); \
112 _ux_utility_memory_copy(buffer_log[buffer_log_count].data, (buf), __local_size__); \
113 } \
114 buffer_log_count ++; \
115 } while(0)
116
117 static ULONG test_tx_ack_count = 0xFFFFFFFF;
118 static ULONG test_tx_ins_count = 0;
119 static ULONG test_tx_ins_way = 0;
120
121 static struct CALLBACK_INVOKE_LOG_STRUCT {
122 VOID *func;
123 VOID *param1;
124 VOID *param2;
125 VOID *param3;
126 } callback_invoke_log[UX_TEST_LOG_SIZE];
127 static ULONG callback_invoke_count = 0;
128
129 #define SAVE_CALLBACK_INVOKE_LOG(f,p1,p2,p3) do { \
130 if (callback_invoke_count < UX_TEST_LOG_SIZE) { \
131 callback_invoke_log[callback_invoke_count].func = (VOID *)(f); \
132 callback_invoke_log[callback_invoke_count].param1 = (VOID *)(p1); \
133 callback_invoke_log[callback_invoke_count].param2 = (VOID *)(p2); \
134 callback_invoke_log[callback_invoke_count].param3 = (VOID *)(p3); \
135 callback_invoke_count++; \
136 } \
137 } while(0)
138 #define RESET_CALLBACK_INVOKE_LOG() do { \
139 callback_invoke_count = 0; \
140 } while(0)
141
142 /* Define device framework. */
143
144 #define D3(d) ((UCHAR)((d) >> 24))
145 #define D2(d) ((UCHAR)((d) >> 16))
146 #define D1(d) ((UCHAR)((d) >> 8))
147 #define D0(d) ((UCHAR)((d) >> 0))
148
149 static unsigned char device_framework_full_speed[] = {
150
151 /* --------------------------------------- Device Descriptor */
152 /* 0 bLength, bDescriptorType */ 18, 0x01,
153 /* 2 bcdUSB */ D0(0x200),D1(0x200),
154 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00,
155 /* 7 bMaxPacketSize0 */ 8,
156 /* 8 idVendor, idProduct */ 0x84, 0x84, 0x02, 0x00,
157 /* 12 bcdDevice */ D0(0x200),D1(0x200),
158 /* 14 iManufacturer, iProduct, iSerialNumber */ 0, 0, 0,
159 /* 17 bNumConfigurations */ 1,
160
161 /* ----------------------------- Device Qualifier Descriptor */
162 /* 0 bLength, bDescriptorType */ 10, 0x06,
163 /* 2 bcdUSB */ D0(0x200),D1(0x200),
164 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00,
165 /* 7 bMaxPacketSize0 */ 8,
166 /* 8 bNumConfigurations */ 1,
167 /* 9 bReserved */ 0,
168
169 /* -------------------------------- Configuration Descriptor *//* 9+8+135+55+62=269 */
170 /* 0 bLength, bDescriptorType */ 9, 0x02,
171 /* 2 wTotalLength */ D0(269),D1(269),
172 /* 4 bNumInterfaces, bConfigurationValue */ 3, 1,
173 /* 6 iConfiguration */ 0,
174 /* 7 bmAttributes, bMaxPower */ 0x80, 50,
175
176 /* ------------------------ Interface Association Descriptor */
177 /* 0 bLength, bDescriptorType */ 8, 0x0B,
178 /* 2 bFirstInterface, bInterfaceCount */ 0, 3,
179 /* 4 bFunctionClass, bFunctionSubClass, bFunctionProtocol */ 0x01, 0x00, 0x20,
180 /* 7 iFunction */ 0,
181
182 /* ------------------------------------ Interface Descriptor *//* 0 Control (9+126=135) */
183 /* 0 bLength, bDescriptorType */ 9, 0x04,
184 /* 2 bInterfaceNumber, bAlternateSetting */ 0, 0,
185 /* 4 bNumEndpoints */ 0,
186 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x01, 0x20,
187 /* 8 iInterface */ 0,
188 /* ---------------- Audio 2.0 AC Interface Header Descriptor *//* (9+8+8+7+17*2+18*2+12*2=126) */
189 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 9, 0x24, 0x01,
190 /* 3 bcdADC, bCategory */ D0(0x200),D1(0x200), 0x08,
191 /* 6 wTotalLength */ D0(126),D1(126),
192 /* 8 bmControls */ 0x00,
193 /* -------------------- Audio 2.0 AC Clock Source Descriptor (0x11) */
194 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x24, 0x0A,
195 /* 3 bClockID, bmAttributes, bmControls */ 0x11, 0x05, 0x01,
196 /* 6 bAssocTerminal, iClockSource */ 0x00, 0,
197 /* -------------------- Audio 2.0 AC Clock Selector Descriptor (1x1, 0x12) */
198 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x24, 0x0B,
199 /* 3 bClockID, bNrInPins, baCSourceID1 */ 0x12, 0x01, 0x11,
200 /* 6 bmControls, iClockSelector */ 0x01, 0,
201 /* -------------------- Audio 2.0 AC Clock Multiplier Descriptor (0x10) */
202 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x24, 0x0C,
203 /* 3 bClockID, bCSourceID, bmControls */ 0x10, 0x12, 0x05,
204 /* 6 iClockMultiplier */ 0,
205 /* ------------------- Audio 2.0 AC Input Terminal Descriptor */
206 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 17, 0x24, 0x02,
207 /* 3 bTerminalID, wTerminalType */ 0x01, D0(0x0201),D1(0x0201),
208 /* 6 bAssocTerminal, bCSourceID */ 0x00, 0x10,
209 /* 8 bNrChannels, bmChannelConfig */ 0x02, D0(0),D1(0),D2(0),D3(0),
210 /* 13 iChannelNames, bmControls, iTerminal */ 0, D0(0),D1(0), 0,
211 /* --------------------- Audio 2.0 AC Feature Unit Descriptor */
212 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 18, 0x24, 0x06,
213 /* 3 bUnitID, bSourceID */ 0x02, 0x01,
214 /* 5 bmaControls(0), bmaControls(...) ... */ D0(0xF),D1(0xF),D2(0xF),D3(0xF), D0(0),D1(0),D2(0),D3(0), D0(0),D1(0),D2(0),D3(0),
215 /* . iFeature */ 0,
216 /* ------------------ Audio 2.0 AC Output Terminal Descriptor */
217 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x03,
218 /* 3 bTerminalID, wTerminalType */ 0x03, D0(0x0101),D1(0x0101),
219 /* 6 bAssocTerminal, bSourceID, bCSourceID */ 0x00, 0x02, 0x10,
220 /* 9 bmControls, iTerminal */ D0(0),D1(0), 0,
221 /* ------------------- Audio 2.0 AC Input Terminal Descriptor */
222 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 17, 0x24, 0x02,
223 /* 3 bTerminalID, wTerminalType */ 0x04, D0(0x0101),D1(0x0101),
224 /* 6 bAssocTerminal, bCSourceID */ 0x00, 0x10,
225 /* 8 bNrChannels, bmChannelConfig */ 0x02, D0(0),D1(0),D2(0),D3(0),
226 /* 13 iChannelNames, bmControls, iTerminal */ 0, D0(0),D1(0), 0,
227 /* --------------------- Audio 2.0 AC Feature Unit Descriptor */
228 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 18, 0x24, 0x06,
229 /* 3 bUnitID, bSourceID */ 0x05, 0x04,
230 /* 5 bmaControls(0), bmaControls(...) ... */ D0(0xF),D1(0xF),D2(0xF),D3(0xF), D0(0),D1(0),D2(0),D3(0), D0(0),D1(0),D2(0),D3(0),
231 /* . iFeature */ 0,
232 /* ------------------ Audio 2.0 AC Output Terminal Descriptor */
233 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x03,
234 /* 3 bTerminalID, wTerminalType */ 0x06, D0(0x0301),D1(0x0301),
235 /* 6 bAssocTerminal, bSourceID, bCSourceID */ 0x00, 0x05, 0x10,
236 /* 9 bmControls, iTerminal */ D0(0),D1(0), 0,
237
238 /* ------------------------------------ Interface Descriptor *//* 1 Stream IN (9+9+16+6+7+8=55) */
239 /* 0 bLength, bDescriptorType */ 9, 0x04,
240 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 0,
241 /* 4 bNumEndpoints */ 0,
242 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
243 /* 8 iInterface */ 0,
244 /* ------------------------------------ Interface Descriptor */
245 /* 0 bLength, bDescriptorType */ 9, 0x04,
246 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 1,
247 /* 4 bNumEndpoints */ 1,
248 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
249 /* 8 iInterface */ 0,
250 /* ------------------------ Audio 2.0 AS Interface Descriptor */
251 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 16, 0x24, 0x01,
252 /* 3 bTerminalLink, bmControls */ 0x03,0x00,
253 /* 5 bFormatType, bmFormats */ 0x01,D0(1),D1(1),D2(1),D3(1),
254 /* 10 bNrChannels, bmChannelConfig */ 2, D0(0),D1(0),D2(0),D3(0),
255 /* 15 iChannelNames */ 0,
256 /* -------------------- Audio 2.0 AS Format Type I Descriptor */
257 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 6, 0x24, 0x02,
258 /* 3 bFormatType, bSubslotSize, bBitResolution */ 0x01, 2, 16,
259 /* ------------------------------------- Endpoint Descriptor */
260 /* 0 bLength, bDescriptorType */ 7, 0x05,
261 /* 2 bEndpointAddress, bmAttributes */ 0x81, 0x0D,
262 /* 4 wMaxPacketSize, bInterval */ D0(256),D1(256), 1,
263 /* ---------- Audio 2.0 AS ISO Audio Data Endpoint Descriptor */
264 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x25, 0x01,
265 /* 3 bmAttributes, bmControls */ 0x00, 0x00,
266 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
267
268 /* ------------------------------------ Interface Descriptor *//* 2 Stream OUT (9+9+16+6+7+8+7=62) */
269 /* 0 bLength, bDescriptorType */ 9, 0x04,
270 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 0,
271 /* 4 bNumEndpoints */ 0,
272 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
273 /* 8 iInterface */ 0,
274 /* ------------------------------------ Interface Descriptor */
275 /* 0 bLength, bDescriptorType */ 9, 0x04,
276 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 1,
277 /* 4 bNumEndpoints */ 2,
278 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
279 /* 8 iInterface */ 0,
280 /* ------------------------ Audio 2.0 AS Interface Descriptor */
281 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 16, 0x24, 0x01,
282 /* 3 bTerminalLink, bmControls */ 0x04,0x00,
283 /* 5 bFormatType, bmFormats */ 0x01,D0(1),D1(1),D2(1),D3(1),
284 /* 10 bNrChannels, bmChannelConfig */ 2, D0(0),D1(0),D2(0),D3(0),
285 /* 15 iChannelNames */ 0,
286 /* ---------------------- Audio 2.0 AS Format Type Descriptor */
287 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 6, 0x24, 0x02,
288 /* 3 bFormatType, bSubslotSize, bBitResolution */ 0x01, 2, 16,
289 /* ------------------------------------- Endpoint Descriptor */
290 /* 0 bLength, bDescriptorType */ 7, 0x05,
291 /* 2 bEndpointAddress, bmAttributes */ 0x02, 0x0D,
292 /* 4 wMaxPacketSize, bInterval */ D0(256),D1(256), 1,
293 /* ---------- Audio 2.0 AS ISO Audio Data Endpoint Descriptor */
294 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x25, 0x01,
295 /* 3 bmAttributes, bmControls */ 0x00, 0x00,
296 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
297 /* ------------------------------------- Endpoint Descriptor */
298 /* 0 bLength, bDescriptorType */ 7, 0x05,
299 /* 2 bEndpointAddress, bmAttributes */ 0x82, 0x11,
300 /* 4 wMaxPacketSize, bInterval */ D0(4),D1(4), 1,
301
302 };
303 #define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
304
305 static unsigned char device_framework_high_speed[] = {
306 /* --------------------------------------- Device Descriptor */
307 /* 0 bLength, bDescriptorType */ 18, 0x01,
308 /* 2 bcdUSB */ D0(0x200),D1(0x200),
309 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00,
310 /* 7 bMaxPacketSize0 */ 0x08,
311 /* 8 idVendor, idProduct */ 0x84, 0x84, 0x02, 0x00,
312 /* 12 bcdDevice */ D0(0x200),D1(0x200),
313 /* 14 iManufacturer, iProduct, iSerialNumber */ 0, 0, 0,
314 /* 17 bNumConfigurations */ 1,
315
316 /* ----------------------------- Device Qualifier Descriptor */
317 /* 0 bLength, bDescriptorType */ 10, 0x06,
318 /* 2 bcdUSB */ D0(0x200),D1(0x200),
319 /* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0x00, 0x00, 0x00,
320 /* 7 bMaxPacketSize0 */ 8,
321 /* 8 bNumConfigurations */ 1,
322 /* 9 bReserved */ 0,
323
324 /* -------------------------------- Configuration Descriptor *//* 9+8+135+55+62=269 */
325 /* 0 bLength, bDescriptorType */ 9, 0x02,
326 /* 2 wTotalLength */ D0(269),D1(269),
327 /* 4 bNumInterfaces, bConfigurationValue */ 3, 1,
328 /* 6 iConfiguration */ 0,
329 /* 7 bmAttributes, bMaxPower */ 0x80, 50,
330
331 /* ------------------------ Interface Association Descriptor */
332 /* 0 bLength, bDescriptorType */ 8, 0x0B,
333 /* 2 bFirstInterface, bInterfaceCount */ 0, 3,
334 /* 4 bFunctionClass, bFunctionSubClass, bFunctionProtocol */ 0x01, 0x00, 0x20,
335 /* 7 iFunction */ 0,
336
337 /* ------------------------------------ Interface Descriptor *//* 0 Control (9+126=135) */
338 /* 0 bLength, bDescriptorType */ 9, 0x04,
339 /* 2 bInterfaceNumber, bAlternateSetting */ 0, 0,
340 /* 4 bNumEndpoints */ 0,
341 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x01, 0x20,
342 /* 8 iInterface */ 0,
343 /* ---------------- Audio 2.0 AC Interface Header Descriptor *//* (9+8+8+7+17*2+18*2+12*2=126) */
344 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 9, 0x24, 0x01,
345 /* 3 bcdADC, bCategory */ D0(0x200),D1(0x200), 0x08,
346 /* 6 wTotalLength */ D0(126),D1(126),
347 /* 8 bmControls */ 0x00,
348 /* -------------------- Audio 2.0 AC Clock Source Descriptor (0x11) */
349 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x24, 0x0A,
350 /* 3 bClockID, bmAttributes, bmControls */ 0x11, 0x05, 0x01,
351 /* 6 bAssocTerminal, iClockSource */ 0x00, 0,
352 /* -------------------- Audio 2.0 AC Clock Selector Descriptor (1x1, 0x12) */
353 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x24, 0x0B,
354 /* 3 bClockID, bNrInPins, baCSourceID1 */ 0x12, 0x01, 0x11,
355 /* 6 bmControls, iClockSelector */ 0x01, 0,
356 /* -------------------- Audio 2.0 AC Clock Multiplier Descriptor (0x10) */
357 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 7, 0x24, 0x0C,
358 /* 3 bClockID, bCSourceID, bmControls */ 0x10, 0x12, 0x05,
359 /* 6 iClockMultiplier */ 0,
360 /* ------------------- Audio 2.0 AC Input Terminal Descriptor */
361 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 17, 0x24, 0x02,
362 /* 3 bTerminalID, wTerminalType */ 0x01, D0(0x0201),D1(0x0201),
363 /* 6 bAssocTerminal, bCSourceID */ 0x00, 0x10,
364 /* 8 bNrChannels, bmChannelConfig */ 0x02, D0(0),D1(0),D2(0),D3(0),
365 /* 13 iChannelNames, bmControls, iTerminal */ 0, D0(0),D1(0), 0,
366 /* --------------------- Audio 2.0 AC Feature Unit Descriptor */
367 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 18, 0x24, 0x06,
368 /* 3 bUnitID, bSourceID */ 0x02, 0x01,
369 /* 5 bmaControls(0), bmaControls(...) ... */ D0(0xF),D1(0xF),D2(0xF),D3(0xF), D0(0),D1(0),D2(0),D3(0), D0(0),D1(0),D2(0),D3(0),
370 /* . iFeature */ 0,
371 /* ------------------ Audio 2.0 AC Output Terminal Descriptor */
372 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x03,
373 /* 3 bTerminalID, wTerminalType */ 0x03, D0(0x0101),D1(0x0101),
374 /* 6 bAssocTerminal, bSourceID, bCSourceID */ 0x00, 0x02, 0x10,
375 /* 9 bmControls, iTerminal */ D0(0),D1(0), 0,
376 /* ------------------- Audio 2.0 AC Input Terminal Descriptor */
377 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 17, 0x24, 0x02,
378 /* 3 bTerminalID, wTerminalType */ 0x04, D0(0x0101),D1(0x0101),
379 /* 6 bAssocTerminal, bCSourceID */ 0x00, 0x10,
380 /* 8 bNrChannels, bmChannelConfig */ 0x02, D0(0),D1(0),D2(0),D3(0),
381 /* 13 iChannelNames, bmControls, iTerminal */ 0, D0(0),D1(0), 0,
382 /* --------------------- Audio 2.0 AC Feature Unit Descriptor */
383 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 18, 0x24, 0x06,
384 /* 3 bUnitID, bSourceID */ 0x05, 0x04,
385 /* 5 bmaControls(0), bmaControls(...) ... */ D0(0xF),D1(0xF),D2(0xF),D3(0xF), D0(0),D1(0),D2(0),D3(0), D0(0),D1(0),D2(0),D3(0),
386 /* . iFeature */ 0,
387 /* ------------------ Audio 2.0 AC Output Terminal Descriptor */
388 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 12, 0x24, 0x03,
389 /* 3 bTerminalID, wTerminalType */ 0x06, D0(0x0301),D1(0x0301),
390 /* 6 bAssocTerminal, bSourceID, bCSourceID */ 0x00, 0x05, 0x10,
391 /* 9 bmControls, iTerminal */ D0(0),D1(0), 0,
392
393 /* ------------------------------------ Interface Descriptor *//* 1 Stream IN (9+9+16+6+7+8=55) */
394 /* 0 bLength, bDescriptorType */ 9, 0x04,
395 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 0,
396 /* 4 bNumEndpoints */ 0,
397 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
398 /* 8 iInterface */ 0,
399 /* ------------------------------------ Interface Descriptor */
400 /* 0 bLength, bDescriptorType */ 9, 0x04,
401 /* 2 bInterfaceNumber, bAlternateSetting */ 1, 1,
402 /* 4 bNumEndpoints */ 1,
403 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
404 /* 8 iInterface */ 0,
405 /* ------------------------ Audio 2.0 AS Interface Descriptor */
406 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 16, 0x24, 0x01,
407 /* 3 bTerminalLink, bmControls */ 0x03,0x00,
408 /* 5 bFormatType, bmFormats */ 0x01,D0(1),D1(1),D2(1),D3(1),
409 /* 10 bNrChannels, bmChannelConfig */ 2, D0(0),D1(0),D2(0),D3(0),
410 /* 15 iChannelNames */ 0,
411 /* -------------------- Audio 2.0 AS Format Type I Descriptor */
412 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 6, 0x24, 0x02,
413 /* 3 bFormatType, bSubslotSize, bBitResolution */ 0x01, 2, 16,
414 /* ------------------------------------- Endpoint Descriptor */
415 /* 0 bLength, bDescriptorType */ 7, 0x05,
416 /* 2 bEndpointAddress, bmAttributes */ 0x81, 0x0D,
417 /* 4 wMaxPacketSize, bInterval */ D0(256),D1(256), 4,
418 /* ---------- Audio 2.0 AS ISO Audio Data Endpoint Descriptor */
419 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x25, 0x01,
420 /* 3 bmAttributes, bmControls */ 0x00, 0x00,
421 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
422
423 /* ------------------------------------ Interface Descriptor *//* 2 Stream OUT (9+9+16+6+7+8+7=62) */
424 /* 0 bLength, bDescriptorType */ 9, 0x04,
425 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 0,
426 /* 4 bNumEndpoints */ 0,
427 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
428 /* 8 iInterface */ 0,
429 /* ------------------------------------ Interface Descriptor */
430 /* 0 bLength, bDescriptorType */ 9, 0x04,
431 /* 2 bInterfaceNumber, bAlternateSetting */ 2, 1,
432 /* 4 bNumEndpoints */ 2,
433 /* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ 0x01, 0x02, 0x20,
434 /* 8 iInterface */ 0,
435 /* ------------------------ Audio 2.0 AS Interface Descriptor */
436 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 16, 0x24, 0x01,
437 /* 3 bTerminalLink, bmControls */ 0x04,0x00,
438 /* 5 bFormatType, bmFormats */ 0x01,D0(1),D1(1),D2(1),D3(1),
439 /* 10 bNrChannels, bmChannelConfig */ 2, D0(0),D1(0),D2(0),D3(0),
440 /* 15 iChannelNames */ 0,
441 /* ---------------------- Audio 2.0 AS Format Type Descriptor */
442 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 6, 0x24, 0x02,
443 /* 3 bFormatType, bSubslotSize, bBitResolution */ 0x01, 2, 16,
444 /* ------------------------------------- Endpoint Descriptor */
445 /* 0 bLength, bDescriptorType */ 7, 0x05,
446 /* 2 bEndpointAddress, bmAttributes */ 0x02, 0x0D,
447 /* 4 wMaxPacketSize, bInterval */ D0(256),D1(256), 4,
448 /* ---------- Audio 2.0 AS ISO Audio Data Endpoint Descriptor */
449 /* 0 bLength, bDescriptorType, bDescriptorSubtype */ 8, 0x25, 0x01,
450 /* 3 bmAttributes, bmControls */ 0x00, 0x00,
451 /* 5 bLockDelayUnits, wLockDelay */ 0x00, D0(0),D1(0),
452 /* ------------------------------------- Endpoint Descriptor */
453 /* 0 bLength, bDescriptorType */ 7, 0x05,
454 /* 2 bEndpointAddress, bmAttributes */ 0x82, 0x11,
455 /* 4 wMaxPacketSize, bInterval */ D0(4),D1(4), 1,
456
457 };
458 #define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
459
460 static unsigned char string_framework[] = {
461
462 /* Manufacturer string descriptor : Index 1 - "Express Logic" */
463 0x09, 0x04, 0x01, 0x0c,
464 0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
465 0x6f, 0x67, 0x69, 0x63,
466
467 /* Product string descriptor : Index 2 - "EL Composite device" */
468 0x09, 0x04, 0x02, 0x13,
469 0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
470 0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
471 0x69, 0x63, 0x65,
472
473 /* Serial Number string descriptor : Index 3 - "0001" */
474 0x09, 0x04, 0x03, 0x04,
475 0x30, 0x30, 0x30, 0x31
476 };
477 #define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
478
479
480 /* Multiple languages are supported on the device, to add
481 a language besides English, the Unicode language code must
482 be appended to the language_id_framework array and the length
483 adjusted accordingly. */
484 static unsigned char language_id_framework[] = {
485
486 /* English. */
487 0x09, 0x04
488 };
489 #define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
490
491 /* Setup requests */
492
493 static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
494 static UX_TEST_SETUP _GetCfgDescr = UX_TEST_SETUP_GetCfgDescr;
495 static UX_TEST_SETUP _SetAddress = UX_TEST_SETUP_SetAddress;
496 static UX_TEST_SETUP _GetDeviceDescriptor = UX_TEST_SETUP_GetDevDescr;
497 static UX_TEST_SETUP _GetConfigDescriptor = UX_TEST_SETUP_GetCfgDescr;
498
499 /* Interaction define */
500
501 /* Hooks define */
502
ux_device_class_audio_tx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)503 static VOID ux_device_class_audio_tx_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 UCHAR tmp[32] = {'i','n','s','e','r','t','A',0};
509
510
511 (void)params;
512 // printf("tTX\n");
513
514 /* Acknowledge frame sent. */
515 if (test_tx_ack_count)
516 {
517 SAVE_BUFFER_LOG(transfer -> ux_slave_transfer_request_data_pointer, transfer -> ux_slave_transfer_request_requested_length);
518 transfer -> ux_slave_transfer_request_actual_length = transfer -> ux_slave_transfer_request_requested_length;
519 transfer -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
520 _ux_utility_semaphore_put(&transfer -> ux_slave_transfer_request_semaphore);
521 }
522 if (test_tx_ack_count != 0xFFFFFFFF && test_tx_ack_count > 0)
523 test_tx_ack_count --;
524
525 /* Insert frames when sent. */
526 if (test_tx_ins_count)
527 {
528 tmp[6] = (test_tx_ins_count % 26) + 'A';
529 if (test_tx_ins_way == 0)
530 ux_device_class_audio_frame_write(slave_audio_tx_stream, tmp, 32);
531 else
532 {
533
534 UCHAR *frame;
535 ULONG frame_length;
536
537
538 ux_device_class_audio_write_frame_get(slave_audio_tx_stream, &frame, &frame_length);
539 _ux_utility_memory_copy(frame, tmp, 32);
540 ux_device_class_audio_write_frame_commit(slave_audio_tx_stream, 32);
541 }
542 }
543 if (test_tx_ins_count != 0xFFFFFFFF && test_tx_ins_count > 0)
544 test_tx_ins_count --;
545 }
546
ux_device_class_audio_rx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)547 static VOID ux_device_class_audio_rx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
548 {
549
550 UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *p = (UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS *)params;
551 UX_SLAVE_TRANSFER *transfer = (UX_SLAVE_TRANSFER *)p -> parameter;
552
553
554 (void)action;
555 (void)params;
556 (void)p;
557 (void)transfer;
558 // printf("tRX\n");
559 slave_audio_rx_transfer = transfer;
560 }
slave_audio_rx_simulate_one_frame(UCHAR * frame,ULONG frame_length)561 static VOID slave_audio_rx_simulate_one_frame(UCHAR *frame, ULONG frame_length)
562 {
563 UX_TEST_ASSERT(slave_audio_rx_transfer);
564 if (frame_length)
565 {
566 _ux_utility_memory_copy(slave_audio_rx_transfer->ux_slave_transfer_request_data_pointer, frame, frame_length);
567 slave_audio_rx_transfer->ux_slave_transfer_request_actual_length = frame_length;
568 slave_audio_rx_transfer->ux_slave_transfer_request_completion_code = UX_SUCCESS;
569 }
570 _ux_utility_semaphore_put(&slave_audio_rx_transfer->ux_slave_transfer_request_semaphore);
571 _ux_utility_thread_sleep(1);
572 }
573
574 static UX_TEST_ACTION ux_device_class_audio_transfer_hook[] =
575 {
576 {
577 .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
578 .function = UX_DCD_TRANSFER_REQUEST,
579 .action_func = ux_device_class_audio_tx_hook,
580 .req_setup = UX_NULL,
581 .req_action = UX_TEST_MATCH_EP,
582 .req_ep_address = 0x81,
583 .do_after = UX_FALSE,
584 .no_return = UX_FALSE,
585 },
586 {
587 .usbx_function = UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION,
588 .function = UX_DCD_TRANSFER_REQUEST,
589 .action_func = ux_device_class_audio_rx_hook,
590 .req_setup = UX_NULL,
591 .req_action = UX_TEST_MATCH_EP,
592 .req_ep_address = 0x02,
593 .do_after = UX_FALSE,
594 .no_return = UX_FALSE,
595 },
596 { 0 },
597 };
598
ux_host_class_audio_tx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)599 static VOID ux_host_class_audio_tx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
600 {
601 UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS *p = (UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS*)params;
602 UX_TRANSFER *transfer = (UX_TRANSFER *)p->parameter;
603 SAVE_CALLBACK_INVOKE_LOG(ux_host_class_audio_tx_hook, transfer->ux_transfer_request_endpoint->ux_endpoint_descriptor.bEndpointAddress, transfer->ux_transfer_request_requested_length, 0);
604 // printf("hTxHook %lx %ld\n", transfer->ux_transfer_request_endpoint->ux_endpoint_descriptor.bEndpointAddress, transfer->ux_transfer_request_requested_length);
605 transfer->ux_transfer_request_actual_length=transfer->ux_transfer_request_requested_length;
606 transfer->ux_transfer_request_completion_code=UX_SUCCESS;
607 if (transfer->ux_transfer_request_completion_function)
608 transfer->ux_transfer_request_completion_function(transfer);
609 }
610
ux_host_class_audio_rx_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)611 static VOID ux_host_class_audio_rx_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
612 {
613 UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS *p = (UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS*)params;
614 UX_TRANSFER *transfer = (UX_TRANSFER *)p->parameter;
615 SAVE_CALLBACK_INVOKE_LOG(ux_host_class_audio_rx_hook, transfer->ux_transfer_request_endpoint->ux_endpoint_descriptor.bEndpointAddress, transfer->ux_transfer_request_requested_length, 0);
616 // printf("hRxHook %lx %ld\n", transfer->ux_transfer_request_endpoint->ux_endpoint_descriptor.bEndpointAddress, transfer->ux_transfer_request_requested_length);
617 transfer->ux_transfer_request_actual_length=transfer->ux_transfer_request_requested_length;
618 transfer->ux_transfer_request_completion_code=UX_SUCCESS;
619 if (transfer->ux_transfer_request_completion_function)
620 transfer->ux_transfer_request_completion_function(transfer);
621 }
622
623 #if UX_DEMO_FEEDBACK
624 static UX_TRANSFER *feedback_transfer;
625 static ULONG feedback_data = 0;
ux_host_class_audio_feedback_hook(struct UX_TEST_ACTION_STRUCT * action,VOID * params)626 static VOID ux_host_class_audio_feedback_hook(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
627 {
628 UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS *p = (UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY_PARAMS*)params;
629 UX_TRANSFER *transfer = (UX_TRANSFER *)p->parameter;
630 // printf("hFeedbackHook %lx %ld, %lx\n", transfer->ux_transfer_request_endpoint->ux_endpoint_descriptor.bEndpointAddress, transfer->ux_transfer_request_requested_length, feedback_data);
631 feedback_transfer = transfer;
632 *(ULONG *)transfer -> ux_transfer_request_data_pointer = feedback_data;
633 if (transfer -> ux_transfer_request_endpoint -> ux_endpoint_device -> ux_device_speed == UX_HIGH_SPEED_DEVICE)
634 transfer -> ux_transfer_request_actual_length = 4;
635 else
636 transfer -> ux_transfer_request_actual_length = 3;
637 tx_event_flags_set(&tx_test_events, 0x01, TX_OR);
638 }
639 #endif
640
641 static UX_TEST_ACTION ux_host_class_audio_transfer_hook[] =
642 {
643 {
644 .usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY,
645 .function = UX_HCD_TRANSFER_REQUEST,
646 .action_func = ux_host_class_audio_tx_hook,
647 .req_setup = UX_NULL,
648 .req_action = UX_TEST_MATCH_EP,
649 .req_ep_address = 0x02,
650 .do_after = UX_FALSE,
651 .no_return = UX_FALSE,
652 },
653 {
654 .usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY,
655 .function = UX_HCD_TRANSFER_REQUEST,
656 .action_func = ux_host_class_audio_rx_hook,
657 .req_setup = UX_NULL,
658 .req_action = UX_TEST_MATCH_EP,
659 .req_ep_address = 0x81,
660 .do_after = UX_FALSE,
661 .no_return = UX_FALSE,
662 },
663 #if UX_DEMO_FEEDBACK
664 {
665 .usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY,
666 .function = UX_HCD_TRANSFER_REQUEST,
667 .action_func = ux_host_class_audio_feedback_hook,
668 .req_setup = UX_NULL,
669 .req_action = UX_TEST_MATCH_EP,
670 .req_ep_address = 0x82,
671 .do_after = UX_FALSE,
672 .no_return = UX_FALSE,
673 },
674 #endif
675 {0},
676 };
677 static UX_TEST_ACTION ux_host_class_audio_tx_action[] =
678 {
679 {
680 .usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY,
681 .function = UX_HCD_TRANSFER_REQUEST,
682 .action_func = ux_host_class_audio_tx_hook,
683 .req_setup = UX_NULL,
684 .req_action = UX_TEST_MATCH_EP,
685 .req_ep_address = 0x02,
686 .do_after = UX_FALSE,
687 .no_return = UX_FALSE,
688 },
689 {
690 .usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY,
691 .function = UX_HCD_TRANSFER_REQUEST,
692 .action_func = ux_host_class_audio_tx_hook,
693 .req_setup = UX_NULL,
694 .req_action = UX_TEST_MATCH_EP,
695 .req_ep_address = 0x02,
696 .do_after = UX_FALSE,
697 .no_return = UX_FALSE,
698 },
699 {0},
700 };
701 static UX_TEST_ACTION ux_host_class_audio_rx_action[] =
702 {
703 {
704 .usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY,
705 .function = UX_HCD_TRANSFER_REQUEST,
706 .action_func = ux_host_class_audio_rx_hook,
707 .req_setup = UX_NULL,
708 .req_action = UX_TEST_MATCH_EP,
709 .req_ep_address = 0x81,
710 .do_after = UX_FALSE,
711 .no_return = UX_FALSE,
712 },
713 {
714 .usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY,
715 .function = UX_HCD_TRANSFER_REQUEST,
716 .action_func = ux_host_class_audio_rx_hook,
717 .req_setup = UX_NULL,
718 .req_action = UX_TEST_MATCH_EP,
719 .req_ep_address = 0x81,
720 .do_after = UX_FALSE,
721 .no_return = UX_FALSE,
722 },
723 {0},
724 };
725
726 /* Define the ISR dispatch. */
727
728 extern VOID (*test_isr_dispatch)(void);
729
730
731 /* Prototype for test control return. */
732
733 void test_control_return(UINT status);
734
error_callback(UINT system_level,UINT system_context,UINT error_code)735 static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
736 {
737
738 error_callback_counter ++;
739 // printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
740
741 if (!error_callback_ignore)
742 {
743 {
744 /* Failed test. */
745 test_control_return(1);
746 }
747 }
748 }
749
sleep_break_on_error(VOID)750 static UINT sleep_break_on_error(VOID)
751 {
752
753 if (error_callback_counter >= 3)
754 return error_callback_counter;
755
756 return UX_SUCCESS;
757 }
758
759 /* Define the ISR dispatch routine. */
760
test_isr(void)761 static void test_isr(void)
762 {
763
764 /* For further expansion of interrupt-level testing. */
765 }
766
slave_audio_activate(VOID * audio_instance)767 static VOID slave_audio_activate(VOID *audio_instance)
768 {
769 slave_audio = (UX_DEVICE_CLASS_AUDIO *)audio_instance;
770 ux_device_class_audio_stream_get(slave_audio, 0, &slave_audio_tx_stream);
771 ux_device_class_audio_stream_get(slave_audio, 1, &slave_audio_rx_stream);
772 // printf("sAUD:%p;%p,%p\n", audio_instance, slave_audio_tx_stream, slave_audio_rx_stream);
773 }
slave_audio_deactivate(VOID * audio_instance)774 static VOID slave_audio_deactivate(VOID *audio_instance)
775 {
776 if ((VOID *)slave_audio == audio_instance)
777 {
778 slave_audio = UX_NULL;
779 slave_audio_tx_stream = UX_NULL;
780 slave_audio_rx_stream = UX_NULL;
781 }
782 }
slave_audio_tx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG alt)783 static VOID slave_audio_tx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG alt)
784 {
785 SAVE_CALLBACK_INVOKE_LOG(slave_audio_tx_stream_change, audio, (ALIGN_TYPE)alt, 0);
786 }
slave_audio_rx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG alt)787 static VOID slave_audio_rx_stream_change(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG alt)
788 {
789 SAVE_CALLBACK_INVOKE_LOG(slave_audio_rx_stream_change, audio, (ALIGN_TYPE)alt, 0);
790
791 slave_audio_rx_transfer = UX_NULL;
792 }
slave_audio_control_process(UX_DEVICE_CLASS_AUDIO * audio,UX_SLAVE_TRANSFER * transfer)793 static UINT slave_audio_control_process(UX_DEVICE_CLASS_AUDIO *audio, UX_SLAVE_TRANSFER *transfer)
794 {
795
796
797 UINT status;
798 UX_DEVICE_CLASS_AUDIO20_CONTROL_GROUP group =
799 {2, g_slave_audio20_control};
800
801
802 SAVE_CALLBACK_INVOKE_LOG(slave_audio_control_process, audio, transfer, 0);
803
804 /* For sampling frequency support. */
805 {
806 UCHAR *setup = transfer -> ux_slave_transfer_request_setup;
807 UCHAR *buffer = transfer -> ux_slave_transfer_request_data_pointer;
808 UCHAR bmRequestType = setup[UX_SETUP_REQUEST_TYPE];
809 UCHAR bRequest = setup[UX_SETUP_REQUEST];
810 UCHAR wValue_CN = setup[UX_SETUP_VALUE];
811 UCHAR wValue_CS = setup[UX_SETUP_VALUE + 1];
812 UCHAR wIndex_iface = setup[UX_SETUP_INDEX];
813 UCHAR wIndex_ID = setup[UX_SETUP_INDEX + 1];
814 ULONG wLength = _ux_utility_long_get(setup + UX_SETUP_LENGTH);
815 /* AC Interface request. */
816 if (audio->ux_device_class_audio_interface->ux_slave_interface_descriptor.bInterfaceNumber == wIndex_iface)
817 {
818 /* AC Get request. */
819 if (bmRequestType == (UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE))
820 {
821
822 /* Clock Selector CUR. */
823 if (wIndex_ID == 0x12 &&
824 wValue_CS == UX_DEVICE_CLASS_AUDIO20_CX_CLOCK_SELECTOR_CONTROL &&
825 bRequest == UX_DEVICE_CLASS_AUDIO20_CUR)
826 {
827 if (wLength < 1)
828 return(UX_ERROR);
829 *buffer = 1;
830 ux_device_stack_transfer_request(transfer, 1, wLength);
831 return(UX_SUCCESS);
832 }
833 /* Clock Multiplier Numerator, Denominator CUR. */
834 if (wIndex_ID == 0x10)
835 {
836 if (wLength < 2)
837 return(UX_ERROR);
838 if (wValue_CS == UX_DEVICE_CLASS_AUDIO20_CM_NUMERATOR_CONTROL)
839 {
840 ux_utility_short_put(buffer, 12);
841 ux_device_stack_transfer_request(transfer, 2, wLength);
842 return(UX_SUCCESS);
843 }
844 if (wValue_CS == UX_DEVICE_CLASS_AUDIO20_CM_DENOMINATOR_CONTROL)
845 {
846 ux_utility_short_put(buffer, 2);
847 ux_device_stack_transfer_request(transfer, 2, wLength);
848 return(UX_SUCCESS);
849 }
850 }
851 /* Clock Source, sampling control. */
852 if (wIndex_ID == 0x11 && wValue_CS == UX_DEVICE_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL)
853 {
854 if (bRequest == UX_DEVICE_CLASS_AUDIO20_CUR)
855 {
856 if (wLength < 4)
857 return(UX_ERROR);
858 ux_utility_long_put(buffer, 8000);
859 ux_device_stack_transfer_request(transfer, 4, wLength);
860 return(UX_SUCCESS);
861 }
862 if (bRequest == UX_DEVICE_CLASS_AUDIO20_RANGE)
863 {
864 if (wLength < 2)
865 return(UX_ERROR);
866 ux_utility_long_put(buffer + 0, 1); /* wNumSubRanges */
867 ux_utility_long_put(buffer + 2, 8000); /* dMIN */
868 ux_utility_long_put(buffer + 6, 8000); /* dMAX */
869 ux_utility_long_put(buffer + 10, 0); /* dRES */
870 ux_device_stack_transfer_request(transfer, UX_MIN(2+4*3, wLength), wLength);
871 return(UX_SUCCESS);
872 }
873 }
874 }
875 }
876 }
877
878 status = ux_device_class_audio20_control_process(audio, transfer, &group);
879 if (status == UX_SUCCESS)
880 {
881 if (g_slave_audio20_control[0].ux_device_class_audio20_control_changed == UX_DEVICE_CLASS_AUDIO20_CONTROL_MUTE_CHANGED)
882 {
883 /* Mute change! */
884 }
885 if (g_slave_audio20_control[0].ux_device_class_audio20_control_changed == UX_DEVICE_CLASS_AUDIO20_CONTROL_VOLUME_CHANGED)
886 {
887 /* Volume change! */
888 }
889 if (g_slave_audio20_control[1].ux_device_class_audio20_control_changed == UX_DEVICE_CLASS_AUDIO20_CONTROL_MUTE_CHANGED)
890 {
891 /* Mute change! */
892 }
893 if (g_slave_audio20_control[1].ux_device_class_audio20_control_changed == UX_DEVICE_CLASS_AUDIO20_CONTROL_VOLUME_CHANGED)
894 {
895 /* Volume change! */
896 }
897 }
898 return(status);
899 }
slave_audio_tx_done(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG length)900 static VOID slave_audio_tx_done(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG length)
901 {
902 SAVE_CALLBACK_INVOKE_LOG(slave_audio_tx_done, audio, (ALIGN_TYPE)length, 0);
903 }
slave_audio_rx_done(UX_DEVICE_CLASS_AUDIO_STREAM * audio,ULONG length)904 static VOID slave_audio_rx_done(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG length)
905 {
906 SAVE_CALLBACK_INVOKE_LOG(slave_audio_rx_done, audio, (ALIGN_TYPE)length, 0);
907 }
908
test_host_change_function(ULONG event,UX_HOST_CLASS * cls,VOID * inst)909 static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
910 {
911
912 UX_HOST_CLASS_AUDIO *audio = (UX_HOST_CLASS_AUDIO *) inst;
913
914
915 switch(event)
916 {
917
918 case UX_DEVICE_INSERTION:
919
920 // printf("hINS:%p,%p:%ld\n", cls, inst, ux_host_class_audio_type_get(audio));
921 if (ux_host_class_audio_type_get(audio) == UX_HOST_CLASS_AUDIO_INPUT)
922 host_audio_rx = audio;
923 else
924 host_audio_tx = audio;
925 break;
926
927 case UX_DEVICE_REMOVAL:
928
929 // printf("hRMV:%p,%p:%ld\n", cls, inst, ux_host_class_audio_type_get(audio));
930 if (audio == host_audio_rx)
931 host_audio_rx = UX_NULL;
932 if (audio == host_audio_tx)
933 host_audio_tx = UX_NULL;
934 break;
935
936 default:
937 break;
938 }
939 return 0;
940 }
941
942
ux_test_hcd_entry_set_cfg(UX_TEST_ACTION * action,VOID * params)943 static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
944 {
945
946 set_cfg_counter ++;
947
948 rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
949
950 rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
951 rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
952 rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
953 }
954 static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
955 /* function, request to match,
956 port action, port status,
957 request action, request EP, request data, request actual length, request status,
958 status, additional callback,
959 no_return */
960 { UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
961 UX_FALSE, UX_TEST_PORT_STATUS_DISC,
962 UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
963 UX_SUCCESS, ux_test_hcd_entry_set_cfg,
964 UX_TRUE}, /* Invoke callback & continue */
965 { 0 }
966 };
967
968
969 /* Define what the initial system looks like. */
970
971 #ifdef CTEST
test_application_define(void * first_unused_memory)972 void test_application_define(void *first_unused_memory)
973 #else
974 void usbx_audio20_device_basic_test_application_define(void *first_unused_memory)
975 #endif
976 {
977
978 UINT status;
979 CHAR * stack_pointer;
980 CHAR * memory_pointer;
981
982
983 /* Inform user. */
984 printf("Running Audio 2.0 Host Basic Functionality Test..................... ");
985
986 #if !UX_TEST_MULTI_IFC_ON || !UX_TEST_MULTI_ALT_ON || !UX_TEST_MULTI_CLS_ON || \
987 !defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) || \
988 !defined(UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT) || \
989 (UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH < 260)
990 printf("SKIP SUCCESS!\n");
991 test_control_return(0);
992 return;
993 #endif
994
995 stepinfo("\n");
996
997 /* Reset testing counts. */
998 ux_test_utility_sim_mutex_create_count_reset();
999 ux_test_utility_sim_sem_create_count_reset();
1000 ux_test_utility_sim_sem_get_count_reset();
1001 /* Reset error generations */
1002 ux_test_utility_sim_sem_error_generation_stop();
1003 ux_test_utility_sim_mutex_error_generation_stop();
1004 ux_test_utility_sim_sem_get_error_generation_stop();
1005
1006 /* Initialize the free memory pointer */
1007 stack_pointer = (CHAR *) usbx_memory;
1008 memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
1009
1010 /* Initialize USBX Memory */
1011 status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
1012 UX_TEST_CHECK_SUCCESS(status);
1013
1014 /* Register the error callback. */
1015 _ux_utility_error_callback_register(error_callback);
1016
1017 /* The code below is required for installing the host portion of USBX */
1018 status = ux_host_stack_initialize(test_host_change_function);
1019 UX_TEST_CHECK_SUCCESS(status);
1020
1021 /* Register Audio class. */
1022 status = ux_host_stack_class_register(_ux_system_host_class_audio_name, ux_host_class_audio_entry);
1023 UX_TEST_CHECK_SUCCESS(status);
1024
1025 /* The code below is required for installing the device portion of USBX. No call back for
1026 device status change in this example. */
1027 status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
1028 device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
1029 string_framework, STRING_FRAMEWORK_LENGTH,
1030 language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
1031 UX_TEST_CHECK_SUCCESS(status);
1032
1033 /* Set the parameters for callback when insertion/extraction of a Audio 2.0 device, no IAD. */
1034 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_thread_entry = ux_device_class_audio_write_thread_entry;
1035 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_change = slave_audio_tx_stream_change;
1036 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_frame_done = slave_audio_tx_done;
1037 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_max_frame_buffer_size = 256;
1038 slave_audio_stream_parameter[0].ux_device_class_audio_stream_parameter_max_frame_buffer_nb = 8;
1039 #if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
1040 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_feedback_thread_entry = ux_device_class_audio_feedback_thread_entry;
1041 #endif
1042 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_thread_entry = ux_device_class_audio_read_thread_entry;
1043 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_change = slave_audio_rx_stream_change;
1044 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_callbacks.ux_device_class_audio_stream_frame_done = slave_audio_rx_done;
1045 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_max_frame_buffer_size = 256;
1046 slave_audio_stream_parameter[1].ux_device_class_audio_stream_parameter_max_frame_buffer_nb = 8;
1047 slave_audio_parameter.ux_device_class_audio_parameter_streams = slave_audio_stream_parameter;
1048 slave_audio_parameter.ux_device_class_audio_parameter_streams_nb = 2;
1049 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_slave_class_audio_instance_activate = slave_audio_activate;
1050 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_slave_class_audio_instance_deactivate = slave_audio_deactivate;
1051 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_device_class_audio_control_process = slave_audio_control_process;
1052 slave_audio_parameter.ux_device_class_audio_parameter_callbacks.ux_device_class_audio_arg = UX_NULL;
1053
1054 #if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
1055 slave_audio_parameter.ux_device_class_audio_parameter_status_queue_size = 2;
1056 slave_audio_parameter.ux_device_class_audio_parameter_status_size = 6;
1057 #endif
1058
1059 g_slave_audio20_control[0].ux_device_class_audio20_control_cs_id = 0x10;
1060 g_slave_audio20_control[0].ux_device_class_audio20_control_sampling_frequency = 48000;
1061 g_slave_audio20_control[0].ux_device_class_audio20_control_fu_id = 2;
1062 g_slave_audio20_control[0].ux_device_class_audio20_control_mute[0] = 0;
1063 g_slave_audio20_control[0].ux_device_class_audio20_control_volume[0] = 0;
1064 g_slave_audio20_control[1].ux_device_class_audio20_control_cs_id = 0x10;
1065 g_slave_audio20_control[1].ux_device_class_audio20_control_sampling_frequency = 48000;
1066 g_slave_audio20_control[1].ux_device_class_audio20_control_fu_id = 5;
1067 g_slave_audio20_control[1].ux_device_class_audio20_control_mute[0] = 0;
1068 g_slave_audio20_control[1].ux_device_class_audio20_control_volume[0] = 0;
1069
1070 #if 0
1071 printf("Memory requirement UX_HOST_CLASS_:\n");
1072 printf(" per _AUDIO: %d bytes\n", sizeof(UX_HOST_CLASS_AUDIO));
1073 printf(" per _AUDIO_TRANSFER_REQUEST: %d bytes\n", sizeof(UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST));
1074 printf(" per _AUDIO_CONTROL: %d bytes\n", sizeof(UX_HOST_CLASS_AUDIO_CONTROL));
1075 printf(" per _AUDIO_SAMPLING: %d bytes\n", sizeof(UX_HOST_CLASS_AUDIO_SAMPLING));
1076 printf(" per _AUDIO_SAMPLING_ATTR: %d bytes\n", sizeof(UX_HOST_CLASS_AUDIO_SAMPLING_CHARACTERISTICS));
1077 #endif
1078
1079 /* Initialize the device Audio class. This class owns interfaces starting with 0, 1, 2. */
1080 status = ux_device_stack_class_register(_ux_system_slave_class_audio_name, ux_device_class_audio_entry,
1081 1, 0, &slave_audio_parameter);
1082 UX_TEST_CHECK_SUCCESS(status);
1083
1084 /* Hook ISO transfers. */
1085 ux_test_link_hooks_from_array(ux_host_class_audio_transfer_hook);
1086
1087 /* Initialize the simulated device controller. */
1088 status = _ux_test_dcd_sim_slave_initialize();
1089 UX_TEST_CHECK_SUCCESS(status);
1090
1091 /* Register all the USB host controllers available in this system */
1092 status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
1093 UX_TEST_CHECK_SUCCESS(status);
1094
1095 /* Create the main event group. */
1096 status = tx_event_flags_create(&tx_test_events, "tx_test_events");
1097 UX_TEST_CHECK_SUCCESS(status);
1098
1099 /* Create the main host simulation thread. */
1100 status = tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
1101 stack_pointer, UX_DEMO_STACK_SIZE,
1102 20, 20, 1, TX_AUTO_START);
1103 UX_TEST_CHECK_SUCCESS(status);
1104
1105 /* Create the main slave simulation thread. */
1106 status = tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
1107 stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
1108 20, 20, 1, TX_AUTO_START);
1109 UX_TEST_CHECK_SUCCESS(status);
1110 }
1111
test_wait_until_expected(VOID ** ptr,ULONG loop,VOID * expected)1112 static UINT test_wait_until_expected(VOID **ptr, ULONG loop, VOID *expected)
1113 {
1114 while(loop)
1115 {
1116 _ux_utility_delay_ms(10);
1117 if (*ptr == expected)
1118 return UX_SUCCESS;
1119 }
1120 return UX_ERROR;
1121 }
test_wait_until_not_expected(VOID ** ptr,ULONG loop,VOID * expected)1122 static UINT test_wait_until_not_expected(VOID **ptr, ULONG loop, VOID *expected)
1123 {
1124 while(loop)
1125 {
1126 _ux_utility_delay_ms(10);
1127 if (*ptr != expected)
1128 return UX_SUCCESS;
1129 }
1130 return UX_ERROR;
1131 }
1132 #define test_wait_until_not_null(ptr, loop) test_wait_until_not_expected(ptr, loop, UX_NULL)
1133 #define test_wait_until_null(ptr, loop) test_wait_until_expected(ptr, loop, UX_NULL)
1134
_memory_tests(void)1135 static void _memory_tests(void)
1136 {
1137 ULONG test_n;
1138 ULONG mem_free;
1139
1140 /* Test disconnect. */
1141 ux_test_dcd_sim_slave_disconnect();
1142 ux_test_hcd_sim_host_disconnect();
1143
1144 /* Reset testing counts. */
1145 ux_test_utility_sim_mutex_create_count_reset();
1146 ux_test_utility_sim_sem_create_count_reset();
1147 ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
1148 /* Save free memory usage. */
1149 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1150 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1151 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1152 tx_thread_sleep(100);
1153 /* Log create counts for further tests. */
1154 rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
1155 rsc_enum_sem_usage = rsc_sem_on_set_cfg;
1156 rsc_enum_mem_usage = mem_free - rsc_mem_free_on_set_cfg;
1157 rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
1158 /* Log create counts when instances active for further tests. */
1159 rsc_audio_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
1160 rsc_audio_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
1161 rsc_audio_mem_usage = rsc_mem_free_on_set_cfg - _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1162 rsc_audio_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
1163 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1164
1165 /* Lock log base for tests. */
1166 ux_test_utility_sim_mem_alloc_log_lock();
1167
1168 stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
1169 stepinfo("cdc mem : %ld\n", rsc_audio_mem_alloc_count);
1170 stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
1171
1172 /* Simulate detach and attach for FS enumeration,
1173 and check if there is memory error in normal enumeration.
1174 */
1175 stepinfo(">>>>>>>>>>>> Enumeration test\n");
1176 mem_free = (~0);
1177 for (test_n = 0; test_n < 3; test_n++)
1178 {
1179 stepinfo("%4ld / 2\n", test_n);
1180
1181 /* Disconnect. */
1182 ux_test_dcd_sim_slave_disconnect();
1183 ux_test_hcd_sim_host_disconnect();
1184
1185 /* Update memory free level (disconnect) */
1186 if (mem_free == (~0))
1187 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1188 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
1189 {
1190
1191 printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1192 test_control_return(1);
1193 }
1194
1195 /* Connect. */
1196 error_callback_counter = 0;
1197 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1198 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1199
1200 /* Wait and break on error. */
1201 ux_test_breakable_sleep(100, sleep_break_on_error);
1202
1203 /* Check */
1204 if (!host_audio_tx || !host_audio_rx)
1205 {
1206
1207 printf("ERROR #12.%ld: Enumeration fail\n", test_n);
1208 test_control_return(1);
1209 }
1210 }
1211
1212 /* Simulate detach and attach for FS enumeration,
1213 and test possible memory allocation error handlings.
1214 */
1215 if (rsc_audio_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
1216 mem_free = (~0);
1217 for (test_n = 0; test_n < rsc_audio_mem_alloc_count; test_n ++)
1218 {
1219
1220 stepinfo("%4ld / %4ld\n", test_n, rsc_audio_mem_alloc_count - 1);
1221
1222 /* Disconnect. */
1223 ux_test_dcd_sim_slave_disconnect();
1224 ux_test_hcd_sim_host_disconnect();
1225
1226 /* Update memory free level (disconnect) */
1227 if (mem_free == (~0))
1228 mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
1229 else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
1230 {
1231
1232 printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1233 test_control_return(1);
1234 }
1235
1236 /* Set memory error generation */
1237 ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
1238
1239 /* Connect. */
1240 error_callback_counter = 0;
1241 ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
1242 ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
1243
1244 /* Wait and break on errors. */
1245 ux_test_breakable_sleep(100, sleep_break_on_error);
1246
1247 /* Check error */
1248 if (host_audio_tx && host_audio_rx)
1249 {
1250
1251 printf("ERROR #12.%ld: device detected when there is memory error\n", test_n);
1252 test_control_return(1);
1253 }
1254 stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
1255 }
1256 ux_test_utility_sim_mem_alloc_error_generation_stop();
1257 if (rsc_audio_mem_alloc_count) stepinfo("\n");
1258 }
1259
_feature_control_tests(void)1260 static void _feature_control_tests(void)
1261 {
1262 UX_HOST_CLASS_AUDIO_CONTROL audio_control;
1263 UINT status;
1264 UCHAR buffer[32];
1265 ULONG actual_length;
1266
1267 #if !defined(UX_HOST_CLASS_AUDIO_DISABLE_CONTROLS)
1268 RESET_CALLBACK_INVOKE_LOG();
1269
1270 audio_control.ux_host_class_audio_control_channel = 1;
1271 audio_control.ux_host_class_audio_control = UX_HOST_CLASS_AUDIO_VOLUME_CONTROL;
1272 status = ux_host_class_audio_control_get(host_audio_tx, &audio_control);
1273 // UX_TEST_ASSERT(status == UX_TRANSFER_STALLED);
1274 UX_TEST_ASSERT(callback_invoke_count == 1);
1275 UX_TEST_ASSERT(callback_invoke_log[0].func == slave_audio_control_process);
1276 UX_TEST_ASSERT(callback_invoke_log[0].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1277
1278 audio_control.ux_host_class_audio_control_channel = 1;
1279 audio_control.ux_host_class_audio_control = UX_HOST_CLASS_AUDIO_VOLUME_CONTROL;
1280 audio_control.ux_host_class_audio_control_cur = 0xfff0;
1281 status = ux_host_class_audio_control_value_set(host_audio_tx, &audio_control);
1282 // UX_TEST_ASSERT(status == UX_TRANSFER_STALLED);
1283 UX_TEST_ASSERT(callback_invoke_count == 2);
1284 UX_TEST_ASSERT(callback_invoke_log[1].func == slave_audio_control_process);
1285 UX_TEST_ASSERT(callback_invoke_log[1].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1286
1287 audio_control.ux_host_class_audio_control_channel = 2;
1288 audio_control.ux_host_class_audio_control = UX_HOST_CLASS_AUDIO_VOLUME_CONTROL;
1289 status = ux_host_class_audio_control_get(host_audio_tx, &audio_control);
1290 // UX_TEST_ASSERT(status == UX_TRANSFER_STALLED);
1291 UX_TEST_ASSERT(callback_invoke_count == 3);
1292 UX_TEST_ASSERT(callback_invoke_log[2].func == slave_audio_control_process);
1293 UX_TEST_ASSERT(callback_invoke_log[2].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1294
1295 audio_control.ux_host_class_audio_control_channel = 2;
1296 audio_control.ux_host_class_audio_control = UX_HOST_CLASS_AUDIO_VOLUME_CONTROL;
1297 audio_control.ux_host_class_audio_control_cur = 0xfff0;
1298 status = ux_host_class_audio_control_value_set(host_audio_tx, &audio_control);
1299 // UX_TEST_ASSERT(status == UX_TRANSFER_STALLED);
1300 UX_TEST_ASSERT(callback_invoke_count == 4);
1301 UX_TEST_ASSERT(callback_invoke_log[3].func == slave_audio_control_process);
1302 UX_TEST_ASSERT(callback_invoke_log[3].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1303 #endif
1304
1305 RESET_CALLBACK_INVOKE_LOG();
1306
1307 audio_control.ux_host_class_audio_control_entity = 0x05;
1308 audio_control.ux_host_class_audio_control_size = 2;
1309 audio_control.ux_host_class_audio_control = UX_HOST_CLASS_AUDIO_VOLUME_CONTROL;
1310
1311 audio_control.ux_host_class_audio_control_channel = 1;
1312 status = ux_host_class_audio_entity_control_get(host_audio_tx, &audio_control);
1313 UX_TEST_ASSERT(callback_invoke_count == 1);
1314 UX_TEST_ASSERT(callback_invoke_log[0].func == slave_audio_control_process);
1315 UX_TEST_ASSERT(callback_invoke_log[0].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1316
1317 audio_control.ux_host_class_audio_control_cur = 0xfff0;
1318 status = ux_host_class_audio_entity_control_value_set(host_audio_tx, &audio_control);
1319 UX_TEST_ASSERT(callback_invoke_count == 2);
1320 UX_TEST_ASSERT(callback_invoke_log[1].func == slave_audio_control_process);
1321 UX_TEST_ASSERT(callback_invoke_log[1].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1322
1323 audio_control.ux_host_class_audio_control_channel = 2;
1324 status = ux_host_class_audio_entity_control_get(host_audio_tx, &audio_control);
1325 UX_TEST_ASSERT(callback_invoke_count == 3);
1326 UX_TEST_ASSERT(callback_invoke_log[2].func == slave_audio_control_process);
1327 UX_TEST_ASSERT(callback_invoke_log[2].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1328
1329 audio_control.ux_host_class_audio_control_cur = 0xfff0;
1330 status = ux_host_class_audio_entity_control_value_set(host_audio_tx, &audio_control);
1331 UX_TEST_ASSERT(callback_invoke_count == 4);
1332 UX_TEST_ASSERT(callback_invoke_log[3].func == slave_audio_control_process);
1333 UX_TEST_ASSERT(callback_invoke_log[3].param1 == slave_audio_rx_stream->ux_device_class_audio_stream_audio);
1334
1335 #if defined(UX_HOST_CLASS_AUDIO_2_SUPPORT) /* Class consts included. */
1336
1337 buffer[0] = 0x5a;
1338 status = ux_host_class_audio_control_request(host_audio_tx, 0,
1339 0x21, UX_CLASS_AUDIO20_CUR,
1340 0 | (UX_CLASS_AUDIO20_FU_MUTE_CONTROL << 8),
1341 0x05,
1342 buffer, 1, &actual_length);
1343 UX_TEST_CHECK_SUCCESS(status);
1344
1345 buffer[0] = 0;
1346 status = ux_host_class_audio_control_request(host_audio_tx, 0,
1347 0xa1, UX_CLASS_AUDIO20_CUR,
1348 0 | (UX_CLASS_AUDIO20_FU_MUTE_CONTROL << 8),
1349 0x05,
1350 buffer, 1, &actual_length);
1351 UX_TEST_CHECK_SUCCESS(status);
1352 UX_TEST_ASSERT(buffer[0] == 0x5a);
1353
1354 status = ux_host_class_audio_control_request(host_audio_tx, 0,
1355 0xa1, UX_CLASS_AUDIO20_CUR,
1356 0 | (UX_CLASS_AUDIO20_CM_DENOMINATOR_CONTROL << 8),
1357 0x10,
1358 buffer, 2, &actual_length);
1359 UX_TEST_CHECK_SUCCESS(status);
1360 UX_TEST_ASSERT(buffer[0] == 2 && buffer[1] == 0);
1361
1362 status = ux_host_class_audio_control_request(host_audio_tx, 0,
1363 0xa1, UX_CLASS_AUDIO20_CUR,
1364 0 | (UX_CLASS_AUDIO20_CM_NUMERATOR_CONTROL << 8),
1365 0x10,
1366 buffer, 2, &actual_length);
1367 UX_TEST_CHECK_SUCCESS(status);
1368 UX_TEST_ASSERT(buffer[0] == 12 && buffer[1] == 0);
1369
1370 status = ux_host_class_audio_control_request(host_audio_tx, 0,
1371 0xa1, UX_CLASS_AUDIO20_CUR,
1372 0 | (UX_CLASS_AUDIO20_CS_SAM_FREQ_CONTROL << 8),
1373 0x11,
1374 buffer, 4, &actual_length);
1375 UX_TEST_CHECK_SUCCESS(status);
1376 UX_TEST_ASSERT(*(ULONG*)buffer == 8000);
1377 #endif
1378 }
1379
_sampling_control_tests(void)1380 static void _sampling_control_tests(void)
1381 {
1382 UINT status;
1383 UX_HOST_CLASS_AUDIO_SAMPLING sampling;
1384
1385 RESET_CALLBACK_INVOKE_LOG();
1386
1387 sampling.ux_host_class_audio_sampling_channels = 2;
1388 sampling.ux_host_class_audio_sampling_frequency = 44100;
1389 sampling.ux_host_class_audio_sampling_resolution = 16;
1390 status = ux_host_class_audio_streaming_sampling_set(host_audio_tx, &sampling);
1391 UX_TEST_CHECK_NOT_SUCCESS(status);
1392
1393 sampling.ux_host_class_audio_sampling_channels = 4;
1394 sampling.ux_host_class_audio_sampling_frequency = 48000;
1395 sampling.ux_host_class_audio_sampling_resolution = 16;
1396 status = ux_host_class_audio_streaming_sampling_set(host_audio_tx, &sampling);
1397 UX_TEST_CHECK_NOT_SUCCESS(status);
1398
1399 sampling.ux_host_class_audio_sampling_channels = 2;
1400 sampling.ux_host_class_audio_sampling_frequency = 48000;
1401 sampling.ux_host_class_audio_sampling_resolution = 32;
1402 status = ux_host_class_audio_streaming_sampling_set(host_audio_tx, &sampling);
1403 UX_TEST_CHECK_NOT_SUCCESS(status);
1404
1405 sampling.ux_host_class_audio_sampling_channels = 2;
1406 sampling.ux_host_class_audio_sampling_frequency = 48000;
1407 sampling.ux_host_class_audio_sampling_resolution = 16;
1408 status = ux_host_class_audio_streaming_sampling_set(host_audio_tx, &sampling);
1409 UX_TEST_CHECK_SUCCESS(status);
1410 UX_TEST_ASSERT(callback_invoke_count > 1); /* There could be multiple requests. */
1411 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].func == slave_audio_rx_stream_change);
1412 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].param1 == slave_audio_rx_stream);
1413 UX_TEST_ASSERT(ux_host_class_audio_max_packet_size_get(host_audio_tx) == 256);
1414 UX_TEST_ASSERT(host_audio_tx->ux_host_class_audio_packet_fraction == 0);
1415 UX_TEST_ASSERT(host_audio_tx->ux_host_class_audio_packet_freq == 1000);
1416 UX_TEST_ASSERT(host_audio_tx->ux_host_class_audio_packet_size == 192);
1417
1418 sampling.ux_host_class_audio_sampling_channels = 2;
1419 sampling.ux_host_class_audio_sampling_frequency = 48000;
1420 sampling.ux_host_class_audio_sampling_resolution = 16;
1421 status = ux_host_class_audio_streaming_sampling_set(host_audio_rx, &sampling);
1422 UX_TEST_CHECK_SUCCESS(status);
1423 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].func == slave_audio_tx_stream_change);
1424 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].param1 == slave_audio_tx_stream);
1425 UX_TEST_ASSERT(ux_host_class_audio_max_packet_size_get(host_audio_rx) == 256);
1426 UX_TEST_ASSERT(host_audio_rx->ux_host_class_audio_packet_fraction == 0);
1427 UX_TEST_ASSERT(host_audio_rx->ux_host_class_audio_packet_freq == 1000);
1428 UX_TEST_ASSERT(host_audio_rx->ux_host_class_audio_packet_size == 192);
1429 }
1430
_audio_request_completion(UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST * transfer)1431 static void _audio_request_completion(UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *transfer)
1432 {
1433 UX_PARAMETER_NOT_USED(transfer);
1434 SAVE_CALLBACK_INVOKE_LOG(_audio_request_completion, transfer, 0, 0);
1435 }
_audio_requests_tests(void)1436 static void _audio_requests_tests(void)
1437 {
1438 UINT status;
1439
1440 RESET_CALLBACK_INVOKE_LOG();
1441
1442 /* Prepare the 2 audio transfer_requests */
1443 audio_transfer1.ux_host_class_audio_transfer_request_completion_function = _audio_request_completion;
1444 audio_transfer2.ux_host_class_audio_transfer_request_completion_function = _audio_request_completion;
1445 audio_transfer1.ux_host_class_audio_transfer_request_class_instance = host_audio_tx;
1446 audio_transfer2.ux_host_class_audio_transfer_request_class_instance = host_audio_tx;
1447 audio_transfer1.ux_host_class_audio_transfer_request_next_audio_transfer_request = &audio_transfer1;
1448 audio_transfer2.ux_host_class_audio_transfer_request_next_audio_transfer_request = UX_NULL;
1449
1450 audio_transfer1.ux_host_class_audio_transfer_request_data_pointer = host_audio_buffer[0];
1451 audio_transfer1.ux_host_class_audio_transfer_request_requested_length = sizeof(host_audio_buffer[0]);
1452 audio_transfer1.ux_host_class_audio_transfer_request.ux_transfer_request_packet_length = 192;
1453
1454 audio_transfer2.ux_host_class_audio_transfer_request_data_pointer = host_audio_buffer[1];
1455 audio_transfer2.ux_host_class_audio_transfer_request_requested_length = sizeof(host_audio_buffer[1]);
1456 audio_transfer2.ux_host_class_audio_transfer_request.ux_transfer_request_packet_length = 192;
1457
1458 // ux_test_set_main_action_list_from_array(ux_host_class_audio_tx_action);
1459
1460 status = ux_host_class_audio_write(host_audio_tx, &audio_transfer1);
1461 UX_TEST_CHECK_SUCCESS(status);
1462 UX_TEST_ASSERT(callback_invoke_count == 2);
1463 UX_TEST_ASSERT(callback_invoke_log[0].func == ux_host_class_audio_tx_hook);
1464 UX_TEST_ASSERT(callback_invoke_log[0].param1 == (void*)0x02);
1465 UX_TEST_ASSERT(callback_invoke_log[0].param2 == (void*)sizeof(host_audio_buffer[0]));
1466 UX_TEST_ASSERT(callback_invoke_log[1].func == _audio_request_completion);
1467 UX_TEST_ASSERT(callback_invoke_log[1].param1 == &audio_transfer1);
1468
1469 status = ux_host_class_audio_write(host_audio_tx, &audio_transfer2);
1470 UX_TEST_CHECK_SUCCESS(status);
1471 UX_TEST_ASSERT(callback_invoke_count == 4);
1472 UX_TEST_ASSERT(callback_invoke_log[2].func == ux_host_class_audio_tx_hook);
1473 UX_TEST_ASSERT(callback_invoke_log[2].param1 == (void*)0x02);
1474 UX_TEST_ASSERT(callback_invoke_log[2].param2 == (void*)sizeof(host_audio_buffer[1]));
1475 UX_TEST_ASSERT(callback_invoke_log[3].func == _audio_request_completion);
1476 UX_TEST_ASSERT(callback_invoke_log[3].param1 == &audio_transfer2);
1477
1478 // ux_test_set_main_action_list_from_array(ux_host_class_audio_rx_action);
1479
1480 status = ux_host_class_audio_read(host_audio_rx, &audio_transfer1);
1481 UX_TEST_CHECK_SUCCESS(status);
1482 UX_TEST_ASSERT(callback_invoke_count == 6);
1483 UX_TEST_ASSERT(callback_invoke_log[4].func == ux_host_class_audio_rx_hook);
1484 UX_TEST_ASSERT(callback_invoke_log[4].param1 == (void*)0x81);
1485 UX_TEST_ASSERT(callback_invoke_log[4].param2 == (void*)256);
1486 UX_TEST_ASSERT(callback_invoke_log[5].func == _audio_request_completion);
1487 UX_TEST_ASSERT(callback_invoke_log[5].param1 == &audio_transfer1);
1488
1489 status = ux_host_class_audio_read(host_audio_rx, &audio_transfer2);
1490 UX_TEST_CHECK_SUCCESS(status);
1491 UX_TEST_ASSERT(callback_invoke_count == 8);
1492 UX_TEST_ASSERT(callback_invoke_log[6].func == ux_host_class_audio_rx_hook);
1493 UX_TEST_ASSERT(callback_invoke_log[6].param1 == (void*)0x81);
1494 UX_TEST_ASSERT(callback_invoke_log[6].param2 == (void*)256);
1495 UX_TEST_ASSERT(callback_invoke_log[7].func == _audio_request_completion);
1496 UX_TEST_ASSERT(callback_invoke_log[7].param1 == &audio_transfer2);
1497 }
1498 #if UX_DEMO_FEEDBACK
_audio_feedback_tests(void)1499 static void _audio_feedback_tests(void)
1500 {
1501 ULONG host_feedback;
1502 UINT status;
1503
1504 tx_thread_suspend(&tx_test_thread_slave_simulation);
1505
1506 host_feedback = 0;
1507 status = ux_host_class_audio_feedback_set(host_audio_tx, (UCHAR *)&host_feedback);
1508 UX_TEST_CHECK_SUCCESS(status);
1509
1510 host_feedback = 0xFF;
1511 status = ux_host_class_audio_feedback_get(host_audio_tx, (UCHAR *)&host_feedback);
1512 UX_TEST_CHECK_SUCCESS(status);
1513 UX_TEST_ASSERT(0 == host_feedback);
1514
1515 tx_thread_resume(&tx_test_thread_slave_simulation);
1516
1517
1518 feedback_data = 0x123456;
1519 ux_utility_delay_ms(20);
1520 status = ux_host_class_audio_feedback_get(host_audio_tx, (UCHAR *)&host_feedback);
1521 UX_TEST_CHECK_SUCCESS(status);
1522 UX_TEST_ASSERT(feedback_data == host_feedback);
1523
1524 feedback_data = 0x654321;
1525 ux_utility_delay_ms(20);
1526 status = ux_host_class_audio_feedback_get(host_audio_tx, (UCHAR *)&host_feedback);
1527 UX_TEST_CHECK_SUCCESS(status);
1528 UX_TEST_ASSERT(feedback_data == host_feedback);
1529 }
1530 #endif
1531
_audio_stop_test(void)1532 static void _audio_stop_test(void)
1533 {
1534 UINT status;
1535 RESET_CALLBACK_INVOKE_LOG();
1536 status = ux_host_class_audio_stop(host_audio_tx);
1537 UX_TEST_CHECK_SUCCESS(status);
1538 UX_TEST_ASSERT(callback_invoke_count == 1);
1539 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].func == slave_audio_rx_stream_change);
1540 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].param1 == slave_audio_rx_stream);
1541
1542 status = ux_host_class_audio_stop(host_audio_rx);
1543 UX_TEST_CHECK_SUCCESS(status);
1544 UX_TEST_ASSERT(callback_invoke_count == 2);
1545 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].func == slave_audio_tx_stream_change);
1546 UX_TEST_ASSERT(callback_invoke_log[callback_invoke_count-1].param1 == slave_audio_tx_stream);
1547 }
1548
tx_test_thread_host_simulation_entry(ULONG arg)1549 void tx_test_thread_host_simulation_entry(ULONG arg)
1550 {
1551
1552 UINT status;
1553 ULONG test_n;
1554 UX_DEVICE *device;
1555 UX_CONFIGURATION *configuration;
1556 UX_INTERFACE *interface;
1557 UCHAR test_tmp[32];
1558 ULONG temp;
1559
1560 /* Test connect. */
1561 status = test_wait_until_not_null((void**)&host_audio_rx, 100);
1562 status |= test_wait_until_not_null((void**)&host_audio_tx, 100);
1563 status |= test_wait_until_not_null((void**)&slave_audio_tx_stream, 100);
1564 status |= test_wait_until_not_null((void**)&slave_audio_rx_stream, 100);
1565 UX_TEST_CHECK_SUCCESS(status);
1566 UX_TEST_ASSERT(ux_host_class_audio_protocol_get(host_audio_rx) == UX_HOST_CLASS_AUDIO_PROTOCOL_IP_VERSION_02_00);
1567 UX_TEST_ASSERT(ux_host_class_audio_type_get(host_audio_rx) == UX_HOST_CLASS_AUDIO_INPUT);
1568 UX_TEST_ASSERT(ux_host_class_audio_speed_get(host_audio_rx) == UX_FULL_SPEED_DEVICE);
1569
1570 /* Check enumeration information. */
1571 UX_TEST_ASSERT(host_audio_rx->ux_host_class_audio_control_interface_number == 0);
1572 UX_TEST_ASSERT(host_audio_rx->ux_host_class_audio_streaming_interface->ux_interface_descriptor.bInterfaceNumber == 1);
1573 UX_TEST_ASSERT(host_audio_tx->ux_host_class_audio_control_interface_number == 0);
1574 UX_TEST_ASSERT(host_audio_tx->ux_host_class_audio_streaming_interface->ux_interface_descriptor.bInterfaceNumber == 2);
1575
1576 _memory_tests();
1577 _feature_control_tests();
1578 _sampling_control_tests();
1579 _audio_requests_tests();
1580 #if UX_DEMO_FEEDBACK
1581 _audio_feedback_tests();
1582 #endif
1583 _audio_stop_test();
1584
1585 /* Wait pending threads. */
1586 _ux_utility_thread_sleep(1);
1587
1588 /* Finally disconnect the device. */
1589 ux_device_stack_disconnect();
1590
1591 /* And deinitialize the class. */
1592 ux_device_stack_class_unregister(_ux_system_slave_class_audio_name, ux_device_class_audio_entry);
1593
1594 /* Deinitialize the device side of usbx. */
1595 _ux_device_stack_uninitialize();
1596
1597 /* And finally the usbx system resources. */
1598 _ux_system_uninitialize();
1599
1600 /* Successful test. */
1601 printf("SUCCESS!\n");
1602 test_control_return(0);
1603
1604 }
1605
1606
1607
tx_test_thread_slave_simulation_entry(ULONG arg)1608 void tx_test_thread_slave_simulation_entry(ULONG arg)
1609 {
1610 while(1)
1611 {
1612
1613 #if UX_DEMO_FEEDBACK
1614 UINT status;
1615 ULONG events;
1616 status = tx_event_flags_get(&tx_test_events, 0x1u, TX_OR_CLEAR, &events, 10);
1617 if (status == UX_SUCCESS)
1618 {
1619 /* Simulate ISO transfer done event. */
1620 feedback_transfer -> ux_transfer_request_completion_code = UX_SUCCESS;
1621 if (feedback_transfer -> ux_transfer_request_completion_function)
1622 feedback_transfer -> ux_transfer_request_completion_function(feedback_transfer);
1623 _ux_host_semaphore_put(&feedback_transfer -> ux_transfer_request_semaphore);
1624 ux_utility_delay_ms(1);
1625 }
1626 #else
1627 /* Sleep so ThreadX on Win32 will delete this thread. */
1628 tx_thread_sleep(10);
1629 #endif
1630 }
1631 }
1632