1 /*
2 * Copyright (c) 2023-2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <stdint.h>
8 #include <stdlib.h>
9
10 #include <sample_usbd.h>
11 #include "feedback.h"
12
13 #include <zephyr/device.h>
14 #include <zephyr/usb/usbd.h>
15 #include <zephyr/usb/class/usbd_uac2.h>
16 #include <zephyr/drivers/i2s.h>
17 #include <zephyr/logging/log.h>
18
19 LOG_MODULE_REGISTER(uac2_sample, LOG_LEVEL_INF);
20
21 #define HEADPHONES_OUT_TERMINAL_ID UAC2_ENTITY_ID(DT_NODELABEL(out_terminal))
22 #define MICROPHONE_IN_TERMINAL_ID UAC2_ENTITY_ID(DT_NODELABEL(in_terminal))
23
24 #define FS_SAMPLES_PER_SOF 48
25 #define HS_SAMPLES_PER_SOF 6
26 #define MAX_SAMPLES_PER_SOF MAX(FS_SAMPLES_PER_SOF, HS_SAMPLES_PER_SOF)
27 #define SAMPLE_FREQUENCY (FS_SAMPLES_PER_SOF * 1000)
28 #define SAMPLE_BIT_WIDTH 16
29 #define NUMBER_OF_CHANNELS 2
30 #define BYTES_PER_SAMPLE DIV_ROUND_UP(SAMPLE_BIT_WIDTH, 8)
31 #define BYTES_PER_SLOT (BYTES_PER_SAMPLE * NUMBER_OF_CHANNELS)
32 #define MIN_BLOCK_SIZE ((MAX_SAMPLES_PER_SOF - 1) * BYTES_PER_SLOT)
33 #define BLOCK_SIZE (MAX_SAMPLES_PER_SOF * BYTES_PER_SLOT)
34 #define MAX_BLOCK_SIZE ((MAX_SAMPLES_PER_SOF + 1) * BYTES_PER_SLOT)
35
36 /* Absolute minimum is 5 TX buffers (1 actively consumed by I2S, 2nd queued as
37 * next buffer, 3rd acquired by USB stack to receive data to, and 2 to handle
38 * SOF/I2S offset errors), but add 2 additional buffers to prevent out of memory
39 * errors when USB host decides to perform rapid terminal enable/disable cycles.
40 */
41 #define I2S_BLOCKS 7
42 K_MEM_SLAB_DEFINE_STATIC(i2s_tx_slab, ROUND_UP(MAX_BLOCK_SIZE, UDC_BUF_GRANULARITY),
43 I2S_BLOCKS, UDC_BUF_ALIGN);
44 K_MEM_SLAB_DEFINE_STATIC(i2s_rx_slab, ROUND_UP(MAX_BLOCK_SIZE, UDC_BUF_GRANULARITY),
45 I2S_BLOCKS, UDC_BUF_ALIGN);
46
47 struct usb_i2s_ctx {
48 const struct device *i2s_dev;
49 bool headphones_enabled;
50 bool microphone_enabled;
51 bool i2s_started;
52 bool rx_started;
53 bool usb_data_received;
54 bool microframes;
55 /* Counter used to determine when to start I2S and then when to start
56 * sending RX packets to host. Overflows are not a problem because this
57 * variable is not necessary after both I2S and RX is started.
58 */
59 uint8_t i2s_counter;
60 struct feedback_ctx *fb;
61
62 /* Leftover samples from I2S receive buffer, already compacted to mono,
63 * that were not sent to host. The buffer, if not NULL, is allocated
64 * from I2S RX slab.
65 */
66 uint8_t *pending_mic_buf;
67 uint8_t pending_mic_samples;
68
69 /* Rolling bit buffers for tracking nominal + 1 and nominal - 1 samples
70 * sent. Bits are mutually exclusive, i.e.:
71 * plus_ones | minus_ones = plus_ones ^ minus_ones
72 *
73 * Used to avoid overcompensation in feedback regulator. LSBs indicate
74 * latest write size.
75 */
76 uint32_t plus_ones;
77 uint32_t minus_ones;
78 };
79
uac2_terminal_update_cb(const struct device * dev,uint8_t terminal,bool enabled,bool microframes,void * user_data)80 static void uac2_terminal_update_cb(const struct device *dev, uint8_t terminal,
81 bool enabled, bool microframes,
82 void *user_data)
83 {
84 struct usb_i2s_ctx *ctx = user_data;
85
86 ctx->microframes = microframes;
87
88 if (terminal == HEADPHONES_OUT_TERMINAL_ID) {
89 ctx->headphones_enabled = enabled;
90 } else if (terminal == MICROPHONE_IN_TERMINAL_ID) {
91 ctx->microphone_enabled = enabled;
92 }
93
94 if (ctx->i2s_started && !ctx->headphones_enabled &&
95 !ctx->microphone_enabled) {
96 i2s_trigger(ctx->i2s_dev, I2S_DIR_BOTH, I2S_TRIGGER_DROP);
97 ctx->i2s_started = false;
98 ctx->rx_started = false;
99 ctx->i2s_counter = 0;
100 ctx->plus_ones = ctx->minus_ones = 0;
101 if (ctx->pending_mic_samples) {
102 k_mem_slab_free(&i2s_rx_slab, ctx->pending_mic_buf);
103 ctx->pending_mic_buf = NULL;
104 ctx->pending_mic_samples = 0;
105 }
106 }
107 }
108
nominal_samples_per_sof(struct usb_i2s_ctx * ctx)109 static int nominal_samples_per_sof(struct usb_i2s_ctx *ctx)
110 {
111 if (USBD_SUPPORTS_HIGH_SPEED && ctx->microframes) {
112 return HS_SAMPLES_PER_SOF;
113 }
114
115 return FS_SAMPLES_PER_SOF;
116 }
117
uac2_get_recv_buf(const struct device * dev,uint8_t terminal,uint16_t size,void * user_data)118 static void *uac2_get_recv_buf(const struct device *dev, uint8_t terminal,
119 uint16_t size, void *user_data)
120 {
121 ARG_UNUSED(dev);
122 struct usb_i2s_ctx *ctx = user_data;
123 void *buf = NULL;
124 int ret;
125
126 if (terminal == HEADPHONES_OUT_TERMINAL_ID) {
127 __ASSERT_NO_MSG(size <= MAX_BLOCK_SIZE);
128
129 if (!ctx->headphones_enabled) {
130 LOG_ERR("Buffer request on disabled terminal");
131 return NULL;
132 }
133
134 ret = k_mem_slab_alloc(&i2s_tx_slab, &buf, K_NO_WAIT);
135 if (ret != 0) {
136 buf = NULL;
137 }
138 }
139
140 return buf;
141 }
142
uac2_data_recv_cb(const struct device * dev,uint8_t terminal,void * buf,uint16_t size,void * user_data)143 static void uac2_data_recv_cb(const struct device *dev, uint8_t terminal,
144 void *buf, uint16_t size, void *user_data)
145 {
146 struct usb_i2s_ctx *ctx = user_data;
147 int nominal = nominal_samples_per_sof(ctx);
148 int ret;
149
150 ctx->usb_data_received = true;
151
152 if (!ctx->headphones_enabled && !ctx->microphone_enabled) {
153 k_mem_slab_free(&i2s_tx_slab, buf);
154 return;
155 }
156
157 if (!size) {
158 /* This code path is expected when host only records microphone
159 * data and is not streaming any audio to the headphones. Simply
160 * transmit as many zero-filled samples were last sent to allow
161 * the feedback regulator to work.
162 *
163 * When host is streaming audio, this can be a transient error.
164 * While the "feedback regulator delay" is likely to differ,
165 * it is still probably best to just zero-fill last sent number
166 * of samples. If we overcompensate as a result, the situation
167 * will stabilize after a while anyway.
168 *
169 * In either case, we have to keep I2S going and the only way
170 * we can control the SOF to I2S offset is by varying the number
171 * of samples sent.
172 */
173 if (ctx->plus_ones & 1) {
174 size = (nominal + 1) * BYTES_PER_SLOT;
175 } else if (ctx->minus_ones & 1) {
176 size = (nominal - 1) * BYTES_PER_SLOT;
177 } else {
178 size = nominal * BYTES_PER_SLOT;
179 }
180 memset(buf, 0, size);
181 }
182
183 LOG_DBG("Received %d data to input terminal %d", size, terminal);
184
185 ret = i2s_write(ctx->i2s_dev, buf, size);
186 if (ret < 0) {
187 ctx->i2s_started = false;
188 ctx->rx_started = false;
189 ctx->i2s_counter = 0;
190 ctx->plus_ones = ctx->minus_ones = 0;
191 if (ctx->pending_mic_samples) {
192 k_mem_slab_free(&i2s_rx_slab, ctx->pending_mic_buf);
193 ctx->pending_mic_buf = NULL;
194 ctx->pending_mic_samples = 0;
195 }
196
197 /* Most likely underrun occurred, prepare I2S restart */
198 i2s_trigger(ctx->i2s_dev, I2S_DIR_BOTH, I2S_TRIGGER_PREPARE);
199
200 ret = i2s_write(ctx->i2s_dev, buf, size);
201 if (ret < 0) {
202 /* Drop data block, will try again on next frame */
203 k_mem_slab_free(&i2s_tx_slab, buf);
204 }
205 }
206
207 if (ret == 0) {
208 ctx->i2s_counter++;
209 }
210 }
211
uac2_buf_release_cb(const struct device * dev,uint8_t terminal,void * buf,void * user_data)212 static void uac2_buf_release_cb(const struct device *dev, uint8_t terminal,
213 void *buf, void *user_data)
214 {
215 if (terminal == MICROPHONE_IN_TERMINAL_ID) {
216 k_mem_slab_free(&i2s_rx_slab, buf);
217 }
218 }
219
220 /* Determine next number of samples to send, called at most once every SOF */
next_mic_num_samples(struct usb_i2s_ctx * ctx)221 static int next_mic_num_samples(struct usb_i2s_ctx *ctx)
222 {
223 int nominal = nominal_samples_per_sof(ctx);
224 int offset = feedback_samples_offset(ctx->fb);
225
226 /* The rolling buffers essentially handle controller dead time, i.e.
227 * the buffers are used to prevent overcompensating on feedback offset.
228 * Remove the oldest entry by shifting the values by one bit.
229 */
230 ctx->plus_ones <<= 1;
231 ctx->minus_ones <<= 1;
232
233 /* At Full-Speed only remember last 8 frames */
234 if (!USBD_SUPPORTS_HIGH_SPEED || !ctx->microframes) {
235 ctx->plus_ones &= 0x000000FF;
236 ctx->minus_ones &= 0x000000FF;
237 }
238
239 if ((offset < 0) && (POPCOUNT(ctx->plus_ones) < -offset)) {
240 /* I2S buffer starts at least 1 sample before SOF, send nominal
241 * + 1 samples to host in order to shift offset towards 0.
242 */
243 ctx->plus_ones |= 1;
244 return nominal + 1;
245 }
246
247 if ((offset > 0) && (POPCOUNT(ctx->minus_ones) < offset)) {
248 /* I2S buffer starts at least 1 sample after SOF, send nominal
249 * - 1 samples to host in order to shift offset towards 0
250 */
251 ctx->minus_ones |= 1;
252 return nominal - 1;
253 }
254
255 /* I2S is either spot on, or the offset is expected to correct soon */
256 return nominal;
257 }
258
process_mic_data(const struct device * dev,struct usb_i2s_ctx * ctx)259 static void process_mic_data(const struct device *dev, struct usb_i2s_ctx *ctx)
260 {
261 size_t num_bytes;
262 uint8_t *dst, *src;
263 uint8_t *mic_buf;
264 void *rx_block;
265 int ret;
266 int samples_to_send, mic_samples, rx_samples, leftover_samples;
267
268 samples_to_send = next_mic_num_samples(ctx);
269
270 if (ctx->pending_mic_samples >= samples_to_send) {
271 /* No need to fetch new I2S samples, this happens shortly after
272 * we have "borrowed" samples from next buffer. This is expected
273 * and means that the streams have synchronized.
274 */
275 rx_block = NULL;
276 rx_samples = 0;
277 } else {
278 ret = i2s_read(ctx->i2s_dev, &rx_block, &num_bytes);
279 if (ret) {
280 /* No data available, I2S will restart soon */
281 return;
282 }
283
284 /* I2S operates on 2 channels (stereo) */
285 rx_samples = num_bytes / (BYTES_PER_SAMPLE * 2);
286 }
287
288 /* Prepare microphone data to send, use pending samples if any */
289 src = rx_block;
290 if (ctx->pending_mic_buf) {
291 mic_buf = ctx->pending_mic_buf;
292 mic_samples = ctx->pending_mic_samples;
293 dst = &ctx->pending_mic_buf[mic_samples * BYTES_PER_SAMPLE];
294 } else if (rx_samples >= 1) {
295 /* First sample is already in place */
296 mic_buf = rx_block;
297 dst = &mic_buf[BYTES_PER_SAMPLE];
298 src += 2 * BYTES_PER_SAMPLE;
299 mic_samples = 1;
300 rx_samples--;
301 } else {
302 /* Something went horribly wrong, free the buffer and leave */
303 k_mem_slab_free(&i2s_rx_slab, rx_block);
304 return;
305 }
306
307 /* Copy as many samples as possible, stop if mic buffer is ready */
308 while ((mic_samples < samples_to_send) && (rx_samples > 0)) {
309 memcpy(dst, src, BYTES_PER_SAMPLE);
310
311 dst += BYTES_PER_SAMPLE;
312 src += 2 * BYTES_PER_SAMPLE;
313
314 mic_samples++;
315 rx_samples--;
316 }
317
318 /* Is mic buffer ready to go? */
319 if (mic_samples < samples_to_send) {
320 /* No, we have to borrow sample from next buffer. This can only
321 * happen if we fully drained current receive buffer.
322 */
323 __ASSERT_NO_MSG(rx_samples == 0);
324
325 if (rx_block != mic_buf) {
326 /* RX buffer no longer needed, samples are in mic_buf */
327 k_mem_slab_free(&i2s_rx_slab, rx_block);
328 }
329
330 ret = i2s_read(ctx->i2s_dev, &rx_block, &num_bytes);
331 if (ret) {
332 /* No data, I2S will likely restart due to error soon */
333 ctx->pending_mic_buf = mic_buf;
334 ctx->pending_mic_samples = mic_samples;
335 return;
336 }
337
338 src = rx_block;
339 rx_samples = num_bytes / (BYTES_PER_SAMPLE * 2);
340 }
341
342 /* Copy remaining sample, under normal conditions (i.e. connected to
343 * non-malicious host) this is guaranteed to fully fill mic_buf.
344 */
345 while ((mic_samples < samples_to_send) && (rx_samples > 0)) {
346 memcpy(dst, src, BYTES_PER_SAMPLE);
347
348 dst += BYTES_PER_SAMPLE;
349 src += 2 * BYTES_PER_SAMPLE;
350
351 mic_samples++;
352 rx_samples--;
353 }
354
355 /* Are we still short on samples? */
356 if (mic_samples < samples_to_send) {
357 /* The only possibility for this code to execute is that we were
358 * short on samples and the next block (pointed to by rx_block)
359 * did not contain enough samples to fill the gap.
360 */
361 __ASSERT_NO_MSG(rx_block != mic_buf);
362
363 /* Bailing out at this point likely leads to faster recovery.
364 * Note that this should never happen during normal operation.
365 */
366 ctx->pending_mic_buf = mic_buf;
367 ctx->pending_mic_samples = mic_samples;
368
369 /* RX buffer is no longer needed */
370 k_mem_slab_free(&i2s_rx_slab, rx_block);
371 return;
372 }
373
374 /* Handle any potential leftover, start by sanitizing length */
375 leftover_samples = mic_samples - samples_to_send + rx_samples;
376 if (leftover_samples > (MAX_BLOCK_SIZE / BYTES_PER_SAMPLE)) {
377 size_t dropped_samples =
378 leftover_samples - (MAX_BLOCK_SIZE / BYTES_PER_SAMPLE);
379
380 LOG_WRN("Too many leftover samples, dropping %d samples",
381 dropped_samples);
382 if (rx_samples >= dropped_samples) {
383 rx_samples -= dropped_samples;
384 } else {
385 mic_samples -= (dropped_samples - rx_samples);
386 rx_samples = 0;
387 }
388
389 leftover_samples = (MAX_BLOCK_SIZE / BYTES_PER_SAMPLE);
390 }
391
392 if (leftover_samples == 0) {
393 /* No leftover samples */
394 if ((rx_block != NULL) && (rx_block != mic_buf)) {
395 /* All samples were copied, free source buffer */
396 k_mem_slab_free(&i2s_rx_slab, rx_block);
397 }
398 rx_block = NULL;
399 } else if ((mic_samples > samples_to_send) ||
400 ((rx_samples > 0) && (rx_block == mic_buf))) {
401 /* Leftover samples have to be copied to new buffer */
402 ret = k_mem_slab_alloc(&i2s_rx_slab, &rx_block, K_NO_WAIT);
403 if (ret != 0) {
404 LOG_WRN("Out of memory dropping %d samples",
405 leftover_samples);
406 mic_samples = samples_to_send;
407 rx_samples = 0;
408 rx_block = NULL;
409 }
410 }
411
412 /* At this point rx_block is either
413 * * NULL if there are no leftover samples, OR
414 * * src buffer if leftover data can be copied from back to front, OR
415 * * brand new buffer if there is leftover data in mic buffer.
416 */
417 ctx->pending_mic_buf = rx_block;
418 ctx->pending_mic_samples = 0;
419
420 /* Copy excess samples from pending mic buf, if any */
421 if (mic_samples > samples_to_send) {
422 size_t bytes;
423
424 /* Samples in mic buffer are already compacted */
425 bytes = (mic_samples - samples_to_send) * BYTES_PER_SAMPLE;
426 memcpy(ctx->pending_mic_buf, &mic_buf[mic_samples], bytes);
427
428 ctx->pending_mic_samples = mic_samples - samples_to_send;
429 dst = &ctx->pending_mic_buf[bytes];
430 } else {
431 dst = ctx->pending_mic_buf;
432 }
433
434 /* Copy excess samples from src buffer, so we don't lose any */
435 while (rx_samples > 0) {
436 memcpy(dst, src, BYTES_PER_SAMPLE);
437
438 dst += BYTES_PER_SAMPLE;
439 src += 2 * BYTES_PER_SAMPLE;
440
441 ctx->pending_mic_samples++;
442 rx_samples--;
443 }
444
445 /* Finally send the microphone samples to host */
446 if (usbd_uac2_send(dev, MICROPHONE_IN_TERMINAL_ID,
447 mic_buf, mic_samples * BYTES_PER_SAMPLE) < 0) {
448 k_mem_slab_free(&i2s_rx_slab, mic_buf);
449 }
450 }
451
uac2_sof(const struct device * dev,void * user_data)452 static void uac2_sof(const struct device *dev, void *user_data)
453 {
454 ARG_UNUSED(dev);
455 struct usb_i2s_ctx *ctx = user_data;
456
457 if (ctx->i2s_started) {
458 feedback_process(ctx->fb);
459 }
460
461 /* If we didn't receive data since last SOF but either terminal is
462 * enabled, then we have to come up with the buffer ourself to keep
463 * I2S going.
464 */
465 if (!ctx->usb_data_received &&
466 (ctx->microphone_enabled || ctx->headphones_enabled)) {
467 /* No data received since last SOF but we have to keep going */
468 void *buf;
469 int ret;
470
471 ret = k_mem_slab_alloc(&i2s_tx_slab, &buf, K_NO_WAIT);
472 if (ret != 0) {
473 buf = NULL;
474 }
475
476 if (buf) {
477 /* Use size 0 to utilize zero-fill functionality */
478 uac2_data_recv_cb(dev, HEADPHONES_OUT_TERMINAL_ID,
479 buf, 0, user_data);
480 }
481 }
482 ctx->usb_data_received = false;
483
484 /* We want to maintain 3 SOFs delay, i.e. samples received from host
485 * during SOF n should be transmitted on I2S during SOF n+3. This
486 * provides enough wiggle room for software scheduling that effectively
487 * eliminates "buffers not provided in time" problem.
488 *
489 * ">= 2" translates into 3 SOFs delay because the timeline is:
490 * USB SOF n
491 * OUT DATA0 n received from host
492 * USB SOF n+1
493 * DATA0 n is available to UDC driver (See Universal Serial Bus
494 * Specification Revision 2.0 5.12.5 Data Prebuffering) and copied
495 * to I2S buffer before SOF n+2; i2s_counter = 1
496 * OUT DATA0 n+1 received from host
497 * USB SOF n+2
498 * DATA0 n+1 is copied; i2s_counter = 2
499 * OUT DATA0 n+2 received from host
500 * USB SOF n+3
501 * This function triggers I2S start
502 * DATA0 n+2 is copied; i2s_counter is no longer relevant
503 * OUT DATA0 n+3 received from host
504 */
505 if (!ctx->i2s_started &&
506 (ctx->headphones_enabled || ctx->microphone_enabled) &&
507 ctx->i2s_counter >= 2) {
508 i2s_trigger(ctx->i2s_dev, I2S_DIR_BOTH, I2S_TRIGGER_START);
509 ctx->i2s_started = true;
510 feedback_start(ctx->fb, ctx->i2s_counter, ctx->microframes);
511 ctx->i2s_counter = 0;
512 }
513
514 /* Start sending I2S RX data only when there are at least 3 buffers
515 * ready with data. This guarantees that there'll always be a buffer
516 * available from which sample can be borrowed.
517 */
518 if (!ctx->rx_started && ctx->i2s_started && ctx->i2s_counter >= 3) {
519 ctx->rx_started = true;
520 }
521
522 if (ctx->rx_started) {
523 process_mic_data(dev, ctx);
524 }
525 }
526
527 static struct uac2_ops usb_audio_ops = {
528 .sof_cb = uac2_sof,
529 .terminal_update_cb = uac2_terminal_update_cb,
530 .get_recv_buf = uac2_get_recv_buf,
531 .data_recv_cb = uac2_data_recv_cb,
532 .buf_release_cb = uac2_buf_release_cb,
533 };
534
535 static struct usb_i2s_ctx main_ctx;
536
main(void)537 int main(void)
538 {
539 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(uac2_headset));
540 struct usbd_context *sample_usbd;
541 struct i2s_config config;
542 int ret;
543
544 main_ctx.i2s_dev = DEVICE_DT_GET(DT_NODELABEL(i2s_rxtx));
545
546 if (!device_is_ready(main_ctx.i2s_dev)) {
547 printk("%s is not ready\n", main_ctx.i2s_dev->name);
548 return 0;
549 }
550
551 config.word_size = SAMPLE_BIT_WIDTH;
552 config.channels = NUMBER_OF_CHANNELS;
553 config.format = I2S_FMT_DATA_FORMAT_I2S;
554 config.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER;
555 config.frame_clk_freq = SAMPLE_FREQUENCY;
556 config.mem_slab = &i2s_tx_slab;
557 config.block_size = MAX_BLOCK_SIZE;
558 config.timeout = 0;
559
560 ret = i2s_configure(main_ctx.i2s_dev, I2S_DIR_TX, &config);
561 if (ret < 0) {
562 printk("Failed to configure TX stream: %d\n", ret);
563 return 0;
564 }
565
566 config.mem_slab = &i2s_rx_slab;
567 ret = i2s_configure(main_ctx.i2s_dev, I2S_DIR_RX, &config);
568 if (ret < 0) {
569 printk("Failed to configure RX stream: %d\n", ret);
570 return 0;
571 }
572
573 main_ctx.fb = feedback_init();
574
575 usbd_uac2_set_ops(dev, &usb_audio_ops, &main_ctx);
576
577 sample_usbd = sample_usbd_init_device(NULL);
578 if (sample_usbd == NULL) {
579 return -ENODEV;
580 }
581
582 ret = usbd_enable(sample_usbd);
583 if (ret) {
584 return ret;
585 }
586
587 return 0;
588 }
589