Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ports/espressif/mpconfigport.mk
Original file line number Diff line number Diff line change
Expand Up @@ -417,5 +417,18 @@ endif
USB_NUM_ENDPOINT_PAIRS = 7
USB_NUM_IN_ENDPOINTS = 5

# usb_audio is compiled in on the S3 but claims no endpoints until
# usb_audio.enable() is called from boot.py, so enabling it by default does not
# affect existing boards. Freeing one IN endpoint (usb_hid.disable()) is then the
# only thing a user needs, with no custom build.
ifeq ($(IDF_TARGET),esp32s3)
# It needs the TinyUSB device stack and audiocore, so leave it off for boards
# that turn either off. The S3 has no AUDIOIO and no AUDIOPWMIO, so audiocore
# follows CIRCUITPY_AUDIOBUSIO here.
ifeq ($(filter 0,$(CIRCUITPY_USB_DEVICE) $(CIRCUITPY_AUDIOCORE) $(CIRCUITPY_AUDIOBUSIO)),)
CIRCUITPY_USB_AUDIO ?= 1
endif
endif

# Usually lots of flash space available
CIRCUITPY_MESSAGE_COMPRESSION_LEVEL ?= 1
24 changes: 24 additions & 0 deletions shared-module/usb_audio/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "py/mphal.h"
#include "py/runtime.h"
#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include "tusb.h"

static bool usb_audio_is_enabled = false;
Expand Down Expand Up @@ -465,10 +466,33 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_reques
usb_audio_usbspeaker_streaming_reset();
} else if (itf == usb_audio_mic_as_itf) {
usb_audio_mic_streaming = streaming;
if (streaming) {
// Prime the FIFO for the first frame; after that each completed
// transfer schedules the next refill via tud_audio_tx_done_isr().
usb_background_schedule();
}
}
return true;
}

// Invoked from the audio class transfer-complete path once the next packet has
// been loaded into the EP IN buffer. TinyUSB services audio completions in ISR
// context, so they never queue a USB event. A port that pumps the optional class
// tasks from a task loop sitting behind tud_task() therefore never refills the
// microphone FIFO. Scheduling the refill here keeps usb_audio independent of how
// a port drives TinyUSB.
bool tud_audio_tx_done_isr(uint8_t rhport, uint16_t n_bytes_sent, uint8_t func_id,
uint8_t ep_in, uint8_t cur_alt_setting) {
(void)rhport;
(void)n_bytes_sent;
(void)func_id;
(void)ep_in;
(void)cur_alt_setting;

usb_background_schedule();
return true;
}

bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void)rhport;
uint8_t const itf = (uint8_t)tu_u16_low(p_request->wIndex);
Expand Down
Loading