10#ifndef ARDUINO_USB_MODE
11#error This Microcontroller has no Native USB interface
13#if ARDUINO_USB_MODE == 1
14#error This sketch should be used when USB is in OTG mode
19#error This Microcontroller has no Native USB interface
27#include "device/usbd.h"
28#include "device/usbd_pvt.h"
49 enum audio_format_type_t {
52 AUDIO_FORMAT_TYPE_III,
61 enum audio_feedback_method_t {
62 AUDIO_FEEDBACK_METHOD_DISABLED,
63 AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED,
64 AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT,
65 AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2,
66 AUDIO_FEEDBACK_METHOD_FIFO_COUNT
75 struct audiod_function_t {
96 bool format_correction;
116 audio_format_type_t format_type_tx;
123 std::vector<uint8_t> ctrl_buf;
124 std::vector<uint8_t> alt_setting;
125 std::vector<uint8_t> lin_buf_out;
126 std::vector<uint8_t> lin_buf_in;
127 std::vector<uint32_t> fb_buf;
128 std::vector<uint8_t> ep_in_sw_buf;
129 std::vector<uint8_t> ep_out_sw_buf;
138 struct audio_feedback_params_t {
463 audio_feedback_params_t*)>
493 driver.name =
"Audio";
495 driver.deinit = [](
void) {
498 driver.reset = [](
uint8_t rhport) {
624 return offsetof(audiod_function_t, ctrl_buf_sz) +
625 sizeof(((audiod_function_t*)0)->ctrl_buf_sz);
657 audio->ctrl_buf.resize(size);
658 audio->ctrl_buf_sz = size;
666 audio->ep_in_sw_buf.data(),
744 uint8_t ep_in = 0, ep_out = 0, ep_fb = 0;
745 uint16_t ep_in_size = 0, ep_out_size = 0;
755 ep_fb =
desc_ep->bEndpointAddress;
757 if (
desc_ep->bmAttributes.usage == 0) {
760 ep_in =
desc_ep->bEndpointAddress;
766 ep_out =
desc_ep->bEndpointAddress;
794 desc_ep->bmAttributes.usage == 0 &&
854 switch (
p_request->bmRequestType_bit.recipient) {
925 audio->alt_setting.size() != 0) {
953 if (audio->ep_fb != 0) {
957 1UL << (audio->feedback.frame_shift -
hs_adjust);
958 if (0 == (frame_count & (
interval - 1))) {
960 audio->feedback.frame_shift);
997 switch (
p_request->bmRequestType_bit.recipient) {
1049 TU_LOG2(
" Unsupported recipient: %d\r\n",
1050 p_request->bmRequestType_bit.recipient);
1078 ->bInterfaceNumber ==
itf) {
1144 ->bInterfaceNumber ==
itf) {
1164 audio->n_channels_tx =
1166 audio->format_type_tx =
1174 AUDIO_FORMAT_TYPE_I) {
1175 audio->n_bytes_per_sample_tx =
1191 if (audio->p_desc) {
1257 TU_LOG2(
" Get itf: %u - current alt: %u\r\n",
itf,
1265 audio->feedback.format_correction;
1271 *(
fb++) = (audio->feedback.value >> 2) & 0xFF;
1272 *(
fb++) = (audio->feedback.value >> 10) & 0xFF;
1273 *(
fb++) = (audio->feedback.value >> 18) & 0xFF;
1276 audio->fb_buf[0] = audio->feedback.value;
1294 (
uint8_t*)audio->fb_buf.data(),
1336 if (audio->ep_in_as_intf_num ==
itf) {
1337 audio->ep_in_as_intf_num = 0;
1338#ifndef TUP_DCD_EDPT_ISO_ALLOC
1353 audio->packet_sz_tx[0] = 0;
1354 audio->packet_sz_tx[1] = 0;
1355 audio->packet_sz_tx[2] = 0;
1361 if (audio->ep_out_as_intf_num ==
itf) {
1362 audio->ep_out_as_intf_num = 0;
1363#ifndef TUP_DCD_EDPT_ISO_ALLOC
1383 tu_memclr(&audio->feedback,
sizeof(audio->feedback));
1419#ifdef TUP_DCD_EDPT_ISO_ALLOC
1432 desc_ep->bmAttributes.usage ==
1437 audio->ep_in_as_intf_num =
itf;
1465 audio->ep_out_as_intf_num =
itf;
1471 audio->lin_buf_out.data(),
1477 &audio->ep_out_ff, audio->ep_out_sz),
1484 desc_ep->bmAttributes.usage ==
1488 audio->feedback.frame_shift =
desc_ep->bInterval - 1;
1507 if (audio->ep_fb != 0) {
1513 audio->feedback.compute_method =
fb_param.method;
1517 audio->feedback.format_correction =
1531 case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED:
1532 case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT:
1533 case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2:
1538 case AUDIO_FEEDBACK_METHOD_FIFO_COUNT: {
1541 audio->feedback.compute.fifo_count.fifo_lvl_thr = fifo_lvl_thr;
1542 audio->feedback.compute.fifo_count.fifo_lvl_avg =
1547 audio->feedback.compute.fifo_count.nom_value =
nominal;
1548 audio->feedback.compute.fifo_count.rate_const[0] =
1551 audio->feedback.compute.fifo_count.rate_const[1] =
1557 audio->feedback.compute.fifo_count.rate_const[0] /= 8;
1558 audio->feedback.compute.fifo_count.rate_const[1] /= 8;
1583 AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED ||
1585 AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT ||
1587 AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2)) {
1615 if ((((1UL <<
k) * sample_freq / mclk_freq) + 1) >
n_frame) {
1616 TU_LOG1(
" UAC2 feedback interval too small\r\n");
1622 if ((mclk_freq % sample_freq) == 0 &&
1624 audio->feedback.compute_method =
1625 AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2;
1626 audio->feedback.compute.power_of_2 =
1627 (
uint8_t)(16 - (audio->feedback.frame_shift - 1) -
1628 tu_log2(mclk_freq / sample_freq));
1629 }
else if (audio->feedback.compute_method ==
1630 AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT) {
1631 audio->feedback.compute.float_const =
1632 (
float)sample_freq / (
float)mclk_freq *
1633 (1UL << (16 - (audio->feedback.frame_shift - 1)));
1635 audio->feedback.compute.fixed.sample_freq = sample_freq;
1636 audio->feedback.compute.fixed.mclk_freq = mclk_freq;
1643 TU_VERIFY(audio->format_type_tx == AUDIO_FORMAT_TYPE_I);
1645 TU_VERIFY(audio->n_bytes_per_sample_tx);
1650 ? audio->interval_tx
1651 : 1 << (audio->interval_tx - 1);
1662 audio->n_bytes_per_sample_tx);
1665 audio->n_bytes_per_sample_tx);
1668 audio->n_bytes_per_sample_tx);
usbd_class_driver_t const * usbd_app_driver_get_cb(uint8_t *count)
Definition USBAudioDevice.h:1710
RxTxMode
The Microcontroller is the Audio Source (TX_MODE) or Audio Sink (RX_MODE). RXTX_MODE is Source and Si...
Definition AudioTypes.h:30
@ RXTX_MODE
Definition AudioTypes.h:30
@ TX_MODE
Definition AudioTypes.h:30
@ RX_MODE
Definition AudioTypes.h:30