-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
samples: usb: add UAC2 implicit feedback sample #70029
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(usb_audio_async_i2s) | ||
|
||
include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) | ||
target_sources(app PRIVATE src/main.c) | ||
|
||
if (CONFIG_SOC_COMPATIBLE_NRF5340_CPUAPP) | ||
target_sources(app PRIVATE src/feedback_nrf53.c) | ||
else() | ||
target_sources(app PRIVATE src/feedback_dummy.c) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Copyright (c) 2023-2024 Nordic Semiconductor ASA | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
# Source common USB sample options used to initialize new experimental USB | ||
# device stack. The scope of these options is limited to USB samples in project | ||
# tree, you cannot use them in your own application. | ||
source "samples/subsys/usb/common/Kconfig.sample_usbd" | ||
|
||
source "Kconfig.zephyr" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
.. zephyr:code-sample:: uac2-implicit-feedback | ||
:name: USB Audio asynchronous implicit feedback sample | ||
:relevant-api: usbd_api uac2_device i2s_interface | ||
|
||
USB Audio 2 implicit feedback sample playing stereo and recording mono audio | ||
on I2S interface. | ||
|
||
Overview | ||
******** | ||
|
||
This sample demonstrates how to implement USB asynchronous bidirectional audio | ||
with implicit feedback. The host adjusts number of stereo samples sent for | ||
headphones playback based on the number of mono microphone samples received. | ||
|
||
Requirements | ||
************ | ||
|
||
Target must be able to measure I2S block start (i.e. first sample from output | ||
buffer gets out) relative to USB SOF. The relative offset must be reported with | ||
single sample accuracy. | ||
|
||
This sample has been tested on :ref:`nrf5340dk_nrf5340`. While for actual audio | ||
experience it is necessary to connect external I2S ADC and I2S DAC, simple echo | ||
can be accomplished by shorting I2S data output with I2S data input. | ||
|
||
Theoretically it should be possible to obtain the timing information based on | ||
I2S and USB interrupts, but currently neither subsystem currently provides | ||
necessary timestamp information. | ||
|
||
Building and Running | ||
******************** | ||
|
||
The code can be found in :zephyr_file:`samples/subsys/usb/uac2_implicit_feedback`. | ||
|
||
To build and flash the application: | ||
|
||
.. zephyr-app-commands:: | ||
:zephyr-app: samples/subsys/usb/uac2_implicit_feedback | ||
:board: nrf5340dk/nrf5340/cpuapp | ||
:goals: build flash | ||
:compact: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright (c) 2023 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <dt-bindings/usb/audio.h> | ||
|
||
/ { | ||
uac2_headset: usb_audio2 { | ||
compatible = "zephyr,uac2"; | ||
status = "okay"; | ||
audio-function = <AUDIO_FUNCTION_HEADSET>; | ||
|
||
uac_aclk: aclk { | ||
compatible = "zephyr,uac2-clock-source"; | ||
clock-type = "internal-programmable"; | ||
frequency-control = "host-programmable"; | ||
sampling-frequencies = <48000>; | ||
}; | ||
|
||
out_terminal: out_terminal { | ||
compatible = "zephyr,uac2-input-terminal"; | ||
clock-source = <&uac_aclk>; | ||
terminal-type = <USB_TERMINAL_STREAMING>; | ||
front-left; | ||
front-right; | ||
}; | ||
|
||
headphones_output: headphones { | ||
compatible = "zephyr,uac2-output-terminal"; | ||
data-source = <&out_terminal>; | ||
clock-source = <&uac_aclk>; | ||
terminal-type = <BIDIRECTIONAL_TERMINAL_HEADSET>; | ||
assoc-terminal = <&mic_input>; | ||
}; | ||
|
||
mic_input: microphone { | ||
compatible = "zephyr,uac2-input-terminal"; | ||
clock-source = <&uac_aclk>; | ||
terminal-type = <BIDIRECTIONAL_TERMINAL_HEADSET>; | ||
/* Circular reference, macros will figure it out and | ||
* provide correct associated terminal ID because the | ||
* terminals associations are always 1-to-1. | ||
* | ||
* assoc-terminal = <&headphones_output>; | ||
*/ | ||
front-left; | ||
}; | ||
|
||
in_terminal: in_terminal { | ||
compatible = "zephyr,uac2-output-terminal"; | ||
data-source = <&mic_input>; | ||
clock-source = <&uac_aclk>; | ||
terminal-type = <USB_TERMINAL_STREAMING>; | ||
}; | ||
|
||
as_iso_out: out_interface { | ||
compatible = "zephyr,uac2-audio-streaming"; | ||
linked-terminal = <&out_terminal>; | ||
implicit-feedback; | ||
subslot-size = <2>; | ||
bit-resolution = <16>; | ||
}; | ||
|
||
as_iso_in: in_interface { | ||
compatible = "zephyr,uac2-audio-streaming"; | ||
linked-terminal = <&in_terminal>; | ||
implicit-feedback; | ||
subslot-size = <2>; | ||
bit-resolution = <16>; | ||
}; | ||
}; | ||
}; |
2 changes: 2 additions & 0 deletions
2
samples/subsys/usb/uac2_implicit_feedback/boards/nrf5340dk_nrf5340_cpuapp.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
#Enable timer for asynchronous feedback | ||
CONFIG_NRFX_TIMER2=y |
29 changes: 29 additions & 0 deletions
29
samples/subsys/usb/uac2_implicit_feedback/boards/nrf5340dk_nrf5340_cpuapp.overlay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright (c) 2023 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include "../app.overlay" | ||
|
||
&pinctrl { | ||
i2s0_default_alt: i2s0_default_alt { | ||
group1 { | ||
psels = <NRF_PSEL(I2S_SCK_M, 1, 15)>, | ||
<NRF_PSEL(I2S_LRCK_M, 1, 12)>, | ||
<NRF_PSEL(I2S_SDOUT, 1, 13)>, | ||
<NRF_PSEL(I2S_SDIN, 1, 14)>; | ||
}; | ||
}; | ||
}; | ||
|
||
&clock { | ||
hfclkaudio-frequency = <12288000>; | ||
}; | ||
|
||
i2s_rxtx: &i2s0 { | ||
status = "okay"; | ||
pinctrl-0 = <&i2s0_default_alt>; | ||
pinctrl-names = "default"; | ||
clock-source = "ACLK"; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CONFIG_I2S=y | ||
|
||
#USB related configs | ||
CONFIG_USB_DEVICE_STACK_NEXT=y | ||
CONFIG_USBD_AUDIO2_CLASS=y | ||
CONFIG_SAMPLE_USBD_PID=0x000F | ||
CONFIG_SAMPLE_USBD_PRODUCT="UAC2 implicit feedback sample" | ||
|
||
#LOG subsystem related configs | ||
CONFIG_LOG=y | ||
CONFIG_USBD_LOG_LEVEL_WRN=y | ||
CONFIG_UDC_DRIVER_LOG_LEVEL_WRN=y |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
sample: | ||
name: USB Audio 2 asynchronous implicit feedback sample | ||
tests: | ||
sample.subsys.usb.uac2_implicit_feedback: | ||
depends_on: | ||
- usbd | ||
- i2s | ||
tags: usb i2s | ||
platform_allow: nrf5340dk/nrf5340/cpuapp | ||
harness: TBD |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef FEEDBACK_H_ | ||
#define FEEDBACK_H_ | ||
|
||
#include <stdint.h> | ||
|
||
/* Nominal number of samples received on each SOF. This sample is currently | ||
* supporting only 48 kHz sample rate. | ||
*/ | ||
#define SAMPLES_PER_SOF 48 | ||
|
||
struct feedback_ctx *feedback_init(void); | ||
void feedback_reset_ctx(struct feedback_ctx *ctx); | ||
void feedback_process(struct feedback_ctx *ctx); | ||
void feedback_start(struct feedback_ctx *ctx, int i2s_blocks_queued); | ||
|
||
/* Return offset between I2S block start and USB SOF in samples. | ||
* | ||
* Positive offset means that I2S block started at least 1 sample after SOF and | ||
* to correct the situation, shorter than nominal buffers are needed. | ||
* | ||
* Negative offset means that I2S block started at least 1 sample before SOF and | ||
* to correct the situation, larger than nominal buffers are needed. | ||
* | ||
* Offset 0 means that I2S block started within 1 sample around SOF. This is the | ||
* dominant value expected during normal operation. | ||
*/ | ||
int feedback_samples_offset(struct feedback_ctx *ctx); | ||
|
||
#endif /* FEEDBACK_H_ */ |
39 changes: 39 additions & 0 deletions
39
samples/subsys/usb/uac2_implicit_feedback/src/feedback_dummy.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/kernel.h> | ||
#include "feedback.h" | ||
|
||
#warning "No target specific feedback code, overruns/underruns will occur" | ||
|
||
struct feedback_ctx *feedback_init(void) | ||
{ | ||
return NULL; | ||
} | ||
|
||
void feedback_process(struct feedback_ctx *ctx) | ||
{ | ||
ARG_UNUSED(ctx); | ||
} | ||
|
||
void feedback_reset_ctx(struct feedback_ctx *ctx) | ||
{ | ||
ARG_UNUSED(ctx); | ||
} | ||
|
||
void feedback_start(struct feedback_ctx *ctx, int i2s_blocks_queued) | ||
{ | ||
ARG_UNUSED(ctx); | ||
ARG_UNUSED(i2s_blocks_queued); | ||
} | ||
|
||
int feedback_samples_offset(struct feedback_ctx *ctx) | ||
{ | ||
ARG_UNUSED(ctx); | ||
|
||
/* Always send nominal number of samples */ | ||
return 0; | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With should normally be executed in these functions? Can some comments be added to guide customers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Read the comment in feedback.h:
https://github.com/zephyrproject-rtos/zephyr/blob/602054402313f885c2a722616ceee87c735668b6/samples/subsys/usb/uac2_implicit_feedback/src/feedback.h#L22-L33
The comment refers to what has to be reported. How this is achieved is entirely up to the implementer.
I only know how to achieve it using DPPI subsystem and TIMER on nRF53. I hope that eventually someone will come up with platform independent solution, but this is not a trivial task at all and I think it would require some sort of interrupt/event timestamping API that is simply not available yet (and some clever filtering because the control goal is to have I2S FRAMESTART and USB SOF happen at the same time, where obviously one interrupt handler will execute before the other and the two will keep "swapping" with each other which one executes first).