10 #ifndef AUDIO_SAMPLE_RATE
11 #define AUDIO_SAMPLE_RATE 48000
19 #ifndef BOARD_TUD_RHPORT
20 #define BOARD_TUD_RHPORT 0
24 #ifndef BOARD_TUD_MAX_SPEED
25 #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
35 #define CFG_TUSB_MCU OPT_MCU_ESP32S2
37 #error CFG_TUSB_MCU must be defined
42 #if !defined(CFG_TUSB_OS) && !defined(ESP32)
43 #define CFG_TUSB_OS OPT_OS_NONE
46 #ifndef CFG_TUSB_DEBUG
47 #define CFG_TUSB_DEBUG 0
51 #define CFG_TUD_ENABLED 1
54 #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
65 #ifndef CFG_TUSB_MEM_SECTION
66 #define CFG_TUSB_MEM_SECTION
69 #ifndef CFG_TUSB_MEM_ALIGN
70 #define CFG_TUSB_MEM_ALIGN __attribute__((aligned(4)))
76 #define _TUSB_CONFIG_H_
78 #ifndef CFG_TUD_ENDPOINT0_SIZE
79 #define CFG_TUD_ENDPOINT0_SIZE 64
83 #define CFG_TUD_AUDIO 1
88 #define CFG_TUD_MIDI 0
89 #define CFG_TUD_VENDOR 0
97 #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN TUD_AUDIO_MIC_ONE_CH_DESC_LEN
98 #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT \
105 #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64
107 #define CFG_TUD_AUDIO_ENABLE_EP_IN 1
108 #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX \
111 #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX \
115 #define CFG_TUD_AUDIO_EP_SZ_IN \
117 CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * \
118 CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX
124 #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX \
125 CFG_TUD_AUDIO_EP_SZ_IN
127 #define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN + 1
137 #define _PID_MAP(itf, n) ((CFG_TUD_##itf) << (n))
139 (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
140 _PID_MAP(MIDI, 3) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5))
143 #include "class/audio/audio_device.h"
151 tusb_desc_device_t
const desc_device = {
152 .bLength =
sizeof(tusb_desc_device_t),
153 .bDescriptorType = TUSB_DESC_DEVICE,
159 .bDeviceClass = TUSB_CLASS_MISC,
160 .bDeviceSubClass = MISC_SUBCLASS_COMMON,
161 .bDeviceProtocol = MISC_PROTOCOL_IAD,
162 .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
165 .idProduct = USB_PID,
168 .iManufacturer = 0x01,
170 .iSerialNumber = 0x03,
172 .bNumConfigurations = 0x01};
176 uint8_t
const *tud_descriptor_device_cb(
void) {
177 return (uint8_t
const *)&desc_device;
183 enum { ITF_NUM_AUDIO_CONTROL = 0, ITF_NUM_AUDIO_STREAMING, ITF_NUM_TOTAL };
185 #define CONFIG_TOTAL_LEN \
186 (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_ONE_CH_DESC_LEN)
188 #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || \
189 CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
192 #define EPNUM_AUDIO 0x03
194 #elif TU_CHECK_MCU(OPT_MCU_NRF5X)
196 #define EPNUM_AUDIO 0x08
199 #define EPNUM_AUDIO 0x01
202 uint8_t
const desc_configuration[] = {
205 TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
208 TUD_AUDIO_MIC_ONE_CH_DESCRIPTOR(
209 ITF_NUM_AUDIO_CONTROL, 0,
210 CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX,
211 CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * 8,
212 0x80 | EPNUM_AUDIO, CFG_TUD_AUDIO_EP_SZ_IN)};
217 uint8_t
const *tud_descriptor_configuration_cb(uint8_t index) {
219 return desc_configuration;
227 char const *string_desc_arr[] = {
228 (
const char[]){0x09, 0x04},
235 static uint16_t _desc_str[32];
240 uint16_t
const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
246 memcpy(&_desc_str[1], string_desc_arr[0], 2);
251 if (!(index <
sizeof(string_desc_arr) /
sizeof(string_desc_arr[0])))
254 const char *str = string_desc_arr[index];
257 chr_count = (uint8_t)strlen(str);
261 for (uint8_t i = 0; i < chr_count; i++) {
262 _desc_str[1 + i] = str[i];
267 _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
278 BLINK_NOT_MOUNTED = 250,
279 BLINK_MOUNTED = 1000,
280 BLINK_SUSPENDED = 2500,
283 static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
284 static int channels = 2;
285 static uint8_t bytesPerSample;
286 static Stream *p_in =
nullptr;
287 static Print *p_out =
nullptr;
291 bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];
293 volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];
298 audio_control_range_2_n_t(
299 1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];
300 audio_control_range_4_n_t(1) sampleFreqRng;
303 uint16_t test_buffer_audio[(CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2];
304 uint16_t startVal = 0;
306 void led_blinking_task(
void);
307 void audio_task(
void);
323 tud_init(BOARD_TUD_RHPORT);
329 sampleFreqRng.wNumSubRanges = 1;
332 sampleFreqRng.subrange[0].bRes = 0;
350 void tud_mount_cb(
void) { blink_interval_ms = BLINK_MOUNTED; }
353 void tud_umount_cb(
void) { blink_interval_ms = BLINK_NOT_MOUNTED; }
359 void tud_suspend_cb(
bool remote_wakeup_en) {
360 (void)remote_wakeup_en;
361 blink_interval_ms = BLINK_SUSPENDED;
365 void tud_resume_cb(
void) { blink_interval_ms = BLINK_MOUNTED; }
371 void audio_task(
void) {
381 bool tud_audio_set_req_ep_cb(uint8_t rhport,
382 tusb_control_request_t
const *p_request,
389 TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
392 uint8_t channelNum = TU_U16_LOW(p_request->wValue);
393 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
394 uint8_t ep = TU_U16_LOW(p_request->wIndex);
404 bool tud_audio_set_req_itf_cb(uint8_t rhport,
405 tusb_control_request_t
const *p_request,
412 TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
415 uint8_t channelNum = TU_U16_LOW(p_request->wValue);
416 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
417 uint8_t itf = TU_U16_LOW(p_request->wIndex);
427 bool tud_audio_set_req_entity_cb(uint8_t rhport,
428 tusb_control_request_t
const *p_request,
433 uint8_t channelNum = TU_U16_LOW(p_request->wValue);
434 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
435 uint8_t itf = TU_U16_LOW(p_request->wIndex);
436 uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
442 TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
447 case AUDIO_FU_CTRL_MUTE:
449 TU_VERIFY(p_request->wLength ==
sizeof(audio_control_cur_1_t));
451 mute[channelNum] = ((audio_control_cur_1_t *)pBuff)->bCur;
453 TU_LOG2(
" Set Mute: %d of channel: %u\r\n", mute[channelNum],
457 case AUDIO_FU_CTRL_VOLUME:
459 TU_VERIFY(p_request->wLength ==
sizeof(audio_control_cur_2_t));
461 volume[channelNum] = (uint16_t)((audio_control_cur_2_t *)pBuff)->bCur;
463 TU_LOG2(
" Set Volume: %d dB of channel: %u\r\n", volume[channelNum],
477 bool tud_audio_get_req_ep_cb(uint8_t rhport,
478 tusb_control_request_t
const *p_request) {
482 uint8_t channelNum = TU_U16_LOW(p_request->wValue);
483 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
484 uint8_t ep = TU_U16_LOW(p_request->wIndex);
496 bool tud_audio_get_req_itf_cb(uint8_t rhport,
497 tusb_control_request_t
const *p_request) {
501 uint8_t channelNum = TU_U16_LOW(p_request->wValue);
502 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
503 uint8_t itf = TU_U16_LOW(p_request->wIndex);
513 bool tud_audio_get_req_entity_cb(uint8_t rhport,
514 tusb_control_request_t
const *p_request) {
518 uint8_t channelNum = TU_U16_LOW(p_request->wValue);
519 uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
522 uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
527 case AUDIO_TE_CTRL_CONNECTOR: {
530 audio_desc_channel_cluster_t ret;
533 ret.bNrChannels = channels;
534 ret.bmChannelConfig = (audio_channel_config_t)0;
535 ret.iChannelNames = 0;
537 TU_LOG2(
" Get terminal connector\r\n");
539 return tud_audio_buffer_and_schedule_control_xfer(
540 rhport, p_request, (
void *)&ret,
sizeof(ret));
553 case AUDIO_FU_CTRL_MUTE:
557 TU_LOG2(
" Get Mute of channel: %u\r\n", channelNum);
558 return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
560 case AUDIO_FU_CTRL_VOLUME:
561 switch (p_request->bRequest) {
562 case AUDIO_CS_REQ_CUR:
563 TU_LOG2(
" Get Volume of channel: %u\r\n", channelNum);
564 return tud_control_xfer(rhport, p_request, &volume[channelNum],
565 sizeof(volume[channelNum]));
567 case AUDIO_CS_REQ_RANGE:
568 TU_LOG2(
" Get Volume range of channel: %u\r\n", channelNum);
571 audio_control_range_2_n_t(1) ret;
573 ret.wNumSubRanges = 1;
574 ret.subrange[0].bMin = -90;
575 ret.subrange[0].bMax = 90;
576 ret.subrange[0].bRes = 1;
578 return tud_audio_buffer_and_schedule_control_xfer(
579 rhport, p_request, (
void *)&ret, sizeof(ret));
598 case AUDIO_CS_CTRL_SAM_FREQ:
600 switch (p_request->bRequest) {
601 case AUDIO_CS_REQ_CUR:
602 TU_LOG2(
" Get Sample Freq.\r\n");
603 return tud_control_xfer(rhport, p_request, &sampFreq,
sizeof(sampFreq));
605 case AUDIO_CS_REQ_RANGE:
606 TU_LOG2(
" Get Sample Freq. range\r\n");
607 return tud_control_xfer(rhport, p_request, &sampleFreqRng,
608 sizeof(sampleFreqRng));
617 case AUDIO_CS_CTRL_CLK_VALID:
619 TU_LOG2(
" Get Sample Freq. valid\r\n");
620 return tud_control_xfer(rhport, p_request, &clkValid,
sizeof(clkValid));
629 TU_LOG2(
" Unsupported entity: %d\r\n", entityID);
633 bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in,
634 uint8_t cur_alt_setting) {
638 (void)cur_alt_setting;
640 tud_audio_write((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2);
645 bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied,
646 uint8_t itf, uint8_t ep_in,
647 uint8_t cur_alt_setting) {
649 (void)n_bytes_copied;
652 (void)cur_alt_setting;
657 if (p_in !=
nullptr) {
658 p_in->readBytes((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2);
660 memset(test_buffer_audio, 0, CFG_TUD_AUDIO_EP_SZ_IN - 2);
666 bool tud_audio_rx_done_pre_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting)
671 (void)cur_alt_setting;
674 bytes_read = tud_audio_read(test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2);
675 if (p_print!=
nullptr){
676 p_print->write(usb_spk_buf, bytes_read);
683 bool tud_audio_set_itf_close_EP_cb(uint8_t rhport,
684 tusb_control_request_t
const *p_request) {
695 void led_blinking_task(
void) {
697 static uint32_t start_ms = 0;
698 static bool led_state =
false;
701 if (
millis() - start_ms < blink_interval_ms)
703 start_ms += blink_interval_ms;
705 digitalWrite(PIN_LED, led_state);
706 led_state = 1 - led_state;