arduino-audio-tools
Loading...
Searching...
No Matches
USBAudioConfig.h
Go to the documentation of this file.
1#pragma once
2#include <stdint.h>
3
4#include <cstring>
5
7
8namespace audio_tools {
9
10// ── Platform-specific default USB endpoint numbers ──────────────────────────
11// Some MCUs' USB peripherals restrict isochronous transfers to one hardwired
12// endpoint number instead of allowing the stack to allocate any free one.
13//
14// nRF52833/nRF52840 caveats:
15// - The USBD peripheral has exactly one isochronous endpoint pair, hardwired
16// to endpoint number 8 (tinyusb dcd_nrf5x.c: EP_ISO_NUM == 8). Opening an
17// isochronous endpoint at any other number hits
18// TU_ASSERT(epnum == EP_ISO_NUM) and the device stops responding -- this
19// is why ep_in/ep_out/ep_fb are pinned here instead of using
20// TinyUSBDevice.allocEndpoint() like on RP2040/SAMD/STM32.
21// - ep_in and ep_fb both resolve to 0x88 (the same physical IN endpoint),
22// which is safe because they're mutually exclusive: enableFeedbackEp()
23// already requires enable_ep_in == false (see USBAudio2DescriptorBuilder),
24// matching the hardware's single ISO IN + single ISO OUT pair exactly.
25// - ep_int (the AC status/change interrupt endpoint) is NOT restricted --
26// endpoints 1-7 (control/bulk/interrupt) are freely assignable on this
27// chip -- so it keeps the generic -1 default below and is still allocated
28// dynamically even on nRF52.
29// - Because the fixed 0x88/0x08 numbers bypass allocEndpoint() entirely,
30// TinyUSBDevice's internal endpoint counters don't know endpoint 8 is
31// taken. Audio + a single CDC Serial (the common composite case) is safe
32// since CDC only needs a handful of low-numbered endpoints, but stacking
33// many other USB classes alongside Audio could in theory let one of them
34// also land on endpoint 8 and collide -- an edge case, not a concern for
35// a simple Audio+CDC composite device.
36#if defined(NRF52840_XXAA) || defined(NRF52833_XXAA)
37#ifndef USB_AUDIO_EP_IN
38#define USB_AUDIO_EP_IN 0x88
39#endif
40#ifndef USB_AUDIO_EP_OUT
41#define USB_AUDIO_EP_OUT 0x08
42#endif
43#ifndef USB_AUDIO_EP_FB
44#define USB_AUDIO_EP_FB 0x88
45#endif
46#endif
47
48// USBAudioDeviceESP32 (arduino-esp32) has no dynamic endpoint allocation of
49// its own -- whatever address is in the config is baked straight into the
50// descriptor -- so it needs real, working defaults.
51#if defined(ESP32)
52#ifndef USB_AUDIO_EP_IN
53#define USB_AUDIO_EP_IN 0x83
54#endif
55#ifndef USB_AUDIO_EP_OUT
56#define USB_AUDIO_EP_OUT 0x03
57#endif
58#ifndef USB_AUDIO_EP_FB
59#define USB_AUDIO_EP_FB 0x84
60#endif
61#ifndef USB_AUDIO_EP_INT
62#define USB_AUDIO_EP_INT 0x85
63#endif
64#endif
65
66// Everywhere else (generic TinyUSB: RP2040, SAMD, STM32) -1 tells
67// USBAudioDeviceTinyUSB::getInterfaceDescriptor() to allocate the endpoint
68// dynamically via TinyUSBDevice.allocEndpoint() instead of using a fixed
69// number. Define any of these yourself (e.g. via a build flag) to support
70// additional boards/cores, or to pin a fixed address, without touching the
71// struct or driver.
72#ifndef USB_AUDIO_EP_IN
73#define USB_AUDIO_EP_IN -1
74#endif
75#ifndef USB_AUDIO_EP_OUT
76#define USB_AUDIO_EP_OUT -1
77#endif
78#ifndef USB_AUDIO_EP_FB
79#define USB_AUDIO_EP_FB -1
80#endif
81#ifndef USB_AUDIO_EP_INT
82#define USB_AUDIO_EP_INT -1
83#endif
84
89struct USBAudioConfig : public AudioInfo {
90
91 // ── Direction ─────────────────────────────────────────────────────────────
92 bool enable_ep_in = true;
93 bool enable_ep_out = true;
94
95 // ── USB endpoint addresses ────────────────────────────────────────────────
108
109 // ── Interface numbering ───────────────────────────────────────────────────
112 uint8_t itf_num_ac = 0;
113
114 // ── Buffering ─────────────────────────────────────────────────────────────
120 uint8_t fifo_packets = 32;
121
122 // ── Device identity ───────────────────────────────────────────────────────
123 uint16_t vid = 0xCafe;
124 uint16_t pid = 0x4002;
125 const char* manufacturer = "Audio Tools";
126 const char* product = "USB Audio";
127 const char* serial = "000001";
128 bool self_powered = true;
129 uint8_t max_power_ma = 100;
130
131 // ── Advanced ──────────────────────────────────────────────────────────────
134
142
147
154
161
162#if defined(FREERTOS_H) || defined(INC_FREERTOS_H)
163 // ── FreeRTOS USB task (RP2040 + FreeRTOS only) ───────────────────────────
169 bool enable_usb_task = true;
172 int usb_task_stack_size = 1024;
175 int usb_task_priority = configMAX_PRIORITIES - 1;
179 int usb_task_write_wait_ms = 5;
180
181#endif
182 // ── Volume Handling ────────────────────────────────────────────────────────
186 bool volume_active = false;
187
188 // ── ESP32-specific ────────────────────────────────────────────────────────
192 bool begin_usb = false;
193
194 // ── Zephyr-specific ───────────────────────────────────────────────────────
199 uint8_t terminal_id = 1;
200
201 bool operator==(const USBAudioConfig& other) {
202 return sample_rate == other.sample_rate && channels == other.channels &&
204
205 enable_ep_in == other.enable_ep_in &&
206 enable_ep_out == other.enable_ep_out &&
207
208 ep_in == other.ep_in && ep_out == other.ep_out &&
209 ep_fb == other.ep_fb &&
210
211 itf_num_ac == other.itf_num_ac &&
212 fifo_packets == other.fifo_packets &&
213
214 vid == other.vid && pid == other.pid &&
215
216 std::strcmp(manufacturer ? manufacturer : "",
217 other.manufacturer ? other.manufacturer : "") == 0 &&
218
219 std::strcmp(product ? product : "",
220 other.product ? other.product : "") == 0 &&
221
222 std::strcmp(serial ? serial : "",
223 other.serial ? other.serial : "") == 0 &&
224
225 self_powered == other.self_powered &&
226 max_power_ma == other.max_power_ma &&
227
232
233 begin_usb == other.begin_usb && terminal_id == other.terminal_id;
234 }
235
236 bool operator!=(const USBAudioConfig& other) { return !(*this == other); }
237};
238
239} // namespace audio_tools
#define USB_AUDIO_EP_IN
Definition USBAudioConfig.h:53
#define USB_AUDIO_EP_FB
Definition USBAudioConfig.h:59
#define USB_AUDIO_EP_INT
Definition USBAudioConfig.h:62
#define USB_AUDIO_EP_OUT
Definition USBAudioConfig.h:56
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition LMSEchoCancellationStream.h:6
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:51
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:53
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:55
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:57
Configuration for USB Audio (inherits sample_rate / channels / bits_per_sample from AudioInfo).
Definition USBAudioConfig.h:89
bool enable_interrupt_ep
Definition USBAudioConfig.h:146
bool operator==(const USBAudioConfig &other)
Definition USBAudioConfig.h:201
int16_t ep_fb
ISO IN (explicit feedback, RX-only mode)
Definition USBAudioConfig.h:106
bool use_linear_buffer_tx
Definition USBAudioConfig.h:160
bool self_powered
Definition USBAudioConfig.h:128
const char * serial
Definition USBAudioConfig.h:127
int16_t ep_in
ISO IN (device → host, capture/microphone)
Definition USBAudioConfig.h:104
bool enable_multi_sample_rate
Definition USBAudioConfig.h:141
const char * product
Definition USBAudioConfig.h:126
int16_t ep_int
INT IN (AC status/change notifications)
Definition USBAudioConfig.h:107
uint8_t max_power_ma
Definition USBAudioConfig.h:129
bool enable_feedback_ep
Enable isochronous feedback endpoint so the host can adjust its clock.
Definition USBAudioConfig.h:133
const char * manufacturer
Definition USBAudioConfig.h:125
uint16_t pid
Definition USBAudioConfig.h:124
uint16_t vid
Definition USBAudioConfig.h:123
int16_t ep_out
ISO OUT (host → device, playback/speaker)
Definition USBAudioConfig.h:105
bool enable_ep_in
device → host (capture / microphone)
Definition USBAudioConfig.h:92
uint8_t itf_num_ac
Definition USBAudioConfig.h:112
uint8_t fifo_packets
Definition USBAudioConfig.h:120
uint8_t terminal_id
Definition USBAudioConfig.h:199
bool enable_ep_in_flow_control
Definition USBAudioConfig.h:153
bool volume_active
Definition USBAudioConfig.h:186
bool use_linear_buffer_rx
Definition USBAudioConfig.h:157
bool operator!=(const USBAudioConfig &other)
Definition USBAudioConfig.h:236
bool enable_ep_out
host → device (playback / speaker)
Definition USBAudioConfig.h:93
bool begin_usb
Definition USBAudioConfig.h:192