2#include <zephyr/device.h>
3#include <zephyr/kernel.h>
4#include <zephyr/logging/log.h>
5#include <zephyr/usb/class/usbd_uac2.h>
6#include <zephyr/usb/usbd.h>
66 block_sz_ = (uint16_t)((frame + 3u) & ~3u);
67 uint8_t count = (uint8_t)(kPipelineDepth * 2u);
69 slab_buf_.resize((
size_t)block_sz_ * count);
70 if (k_mem_slab_init(&slab_, slab_buf_.data(), block_sz_, count) != 0) {
71 LOG_ERR(
"USBAudioDeviceZephyr: k_mem_slab_init failed");
76 uac2_dev_ = DEVICE_DT_GET(DT_ALIAS(uac2_dev));
77 if (!device_is_ready(uac2_dev_)) {
78 LOG_ERR(
"USBAudioDeviceZephyr: UAC2 device not ready");
83 static const struct uac2_ops ops = {
84 .terminal_update_cb = s_terminal_update,
85 .get_recv_buf = s_get_recv_buf,
86 .data_recv_cb = s_data_recv,
87 .buf_release_cb = s_buf_release,
88 .get_explicit_feedback = s_get_feedback,
90 usbd_uac2_set_ops(uac2_dev_, &ops,
this);
93 LOG_INF(
"USBAudioDeviceZephyr: started (%u Hz, %u ch, %u bit)",
102 LOG_INF(
"USBAudioDeviceZephyr: stopped");
106 rx_cb_ = std::move(cb);
110 tx_cb_ = std::move(cb);
128 "USBAudioDeviceZephyr: audio format change ignored — "
129 "DTS descriptor is fixed at build time");
141 BaseBuffer<uint8_t>& bufferRx()
override {
return default_buffer_rx_; }
144 RingBuffer<uint8_t> default_buffer_tx_{1};
145 RingBuffer<uint8_t> default_buffer_rx_{1};
149 static void s_terminal_update(
const struct device* ,
150 uint8_t ,
bool enabled,
151 bool ,
void* user_data) {
153 self->streaming_ = enabled;
154 if (enabled && self->config_.enable_ep_in) {
155 self->primeTxPipeline();
157 LOG_INF(
"USBAudioDeviceZephyr: streaming %s",
158 enabled ?
"started" :
"stopped");
161 static void* s_get_recv_buf(
const struct device* ,
165 if (!self->is_active_ || !self->config_.enable_ep_out)
return nullptr;
167 if (k_mem_slab_alloc(&self->slab_, &buf, K_NO_WAIT) != 0) {
168 LOG_WRN(
"USBAudioDeviceZephyr: slab alloc failed (overrun)");
174 static void s_data_recv(
const struct device* , uint8_t ,
175 void* buf, uint16_t size,
void* user_data) {
177 if (!self->is_active_ || !buf) {
178 if (buf) k_mem_slab_free(&self->slab_, buf);
182 self->rx_cb_(
static_cast<const uint8_t*
>(buf), size);
184 k_mem_slab_free(&self->slab_, buf);
187 static void s_buf_release(
const struct device* , uint8_t ,
188 void* buf,
void* user_data) {
191 k_mem_slab_free(&self->slab_, buf);
193 if (!self->is_active_ || !self->streaming_ || !self->tx_cb_)
return;
195 void* next =
nullptr;
196 if (k_mem_slab_alloc(&self->slab_, &next, K_NO_WAIT) != 0)
return;
199 self->tx_cb_(
static_cast<uint8_t*
>(next), self->block_sz_);
200 if (filled < self->block_sz_) {
201 memset(
static_cast<uint8_t*
>(next) + filled, 0,
202 (
size_t)(self->block_sz_ - filled));
204 if (usbd_uac2_send(self->uac2_dev_, self->config_.terminal_id, next,
205 self->block_sz_) != 0) {
206 k_mem_slab_free(&self->slab_, next);
210 static uint32_t s_get_feedback(
const struct device* ,
211 uint8_t ,
void* user_data) {
213 uint32_t spf = self->config_.sample_rate / 1000U;
214 return (spf << 14) & 0x00FFFFFFu;
219 void primeTxPipeline() {
221 for (uint8_t i = 0; i < kPipelineDepth; ++i) {
223 if (k_mem_slab_alloc(&slab_, &buf, K_NO_WAIT) != 0)
break;
224 uint16_t filled = tx_cb_(
static_cast<uint8_t*
>(buf), block_sz_);
225 if (filled < block_sz_) {
226 memset(
static_cast<uint8_t*
>(buf) + filled, 0,
227 (
size_t)(block_sz_ - filled));
229 if (usbd_uac2_send(uac2_dev_, config_.
terminal_id, buf, block_sz_) != 0) {
230 k_mem_slab_free(&slab_, buf);
238 USBAudioConfig config_;
239 const struct device* uac2_dev_ =
nullptr;
240 struct k_mem_slab slab_{};
241 std::vector<uint8_t> slab_buf_;
242 bool is_active_ =
false;
243 bool streaming_ =
false;
244 uint16_t block_sz_ = 0;
246 std::function<void(
const uint8_t*, uint16_t)> rx_cb_;
247 std::function<uint16_t(uint8_t*, uint16_t)> tx_cb_;
249 static constexpr uint8_t kPipelineDepth = 3;
LOG_MODULE_DECLARE(usb_audio_device_zephyr, LOG_LEVEL_INF)
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:26
@ RXTX_MODE
Definition AudioTypes.h:26
@ TX_MODE
Definition AudioTypes.h:26
@ RX_MODE
Definition AudioTypes.h:26
USBAudioDeviceESP32 USBAudioStream
USBAudioStream type alias for ESP32.
Definition USBAudioDeviceESP32.h:207