1 /*
2 * Copyright (c) 2024, sakumisu
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "usbd_core.h"
7 #include "usbd_audio.h"
8
9 #define USING_FEEDBACK 0
10
11 #define USBD_VID 0xffff
12 #define USBD_PID 0xffff
13 #define USBD_MAX_POWER 100
14 #define USBD_LANGID_STRING 1033
15
16 #ifdef CONFIG_USB_HS
17 #define EP_INTERVAL 0x04
18 #define FEEDBACK_ENDP_PACKET_SIZE 0x04
19 #else
20 #define EP_INTERVAL 0x01
21 #define FEEDBACK_ENDP_PACKET_SIZE 0x03
22 #endif
23
24 #define AUDIO_OUT_EP 0x02
25 #define AUDIO_IN_EP 0x81
26 #define AUDIO_OUT_FEEDBACK_EP 0x83
27
28 #define AUDIO_OUT_CLOCK_ID 0x01
29 #define AUDIO_OUT_FU_ID 0x03
30 #define AUDIO_IN_CLOCK_ID 0x05
31 #define AUDIO_IN_FU_ID 0x07
32
33 #define AUDIO_OUT_MAX_FREQ 96000
34 #define AUDIO_IN_MAX_FREQ 16000
35
36 #define HALF_WORD_BYTES 2 //2 half word (one channel)
37 #define SAMPLE_BITS 16 //16 bit per channel
38
39 #define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
40
41 #define IN_CHANNEL_NUM 2
42
43 #if IN_CHANNEL_NUM == 1
44 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
45 #define INPUT_CH_ENABLE 0x00000000
46 #elif IN_CHANNEL_NUM == 2
47 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
48 #define INPUT_CH_ENABLE 0x00000003
49 #elif IN_CHANNEL_NUM == 3
50 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
51 #define INPUT_CH_ENABLE 0x00000007
52 #elif IN_CHANNEL_NUM == 4
53 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
54 #define INPUT_CH_ENABLE 0x0000000f
55 #elif IN_CHANNEL_NUM == 5
56 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
57 #define INPUT_CH_ENABLE 0x0000001f
58 #elif IN_CHANNEL_NUM == 6
59 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
60 #define INPUT_CH_ENABLE 0x0000003F
61 #elif IN_CHANNEL_NUM == 7
62 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
63 #define INPUT_CH_ENABLE 0x0000007f
64 #elif IN_CHANNEL_NUM == 8
65 #define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
66 #define INPUT_CH_ENABLE 0x000000ff
67 #endif
68
69 #define OUT_CHANNEL_NUM 2
70
71 #if OUT_CHANNEL_NUM == 1
72 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
73 #define OUTPUT_CH_ENABLE 0x00000000
74 #elif OUT_CHANNEL_NUM == 2
75 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
76 #define OUTPUT_CH_ENABLE 0x00000003
77 #elif OUT_CHANNEL_NUM == 3
78 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
79 #define OUTPUT_CH_ENABLE 0x00000007
80 #elif OUT_CHANNEL_NUM == 4
81 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
82 #define OUTPUT_CH_ENABLE 0x0000000f
83 #elif OUT_CHANNEL_NUM == 5
84 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
85 #define OUTPUT_CH_ENABLE 0x0000001f
86 #elif OUT_CHANNEL_NUM == 6
87 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
88 #define OUTPUT_CH_ENABLE 0x0000003F
89 #elif OUT_CHANNEL_NUM == 7
90 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
91 #define OUTPUT_CH_ENABLE 0x0000007f
92 #elif OUT_CHANNEL_NUM == 8
93 #define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
94 #define OUTPUT_CH_ENABLE 0x000000ff
95 #endif
96
97 /* AudioFreq * DataSize (2 bytes) * NumChannels */
98 #define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_OUT_MAX_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
99 #define AUDIO_IN_PACKET ((uint32_t)((AUDIO_IN_MAX_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
100
101 #if USING_FEEDBACK == 0
102 #define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
103 AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
104 AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
105 AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
106 AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
107 AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
108 AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
109 AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
110 AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
111 AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
112 AUDIO_V2_AS_DESCRIPTOR_INIT_LEN + \
113 AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
114 #else
115 #define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
116 AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
117 AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
118 AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
119 AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
120 AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
121 AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
122 AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
123 AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
124 AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
125 AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN + \
126 AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
127 #endif
128
129 #define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \
130 AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
131 AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
132 AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
133 AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
134 AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
135 AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
136 AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
137 AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
138
139 #ifdef CONFIG_USBDEV_ADVANCE_DESC
140 static const uint8_t device_descriptor[] = {
141 USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
142 };
143
144 static const uint8_t config_descriptor[] = {
145 USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
146 AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00),
147 AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
148 AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
149 AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL),
150 AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
151 AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03),
152 AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
153 AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL),
154 AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000),
155 #if USING_FEEDBACK == 0
156 AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
157 #else
158 AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
159 #endif
160 AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
161 };
162
163 static const uint8_t device_quality_descriptor[] = {
164 ///////////////////////////////////////
165 /// device qualifier descriptor
166 ///////////////////////////////////////
167 0x0a,
168 USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
169 0x00,
170 0x02,
171 0x00,
172 0x00,
173 0x00,
174 0x40,
175 0x00,
176 0x00,
177 };
178
179 static const char *string_descriptors[] = {
180 (const char[]){ 0x09, 0x04 }, /* Langid */
181 "CherryUSB", /* Manufacturer */
182 "CherryUSB UAC DEMO", /* Product */
183 "2022123456", /* Serial Number */
184 };
185
device_descriptor_callback(uint8_t speed)186 static const uint8_t *device_descriptor_callback(uint8_t speed)
187 {
188 return device_descriptor;
189 }
190
config_descriptor_callback(uint8_t speed)191 static const uint8_t *config_descriptor_callback(uint8_t speed)
192 {
193 return config_descriptor;
194 }
195
device_quality_descriptor_callback(uint8_t speed)196 static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
197 {
198 return device_quality_descriptor;
199 }
200
string_descriptor_callback(uint8_t speed,uint8_t index)201 static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
202 {
203 if (index > 3) {
204 return NULL;
205 }
206 return string_descriptors[index];
207 }
208
209 const struct usb_descriptor audio_v2_descriptor = {
210 .device_descriptor_callback = device_descriptor_callback,
211 .config_descriptor_callback = config_descriptor_callback,
212 .device_quality_descriptor_callback = device_quality_descriptor_callback,
213 .string_descriptor_callback = string_descriptor_callback
214 };
215 #else
216 uint8_t audio_v2_descriptor[] = {
217 USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
218 USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
219 AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00),
220 AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
221 AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
222 AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL),
223 AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
224 AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03),
225 AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
226 AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL),
227 AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000),
228 #if USING_FEEDBACK == 0
229 AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
230 #else
231 AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
232 #endif
233 AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
234 ///////////////////////////////////////
235 /// string0 descriptor
236 ///////////////////////////////////////
237 USB_LANGID_INIT(USBD_LANGID_STRING),
238 ///////////////////////////////////////
239 /// string1 descriptor
240 ///////////////////////////////////////
241 0x14, /* bLength */
242 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
243 'C', 0x00, /* wcChar0 */
244 'h', 0x00, /* wcChar1 */
245 'e', 0x00, /* wcChar2 */
246 'r', 0x00, /* wcChar3 */
247 'r', 0x00, /* wcChar4 */
248 'y', 0x00, /* wcChar5 */
249 'U', 0x00, /* wcChar6 */
250 'S', 0x00, /* wcChar7 */
251 'B', 0x00, /* wcChar8 */
252 ///////////////////////////////////////
253 /// string2 descriptor
254 ///////////////////////////////////////
255 0x26, /* bLength */
256 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
257 'C', 0x00, /* wcChar0 */
258 'h', 0x00, /* wcChar1 */
259 'e', 0x00, /* wcChar2 */
260 'r', 0x00, /* wcChar3 */
261 'r', 0x00, /* wcChar4 */
262 'y', 0x00, /* wcChar5 */
263 'U', 0x00, /* wcChar6 */
264 'S', 0x00, /* wcChar7 */
265 'B', 0x00, /* wcChar8 */
266 ' ', 0x00, /* wcChar9 */
267 'U', 0x00, /* wcChar10 */
268 'A', 0x00, /* wcChar11 */
269 'C', 0x00, /* wcChar12 */
270 ' ', 0x00, /* wcChar13 */
271 'D', 0x00, /* wcChar14 */
272 'E', 0x00, /* wcChar15 */
273 'M', 0x00, /* wcChar16 */
274 'O', 0x00, /* wcChar17 */
275 ///////////////////////////////////////
276 /// string3 descriptor
277 ///////////////////////////////////////
278 0x16, /* bLength */
279 USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
280 '2', 0x00, /* wcChar0 */
281 '0', 0x00, /* wcChar1 */
282 '2', 0x00, /* wcChar2 */
283 '1', 0x00, /* wcChar3 */
284 '0', 0x00, /* wcChar4 */
285 '3', 0x00, /* wcChar5 */
286 '1', 0x00, /* wcChar6 */
287 '0', 0x00, /* wcChar7 */
288 '0', 0x00, /* wcChar8 */
289 #if USING_FEEDBACK == 0
290 '3', 0x00, /* wcChar9 */
291 #else
292 '4', 0x00, /* wcChar9 */
293 #endif
294 #ifdef CONFIG_USB_HS
295 ///////////////////////////////////////
296 /// device qualifier descriptor
297 ///////////////////////////////////////
298 0x0a,
299 USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
300 0x00,
301 0x02,
302 0x00,
303 0x00,
304 0x00,
305 0x40,
306 0x00,
307 0x00,
308 #endif
309 0x00
310 };
311 #endif
312
313 static const uint8_t speaker_default_sampling_freq_table[] = {
314 AUDIO_SAMPLE_FREQ_NUM(5),
315 AUDIO_SAMPLE_FREQ_4B(8000),
316 AUDIO_SAMPLE_FREQ_4B(8000),
317 AUDIO_SAMPLE_FREQ_4B(0x00),
318 AUDIO_SAMPLE_FREQ_4B(16000),
319 AUDIO_SAMPLE_FREQ_4B(16000),
320 AUDIO_SAMPLE_FREQ_4B(0x00),
321 AUDIO_SAMPLE_FREQ_4B(32000),
322 AUDIO_SAMPLE_FREQ_4B(32000),
323 AUDIO_SAMPLE_FREQ_4B(0x00),
324 AUDIO_SAMPLE_FREQ_4B(48000),
325 AUDIO_SAMPLE_FREQ_4B(48000),
326 AUDIO_SAMPLE_FREQ_4B(0x00),
327 AUDIO_SAMPLE_FREQ_4B(96000),
328 AUDIO_SAMPLE_FREQ_4B(96000),
329 AUDIO_SAMPLE_FREQ_4B(0x00)
330 };
331
332 static const uint8_t mic_default_sampling_freq_table[] = {
333 AUDIO_SAMPLE_FREQ_NUM(1),
334 AUDIO_SAMPLE_FREQ_4B(16000),
335 AUDIO_SAMPLE_FREQ_4B(16000),
336 AUDIO_SAMPLE_FREQ_4B(0x00)
337 };
338
339 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
340 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
341
342 volatile bool tx_flag = 0;
343 volatile bool rx_flag = 0;
344 volatile bool ep_tx_busy_flag = false;
345 volatile uint32_t s_mic_sample_rate;
346 volatile uint32_t s_speaker_sample_rate;
347
usbd_event_handler(uint8_t busid,uint8_t event)348 static void usbd_event_handler(uint8_t busid, uint8_t event)
349 {
350 switch (event) {
351 case USBD_EVENT_RESET:
352 break;
353 case USBD_EVENT_CONNECTED:
354 break;
355 case USBD_EVENT_DISCONNECTED:
356 break;
357 case USBD_EVENT_RESUME:
358 break;
359 case USBD_EVENT_SUSPEND:
360 break;
361 case USBD_EVENT_CONFIGURED:
362 break;
363 case USBD_EVENT_SET_REMOTE_WAKEUP:
364 break;
365 case USBD_EVENT_CLR_REMOTE_WAKEUP:
366 break;
367
368 default:
369 break;
370 }
371 }
372
usbd_audio_open(uint8_t busid,uint8_t intf)373 void usbd_audio_open(uint8_t busid, uint8_t intf)
374 {
375 if (intf == 1) {
376 rx_flag = 1;
377 /* setup first out ep read transfer */
378 usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
379 #if USING_FEEDBACK == 1
380 #ifdef CONFIG_USB_HS
381 uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
382 AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
383 #else
384 uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
385 AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
386 #endif
387 usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
388 #endif
389 USB_LOG_RAW("OPEN1\r\n");
390 } else {
391 tx_flag = 1;
392 USB_LOG_RAW("OPEN2\r\n");
393 }
394 }
395
usbd_audio_close(uint8_t busid,uint8_t intf)396 void usbd_audio_close(uint8_t busid, uint8_t intf)
397 {
398 if (intf == 1) {
399 rx_flag = 0;
400 USB_LOG_RAW("CLOSE1\r\n");
401 } else {
402 tx_flag = 0;
403 USB_LOG_RAW("CLOSE2\r\n");
404 }
405 }
406
usbd_audio_set_sampling_freq(uint8_t busid,uint8_t ep,uint32_t sampling_freq)407 void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
408 {
409 if (ep == AUDIO_OUT_EP) {
410 s_speaker_sample_rate = sampling_freq;
411 } else if (ep == AUDIO_IN_EP) {
412 s_mic_sample_rate = sampling_freq;
413 }
414 }
415
usbd_audio_get_sampling_freq(uint8_t busid,uint8_t ep)416 uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
417 {
418 (void)busid;
419
420 uint32_t freq = 0;
421
422 if (ep == AUDIO_OUT_EP) {
423 freq = s_speaker_sample_rate;
424 } else if (ep == AUDIO_IN_EP) {
425 freq = s_mic_sample_rate;
426 }
427
428 return freq;
429 }
430
usbd_audio_get_sampling_freq_table(uint8_t busid,uint8_t ep,uint8_t ** sampling_freq_table)431 void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sampling_freq_table)
432 {
433 if (ep == AUDIO_OUT_EP) {
434 *sampling_freq_table = (uint8_t *)speaker_default_sampling_freq_table;
435 } else if (ep == AUDIO_IN_EP) {
436 *sampling_freq_table = (uint8_t *)mic_default_sampling_freq_table;
437 } else {
438 }
439 }
440
usbd_audio_iso_out_callback(uint8_t busid,uint8_t ep,uint32_t nbytes)441 void usbd_audio_iso_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
442 {
443 USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
444 usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
445 }
446
usbd_audio_iso_in_callback(uint8_t busid,uint8_t ep,uint32_t nbytes)447 void usbd_audio_iso_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
448 {
449 USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
450 ep_tx_busy_flag = false;
451 }
452
453 #if USING_FEEDBACK == 1
usbd_audio_iso_out_feedback_callback(uint8_t busid,uint8_t ep,uint32_t nbytes)454 void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
455 {
456 USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
457 #ifdef CONFIG_USB_HS
458 uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(s_speaker_sample_rate);
459 AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
460 #else
461 uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(s_speaker_sample_rate);
462 AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
463 #endif
464 usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
465 }
466 #endif
467
468 static struct usbd_endpoint audio_out_ep = {
469 .ep_cb = usbd_audio_iso_out_callback,
470 .ep_addr = AUDIO_OUT_EP
471 };
472
473 static struct usbd_endpoint audio_in_ep = {
474 .ep_cb = usbd_audio_iso_in_callback,
475 .ep_addr = AUDIO_IN_EP
476 };
477
478 #if USING_FEEDBACK == 1
479 static struct usbd_endpoint audio_out_feedback_ep = {
480 .ep_cb = usbd_audio_iso_out_feedback_callback,
481 .ep_addr = AUDIO_OUT_FEEDBACK_EP
482 };
483 #endif
484
485 struct usbd_interface intf0;
486 struct usbd_interface intf1;
487 struct usbd_interface intf2;
488
489 struct audio_entity_info audio_entity_table[] = {
490 { .bEntityId = AUDIO_OUT_CLOCK_ID,
491 .bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE,
492 .ep = AUDIO_OUT_EP },
493 { .bEntityId = AUDIO_OUT_FU_ID,
494 .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
495 .ep = AUDIO_OUT_EP },
496 { .bEntityId = AUDIO_IN_CLOCK_ID,
497 .bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE,
498 .ep = AUDIO_IN_EP },
499 { .bEntityId = AUDIO_IN_FU_ID,
500 .bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
501 .ep = AUDIO_IN_EP },
502 };
503
audio_v2_init(uint8_t busid,uintptr_t reg_base)504 void audio_v2_init(uint8_t busid, uintptr_t reg_base)
505 {
506 #ifdef CONFIG_USBDEV_ADVANCE_DESC
507 usbd_desc_register(busid, &audio_v2_descriptor);
508 #else
509 usbd_desc_register(busid, audio_v2_descriptor);
510 #endif
511 usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4));
512 usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 4));
513 usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0200, audio_entity_table, 4));
514 usbd_add_endpoint(busid, &audio_in_ep);
515 usbd_add_endpoint(busid, &audio_out_ep);
516 #if USING_FEEDBACK == 1
517 usbd_add_endpoint(busid, &audio_out_feedback_ep);
518 #endif
519
520 usbd_initialize(busid, reg_base, usbd_event_handler);
521 }
522
audio_v2_test(uint8_t busid)523 void audio_v2_test(uint8_t busid)
524 {
525 if (tx_flag) {
526 memset(write_buffer, 'a', AUDIO_IN_PACKET);
527 ep_tx_busy_flag = true;
528 usbd_ep_start_write(busid, AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
529 while (ep_tx_busy_flag) {
530 if (tx_flag == false) {
531 break;
532 }
533 }
534 }
535 if (rx_flag) {
536 }
537 }
538