14#ifndef ARDUINO_USB_MODE
15#error This Microcontroller has no Native USB interface
17#if ARDUINO_USB_MODE == 1
18#error This sketch should be used when USB is in OTG mode
22#if !defined(USE_TINYUSB) && !defined(ARDUINO_ARCH_STM32) && !defined(IS_ZEPHYR)
23#error This Microcontroller has no Native USB interface
27#include "AudioLogger.h"
32#include "device/usbd.h"
33#include "device/usbd_pvt.h"
37#define USB_DESCR_MAX_LEN 512
42#ifdef TUD_AUDIO20_DESC_IAD_LEN
43#define TUD_AUDIO_DESC_IAD_LEN TUD_AUDIO20_DESC_IAD_LEN
44#define AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL \
45 AUDIO20_CS_AC_INTERFACE_INPUT_TERMINAL
46#define AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL \
47 AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL
48#define AUDIO_CS_CTRL_SAM_FREQ AUDIO20_CS_CTRL_SAM_FREQ
49#define AUDIO_CS_CTRL_CLK_VALID AUDIO20_CS_CTRL_CLK_VALID
50#define AUDIO_CS_REQ_CUR AUDIO20_CS_REQ_CUR
51#define AUDIO_CS_REQ_RANGE AUDIO20_CS_REQ_RANGE
52#define AUDIO_CS_AS_INTERFACE_AS_GENERAL AUDIO20_CS_AS_INTERFACE_AS_GENERAL
53#define AUDIO_CS_AS_INTERFACE_FORMAT_TYPE AUDIO20_CS_AS_INTERFACE_FORMAT_TYPE
54#define audio_desc_cs_ac_interface_t audio20_desc_cs_ac_interface_t
55#define audio_desc_cs_as_interface_t audio20_desc_cs_as_interface_t
56#define audio_desc_type_I_format_t audio20_desc_type_I_format_t
58#define TUSB_EDPT_XFER(rp, ep, buf, sz) usbd_edpt_xfer(rp, ep, buf, sz, false)
59#define TUSB_EDPT_XFER_FIFO(rp, ep, ff, sz) \
60 usbd_edpt_xfer_fifo(rp, ep, ff, sz, false)
61#define TUSB_FIFO_CONFIG(f, buf, d, ov) tu_fifo_config(f, buf, d, ov)
64#define TUSB_EDPT_XFER(rp, ep, buf, sz) usbd_edpt_xfer(rp, ep, buf, sz)
65#define TUSB_EDPT_XFER_FIFO(rp, ep, ff, sz) usbd_edpt_xfer_fifo(rp, ep, ff, sz)
66#define TUSB_FIFO_CONFIG(f, buf, d, ov) tu_fifo_config(f, buf, d, 1, ov)
69#ifndef AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL
70#define AUDIO10_CS_AC_INTERFACE_INPUT_TERMINAL \
71 AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL
73#ifndef AUDIO_CS_CTRL_CLK_VALID
74#define AUDIO_CS_CTRL_CLK_VALID 0x02u
76#ifndef AUDIO_CS_REQ_RANGE
77#define AUDIO_CS_REQ_RANGE 0x02u
82#ifndef AUDIO_FU_CTRL_MUTE
83#define AUDIO_FU_CTRL_MUTE 0x01u
85#ifndef AUDIO_FU_CTRL_VOLUME
86#define AUDIO_FU_CTRL_VOLUME 0x02u
93 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000};
117 enum audio_format_type_t {
119 AUDIO_FORMAT_TYPE_II,
120 AUDIO_FORMAT_TYPE_III,
129 enum audio_feedback_method_t {
130 AUDIO_FEEDBACK_METHOD_DISABLED,
131 AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED,
132 AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT,
133 AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2,
134 AUDIO_FEEDBACK_METHOD_FIFO_COUNT
143 struct audiod_function_t {
145 uint8_t
const* p_desc;
157 uint16_t desc_length;
163 uint8_t compute_method;
164 bool format_correction;
169 uint32_t sample_freq;
174 uint32_t fifo_lvl_avg;
175 uint16_t fifo_lvl_thr;
176 uint16_t rate_const[2];
180 uint32_t sample_rate_tx;
181 uint16_t packet_sz_tx[3];
182 uint8_t bclock_id_tx;
184 audio_format_type_t format_type_tx;
185 uint8_t n_channels_tx;
186 uint8_t n_bytes_per_sample_tx;
190 uint32_t tx_sample_acc;
195 std::vector<uint8_t> ctrl_buf;
196 std::vector<uint8_t> alt_setting;
197 std::vector<uint8_t> lin_buf_out;
198 std::vector<uint8_t> lin_buf_in;
199 std::vector<uint32_t> fb_buf;
200 std::vector<uint8_t> ep_in_sw_buf;
201 std::vector<uint8_t> ep_out_sw_buf;
210 struct audio_feedback_params_t {
212 uint32_t sample_freq;
260 LOGE(
"Unsupported bits_per_sample: %d (must be 16, 24, or 32)",
276 "Could not change channel count from %d to %d: channel count is "
282 "Could not change bits per sample from %d to %d: bits per sample is "
320 LOGE(
"Unsupported bits_per_sample: %d (must be 16, 24, or 32)",
344 mute_.assign(vol_sz,
false);
350 LOGE(
"beginUSB failed");
359 for (uint8_t ch = 0; ch < (uint8_t)
volume_.size(); ch++) {
412 LOGW(
"setVolume %f channel: %d", vol, channel);
413 if (channel >=
volume_.size())
return false;
424 return (channel <
mute_.size()) ?
mute_[channel] :
false;
432 LOGW(
"setMute %s channel: %d", m ?
"true" :
"false", channel);
433 if (channel >=
mute_.size())
return false;
478 if (fct.ep_in != 0)
return true;
486 if (fct.ep_out != 0)
return true;
500 bool mounted()
const {
return tud_mounted(); }
507 tusb_control_request_t
const*)>
517 tusb_control_request_t
const*)>
554 audiod_function_t*, uint16_t)>
574 tusb_control_request_t
const*)>
585 tusb_control_request_t
const*, uint8_t*)>
596 tusb_control_request_t
const*, uint8_t*)>
607 tusb_control_request_t
const*, uint8_t*)>
617 tusb_control_request_t
const*)>
628 audio_feedback_params_t*)>
645 size_t write(
const uint8_t* data,
size_t len) {
660 while (written < len) {
702 tu_fifo_clear(&audio.ep_in_ff);
703 tu_fifo_clear(&audio.ep_out_ff);
704 std::fill(audio.lin_buf_in.begin(), audio.lin_buf_in.end(), 0);
705 std::fill(audio.lin_buf_out.begin(), audio.lin_buf_out.end(), 0);
748 static usbd_class_driver_t driver;
749 driver.name =
"AUDIO";
750 driver.init = [](void) {
753 driver.deinit = [](void) {
756 driver.reset = [](uint8_t rhport) {
759 driver.open = [](uint8_t rhport, tusb_desc_interface_t
const* itf_desc,
764 driver.control_xfer_cb = [](uint8_t rhport, uint8_t stage,
765 tusb_control_request_t
const* request) {
767 rhport, stage, request);
769 driver.xfer_cb = [](uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
770 uint32_t xferred_bytes) {
772 rhport, ep_addr, result, xferred_bytes);
774 driver.sof = [](uint8_t rhport, uint32_t frame_count) {
842 uint16_t xferred_bytes)>
846 tusb_control_request_t
const*)>
850 tusb_control_request_t
const*)>
857 tusb_control_request_t
const* p_request)>
860 tusb_control_request_t
const* p_request, uint8_t* pBuff)>
864 tusb_control_request_t
const* p_request, uint8_t* pBuff)>
868 tusb_control_request_t
const* p_request, uint8_t* pBuff)>
872 tusb_control_request_t
const* p_request)>
876 audio_feedback_params_t* feedback_param)>
928 processVolume<int8_t>((int8_t*)data, len);
931 processVolume<int16_t>((int16_t*)data, len / 2);
937 processVolume<int32_t>((int32_t*)data, len / 4);
948 if (
volume_.empty())
return 1.0f;
949 if (
mute_[0])
return 0.0f;
951 if (channel >=
volume_.size())
return master;
952 if (
mute_[channel])
return 0.0f;
953 return master *
volume_[channel];
956 template <
typename T>
959 for (
size_t i = 0; i < sample_count; i++) {
960 uint8_t ch = (uint8_t)(i % ch_count) + 1;
962 data[i] = (T)(data[i] * vol);
977 LOGW(
"Sample rate changed to %u Hz", rate);
982 for (
auto& fct :
audiod_fct_) fct.sample_rate_tx = rate;
1008 if (vol <= 0.0f)
return (int16_t)0x8000;
1009 if (vol >= 1.0f)
return 0;
1016 if (v == (int16_t)0x8000)
return 0.0f;
1017 if (v >= 0)
return 1.0f;
1038 if (!tud_mounted())
return;
1039 for (uint8_t i = 0; i < (uint8_t)
audiod_fct_.size(); i++) {
1079 return bps == 16 || bps == 24 || bps == 32;
1096 while (p < sz) p <<= 1;
1103 return offsetof(audiod_function_t, ctrl_buf_sz) +
1104 sizeof(((audiod_function_t*)0)->ctrl_buf_sz);
1111 uint8_t frame_shift) {
1114 switch (audio->feedback.compute_method) {
1115 case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: {
1123 : tu_fifo_count(&audio->ep_out_ff);
1125 audio->feedback.compute.fifo_count.fifo_lvl_avg =
1126 audio->feedback.compute.fifo_count.fifo_lvl_avg -
1127 (audio->feedback.compute.fifo_count.fifo_lvl_avg >> 8) +
1128 ((uint32_t)ff_count << 8);
1129 uint32_t avg = audio->feedback.compute.fifo_count.fifo_lvl_avg >> 8;
1130 uint32_t thr = audio->feedback.compute.fifo_count.fifo_lvl_thr;
1131 uint32_t nom = audio->feedback.compute.fifo_count.nom_value;
1133 audio->feedback.value =
1134 nom + (uint32_t)audio->feedback.compute.fifo_count.rate_const[0] *
1138 (uint32_t)audio->feedback.compute.fifo_count.rate_const[1] *
1140 audio->feedback.value =
1141 (nom > drop) ? nom - drop : audio->feedback.min_value;
1143 audio->feedback.value =
1144 TU_MIN(TU_MAX(audio->feedback.value, audio->feedback.min_value),
1145 audio->feedback.max_value);
1148 case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2:
1149 audio->feedback.value = 1UL << audio->feedback.compute.power_of_2;
1152 case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT:
1153 audio->feedback.value =
1154 (uint32_t)(audio->feedback.compute.float_const *
1155 (
float)(1UL << (16u - (frame_shift - 1u))));
1158 case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED: {
1159 uint32_t frame_div =
1160 (TUSB_SPEED_FULL == tud_speed_get()) ? 1000u : 8000u;
1161 audio->feedback.value =
1162 (audio->feedback.compute.fixed.sample_freq << 16) / frame_div;
1169 if (usbd_edpt_claim(audio->rhport, audio->ep_fb)) {
1184 audio->ctrl_buf.resize(size);
1185 audio->ctrl_buf_sz = size;
1193 audio->lin_buf_in.resize(max_pkt);
1202 tu_fifo_config_mutex(&audio->ep_out_ff, NULL,
1206 audio->lin_buf_out.resize(max_pkt);
1209 audio->fb_buf.resize(1);
1232 tu_fifo_clear(&audio->ep_in_ff);
1236 tu_fifo_clear(&audio->ep_out_ff);
1242 uint16_t
audiod_open(uint8_t rhport, tusb_desc_interface_t
const* itf_desc,
1245 TU_VERIFY(TUSB_CLASS_AUDIO == itf_desc->bInterfaceClass &&
1246 AUDIO_SUBCLASS_CONTROL == itf_desc->bInterfaceSubClass);
1247 TU_VERIFY(itf_desc->bInterfaceProtocol == AUDIO_INT_PROTOCOL_CODE_V2);
1248 TU_ASSERT(itf_desc->bNumEndpoints <= 1);
1249 if (itf_desc->bNumEndpoints == 1) {
1252 TU_VERIFY(itf_desc->bAlternateSetting == 0);
1263 uint8_t ep_in = 0, ep_out = 0, ep_fb = 0;
1264 uint16_t ep_in_size = 0, ep_out_size = 0;
1265 tusb_desc_endpoint_t
const* desc_ep_out =
nullptr;
1267 uint8_t
const* p_desc_end =
1268 p_desc +
audiod_fct_[i].desc_length - TUD_AUDIO_DESC_IAD_LEN;
1269 while (p_desc_end - p_desc > 0) {
1270 if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) {
1271 tusb_desc_endpoint_t
const* desc_ep =
1272 (tusb_desc_endpoint_t
const*)p_desc;
1273 if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) {
1275 ep_fb = desc_ep->bEndpointAddress;
1277 if (desc_ep->bmAttributes.usage == 0) {
1279 tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
1280 ep_in = desc_ep->bEndpointAddress;
1282 TU_MAX(tu_edpt_packet_size(desc_ep), ep_in_size);
1284 tu_edpt_dir(desc_ep->bEndpointAddress) ==
1286 ep_out = desc_ep->bEndpointAddress;
1288 TU_MAX(tu_edpt_packet_size(desc_ep), ep_out_size);
1289 desc_ep_out = desc_ep;
1294 p_desc = tu_desc_next(p_desc);
1297 bool alloc_ok = usbd_edpt_iso_alloc(rhport, ep_in, ep_in_size);
1298 LOGD(
"iso_alloc IN ep=0x%02x sz=%u: %s", ep_in, ep_in_size,
1299 alloc_ok ?
"OK" :
"FAIL");
1302 bool alloc_ok = usbd_edpt_iso_alloc(rhport, ep_out, ep_out_size);
1303 LOGD(
"iso_alloc OUT ep=0x%02x sz=%u: %s", ep_out, ep_out_size,
1304 alloc_ok ?
"OK" :
"FAIL");
1305#ifdef TUP_DCD_EDPT_ISO_ALLOC
1311 usbd_edpt_iso_activate(rhport, desc_ep_out);
1312 usbd_edpt_release(rhport, ep_out);
1313 LOGD(
"iso_activate+release OUT: done");
1318 usbd_edpt_iso_alloc(rhport, ep_fb, 4);
1329 uint8_t
const* p_desc_end =
1330 p_desc +
audiod_fct_[i].desc_length - TUD_AUDIO_DESC_IAD_LEN;
1331 while (p_desc_end - p_desc > 0) {
1332 if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) {
1334 tusb_desc_endpoint_t
const* desc_ep =
1335 (tusb_desc_endpoint_t
const*)p_desc;
1336 if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS &&
1337 desc_ep->bmAttributes.usage == 0 &&
1338 tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) {
1342 }
else if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE) {
1343 if (tu_desc_subtype(p_desc) ==
1344 AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL) {
1345 if (tu_unaligned_read16(p_desc + 4) ==
1346 AUDIO_TERM_TYPE_USB_STREAMING) {
1349 }
else if (tu_desc_subtype(p_desc) ==
1350 AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL) {
1351 if (tu_unaligned_read16(p_desc + 4) ==
1352 AUDIO_TERM_TYPE_USB_STREAMING) {
1357 p_desc = tu_desc_next(p_desc);
1363 uint8_t
const* p_desc_end =
1364 p_desc +
audiod_fct_[i].desc_length - TUD_AUDIO_DESC_IAD_LEN;
1365 while (p_desc_end - p_desc > 0) {
1366 if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) {
1367 tusb_desc_endpoint_t
const* desc_ep =
1368 (tusb_desc_endpoint_t
const*)p_desc;
1369 uint8_t
const ep_addr = desc_ep->bEndpointAddress;
1370 if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN &&
1371 desc_ep->bmAttributes.xfer == TUSB_XFER_INTERRUPT) {
1372 if (usbd_edpt_open(
audiod_fct_[i].rhport, desc_ep)) {
1375 LOGE(
" UAC2: interrupt EP 0x%02x open failed", ep_addr);
1380 p_desc = tu_desc_next(p_desc);
1388 uint16_t drv_len =
audiod_fct_[i].desc_length - TUD_AUDIO_DESC_IAD_LEN;
1393 tusb_control_request_t
const* request) {
1394 if (stage == CONTROL_STAGE_SETUP) {
1396 }
else if (stage == CONTROL_STAGE_DATA) {
1404 tusb_control_request_t
const* p_request) {
1406 if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS &&
1407 p_request->bmRequestType_bit.direction == TUSB_DIR_OUT) {
1410 switch (p_request->bmRequestType_bit.recipient) {
1411 case TUSB_REQ_RCPT_INTERFACE: {
1412 uint8_t itf = TU_U16_LOW(p_request->wIndex);
1413 uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
1415 if (entityID != 0) {
1417 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
1418 uint8_t* cb =
audiod_fct_[func_id].ctrl_buf.data();
1422 ctrlSel == AUDIO_CS_CTRL_SAM_FREQ &&
1423 p_request->bRequest == AUDIO_CS_REQ_CUR) {
1429 p_request->bRequest == AUDIO_CS_REQ_CUR) {
1430 uint8_t channel = TU_U16_LOW(p_request->wValue);
1452 this, rhport, p_request,
1458 case TUSB_REQ_RCPT_ENDPOINT: {
1459 uint8_t ep = TU_U16_LOW(p_request->wIndex);
1467 this, rhport, p_request,
audiod_fct_[func_id].ctrl_buf.data());
1481 uint32_t xferred_bytes) {
1483 (void)xferred_bytes;
1484 for (uint8_t func_id = 0; func_id <
getAudioCount(); func_id++) {
1491 audio->alt_setting.size() != 0) {
1498 if (frame_bytes > audio->ep_in_sz) frame_bytes = audio->ep_in_sz;
1504 uint8_t* dst = audio->lin_buf_in.data();
1507 if (n < frame_bytes) memset(dst + n, 0, frame_bytes - n);
1517 if (xferred_bytes > 0)
1519 (
int)xferred_bytes);
1521 rx_done_cb_(
this, rhport, audio, (uint16_t)xferred_bytes);
1522 (void)
TUSB_EDPT_XFER(rhport, audio->ep_out, audio->lin_buf_out.data(),
1526 if (xferred_bytes > 0) {
1529 tu_fifo_read_n(&audio->ep_out_ff, tmp, (uint16_t)xferred_bytes);
1533 rx_done_cb_(
this, rhport, audio, (uint16_t)xferred_bytes);
1554 if (audio->ep_fb != 0) {
1555 uint8_t
const hs_adjust =
1556 (TUSB_SPEED_HIGH == tud_speed_get()) ? 3 : 0;
1557 uint32_t
const interval =
1558 1UL << (audio->feedback.frame_shift - hs_adjust);
1559 if (0 == (frame_count & (interval - 1))) {
1561 audio->feedback.frame_shift);
1570 tusb_control_request_t
const* p_request,
1572 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
1574 p_request->bRequest == AUDIO_CS_REQ_CUR) {
1576 return tud_control_xfer(rhport, p_request, cb, 1);
1578 if (ctrlSel == AUDIO_CS_CTRL_SAM_FREQ) {
1580 if (p_request->bRequest == AUDIO_CS_REQ_CUR) {
1581 memcpy(cb, &rate, 4);
1582 return tud_control_xfer(rhport, p_request, cb, 4);
1588 memcpy(cb, &cnt, 2);
1592 memcpy(cb + 2 + i * 12, &r, 4);
1593 memcpy(cb + 2 + i * 12 + 4, &r, 4);
1594 memcpy(cb + 2 + i * 12 + 8, &z, 4);
1596 return tud_control_xfer(rhport, p_request, cb,
1602 memcpy(cb, &cnt, 2);
1603 memcpy(cb + 2, &rate, 4);
1604 memcpy(cb + 6, &rate, 4);
1605 memcpy(cb + 10, &z, 4);
1606 return tud_control_xfer(rhport, p_request, cb, 14);
1615 tusb_control_request_t
const* p_request,
1617 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
1618 uint8_t channel = TU_U16_LOW(p_request->wValue);
1620 p_request->bRequest == AUDIO_CS_REQ_CUR) {
1621 cb[0] =
isMute(channel) ? 1 : 0;
1622 return tud_control_xfer(rhport, p_request, cb, 1);
1625 if (p_request->bRequest == AUDIO_CS_REQ_CUR) {
1628 return tud_control_xfer(rhport, p_request, cb, 2);
1632 int16_t vmin = -25600, vmax = 0, vres = 256;
1633 memcpy(cb + 0, &cnt, 2);
1634 memcpy(cb + 2, &vmin, 2);
1635 memcpy(cb + 4, &vmax, 2);
1636 memcpy(cb + 6, &vres, 2);
1637 return tud_control_xfer(rhport, p_request, cb, 8);
1645 tusb_control_request_t
const* p_request,
1647 uint8_t func_id = 0;
1648 uint8_t* cb =
audiod_fct_[func_id].ctrl_buf.data();
1649 bool is_get = (p_request->bmRequestType_bit.direction == TUSB_DIR_IN);
1654 return tud_control_xfer(rhport, p_request, cb,
1661 return tud_control_xfer(rhport, p_request, cb,
1666 uint8_t itf = TU_U16_LOW(p_request->wIndex);
1668 tud_control_status(rhport, p_request);
1672 return tud_control_xfer(rhport, p_request,
1679 tusb_control_request_t
const* p_request) {
1680 uint8_t itf = TU_U16_LOW(p_request->wIndex);
1683 if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) {
1687 return tud_control_xfer(rhport, p_request,
1694 tusb_control_request_t
const* p_request) {
1695 uint8_t ep = TU_U16_LOW(p_request->wIndex);
1698 if (p_request->bmRequestType_bit.direction == TUSB_DIR_IN) {
1702 return tud_control_xfer(rhport, p_request,
1709 tusb_control_request_t
const* p_request) {
1710 if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD) {
1711 switch (p_request->bRequest) {
1712 case TUSB_REQ_GET_INTERFACE:
1714 case TUSB_REQ_SET_INTERFACE:
1716 case TUSB_REQ_CLEAR_FEATURE:
1723 if (p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS) {
1724 switch (p_request->bmRequestType_bit.recipient) {
1725 case TUSB_REQ_RCPT_INTERFACE: {
1726 uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
1727 return (entityID != 0)
1731 case TUSB_REQ_RCPT_ENDPOINT:
1750 ((tusb_desc_interface_t
const*)
audiod_fct_[i].p_desc)
1751 ->bInterfaceNumber == itf) {
1754 uint8_t
const* p_desc =
1756 uint8_t
const* p_desc_end =
1757 ((audio_desc_cs_ac_interface_t
const*)p_desc)->wTotalLength +
1759 p_desc = tu_desc_next(p_desc);
1763 while (p_desc_end - p_desc > 0) {
1764 if (p_desc[3] == entityID)
1769 p_desc = tu_desc_next(p_desc);
1781 uint8_t
const* p_desc_end =
1785 uint8_t
const* p_desc = tu_desc_next(
audiod_fct_[i].p_desc);
1786 p_desc += ((audio_desc_cs_ac_interface_t
const*)p_desc)->wTotalLength;
1790 while (p_desc_end - p_desc > 0) {
1791 if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT &&
1792 ((tusb_desc_endpoint_t
const*)p_desc)->bEndpointAddress == ep) {
1796 p_desc = tu_desc_next(p_desc);
1809 uint8_t
const* p_desc_end =
audiod_fct_[i].p_desc +
1811 TUD_AUDIO_DESC_IAD_LEN;
1814 while (p_desc_end - p_desc > 0) {
1815 if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE &&
1816 ((tusb_desc_interface_t
const*)
audiod_fct_[i].p_desc)
1817 ->bInterfaceNumber == itf) {
1821 p_desc = tu_desc_next(p_desc);
1829 uint8_t
const* p_desc) {
1834 if (audio->sample_rate_tx == 0)
1837 p_desc = tu_desc_next(p_desc);
1842 if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE &&
1843 tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_AS_GENERAL) {
1844 audio->n_channels_tx =
1845 ((audio_desc_cs_as_interface_t
const*)p_desc)->bNrChannels;
1846 audio->format_type_tx =
1847 (audio_format_type_t)(((audio_desc_cs_as_interface_t
const*)p_desc)
1850 p_desc = tu_desc_next(p_desc);
1851 if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE &&
1852 tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_FORMAT_TYPE &&
1853 ((audio_desc_type_I_format_t
const*)p_desc)->bFormatType ==
1854 AUDIO_FORMAT_TYPE_I) {
1855 audio->n_bytes_per_sample_tx =
1856 ((audio_desc_type_I_format_t
const*)p_desc)->bSubslotSize;
1862 if (audio->n_channels_tx == 0) audio->n_channels_tx =
config_.
channels;
1863 if (audio->n_bytes_per_sample_tx == 0)
1865 if (audio->format_type_tx == 0) audio->format_type_tx = AUDIO_FORMAT_TYPE_I;
1877 uint8_t
const** pp_desc_int) {
1878 if (audio->p_desc) {
1880 uint8_t
const* p_desc_end =
1881 audio->p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN;
1884 uint8_t
const* p_desc = tu_desc_next(audio->p_desc);
1885 p_desc += ((audio_desc_cs_ac_interface_t
const*)p_desc)->wTotalLength;
1890 while (p_desc_end - p_desc > 0) {
1893 if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE &&
1894 ((tusb_desc_interface_t
const*)p_desc)->bAlternateSetting == 0) {
1895 if (((tusb_desc_interface_t
const*)p_desc)->bInterfaceNumber == itf) {
1897 *pp_desc_int = p_desc;
1903 p_desc = tu_desc_next(p_desc);
1917 uint8_t
const** pp_desc_int) {
1932 tusb_control_request_t
const* p_request) {
1933 uint8_t
const itf = tu_u16_low(p_request->wIndex);
1936 uint8_t func_id, idxItf;
1937 uint8_t
const* dummy;
1941 TU_VERIFY(tud_control_xfer(rhport, p_request,
1944 LOGI(
" Get itf: %u - current alt: %u", itf,
1951 bool apply_correction = (TUSB_SPEED_FULL == tud_speed_get()) &&
1952 audio->feedback.format_correction;
1954 if (apply_correction) {
1955 uint8_t* fb = (uint8_t*)audio->fb_buf.data();
1958 *(fb++) = (audio->feedback.value >> 2) & 0xFF;
1959 *(fb++) = (audio->feedback.value >> 10) & 0xFF;
1960 *(fb++) = (audio->feedback.value >> 18) & 0xFF;
1963 audio->fb_buf[0] = audio->feedback.value;
1981 (uint8_t*)audio->fb_buf.data(),
1982 apply_correction ? 3 : 4);
1986 void closeEpIn(uint8_t rhport, audiod_function_t* audio, uint8_t itf,
1987 tusb_control_request_t
const* p_request) {
1988 if (!
isEpInEnabled() || audio->ep_in_as_intf_num != itf)
return;
1989 audio->ep_in_as_intf_num = 0;
1990#ifndef TUP_DCD_EDPT_ISO_ALLOC
1991 usbd_edpt_close(rhport, audio->ep_in);
1993 tu_fifo_clear(&audio->ep_in_ff);
1999 audio->packet_sz_tx[0] = 0;
2000 audio->packet_sz_tx[1] = 0;
2001 audio->packet_sz_tx[2] = 0;
2006 void closeEpOut(uint8_t rhport, audiod_function_t* audio, uint8_t itf,
2007 tusb_control_request_t
const* p_request) {
2008 if (!
isEpOutEnabled() || audio->ep_out_as_intf_num != itf)
return;
2009 audio->ep_out_as_intf_num = 0;
2010#ifndef TUP_DCD_EDPT_ISO_ALLOC
2011 usbd_edpt_close(rhport, audio->ep_out);
2013 tu_fifo_clear(&audio->ep_out_ff);
2019 tu_memclr(&audio->feedback,
sizeof(audio->feedback));
2026 uint8_t dir = TUSB_DIR_IN) {
2027#ifdef TUP_DCD_EDPT_ISO_ALLOC
2032 if (dir == TUSB_DIR_OUT &&
2033 desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
2035 return usbd_edpt_iso_activate(rhport, desc_ep);
2038 return usbd_edpt_open(rhport, desc_ep);
2043 void openEpIn(uint8_t rhport, audiod_function_t* audio, uint8_t itf,
2044 tusb_desc_endpoint_t
const* desc_ep,
2045 uint8_t
const* p_desc_for_params) {
2046 audio->ep_in = desc_ep->bEndpointAddress;
2047 audio->ep_in_as_intf_num = itf;
2048 audio->ep_in_sz = tu_edpt_packet_size(desc_ep);
2049 if (audio->ep_in_sz == 0)
return;
2056 if (first_pkt > audio->ep_in_sz) first_pkt = audio->ep_in_sz;
2057 audio->lin_buf_in.assign(audio->ep_in_sz, 0);
2059 audio->lin_buf_in.data(), first_pkt);
2064 void openEpOut(uint8_t rhport, audiod_function_t* audio, uint8_t itf,
2065 tusb_desc_endpoint_t
const* desc_ep) {
2066 LOGD(
"openEpOut: ep=0x%02x sz=%u", desc_ep->bEndpointAddress,
2067 tu_edpt_packet_size(desc_ep));
2068 audio->ep_out = desc_ep->bEndpointAddress;
2069 audio->ep_out_as_intf_num = itf;
2070 audio->ep_out_sz = tu_edpt_packet_size(desc_ep);
2071 if (audio->ep_out_sz == 0)
return;
2076 if (audio->lin_buf_out.size() < audio->ep_out_sz)
2077 audio->lin_buf_out.assign(audio->ep_out_sz, 0);
2079 audio->lin_buf_out.data(),
2081 LOGD(
" XFER armed: %s, buf=%p sz=%u", xfer_ok ?
"OK" :
"FAIL",
2082 audio->lin_buf_out.data(), audio->ep_out_sz);
2087 LOGD(
" XFER_FIFO armed: %s", xfer_ok ?
"OK" :
"FAIL");
2094 tusb_desc_endpoint_t
const* desc_ep) {
2095 audio->ep_fb = desc_ep->bEndpointAddress;
2096 audio->feedback.frame_shift = desc_ep->bInterval - 1;
2103 audio_feedback_params_t fb_param = {};
2104 fb_param.method = AUDIO_FEEDBACK_METHOD_FIFO_COUNT;
2108 audio->feedback.compute_method = fb_param.method;
2110 if (TUSB_SPEED_FULL == tud_speed_get() &&
2112 audio->feedback.format_correction =
2115 uint32_t
const frame_div =
2116 (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000;
2117 audio->feedback.min_value = ((fb_param.sample_freq - 1) / frame_div) << 16;
2118 audio->feedback.max_value = (fb_param.sample_freq / frame_div + 1) << 16;
2120 switch (fb_param.method) {
2121 case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED:
2122 case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT:
2123 case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2:
2125 fb_param.frequency.mclk_freq);
2127 case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: {
2130 if (fifo_depth == 0) fifo_depth = 1;
2131 uint16_t fifo_lvl_thr = fifo_depth / 2;
2132 audio->feedback.compute.fifo_count.fifo_lvl_thr = fifo_lvl_thr;
2133 audio->feedback.compute.fifo_count.fifo_lvl_avg =
2134 ((uint32_t)fifo_lvl_thr) << 16;
2136 ((fb_param.sample_freq / 100) << 16) / (frame_div / 100);
2137 audio->feedback.compute.fifo_count.nom_value = nominal;
2138 audio->feedback.compute.fifo_count.rate_const[0] =
2139 (uint16_t)((audio->feedback.max_value - nominal) / fifo_lvl_thr);
2140 audio->feedback.compute.fifo_count.rate_const[1] =
2141 (uint16_t)((nominal - audio->feedback.min_value) / fifo_lvl_thr);
2142 if (tud_speed_get() == TUSB_SPEED_HIGH) {
2143 audio->feedback.compute.fifo_count.rate_const[0] /= 8;
2144 audio->feedback.compute.fifo_count.rate_const[1] /= 8;
2154 uint8_t func_id, uint8_t itf, uint8_t alt) {
2155 uint8_t
const* p_desc = audio->p_desc;
2156 uint8_t
const* p_desc_end =
2157 p_desc + audio->desc_length - TUD_AUDIO_DESC_IAD_LEN;
2158 LOGD(
" openEPs: p_desc=%p end=%p len=%u itf=%u alt=%u",
2159 p_desc, p_desc_end, audio->desc_length, itf, alt);
2161 while (p_desc_end - p_desc > 0) {
2162 if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE &&
2163 ((tusb_desc_interface_t
const*)p_desc)->bInterfaceNumber == itf &&
2164 ((tusb_desc_interface_t
const*)p_desc)->bAlternateSetting == alt) {
2165 uint8_t
const* p_desc_for_params =
2167 uint8_t foundEPs = 0;
2168 uint8_t nEps = ((tusb_desc_interface_t
const*)p_desc)->bNumEndpoints;
2169 LOGD(
" matched itf=%u alt=%u nEps=%u", itf, alt, nEps);
2171 while (foundEPs < nEps && (p_desc_end - p_desc > 0)) {
2172 LOGD(
" scan: type=0x%02x len=%u offset=%d",
2173 p_desc[1], p_desc[0], (
int)(p_desc - audio->p_desc));
2174 if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) {
2175 tusb_desc_endpoint_t
const* desc_ep =
2176 (tusb_desc_endpoint_t
const*)p_desc;
2178 LOGD(
" activating ep=0x%02x type=%u...",
2179 desc_ep->bEndpointAddress, desc_ep->bmAttributes.xfer);
2181 tu_edpt_dir(desc_ep->bEndpointAddress))) {
2182 LOGD(
" activateEndpoint FAILED");
2183 p_desc = tu_desc_next(p_desc);
2186 LOGD(
" activated OK");
2189 if (!(tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_OUT &&
2190 desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS))
2191 usbd_edpt_clear_stall(rhport, desc_ep->bEndpointAddress);
2193 uint8_t ep_addr = desc_ep->bEndpointAddress;
2194 if (
isEpInEnabled() && tu_edpt_dir(ep_addr) == TUSB_DIR_IN &&
2195 desc_ep->bmAttributes.usage == 0x00)
2196 openEpIn(rhport, audio, itf, desc_ep, p_desc_for_params);
2199 if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT)
2202 tu_edpt_dir(ep_addr) == TUSB_DIR_IN &&
2203 desc_ep->bmAttributes.usage == 1)
2208 p_desc = tu_desc_next(p_desc);
2211 if (foundEPs != nEps)
return true;
2218 p_desc = tu_desc_next(p_desc);
2225 tusb_control_request_t
const* p_request) {
2226 uint8_t
const itf = tu_u16_low(p_request->wIndex);
2227 uint8_t
const alt = tu_u16_low(p_request->wValue);
2228 LOGD(
"SET_ITF itf=%u alt=%u [start]", itf, alt);
2230 uint8_t func_id, idxItf;
2231 uint8_t
const* p_desc;
2234 LOGD(
" AS interface %u not found", itf);
2235 tud_control_status(rhport, p_request);
2238 LOGD(
" found func=%u idx=%u", func_id, idxItf);
2244 closeEpIn(rhport, audio, itf, p_request);
2248 audio->alt_setting[idxItf] = alt;
2250 tud_control_status(rhport, p_request);
2255 bool enable_sof =
false;
2262 usbd_sof_enable(rhport, SOF_CONSUMER_AUDIO, enable_sof);
2271 uint32_t mclk_freq) {
2278 uint32_t
const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13;
2279 uint32_t
const n_frame = (1UL << audio->feedback.frame_shift);
2281 if ((((1UL << k) * sample_freq / mclk_freq) + 1) > n_frame) {
2282 LOGE(
" UAC2 feedback interval too small");
2288 if ((mclk_freq % sample_freq) == 0 &&
2289 tu_is_power_of_two(mclk_freq / sample_freq)) {
2290 audio->feedback.compute_method =
2291 AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2;
2292 audio->feedback.compute.power_of_2 =
2293 (uint8_t)(16 - (audio->feedback.frame_shift - 1) -
2294 tu_log2(mclk_freq / sample_freq));
2295 }
else if (audio->feedback.compute_method ==
2296 AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) {
2297 audio->feedback.compute.float_const =
2298 (float)sample_freq / (
float)mclk_freq *
2299 (1UL << (16 - (audio->feedback.frame_shift - 1)));
2301 audio->feedback.compute.fixed.sample_freq = sample_freq;
2302 audio->feedback.compute.fixed.mclk_freq = mclk_freq;
2309 TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I);
2310 TU_VERIFY(audio->n_channels_tx);
2311 TU_VERIFY(audio->n_bytes_per_sample_tx);
2312 TU_VERIFY(audio->interval_tx);
2313 TU_VERIFY(audio->sample_rate_tx);
2316 audio->tx_sample_acc = 0;
2318 const uint8_t interval = (tud_speed_get() == TUSB_SPEED_FULL)
2319 ? audio->interval_tx
2320 : 1 << (audio->interval_tx - 1);
2322 const uint16_t sample_normimal =
2323 (uint16_t)(audio->sample_rate_tx * interval /
2324 ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000));
2325 const uint16_t sample_reminder =
2326 (uint16_t)(audio->sample_rate_tx * interval %
2327 ((tud_speed_get() == TUSB_SPEED_FULL) ? 1000 : 8000));
2329 const uint16_t packet_sz_tx_min =
2330 (uint16_t)((sample_normimal - 1) * audio->n_channels_tx *
2331 audio->n_bytes_per_sample_tx);
2332 const uint16_t packet_sz_tx_norm =
2333 (uint16_t)(sample_normimal * audio->n_channels_tx *
2334 audio->n_bytes_per_sample_tx);
2335 const uint16_t packet_sz_tx_max =
2336 (uint16_t)((sample_normimal + 1) * audio->n_channels_tx *
2337 audio->n_bytes_per_sample_tx);
2340 TU_ASSERT(packet_sz_tx_max <= audio->ep_in_sz);
2343 if (sample_reminder) {
2346 audio->packet_sz_tx[0] = packet_sz_tx_norm;
2347 audio->packet_sz_tx[1] = packet_sz_tx_norm;
2348 audio->packet_sz_tx[2] = packet_sz_tx_max;
2352 audio->packet_sz_tx[0] = packet_sz_tx_min;
2353 audio->packet_sz_tx[1] = packet_sz_tx_norm;
2354 audio->packet_sz_tx[2] = packet_sz_tx_max;
2366 if (audio->sample_rate_tx == 0 || audio->n_channels_tx == 0 ||
2367 audio->n_bytes_per_sample_tx == 0) {
2369 return audio->ep_in_sz;
2371 const uint32_t denom = (tud_speed_get() == TUSB_SPEED_FULL) ? 1000u : 8000u;
2372 const uint8_t iv = audio->interval_tx ? audio->interval_tx : 1;
2373 const uint32_t interval =
2374 (tud_speed_get() == TUSB_SPEED_FULL) ? iv : (1u << (iv - 1));
2376 audio->tx_sample_acc += audio->sample_rate_tx * interval;
2377 const uint32_t samples = audio->tx_sample_acc / denom;
2378 audio->tx_sample_acc -= samples * denom;
2381 samples * audio->n_channels_tx * audio->n_bytes_per_sample_tx;
2382 if (bytes > audio->ep_in_sz) bytes = audio->ep_in_sz;
2383 return (uint16_t)bytes;
2390 return tu_fifo_write_n(&
audiod_fct_[func_id].ep_in_ff, data, len);
2395 return tu_fifo_count(&
audiod_fct_[func_id].ep_out_ff);
2400 return tu_fifo_read_n(&
audiod_fct_[func_id].ep_out_ff, buffer, bufsize);
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define AUDIO_CS_CTRL_CLK_VALID
Definition USBAudioDeviceBase.h:74
#define TUSB_EDPT_XFER(rp, ep, buf, sz)
Definition USBAudioDeviceBase.h:64
#define TUSB_FIFO_CONFIG(f, buf, d, ov)
Definition USBAudioDeviceBase.h:66
#define AUDIO_FU_CTRL_VOLUME
Definition USBAudioDeviceBase.h:86
#define AUDIO_FU_CTRL_MUTE
Definition USBAudioDeviceBase.h:83
#define AUDIO_CS_REQ_RANGE
Definition USBAudioDeviceBase.h:77
#define USB_DESCR_MAX_LEN
Definition USBAudioDeviceBase.h:37
usbd_class_driver_t const * usbd_app_driver_get_cb(uint8_t *count)
Definition USBAudioDeviceBase.h:2408
#define TUSB_EDPT_XFER_FIFO(rp, ep, ff, sz)
Definition USBAudioDeviceBase.h:65
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