summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2025-07-11 15:47:55 +0200
committerHiFiPhile <[email protected]>2025-07-11 15:47:55 +0200
commitf074815405f9c510f3f1eb57f3cbdab40e9e1caa (patch)
tree27157de2ae8ef662974a9d87a8119c12f3fbdffb /examples
parent69f6b57772ad4f2923dcf48aabaaba044085c4b0 (diff)
parent29c2af7651f9075a63a036e94c7bbe3d0d00c31a (diff)
Merge branch 'master' into feature/usbtmc_vendor-specific
Diffstat (limited to 'examples')
-rw-r--r--examples/build_system/cmake/cpu/cortex-m55.cmake26
-rw-r--r--examples/build_system/make/cpu/cortex-m55.mk28
-rw-r--r--examples/build_system/make/make.mk24
-rw-r--r--examples/device/audio_4_channel_mic/src/main.c260
-rw-r--r--examples/device/audio_4_channel_mic/src/tusb_config.h15
-rw-r--r--examples/device/audio_4_channel_mic_freertos/src/main.c324
-rw-r--r--examples/device/audio_4_channel_mic_freertos/src/tusb_config.h17
-rw-r--r--examples/device/audio_test/src/main.c214
-rwxr-xr-xexamples/device/audio_test/src/plot_audio_samples.py4
-rw-r--r--examples/device/audio_test/src/tusb_config.h2
-rw-r--r--examples/device/audio_test_freertos/src/main.c257
-rwxr-xr-xexamples/device/audio_test_freertos/src/plot_audio_samples.py4
-rw-r--r--examples/device/audio_test_freertos/src/tusb_config.h4
-rw-r--r--examples/device/audio_test_multi_rate/src/main.c286
-rw-r--r--examples/device/audio_test_multi_rate/src/tusb_config.h3
-rw-r--r--examples/device/board_test/src/main.c27
-rw-r--r--examples/device/board_test/src/tusb_config.h2
-rw-r--r--examples/device/cdc_dual_ports/src/main.c16
-rw-r--r--examples/device/cdc_dual_ports/src/tusb_config.h2
-rw-r--r--examples/device/cdc_dual_ports/src/usb_descriptors.c54
-rw-r--r--examples/device/cdc_msc/src/main.c10
-rw-r--r--examples/device/cdc_msc/src/msc_disk.c18
-rw-r--r--examples/device/cdc_msc/src/tusb_config.h4
-rw-r--r--examples/device/cdc_msc/src/usb_descriptors.c11
-rw-r--r--examples/device/cdc_msc_freertos/src/main.c21
-rw-r--r--examples/device/cdc_msc_freertos/src/msc_disk.c200
-rw-r--r--examples/device/cdc_msc_freertos/src/tusb_config.h4
-rw-r--r--examples/device/cdc_msc_freertos/src/usb_descriptors.c24
-rw-r--r--examples/device/cdc_uac2/skip.txt8
-rw-r--r--examples/device/cdc_uac2/src/main.c3
-rw-r--r--examples/device/cdc_uac2/src/tusb_config.h11
-rw-r--r--examples/device/cdc_uac2/src/uac2_app.c51
-rw-r--r--examples/device/cdc_uac2/src/usb_descriptors.c69
-rw-r--r--examples/device/dynamic_configuration/src/msc_disk.c17
-rw-r--r--examples/device/hid_composite_freertos/src/main.c11
-rw-r--r--examples/device/hid_composite_freertos/src/tusb_config.h2
-rw-r--r--examples/device/midi_test_freertos/src/main.c8
-rw-r--r--examples/device/msc_dual_lun/src/msc_disk_dual.c18
-rw-r--r--examples/device/net_lwip_webserver/Makefile2
-rw-r--r--examples/device/net_lwip_webserver/skip.txt2
-rw-r--r--examples/device/net_lwip_webserver/src/lwipopts.h1
-rw-r--r--examples/device/net_lwip_webserver/src/main.c97
-rw-r--r--examples/device/net_lwip_webserver/src/tusb_config.h2
-rw-r--r--examples/device/uac2_headset/src/main.c262
-rw-r--r--examples/device/uac2_headset/src/tusb_config.h4
-rw-r--r--examples/device/uac2_speaker_fb/src/main.c261
-rw-r--r--examples/device/video_capture/src/main.c6
-rw-r--r--examples/device/video_capture/src/tusb_config.h2
-rw-r--r--examples/device/video_capture_2ch/src/main.c6
-rw-r--r--examples/device/video_capture_2ch/src/tusb_config.h2
-rw-r--r--examples/dual/host_hid_to_device_cdc/only.txt1
-rw-r--r--examples/dual/host_hid_to_device_cdc/src/main.c8
-rw-r--r--examples/dual/host_info_to_device_cdc/only.txt1
-rw-r--r--examples/dual/host_info_to_device_cdc/src/main.c46
-rw-r--r--examples/host/bare_api/only.txt5
-rw-r--r--examples/host/cdc_msc_hid/only.txt5
-rw-r--r--examples/host/cdc_msc_hid/src/cdc_app.c16
-rw-r--r--examples/host/cdc_msc_hid/src/hid_app.c100
-rw-r--r--examples/host/cdc_msc_hid/src/tusb_config.h5
-rw-r--r--examples/host/cdc_msc_hid_freertos/only.txt4
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/cdc_app.c2
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/main.c8
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/tusb_config.h7
-rw-r--r--examples/host/device_info/only.txt5
-rw-r--r--examples/host/device_info/src/main.c8
-rw-r--r--examples/host/device_info/src/tusb_config.h2
-rw-r--r--examples/host/hid_controller/only.txt5
-rw-r--r--examples/host/midi_rx/only.txt5
-rw-r--r--examples/host/midi_rx/src/tusb_config.h2
-rw-r--r--examples/host/msc_file_explorer/only.txt5
-rw-r--r--examples/typec/power_delivery/src/main.c5
71 files changed, 1389 insertions, 1562 deletions
diff --git a/examples/build_system/cmake/cpu/cortex-m55.cmake b/examples/build_system/cmake/cpu/cortex-m55.cmake
new file mode 100644
index 000000000..a7a57957c
--- /dev/null
+++ b/examples/build_system/cmake/cpu/cortex-m55.cmake
@@ -0,0 +1,26 @@
+if (TOOLCHAIN STREQUAL "gcc")
+ set(TOOLCHAIN_COMMON_FLAGS
+ -mthumb
+ -mcpu=cortex-m55
+ -mfloat-abi=hard
+ -mfpu=fpv5-d16
+ -mcmse
+ )
+ set(FREERTOS_PORT GCC_ARM_CM55_NTZ_NONSECURE CACHE INTERNAL "")
+
+elseif (TOOLCHAIN STREQUAL "clang")
+ set(TOOLCHAIN_COMMON_FLAGS
+ --target=arm-none-eabi
+ -mcpu=cortex-m55
+ -mfpu=fpv5-d16
+ )
+ set(FREERTOS_PORT GCC_ARM_CM55_NTZ_NONSECURE CACHE INTERNAL "")
+
+elseif (TOOLCHAIN STREQUAL "iar")
+ set(TOOLCHAIN_COMMON_FLAGS
+ --cpu cortex-m55
+ --fpu VFPv5_D16
+ )
+ set(FREERTOS_PORT IAR_ARM_CM55_NTZ_NONSECURE CACHE INTERNAL "")
+
+endif ()
diff --git a/examples/build_system/make/cpu/cortex-m55.mk b/examples/build_system/make/cpu/cortex-m55.mk
new file mode 100644
index 000000000..de627caed
--- /dev/null
+++ b/examples/build_system/make/cpu/cortex-m55.mk
@@ -0,0 +1,28 @@
+ifeq ($(TOOLCHAIN),gcc)
+ CFLAGS += \
+ -mthumb \
+ -mcpu=cortex-m55 \
+ -mfloat-abi=hard \
+ -mfpu=fpv5-d16 \
+ -mcmse
+
+else ifeq ($(TOOLCHAIN),clang)
+ CFLAGS += \
+ --target=arm-none-eabi \
+ -mcpu=cortex-m55 \
+ -mfpu=fpv5-d16 \
+
+else ifeq ($(TOOLCHAIN),iar)
+ CFLAGS += \
+ --cpu cortex-m55 \
+ --fpu VFPv5_D16 \
+
+ ASFLAGS += \
+ --cpu cortex-m55 \
+ --fpu VFPv5_D16 \
+
+else
+ $(error "TOOLCHAIN is not supported")
+endif
+
+FREERTOS_PORTABLE_SRC ?= $(FREERTOS_PORTABLE_PATH)/ARM_CM55_NTZ/non_secure
diff --git a/examples/build_system/make/make.mk b/examples/build_system/make/make.mk
index 3101b66b9..f70748d34 100644
--- a/examples/build_system/make/make.mk
+++ b/examples/build_system/make/make.mk
@@ -2,6 +2,9 @@
# Common make definition for all examples
# ---------------------------------------
+# upper helper function
+to_upper = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$(subst -,_,$(1))))))))))))))))))))))))))))
+
#-------------------------------------------------------------
# Toolchain
# Can be changed via TOOLCHAIN=gcc|iar or CC=arm-none-eabi-gcc|iccarm|clang
@@ -109,7 +112,7 @@ INC += \
$(TOP)/$(FAMILY_PATH) \
$(TOP)/src \
-BOARD_UPPER = $(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$(subst -,_,$(BOARD))))))))))))))))))))))))))))
+BOARD_UPPER = $(call to_upper,$(BOARD))
CFLAGS += -DBOARD_$(BOARD_UPPER)
ifdef CFLAGS_CLI
@@ -120,27 +123,24 @@ endif
ifeq (${MAX3421_HOST},1)
SRC_C += src/portable/analog/max3421/hcd_max3421.c
CFLAGS += -DCFG_TUH_MAX3421=1
- CMAKE_DEFSYM += -DMAX3421_HOST=1
endif
# Log level is mapped to TUSB DEBUG option
ifneq ($(LOG),)
- CMAKE_DEFSYM += -DLOG=$(LOG)
CFLAGS += -DCFG_TUSB_DEBUG=$(LOG)
endif
# Logger: default is uart, can be set to rtt or swo
-ifneq ($(LOGGER),)
- CMAKE_DEFSYM += -DLOGGER=$(LOGGER)
-endif
-
ifeq ($(LOGGER),rtt)
- CFLAGS += -DLOGGER_RTT -DSEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
- RTT_SRC = lib/SEGGER_RTT
- INC += $(TOP)/$(RTT_SRC)/RTT
- SRC_C += $(RTT_SRC)/RTT/SEGGER_RTT.c
-else ifeq ($(LOGGER),swo)
+ CFLAGS += -DLOGGER_RTT
+ #CFLAGS += -DSEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
+ INC += $(TOP)/$(lib/SEGGER_RTT)/RTT
+ SRC_C += $(lib/SEGGER_RTT)/RTT/SEGGER_RTT.c
+endif
+ifeq ($(LOGGER),swo)
CFLAGS += -DLOGGER_SWO
+else
+ CFLAGS += -DLOGGER_UART
endif
# CPU specific flags
diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c
index e8c40309e..9b169e77e 100644
--- a/examples/device/audio_4_channel_mic/src/main.c
+++ b/examples/device/audio_4_channel_mic/src/main.c
@@ -31,10 +31,10 @@
* $ python3 plot_audio_samples.py
*/
-#include <stdlib.h>
+#include <math.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <math.h>
#include "bsp/board_api.h"
#include "tusb.h"
@@ -43,14 +43,14 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
-#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE
+#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE
/* Blink pattern
* - 250 ms : device not mounted
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum {
+enum {
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
@@ -60,36 +60,29 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
// Audio controls
// Current states
-bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
-uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0
uint32_t sampFreq;
uint8_t clkValid;
// Range states
-audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
-audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
+audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state
+audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
-// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2
-uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000/CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO];
-#else
// Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3
-uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000];
-#endif
+uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX * CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000];
void led_blinking_task(void);
void audio_task(void);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// init device stack on configured roothub port
tusb_rhport_init_t dev_init = {
- .role = TUSB_ROLE_DEVICE,
- .speed = TUSB_SPEED_AUTO
- };
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO};
tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
@@ -106,47 +99,23 @@ int main(void)
sampleFreqRng.subrange[0].bRes = 0;
// Generate dummy data
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
- uint16_t * p_buff = i2s_dummy_buffer[0];
+ uint16_t *p_buff = i2s_dummy_buffer;
uint16_t dataVal = 0;
- for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
- {
+ for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE / 1000; cnt++) {
// CH0 saw wave
*p_buff++ = dataVal;
// CH1 inverted saw wave
- *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal;
- dataVal+= 32;
- }
- p_buff = i2s_dummy_buffer[1];
- for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
- {
+ *p_buff++ = 3200 + AUDIO_SAMPLE_RATE / 1000 - dataVal;
+ dataVal += 32;
// CH3 square wave
- *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000;
+ *p_buff++ = cnt < (AUDIO_SAMPLE_RATE / 1000 / 2) ? 3400 : 5000;
// CH4 sinus wave
- float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000);
- *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000);
+ float t = 2 * 3.1415f * cnt / (AUDIO_SAMPLE_RATE / 1000);
+ *p_buff++ = (uint16_t) ((int16_t) (sinf(t) * 750) + 6000);
}
-#else
- uint16_t * p_buff = i2s_dummy_buffer;
- uint16_t dataVal = 0;
- for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
- {
- // CH0 saw wave
- *p_buff++ = dataVal;
- // CH1 inverted saw wave
- *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal;
- dataVal+= 32;
- // CH3 square wave
- *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000;
- // CH4 sinus wave
- float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000);
- *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000);
- }
-#endif
- while (1)
- {
- tud_task(); // tinyusb device task
+ while (1) {
+ tud_task();// tinyusb device task
led_blinking_task();
audio_task();
}
@@ -157,29 +126,25 @@ int main(void)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
+void tud_suspend_cb(bool remote_wakeup_en) {
(void) remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
+void tud_resume_cb(void) {
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
}
@@ -187,23 +152,15 @@ void tud_resume_cb(void)
// AUDIO Task
//--------------------------------------------------------------------+
-void audio_task(void)
-{
- // Yet to be filled - e.g. read audio from I2S buffer.
- // Here we simulate a I2S receive callback every 1ms.
+// This task simulates an audio receive callback, one frame is received every 1ms.
+// We assume that the audio data is read from an I2S buffer.
+// In a real application, this would be replaced with actual I2S receive callback.
+void audio_task(void) {
static uint32_t start_ms = 0;
uint32_t curr_ms = board_millis();
- if ( start_ms == curr_ms ) return; // not enough time
+ if (start_ms == curr_ms) return;// not enough time
start_ms = curr_ms;
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
- // Write I2S buffer into FIFO
- for (uint8_t cnt=0; cnt < 2; cnt++)
- {
- tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX);
- }
-#else
- tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX);
-#endif
+ tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX);
}
//--------------------------------------------------------------------+
@@ -211,8 +168,7 @@ void audio_task(void)
//--------------------------------------------------------------------+
// Invoked when audio class specific set request received for an EP
-bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -224,14 +180,15 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an interface
-bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -243,14 +200,15 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an entity
-bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -265,40 +223,37 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// If request is for our feature unit
- if ( entityID == 2 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Request uses format layout 1
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
- mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;
+ mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur;
TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
- return true;
+ return true;
case AUDIO_FU_CTRL_VOLUME:
// Request uses format layout 2
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
- volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur;
+ volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur;
TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
- return true;
+ return true;
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
- return false;
+ return false;
}
}
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an EP
-bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -306,16 +261,17 @@ bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
// return tud_control_xfer(rhport, p_request, &tmp, 1);
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an interface
-bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -323,14 +279,15 @@ bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an entity
-bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -340,12 +297,9 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
// Input terminal (Microphone input)
- if (entityID == 1)
- {
- switch ( ctrlSel )
- {
- case AUDIO_TE_CTRL_CONNECTOR:
- {
+ if (entityID == 1) {
+ switch (ctrlSel) {
+ case AUDIO_TE_CTRL_CONNECTOR: {
// The terminal connector control only has a get request with only the CUR attribute.
audio_desc_channel_cluster_t ret;
@@ -356,9 +310,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_LOG2(" Get terminal connector\r\n");
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
- }
- break;
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
+ } break;
// Unknown/Unsupported control selector
default:
@@ -368,10 +321,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Feature unit
- if (entityID == 2)
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
// There does not exist a range parameter block for mute
@@ -379,8 +330,7 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
case AUDIO_FU_CTRL_VOLUME:
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
@@ -390,21 +340,21 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
// Copy values - only for testing - better is version below
audio_control_range_2_n_t(1)
- ret;
+ ret;
ret.wNumSubRanges = 1;
- ret.subrange[0].bMin = -90; // -90 dB
- ret.subrange[0].bMax = 90; // +90 dB
- ret.subrange[0].bRes = 1; // 1 dB steps
+ ret.subrange[0].bMin = -90;// -90 dB
+ ret.subrange[0].bMax = 90; // +90 dB
+ ret.subrange[0].bRes = 1; // 1 dB steps
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
// Unknown/Unsupported control
default:
@@ -414,14 +364,11 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Clock Source unit
- if ( entityID == 4 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 4) {
+ switch (ctrlSel) {
case AUDIO_CS_CTRL_SAM_FREQ:
// channelNum is always zero in this case
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Sample Freq.\r\n");
// Buffered control transfer is needed for IN flow control to work
@@ -431,12 +378,12 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_LOG2(" Get Sample Freq. range\r\n");
return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
- // Unknown/Unsupported control
+ // Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
case AUDIO_CS_CTRL_CLK_VALID:
// Only cur attribute exists for this request
@@ -451,59 +398,20 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
TU_LOG2(" Unsupported entity: %d\r\n", entityID);
- return false; // Yet not implemented
-}
-
-bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
-
- // In read world application data flow is driven by I2S clock,
- // both tud_audio_tx_done_pre_load_cb() & tud_audio_tx_done_post_load_cb() are hardly used.
- // For example in your I2S receive callback:
- // void I2S_Rx_Callback(int channel, const void* data, uint16_t samples)
- // {
- // tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO);
- // }
-
- return true;
-}
-
-bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) n_bytes_copied;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- return true;
-}
-
-bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
- (void) rhport;
- (void) p_request;
-
- return true;
+ return false;// Yet not implemented
}
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void)
-{
+void led_blinking_task(void) {
static uint32_t start_ms = 0;
static bool led_state = false;
// Blink every interval ms
- if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
+ if (board_millis() - start_ms < blink_interval_ms) return;// not enough time
start_ms += blink_interval_ms;
board_led_write(led_state);
- led_state = 1 - led_state; // toggle
+ led_state = 1 - led_state;// toggle
}
diff --git a/examples/device/audio_4_channel_mic/src/tusb_config.h b/examples/device/audio_4_channel_mic/src/tusb_config.h
index 46484f847..446a7a32a 100644
--- a/examples/device/audio_4_channel_mic/src/tusb_config.h
+++ b/examples/device/audio_4_channel_mic/src/tusb_config.h
@@ -115,26 +115,11 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
-#define CFG_TUD_AUDIO_ENABLE_ENCODING 1
#define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
-
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN
-
-#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1
-#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value
-#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX)
-#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Example write FIFO every 1ms, so it should be 8 times larger for HS device
-
-#else
-
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/examples/device/audio_4_channel_mic_freertos/src/main.c b/examples/device/audio_4_channel_mic_freertos/src/main.c
index c9de4029a..9c76380a2 100644
--- a/examples/device/audio_4_channel_mic_freertos/src/main.c
+++ b/examples/device/audio_4_channel_mic_freertos/src/main.c
@@ -31,50 +31,50 @@
* $ python3 plot_audio_samples.py
*/
-#include <stdlib.h>
+#include <math.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <math.h>
#include "bsp/board_api.h"
#include "tusb.h"
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
// ESP-IDF need "freertos/" prefix in include path.
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
#include "freertos/FreeRTOS.h"
- #include "freertos/semphr.h"
#include "freertos/queue.h"
+ #include "freertos/semphr.h"
#include "freertos/task.h"
#include "freertos/timers.h"
- #define USBD_STACK_SIZE 4096
+ #define USBD_STACK_SIZE 4096
#else
#include "FreeRTOS.h"
- #include "semphr.h"
#include "queue.h"
+ #include "semphr.h"
#include "task.h"
#include "timers.h"
// Increase stack size when debug log is enabled
- #define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
+ #define USBD_STACK_SIZE (4 * configMINIMAL_STACK_SIZE / 2) * (CFG_TUSB_DEBUG ? 2 : 1)
#endif
-#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
-#define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE
+#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
+#define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
-#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE
+#define AUDIO_SAMPLE_RATE CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE
/* Blink pattern
* - 250 ms : device not mounted
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum {
+enum {
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
@@ -82,13 +82,13 @@ enum {
// static task
#if configSUPPORT_STATIC_ALLOCATION
-StackType_t blinky_stack[BLINKY_STACK_SIZE];
+StackType_t blinky_stack[BLINKY_STACK_SIZE];
StaticTask_t blinky_taskdef;
-StackType_t usb_device_stack[USBD_STACK_SIZE];
+StackType_t usb_device_stack[USBD_STACK_SIZE];
StaticTask_t usb_device_taskdef;
-StackType_t audio_stack[AUDIO_STACK_SIZE];
+StackType_t audio_stack[AUDIO_STACK_SIZE];
StaticTask_t audio_taskdef;
#endif
@@ -96,30 +96,24 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
// Audio controls
// Current states
-bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
-uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0
uint32_t sampFreq;
uint8_t clkValid;
// Range states
-audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
-audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
+audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state
+audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
-// Audio test data, each buffer contains 2 channels, buffer[0] for CH0-1, buffer[1] for CH1-2
-uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000/CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO];
-#else
// Audio test data, 4 channels muxed together, buffer[0] for CH0, buffer[1] for CH1, buffer[2] for CH2, buffer[3] for CH3
-uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX*CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE/1000];
-#endif
+uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX * CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000];
-void led_blinking_task(void* param);
-void usb_device_task(void* param);
-void audio_task(void* param);
+void led_blinking_task(void *param);
+void usb_device_task(void *param);
+void audio_isr_task(void *param);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// Init values
@@ -132,87 +126,62 @@ int main(void)
sampleFreqRng.subrange[0].bRes = 0;
// Generate dummy data
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
- uint16_t * p_buff = i2s_dummy_buffer[0];
+ uint16_t *p_buff = i2s_dummy_buffer;
uint16_t dataVal = 0;
- for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
- {
+ for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE / 1000; cnt++) {
// CH0 saw wave
*p_buff++ = dataVal;
// CH1 inverted saw wave
- *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal;
- dataVal+= 32;
- }
- p_buff = i2s_dummy_buffer[1];
- for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
- {
+ *p_buff++ = 3200 + AUDIO_SAMPLE_RATE / 1000 - dataVal;
+ dataVal += 32;
// CH3 square wave
- *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000;
+ *p_buff++ = cnt < (AUDIO_SAMPLE_RATE / 1000 / 2) ? 3400 : 5000;
// CH4 sinus wave
- float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000);
- *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000);
+ float t = 2 * 3.1415f * cnt / (AUDIO_SAMPLE_RATE / 1000);
+ *p_buff++ = (uint16_t) ((int16_t) (sinf(t) * 750) + 6000);
}
-#else
- uint16_t * p_buff = i2s_dummy_buffer;
- uint16_t dataVal = 0;
- for (uint16_t cnt = 0; cnt < AUDIO_SAMPLE_RATE/1000; cnt++)
- {
- // CH0 saw wave
- *p_buff++ = dataVal;
- // CH1 inverted saw wave
- *p_buff++ = 3200 + AUDIO_SAMPLE_RATE/1000 - dataVal;
- dataVal+= 32;
- // CH3 square wave
- *p_buff++ = cnt < (AUDIO_SAMPLE_RATE/1000/2) ? 3400:5000;
- // CH4 sinus wave
- float t = 2*3.1415f * cnt / (AUDIO_SAMPLE_RATE/1000);
- *p_buff++ = (uint16_t)((int16_t)(sinf(t) * 750) + 6000);
- }
-#endif
#if configSUPPORT_STATIC_ALLOCATION
// blinky task
xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef);
// Create a task for tinyusb device stack
- xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
+ xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, usb_device_stack, &usb_device_taskdef);
- // Create a task for audio
- xTaskCreateStatic(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES-1, audio_stack, &audio_taskdef);
+ // Audio receive (I2S) ISR simulation
+ // To simulate a ISR the priority is set to the highest
+ xTaskCreateStatic(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, audio_stack, &audio_taskdef);
#else
xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL);
- xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
- xTaskCreate(audio_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
+ xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL);
+ xTaskCreate(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
#endif
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
- #if !TUSB_MCU_VENDOR_ESPRESSIF
+ // only start scheduler for non-espressif mcu
+ #ifndef ESP_PLATFORM
vTaskStartScheduler();
#endif
return 0;
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
-void app_main(void)
-{
+#ifdef ESP_PLATFORM
+void app_main(void) {
main();
}
#endif
// USB Device Driver task
// This top level thread process all usb events and invoke callbacks
-void usb_device_task(void* param)
-{
+void usb_device_task(void *param) {
(void) param;
// init device stack on configured roothub port
// This should be called after scheduler/kernel is started.
// Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API.
tusb_rhport_init_t dev_init = {
- .role = TUSB_ROLE_DEVICE,
- .speed = TUSB_SPEED_AUTO
- };
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO};
tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
@@ -220,8 +189,7 @@ void usb_device_task(void* param)
}
// RTOS forever loop
- while (1)
- {
+ while (1) {
// tinyusb device task
tud_task();
}
@@ -232,29 +200,25 @@ void usb_device_task(void* param)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
+void tud_suspend_cb(bool remote_wakeup_en) {
(void) remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
+void tud_resume_cb(void) {
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
}
@@ -262,22 +226,14 @@ void tud_resume_cb(void)
// AUDIO Task
//--------------------------------------------------------------------+
-void audio_task(void* param)
-{
+// This task simulates an audio receive ISR, one frame is received every 1ms.
+// We assume that the audio data is read from an I2S buffer.
+// In a real application, this would be replaced with actual I2S receive callback.
+void audio_isr_task(void *param) {
(void) param;
- // Yet to be filled - e.g. read audio from I2S buffer.
- // Here we simulate a I2S receive callback every 1ms.
while (1) {
vTaskDelay(1);
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
- // Write I2S buffer into FIFO
- for (uint8_t cnt=0; cnt < 2; cnt++)
- {
- tud_audio_write_support_ff(cnt, i2s_dummy_buffer[cnt], AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX);
- }
-#else
- tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX);
-#endif
+ tud_audio_write(i2s_dummy_buffer, AUDIO_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX);
}
}
@@ -286,8 +242,7 @@ void audio_task(void* param)
//--------------------------------------------------------------------+
// Invoked when audio class specific set request received for an EP
-bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -299,14 +254,15 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an interface
-bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -318,14 +274,15 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an entity
-bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -340,40 +297,36 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// If request is for our feature unit
- if ( entityID == 2 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Request uses format layout 1
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
- mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;
+ mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur;
- TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
- return true;
+ TU_LOG1(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
+ return true;
case AUDIO_FU_CTRL_VOLUME:
// Request uses format layout 2
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
- volume[channelNum] = ((audio_control_cur_2_t*) pBuff)->bCur;
-
- TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
- return true;
+ volume[channelNum] = ((audio_control_cur_2_t *) pBuff)->bCur;
+ TU_LOG1(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
+ return true;
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
- return false;
+ return false;
}
}
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an EP
-bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -381,14 +334,15 @@ bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an interface
-bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -396,14 +350,15 @@ bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an entity
-bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -413,12 +368,9 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
// Input terminal (Microphone input)
- if (entityID == 1)
- {
- switch ( ctrlSel )
- {
- case AUDIO_TE_CTRL_CONNECTOR:
- {
+ if (entityID == 1) {
+ switch (ctrlSel) {
+ case AUDIO_TE_CTRL_CONNECTOR: {
// The terminal connector control only has a get request with only the CUR attribute.
audio_desc_channel_cluster_t ret;
@@ -427,11 +379,10 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
ret.bmChannelConfig = 0;
ret.iChannelNames = 0;
- TU_LOG2(" Get terminal connector\r\n");
+ TU_LOG1(" Get terminal connector\r\n");
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
- }
- break;
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
+ } break;
// Unknown/Unsupported control selector
default:
@@ -441,43 +392,39 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Feature unit
- if (entityID == 2)
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
// There does not exist a range parameter block for mute
- TU_LOG2(" Get Mute of channel: %u\r\n", channelNum);
+ TU_LOG1(" Get Mute of channel: %u\r\n", channelNum);
return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
case AUDIO_FU_CTRL_VOLUME:
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
- TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
+ TU_LOG1(" Get Volume of channel: %u\r\n", channelNum);
return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
case AUDIO_CS_REQ_RANGE:
- TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum);
+ TU_LOG1(" Get Volume range of channel: %u\r\n", channelNum);
// Copy values - only for testing - better is version below
- audio_control_range_2_n_t(1)
- ret;
+ audio_control_range_2_n_t(1) ret;
ret.wNumSubRanges = 1;
- ret.subrange[0].bMin = -90; // -90 dB
- ret.subrange[0].bMax = 90; // +90 dB
- ret.subrange[0].bRes = 1; // 1 dB steps
+ ret.subrange[0].bMin = -90;// -90 dB
+ ret.subrange[0].bMax = 90; // +90 dB
+ ret.subrange[0].bRes = 1; // 1 dB steps
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
// Unknown/Unsupported control
default:
@@ -487,33 +434,30 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Clock Source unit
- if ( entityID == 4 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 4) {
+ switch (ctrlSel) {
case AUDIO_CS_CTRL_SAM_FREQ:
// channelNum is always zero in this case
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
- TU_LOG2(" Get Sample Freq.\r\n");
+ TU_LOG1(" Get Sample Freq.\r\n");
// Buffered control transfer is needed for IN flow control to work
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
case AUDIO_CS_REQ_RANGE:
- TU_LOG2(" Get Sample Freq. range\r\n");
+ TU_LOG1(" Get Sample Freq. range\r\n");
return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
- // Unknown/Unsupported control
+ // Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
case AUDIO_CS_CTRL_CLK_VALID:
// Only cur attribute exists for this request
- TU_LOG2(" Get Sample Freq. valid\r\n");
+ TU_LOG1(" Get Sample Freq. valid\r\n");
return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
// Unknown/Unsupported control
@@ -523,52 +467,14 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
}
- TU_LOG2(" Unsupported entity: %d\r\n", entityID);
- return false; // Yet not implemented
-}
-
-bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
-
- // In read world application data flow is driven by I2S clock,
- // both tud_audio_tx_done_pre_load_cb() & tud_audio_tx_done_post_load_cb() are hardly used.
- // For example in your I2S receive callback:
- // void I2S_Rx_Callback(int channel, const void* data, uint16_t samples)
- // {
- // tud_audio_write_support_ff(channel, data, samples * N_BYTES_PER_SAMPLE * N_CHANNEL_PER_FIFO);
- // }
-
- return true;
-}
-
-bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) n_bytes_copied;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- return true;
-}
-
-bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
- (void) rhport;
- (void) p_request;
-
- return true;
+ TU_LOG1(" Unsupported entity: %d\r\n", entityID);
+ return false;// Yet not implemented
}
///--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void* param) {
+void led_blinking_task(void *param) {
(void) param;
static uint32_t start_ms = 0;
static bool led_state = false;
@@ -579,6 +485,6 @@ void led_blinking_task(void* param) {
start_ms += blink_interval_ms;
board_led_write(led_state);
- led_state = 1 - led_state; // toggle
+ led_state = 1 - led_state;// toggle
}
}
diff --git a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h
index 5cd93b0d6..f7c0efe08 100644
--- a/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h
+++ b/examples/device/audio_4_channel_mic_freertos/src/tusb_config.h
@@ -59,7 +59,7 @@ extern "C" {
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
@@ -121,26 +121,11 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 4 // This value is not required by the driver, it parses this information from the descriptor once the alternate interface is set by the host - we use it for the setup
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
-#define CFG_TUD_AUDIO_ENABLE_ENCODING 1
#define CFG_TUD_AUDIO_EP_IN_FLOW_CONTROL 1
-#if CFG_TUD_AUDIO_ENABLE_ENCODING
-
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_EP_SZ_IN
-
-#define CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING 1
-#define CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX 2 // One I2S stream contains two channels, each stream is saved within one support FIFO - this value is currently fixed, the driver does not support a changing value
-#define CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO (CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / CFG_TUD_AUDIO_FUNC_1_CHANNEL_PER_FIFO_TX)
-#define CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * (CFG_TUD_AUDIO_EP_SZ_IN / CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO) // Example write FIFO every 1ms, so it should be 8 times larger for HS device
-
-#else
-
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/examples/device/audio_test/src/main.c b/examples/device/audio_test/src/main.c
index 018c48994..07728e24a 100644
--- a/examples/device/audio_test/src/main.c
+++ b/examples/device/audio_test/src/main.c
@@ -31,8 +31,8 @@
* $ python3 plot_audio_samples.py
*/
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "bsp/board_api.h"
@@ -47,7 +47,7 @@
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum {
+enum {
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
@@ -57,32 +57,30 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
// Audio controls
// Current states
-bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
-uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0
uint32_t sampFreq;
uint8_t clkValid;
// Range states
-audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
-audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
+audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state
+audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
// Audio test data
-uint16_t test_buffer_audio[(CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2];
+uint16_t test_buffer_audio[CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / 2];
uint16_t startVal = 0;
void led_blinking_task(void);
void audio_task(void);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// init device stack on configured roothub port
tusb_rhport_init_t dev_init = {
- .role = TUSB_ROLE_DEVICE,
- .speed = TUSB_SPEED_AUTO
- };
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO};
tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
@@ -98,9 +96,8 @@ int main(void)
sampleFreqRng.subrange[0].bMax = CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE;
sampleFreqRng.subrange[0].bRes = 0;
- while (1)
- {
- tud_task(); // tinyusb device task
+ while (1) {
+ tud_task();// tinyusb device task
led_blinking_task();
audio_task();
}
@@ -111,40 +108,45 @@ int main(void)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
+void tud_suspend_cb(bool remote_wakeup_en) {
(void) remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
+void tud_resume_cb(void) {
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
}
+
//--------------------------------------------------------------------+
// AUDIO Task
//--------------------------------------------------------------------+
-void audio_task(void)
-{
- // Yet to be filled - e.g. put meas data into TX FIFOs etc.
- // asm("nop");
+// This task simulates an audio receive callback, one frame is received every 1ms.
+// We assume that the audio data is read from an I2S buffer.
+// In a real application, this would be replaced with actual I2S receive callback.
+void audio_task(void) {
+ static uint32_t start_ms = 0;
+ uint32_t curr_ms = board_millis();
+ if (start_ms == curr_ms) return;// not enough time
+ start_ms = curr_ms;
+ for (size_t cnt = 0; cnt < sizeof(test_buffer_audio) / 2; cnt++) {
+ test_buffer_audio[cnt] = startVal++;
+ }
+ tud_audio_write((uint8_t *) test_buffer_audio, sizeof(test_buffer_audio));
}
//--------------------------------------------------------------------+
@@ -152,8 +154,7 @@ void audio_task(void)
//--------------------------------------------------------------------+
// Invoked when audio class specific set request received for an EP
-bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -165,14 +166,15 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an interface
-bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -184,14 +186,15 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an entity
-bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -206,40 +209,37 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// If request is for our feature unit
- if ( entityID == 2 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Request uses format layout 1
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
- mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;
+ mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur;
TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
- return true;
+ return true;
case AUDIO_FU_CTRL_VOLUME:
// Request uses format layout 2
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
- volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur;
+ volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur;
TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
- return true;
+ return true;
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
- return false;
+ return false;
}
}
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an EP
-bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -247,16 +247,17 @@ bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
// return tud_control_xfer(rhport, p_request, &tmp, 1);
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an interface
-bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -264,14 +265,15 @@ bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an entity
-bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -281,12 +283,9 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
// Input terminal (Microphone input)
- if (entityID == 1)
- {
- switch ( ctrlSel )
- {
- case AUDIO_TE_CTRL_CONNECTOR:
- {
+ if (entityID == 1) {
+ switch (ctrlSel) {
+ case AUDIO_TE_CTRL_CONNECTOR: {
// The terminal connector control only has a get request with only the CUR attribute.
audio_desc_channel_cluster_t ret;
@@ -297,9 +296,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_LOG2(" Get terminal connector\r\n");
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
- }
- break;
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
+ } break;
// Unknown/Unsupported control selector
default:
@@ -309,43 +307,40 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Feature unit
- if (entityID == 2)
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
// There does not exist a range parameter block for mute
TU_LOG2(" Get Mute of channel: %u\r\n", channelNum);
- return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1);
case AUDIO_FU_CTRL_VOLUME:
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
- return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
case AUDIO_CS_REQ_RANGE:
TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum);
// Copy values - only for testing - better is version below
audio_control_range_2_n_t(1)
- ret;
+ ret;
ret.wNumSubRanges = 1;
- ret.subrange[0].bMin = -90; // -90 dB
- ret.subrange[0].bMax = 90; // +90 dB
- ret.subrange[0].bRes = 1; // 1 dB steps
+ ret.subrange[0].bMin = -90;// -90 dB
+ ret.subrange[0].bMax = 90; // +90 dB
+ ret.subrange[0].bRes = 1; // 1 dB steps
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
// Unknown/Unsupported control
default:
@@ -355,33 +350,30 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Clock Source unit
- if ( entityID == 4 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 4) {
+ switch (ctrlSel) {
case AUDIO_CS_CTRL_SAM_FREQ:
// channelNum is always zero in this case
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Sample Freq.\r\n");
- return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
case AUDIO_CS_REQ_RANGE:
TU_LOG2(" Get Sample Freq. range\r\n");
- return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
- // Unknown/Unsupported control
+ // Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
case AUDIO_CS_CTRL_CLK_VALID:
// Only cur attribute exists for this request
TU_LOG2(" Get Sample Freq. valid\r\n");
- return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
// Unknown/Unsupported control
default:
@@ -391,39 +383,10 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
TU_LOG2(" Unsupported entity: %d\r\n", entityID);
- return false; // Yet not implemented
-}
-
-bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- tud_audio_write ((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2);
-
- return true;
-}
-
-bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) n_bytes_copied;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- for (size_t cnt = 0; cnt < (CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2; cnt++)
- {
- test_buffer_audio[cnt] = startVal++;
- }
-
- return true;
+ return false;// Yet not implemented
}
-bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
(void) p_request;
startVal = 0;
@@ -434,15 +397,14 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void)
-{
+void led_blinking_task(void) {
static uint32_t start_ms = 0;
static bool led_state = false;
// Blink every interval ms
- if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
+ if (board_millis() - start_ms < blink_interval_ms) return;// not enough time
start_ms += blink_interval_ms;
board_led_write(led_state);
- led_state = 1 - led_state; // toggle
+ led_state = 1 - led_state;// toggle
}
diff --git a/examples/device/audio_test/src/plot_audio_samples.py b/examples/device/audio_test/src/plot_audio_samples.py
index ea6aa661e..2be8948ea 100755
--- a/examples/device/audio_test/src/plot_audio_samples.py
+++ b/examples/device/audio_test/src/plot_audio_samples.py
@@ -12,11 +12,11 @@ if __name__ == '__main__':
# print(sd.query_devices())
fs = 48000 # Sample rate
- duration = 100e-3 # Duration of recording
+ duration = 3 # Duration of recording
if platform.system() == 'Windows':
# MME is needed since there are more than one MicNode device APIs (at least in Windows)
- device = 'Microphone (MicNode) MME'
+ device = 'Microphone (MicNode), Windows WASAPI'
elif platform.system() == 'Darwin':
device = 'MicNode'
else:
diff --git a/examples/device/audio_test/src/tusb_config.h b/examples/device/audio_test/src/tusb_config.h
index 8c021e23c..b38958d7c 100644
--- a/examples/device/audio_test/src/tusb_config.h
+++ b/examples/device/audio_test/src/tusb_config.h
@@ -117,7 +117,7 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor!
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
+#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
#ifdef __cplusplus
}
diff --git a/examples/device/audio_test_freertos/src/main.c b/examples/device/audio_test_freertos/src/main.c
index c5143c3fc..b1119c888 100644
--- a/examples/device/audio_test_freertos/src/main.c
+++ b/examples/device/audio_test_freertos/src/main.c
@@ -31,36 +31,37 @@
* $ python3 plot_audio_samples.py
*/
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "bsp/board_api.h"
#include "tusb.h"
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
// ESP-IDF need "freertos/" prefix in include path.
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
#include "freertos/FreeRTOS.h"
- #include "freertos/semphr.h"
#include "freertos/queue.h"
+ #include "freertos/semphr.h"
#include "freertos/task.h"
#include "freertos/timers.h"
- #define USBD_STACK_SIZE 4096
+ #define USBD_STACK_SIZE 4096
#else
#include "FreeRTOS.h"
- #include "semphr.h"
#include "queue.h"
+ #include "semphr.h"
#include "task.h"
#include "timers.h"
// Increase stack size when debug log is enabled
- #define USBD_STACK_SIZE (4*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
+ #define USBD_STACK_SIZE (4 * configMINIMAL_STACK_SIZE / 2) * (CFG_TUSB_DEBUG ? 2 : 1)
#endif
-#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
+#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
+#define AUDIO_STACK_SIZE configMINIMAL_STACK_SIZE
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
@@ -71,7 +72,7 @@
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum {
+enum {
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
@@ -82,34 +83,36 @@ enum {
StackType_t blinky_stack[BLINKY_STACK_SIZE];
StaticTask_t blinky_taskdef;
-StackType_t usb_device_stack[USBD_STACK_SIZE];
+StackType_t usb_device_stack[USBD_STACK_SIZE];
StaticTask_t usb_device_taskdef;
+
+StackType_t audio_stack[AUDIO_STACK_SIZE];
+StaticTask_t audio_taskdef;
#endif
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
// Audio controls
// Current states
-bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
-uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0
uint32_t sampFreq;
uint8_t clkValid;
// Range states
-audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
-audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
+audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state
+audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
// Audio test data
-uint16_t test_buffer_audio[(CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2];
+uint16_t test_buffer_audio[CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX / 2];
uint16_t startVal = 0;
-void led_blinking_task(void* param);
-void usb_device_task(void* param);
-void audio_task(void);
+void led_blinking_task(void *param);
+void usb_device_task(void *param);
+void audio_isr_task(void *param);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// Init values
@@ -126,21 +129,26 @@ int main(void)
xTaskCreateStatic(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, blinky_stack, &blinky_taskdef);
// Create a task for tinyusb device stack
- xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef);
+ xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, usb_device_stack, &usb_device_taskdef);
+
+ // Audio receive (I2S) ISR simulation
+ // To simulate a ISR the priority is set to the highest
+ xTaskCreateStatic(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, audio_stack, &audio_taskdef);
#else
xTaskCreate(led_blinking_task, "blinky", BLINKY_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
+ xTaskCreate(audio_isr_task, "audio", AUDIO_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
#endif
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
- #if !TUSB_MCU_VENDOR_ESPRESSIF
+ // only start scheduler for non-espressif mcu
+ #ifndef ESP_PLATFORM
vTaskStartScheduler();
#endif
return 0;
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
void app_main(void) {
main();
}
@@ -148,17 +156,15 @@ void app_main(void) {
// USB Device Driver task
// This top level thread process all usb events and invoke callbacks
-void usb_device_task(void* param)
-{
+void usb_device_task(void *param) {
(void) param;
// init device stack on configured roothub port
// This should be called after scheduler/kernel is started.
// Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API.
tusb_rhport_init_t dev_init = {
- .role = TUSB_ROLE_DEVICE,
- .speed = TUSB_SPEED_AUTO
- };
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO};
tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
@@ -166,8 +172,7 @@ void usb_device_task(void* param)
}
// RTOS forever loop
- while (1)
- {
+ while (1) {
// tinyusb device task
tud_task();
}
@@ -204,10 +209,18 @@ void tud_resume_cb(void) {
// AUDIO Task
//--------------------------------------------------------------------+
-void audio_task(void)
-{
- // Yet to be filled - e.g. put meas data into TX FIFOs etc.
- // asm("nop");
+// This task simulates an audio receive ISR, one frame is received every 1ms.
+// We assume that the audio data is read from an I2S buffer.
+// In a real application, this would be replaced with actual I2S receive callback.
+void audio_isr_task(void *param) {
+ (void) param;
+ while (1) {
+ vTaskDelay(1);
+ for (size_t cnt = 0; cnt < sizeof(test_buffer_audio) / 2; cnt++) {
+ test_buffer_audio[cnt] = startVal++;
+ }
+ tud_audio_write((uint8_t *) test_buffer_audio, sizeof(test_buffer_audio));
+ }
}
//--------------------------------------------------------------------+
@@ -215,8 +228,7 @@ void audio_task(void)
//--------------------------------------------------------------------+
// Invoked when audio class specific set request received for an EP
-bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -228,14 +240,15 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an interface
-bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -247,14 +260,15 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an entity
-bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -269,40 +283,36 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// If request is for our feature unit
- if ( entityID == 2 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Request uses format layout 1
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
- mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;
+ mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur;
- TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
- return true;
+ TU_LOG1(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
+ return true;
case AUDIO_FU_CTRL_VOLUME:
// Request uses format layout 2
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
- volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur;
-
- TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
- return true;
+ volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur;
+ TU_LOG1(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
+ return true;
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
- return false;
+ return false;
}
}
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an EP
-bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -310,14 +320,15 @@ bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an interface
-bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -325,14 +336,15 @@ bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an entity
-bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -342,12 +354,9 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
// Input terminal (Microphone input)
- if (entityID == 1)
- {
- switch ( ctrlSel )
- {
- case AUDIO_TE_CTRL_CONNECTOR:
- {
+ if (entityID == 1) {
+ switch (ctrlSel) {
+ case AUDIO_TE_CTRL_CONNECTOR: {
// The terminal connector control only has a get request with only the CUR attribute.
audio_desc_channel_cluster_t ret;
@@ -356,11 +365,10 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
ret.bmChannelConfig = (audio_channel_config_t) 0;
ret.iChannelNames = 0;
- TU_LOG2(" Get terminal connector\r\n");
+ TU_LOG1(" Get terminal connector\r\n");
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
- }
- break;
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
+ } break;
// Unknown/Unsupported control selector
default:
@@ -370,43 +378,40 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Feature unit
- if (entityID == 2)
- {
- switch ( ctrlSel )
- {
+ if (entityID == 2) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
// There does not exist a range parameter block for mute
- TU_LOG2(" Get Mute of channel: %u\r\n", channelNum);
- return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
+ TU_LOG1(" Get Mute of channel: %u\r\n", channelNum);
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1);
case AUDIO_FU_CTRL_VOLUME:
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
- TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
- return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
+ TU_LOG1(" Get Volume of channel: %u\r\n", channelNum);
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
case AUDIO_CS_REQ_RANGE:
- TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum);
+ TU_LOG1(" Get Volume range of channel: %u\r\n", channelNum);
// Copy values - only for testing - better is version below
audio_control_range_2_n_t(1)
- ret;
+ ret;
ret.wNumSubRanges = 1;
- ret.subrange[0].bMin = -90; // -90 dB
- ret.subrange[0].bMax = 90; // +90 dB
- ret.subrange[0].bRes = 1; // 1 dB steps
+ ret.subrange[0].bMin = -90;// -90 dB
+ ret.subrange[0].bMax = 90; // +90 dB
+ ret.subrange[0].bRes = 1; // 1 dB steps
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
// Unknown/Unsupported control
default:
@@ -416,33 +421,30 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Clock Source unit
- if ( entityID == 4 )
- {
- switch ( ctrlSel )
- {
+ if (entityID == 4) {
+ switch (ctrlSel) {
case AUDIO_CS_CTRL_SAM_FREQ:
// channelNum is always zero in this case
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
- TU_LOG2(" Get Sample Freq.\r\n");
- return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
+ TU_LOG1(" Get Sample Freq.\r\n");
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
case AUDIO_CS_REQ_RANGE:
- TU_LOG2(" Get Sample Freq. range\r\n");
- return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
+ TU_LOG1(" Get Sample Freq. range\r\n");
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
- // Unknown/Unsupported control
+ // Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
case AUDIO_CS_CTRL_CLK_VALID:
// Only cur attribute exists for this request
- TU_LOG2(" Get Sample Freq. valid\r\n");
- return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
+ TU_LOG1(" Get Sample Freq. valid\r\n");
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
// Unknown/Unsupported control
default:
@@ -451,40 +453,11 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
}
- TU_LOG2(" Unsupported entity: %d\r\n", entityID);
- return false; // Yet not implemented
-}
-
-bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- tud_audio_write ((uint8_t *)test_buffer_audio, CFG_TUD_AUDIO_EP_SZ_IN - 2);
-
- return true;
-}
-
-bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) n_bytes_copied;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- for (size_t cnt = 0; cnt < (CFG_TUD_AUDIO_EP_SZ_IN - 2) / 2; cnt++)
- {
- test_buffer_audio[cnt] = startVal++;
- }
-
- return true;
+ TU_LOG1(" Unsupported entity: %d\r\n", entityID);
+ return false;// Yet not implemented
}
-bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
(void) p_request;
startVal = 0;
@@ -495,7 +468,7 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void* param) {
+void led_blinking_task(void *param) {
(void) param;
static uint32_t start_ms = 0;
static bool led_state = false;
@@ -506,6 +479,6 @@ void led_blinking_task(void* param) {
start_ms += blink_interval_ms;
board_led_write(led_state);
- led_state = 1 - led_state; // toggle
+ led_state = 1 - led_state;// toggle
}
}
diff --git a/examples/device/audio_test_freertos/src/plot_audio_samples.py b/examples/device/audio_test_freertos/src/plot_audio_samples.py
index 46738eb3f..b6d8e824b 100755
--- a/examples/device/audio_test_freertos/src/plot_audio_samples.py
+++ b/examples/device/audio_test_freertos/src/plot_audio_samples.py
@@ -11,11 +11,11 @@ if __name__ == '__main__':
# print(sd.query_devices())
fs = 48000 # Sample rate
- duration = 1000e-3 # Duration of recording
+ duration = 3 # Duration of recording
if platform.system() == 'Windows':
# MME is needed since there are more than one MicNode device APIs (at least in Windows)
- device = 'Microphone (MicNode) MME'
+ device = 'Microphone (MicNode), Windows WASAPI'
elif platform.system() == 'Darwin':
device = 'MicNode'
else:
diff --git a/examples/device/audio_test_freertos/src/tusb_config.h b/examples/device/audio_test_freertos/src/tusb_config.h
index 61c5cbb96..b708e2541 100644
--- a/examples/device/audio_test_freertos/src/tusb_config.h
+++ b/examples/device/audio_test_freertos/src/tusb_config.h
@@ -59,7 +59,7 @@ extern "C" {
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
@@ -123,7 +123,7 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 1 // Driver gets this info from the descriptors - we define it here to use it to setup the descriptors and to do calculations with it below - be aware: for different number of channels you need another descriptor!
#define CFG_TUD_AUDIO_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX CFG_TUD_AUDIO_EP_SZ_IN
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
+#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_EP_SZ_IN // Example write FIFO every 1ms, so it should be 8 times larger for HS device
#ifdef __cplusplus
}
diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c
index 8fa902a04..704a75b09 100644
--- a/examples/device/audio_test_multi_rate/src/main.c
+++ b/examples/device/audio_test_multi_rate/src/main.c
@@ -32,8 +32,8 @@
* $ python3 plot_audio_samples.py
*/
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "bsp/board_api.h"
@@ -49,7 +49,7 @@
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum {
+enum {
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
@@ -59,8 +59,8 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
// Audio controls
// Current states
-bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
-uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+bool mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1]; // +1 for master channel 0
+uint16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// +1 for master channel 0
uint32_t sampFreq;
uint8_t bytesPerSample;
uint8_t clkValid;
@@ -68,39 +68,36 @@ uint8_t clkValid;
// Range states
// List of supported sample rates
static const uint32_t sampleRatesList[] =
-{
- 32000, 48000, 96000
-};
+ {
+ 32000, 48000, 96000};
-#define N_sampleRates TU_ARRAY_SIZE(sampleRatesList)
+#define N_sampleRates TU_ARRAY_SIZE(sampleRatesList)
// Bytes per format of every Alt settings
static const uint8_t bytesPerSampleAltList[CFG_TUD_AUDIO_FUNC_1_N_FORMATS] =
-{
- CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX,
- CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX,
+ {
+ CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX,
+ CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX,
};
-audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX+1]; // Volume range state
+audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX + 1];// Volume range state
// Audio test data
-CFG_TUD_MEM_ALIGN uint8_t test_buffer_audio[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX];
+CFG_TUD_MEM_ALIGN uint8_t test_buffer_audio[(TUD_OPT_HIGH_SPEED ? 8 : 1) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX];
uint16_t startVal = 0;
void led_blinking_task(void);
void audio_task(void);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// init device stack on configured roothub port
tusb_rhport_init_t dev_init = {
- .role = TUSB_ROLE_DEVICE,
- .speed = TUSB_SPEED_AUTO
- };
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO};
tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
@@ -111,9 +108,8 @@ int main(void)
sampFreq = sampleRatesList[0];
clkValid = 1;
- while (1)
- {
- tud_task(); // tinyusb device task
+ while (1) {
+ tud_task();// tinyusb device task
led_blinking_task();
audio_task();
}
@@ -127,29 +123,25 @@ int main(void)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
+void tud_suspend_cb(bool remote_wakeup_en) {
(void) remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
+void tud_resume_cb(void) {
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
}
@@ -157,10 +149,29 @@ void tud_resume_cb(void)
// AUDIO Task
//--------------------------------------------------------------------+
-void audio_task(void)
-{
- // Yet to be filled - e.g. put meas data into TX FIFOs etc.
- // asm("nop");
+// This task simulates an audio receive callback, one frame is received every 1ms.
+// We assume that the audio data is read from an I2S buffer.
+// In a real application, this would be replaced with actual I2S receive callback.
+void audio_task(void) {
+ static uint32_t start_ms = 0;
+ uint32_t curr_ms = board_millis();
+ if (start_ms == curr_ms) return;// not enough time
+ start_ms = curr_ms;
+ // 16bit
+ if (bytesPerSample == 2) {
+ uint16_t *pData_16 = (uint16_t *) ((void *) test_buffer_audio);
+ for (size_t cnt = 0; cnt < sampFreq / 1000; cnt++) {
+ pData_16[cnt] = startVal++;
+ }
+ }
+ // 24bit in 32bit slot
+ else if (bytesPerSample == 4) {
+ uint32_t *pData_32 = (uint32_t *) ((void *) test_buffer_audio);
+ for (size_t cnt = 0; cnt < sampFreq / 1000; cnt++) {
+ pData_32[cnt] = (uint32_t) startVal++ << 16U;
+ }
+ }
+ tud_audio_write((uint8_t *) test_buffer_audio, (uint16_t) (sampFreq / 1000 * bytesPerSample));
}
//--------------------------------------------------------------------+
@@ -168,23 +179,20 @@ void audio_task(void)
//--------------------------------------------------------------------+
// Invoked when set interface is called, typically on start/stop streaming or format change
-bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
- (void)rhport;
+bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
+ (void) rhport;
//uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));
// Clear buffer when streaming format is changed
- if(alt != 0)
- {
- bytesPerSample = bytesPerSampleAltList[alt-1];
+ if (alt != 0) {
+ bytesPerSample = bytesPerSampleAltList[alt - 1];
}
return true;
}
// Invoked when audio class specific set request received for an EP
-bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -196,14 +204,15 @@ bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an interface
-bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
(void) pBuff;
@@ -215,14 +224,15 @@ bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific set request received for an entity
-bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
-{
+bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -237,49 +247,45 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// If request is for our feature unit
- if ( entityID == UAC2_ENTITY_FEATURE_UNIT )
- {
- switch ( ctrlSel )
- {
+ if (entityID == UAC2_ENTITY_FEATURE_UNIT) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Request uses format layout 1
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
- mute[channelNum] = ((audio_control_cur_1_t*) pBuff)->bCur;
+ mute[channelNum] = ((audio_control_cur_1_t *) pBuff)->bCur;
TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
- return true;
+ return true;
case AUDIO_FU_CTRL_VOLUME:
// Request uses format layout 2
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
- volume[channelNum] = (uint16_t) ((audio_control_cur_2_t*) pBuff)->bCur;
+ volume[channelNum] = (uint16_t) ((audio_control_cur_2_t *) pBuff)->bCur;
TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
- return true;
+ return true;
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
- return false;
+ return false;
}
}
// Clock Source unit
- if ( entityID == UAC2_ENTITY_CLOCK )
- {
- switch ( ctrlSel )
- {
+ if (entityID == UAC2_ENTITY_CLOCK) {
+ switch (ctrlSel) {
case AUDIO_CS_CTRL_SAM_FREQ:
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_4_t));
- sampFreq = (uint32_t)((audio_control_cur_4_t *)pBuff)->bCur;
+ sampFreq = (uint32_t) ((audio_control_cur_4_t *) pBuff)->bCur;
TU_LOG2("Clock set current freq: %" PRIu32 "\r\n", sampFreq);
return true;
- break;
+ break;
// Unknown/Unsupported control
default:
@@ -288,12 +294,11 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
}
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an EP
-bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -301,16 +306,17 @@ bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_re
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) ep;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) ep;
// return tud_control_xfer(rhport, p_request, &tmp, 1);
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an interface
-bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -318,14 +324,15 @@ bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_r
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
- (void) channelNum; (void) ctrlSel; (void) itf;
+ (void) channelNum;
+ (void) ctrlSel;
+ (void) itf;
- return false; // Yet not implemented
+ return false;// Yet not implemented
}
// Invoked when audio class specific get request received for an entity
-bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
// Page 91 in UAC2 specification
@@ -335,12 +342,9 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
// Input terminal (Microphone input)
- if (entityID == UAC2_ENTITY_INPUT_TERMINAL)
- {
- switch ( ctrlSel )
- {
- case AUDIO_TE_CTRL_CONNECTOR:
- {
+ if (entityID == UAC2_ENTITY_INPUT_TERMINAL) {
+ switch (ctrlSel) {
+ case AUDIO_TE_CTRL_CONNECTOR: {
// The terminal connector control only has a get request with only the CUR attribute.
audio_desc_channel_cluster_t ret;
@@ -351,9 +355,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
TU_LOG2(" Get terminal connector\r\n");
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
- }
- break;
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
+ } break;
// Unknown/Unsupported control selector
default:
@@ -363,43 +366,40 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Feature unit
- if (entityID == UAC2_ENTITY_FEATURE_UNIT)
- {
- switch ( ctrlSel )
- {
+ if (entityID == UAC2_ENTITY_FEATURE_UNIT) {
+ switch (ctrlSel) {
case AUDIO_FU_CTRL_MUTE:
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
// There does not exist a range parameter block for mute
TU_LOG2(" Get Mute of channel: %u\r\n", channelNum);
- return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &mute[channelNum], 1);
case AUDIO_FU_CTRL_VOLUME:
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
- return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
case AUDIO_CS_REQ_RANGE:
TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum);
// Copy values - only for testing - better is version below
audio_control_range_2_n_t(1)
- ret;
+ ret;
ret.wNumSubRanges = 1;
- ret.subrange[0].bMin = -90; // -90 dB
- ret.subrange[0].bMax = 30; // +30 dB
- ret.subrange[0].bRes = 1; // 1 dB steps
+ ret.subrange[0].bMin = -90;// -90 dB
+ ret.subrange[0].bMax = 30; // +30 dB
+ ret.subrange[0].bRes = 1; // 1 dB steps
- return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*) &ret, sizeof(ret));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void *) &ret, sizeof(ret));
// Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
// Unknown/Unsupported control
default:
@@ -409,46 +409,40 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
// Clock Source unit
- if ( entityID == UAC2_ENTITY_CLOCK )
- {
- switch ( ctrlSel )
- {
+ if (entityID == UAC2_ENTITY_CLOCK) {
+ switch (ctrlSel) {
case AUDIO_CS_CTRL_SAM_FREQ:
// channelNum is always zero in this case
- switch ( p_request->bRequest )
- {
+ switch (p_request->bRequest) {
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Sample Freq.\r\n");
- return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
- case AUDIO_CS_REQ_RANGE:
- {
+ case AUDIO_CS_REQ_RANGE: {
TU_LOG2(" Get Sample Freq. range\r\n");
audio_control_range_4_n_t(N_sampleRates) rangef =
- {
- .wNumSubRanges = tu_htole16(N_sampleRates)
- };
+ {
+ .wNumSubRanges = tu_htole16(N_sampleRates)};
TU_LOG1("Clock get %d freq ranges\r\n", N_sampleRates);
- for(uint8_t i = 0; i < N_sampleRates; i++)
- {
- rangef.subrange[i].bMin = (int32_t)sampleRatesList[i];
- rangef.subrange[i].bMax = (int32_t)sampleRatesList[i];
- rangef.subrange[i].bRes = 0;
- TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes);
+ for (uint8_t i = 0; i < N_sampleRates; i++) {
+ rangef.subrange[i].bMin = (int32_t) sampleRatesList[i];
+ rangef.subrange[i].bMax = (int32_t) sampleRatesList[i];
+ rangef.subrange[i].bRes = 0;
+ TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int) rangef.subrange[i].bMin, (int) rangef.subrange[i].bMax, (int) rangef.subrange[i].bRes);
}
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &rangef, sizeof(rangef));
}
- // Unknown/Unsupported control
+ // Unknown/Unsupported control
default:
TU_BREAKPOINT();
return false;
}
- break;
+ break;
case AUDIO_CS_CTRL_CLK_VALID:
// Only cur attribute exists for this request
TU_LOG2(" Get Sample Freq. valid\r\n");
- return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
// Unknown/Unsupported control
default:
@@ -458,53 +452,10 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *
}
TU_LOG2(" Unsupported entity: %d\r\n", entityID);
- return false; // Yet not implemented
-}
-
-bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- tud_audio_write((uint8_t *)test_buffer_audio, (uint16_t)(sampFreq / (TUD_OPT_HIGH_SPEED ? 8000 : 1000) * bytesPerSample));
-
- return true;
-}
-
-bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void) rhport;
- (void) n_bytes_copied;
- (void) itf;
- (void) ep_in;
- (void) cur_alt_setting;
-
- // 16bit
- if(bytesPerSample == 2)
- {
- uint16_t* pData_16 = (uint16_t*)((void*)test_buffer_audio);
- for (size_t cnt = 0; cnt < sampFreq / (TUD_OPT_HIGH_SPEED ? 8000 : 1000); cnt++)
- {
- pData_16[cnt] = startVal++;
- }
- }
- // 24bit in 32bit slot
- else if(bytesPerSample == 4)
- {
- uint32_t* pData_32 = (uint32_t*)((void*)test_buffer_audio);
- for (size_t cnt = 0; cnt < sampFreq / (TUD_OPT_HIGH_SPEED ? 8000 : 1000); cnt++)
- {
- pData_32[cnt] = (uint32_t)startVal++ << 16U;
- }
- }
-
- return true;
+ return false;// Yet not implemented
}
-bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
+bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
(void) rhport;
(void) p_request;
startVal = 0;
@@ -515,15 +466,14 @@ bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void)
-{
+void led_blinking_task(void) {
static uint32_t start_ms = 0;
static bool led_state = false;
// Blink every interval ms
- if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
+ if (board_millis() - start_ms < blink_interval_ms) return;// not enough time
start_ms += blink_interval_ms;
board_led_write(led_state);
- led_state = 1 - led_state; // toggle
+ led_state = 1 - led_state;// toggle
}
diff --git a/examples/device/audio_test_multi_rate/src/tusb_config.h b/examples/device/audio_test_multi_rate/src/tusb_config.h
index 1c8288bce..d9b925dcf 100644
--- a/examples/device/audio_test_multi_rate/src/tusb_config.h
+++ b/examples/device/audio_test_multi_rate/src/tusb_config.h
@@ -133,7 +133,8 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX
+#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX // Example write FIFO every 1ms, so it should be 8 times larger for HS device
+
#ifdef __cplusplus
}
#endif
diff --git a/examples/device/board_test/src/main.c b/examples/device/board_test/src/main.c
index 2269d45f1..d91a8760e 100644
--- a/examples/device/board_test/src/main.c
+++ b/examples/device/board_test/src/main.c
@@ -49,25 +49,34 @@ int main(void) {
while (1) {
uint32_t interval_ms = board_button_read() ? BLINK_PRESSED : BLINK_UNPRESSED;
+ int ch = board_getchar();
+ if (ch > 0) {
+ board_putchar(ch);
+ #ifndef LOGGER_UART
+ board_uart_write(&ch, 1);
+ #endif
+ }
+
// Blink and print every interval ms
if (!(board_millis() - start_ms < interval_ms)) {
- board_uart_write(HELLO_STR, strlen(HELLO_STR));
-
start_ms = board_millis();
+ if (ch < 0) {
+ // skip if echoing
+ printf(HELLO_STR);
+
+ #ifndef LOGGER_UART
+ board_uart_write(HELLO_STR, strlen(HELLO_STR));
+ #endif
+ }
+
board_led_write(led_state);
led_state = 1 - led_state; // toggle
}
-
- // echo
- uint8_t ch;
- if (board_uart_read(&ch, 1) > 0) {
- board_uart_write(&ch, 1);
- }
}
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
void app_main(void) {
main();
}
diff --git a/examples/device/board_test/src/tusb_config.h b/examples/device/board_test/src/tusb_config.h
index 8ac3bc8de..81829d450 100644
--- a/examples/device/board_test/src/tusb_config.h
+++ b/examples/device/board_test/src/tusb_config.h
@@ -44,7 +44,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c
index 63ae8a8c9..5a3e18358 100644
--- a/examples/device/cdc_dual_ports/src/main.c
+++ b/examples/device/cdc_dual_ports/src/main.c
@@ -98,27 +98,33 @@ void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
-
//--------------------------------------------------------------------+
// USB CDC
//--------------------------------------------------------------------+
static void cdc_task(void) {
- uint8_t itf;
-
- for (itf = 0; itf < CFG_TUD_CDC; itf++) {
+ for (uint8_t itf = 0; itf < CFG_TUD_CDC; itf++) {
// connected() check for DTR bit
// Most but not all terminal client set this when making connection
// if ( tud_cdc_n_connected(itf) )
{
if (tud_cdc_n_available(itf)) {
uint8_t buf[64];
-
uint32_t count = tud_cdc_n_read(itf, buf, sizeof(buf));
// echo back to both serial ports
echo_serial_port(0, buf, count);
echo_serial_port(1, buf, count);
}
+
+ // Press on-board button to send Uart status notification
+ static uint32_t btn_prev = 0;
+ static cdc_notify_uart_state_t uart_state = { .value = 0 };
+ const uint32_t btn = board_button_read();
+ if (!btn_prev && btn) {
+ uart_state.dsr ^= 1;
+ tud_cdc_notify_uart_state(&uart_state);
+ }
+ btn_prev = btn;
}
}
}
diff --git a/examples/device/cdc_dual_ports/src/tusb_config.h b/examples/device/cdc_dual_ports/src/tusb_config.h
index 070f08ed1..7f7df3909 100644
--- a/examples/device/cdc_dual_ports/src/tusb_config.h
+++ b/examples/device/cdc_dual_ports/src/tusb_config.h
@@ -97,6 +97,8 @@
#define CFG_TUD_MIDI 0
#define CFG_TUD_VENDOR 0
+#define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint
+
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c
index 7776eb958..bbcb479f5 100644
--- a/examples/device/cdc_dual_ports/src/usb_descriptors.c
+++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c
@@ -42,8 +42,7 @@
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
-tusb_desc_device_t const desc_device =
-{
+tusb_desc_device_t const desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
@@ -68,16 +67,14 @@ tusb_desc_device_t const desc_device =
// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
-uint8_t const * tud_descriptor_device_cb(void)
-{
+uint8_t const *tud_descriptor_device_cb(void) {
return (uint8_t const *) &desc_device;
}
//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
-enum
-{
+enum {
ITF_NUM_CDC_0 = 0,
ITF_NUM_CDC_0_DATA,
ITF_NUM_CDC_1,
@@ -130,36 +127,32 @@ enum
#define EPNUM_CDC_1_IN 0x84
#endif
-uint8_t const desc_fs_configuration[] =
-{
+uint8_t const desc_fs_configuration[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 16, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 16, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
};
#if TUD_OPT_HIGH_SPEED
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
-
-uint8_t const desc_hs_configuration[] =
-{
+uint8_t const desc_hs_configuration[] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 512),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 16, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 512),
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 512),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 16, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 512),
};
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
-tusb_desc_device_qualifier_t const desc_device_qualifier =
-{
+tusb_desc_device_qualifier_t const desc_device_qualifier = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
@@ -177,34 +170,31 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
// device_qualifier descriptor describes information about a high-speed capable device that would
// change if the device were operating at the other speed. If not highspeed capable stall this request.
-uint8_t const* tud_descriptor_device_qualifier_cb(void)
-{
- return (uint8_t const*) &desc_device_qualifier;
+uint8_t const *tud_descriptor_device_qualifier_cb(void) {
+ return (uint8_t const *) &desc_device_qualifier;
}
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
-uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
-{
- (void) index; // for multiple configurations
+uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {
+ (void) index;// for multiple configurations
// if link speed is high return fullspeed config, and vice versa
- return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration;
+ return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration;
}
-#endif // highspeed
+#endif// highspeed
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
-uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
-{
+uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
(void) index; // for multiple configurations
#if TUD_OPT_HIGH_SPEED
// Although we are highspeed, host may be fullspeed.
- return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
+ return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
#else
return desc_fs_configuration;
#endif
@@ -223,8 +213,7 @@ enum {
};
// array of pointer to string descriptors
-char const *string_desc_arr[] =
-{
+char const *string_desc_arr[] = {
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"TinyUSB", // 1: Manufacturer
"TinyUSB Device", // 2: Product
@@ -254,14 +243,14 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
- if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
+ if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; }
const char *str = string_desc_arr[index];
// Cap at max char
chr_count = strlen(str);
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
- if ( chr_count > max_count ) chr_count = max_count;
+ if ( chr_count > max_count ) { chr_count = max_count; }
// Convert ASCII string into UTF-16
for ( size_t i = 0; i < chr_count; i++ ) {
@@ -272,6 +261,5 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
// first byte is length (including header), second byte is string type
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
-
return _desc_str;
}
diff --git a/examples/device/cdc_msc/src/main.c b/examples/device/cdc_msc/src/main.c
index f36c910d7..5cd93e7dd 100644
--- a/examples/device/cdc_msc/src/main.c
+++ b/examples/device/cdc_msc/src/main.c
@@ -119,6 +119,16 @@ void cdc_task(void) {
tud_cdc_write(buf, count);
tud_cdc_write_flush();
}
+
+ // Press on-board button to send Uart status notification
+ static uint32_t btn_prev = 0;
+ static cdc_notify_uart_state_t uart_state = { .value = 0 };
+ const uint32_t btn = board_button_read();
+ if (!btn_prev && btn) {
+ uart_state.dsr ^= 1;
+ tud_cdc_notify_uart_state(&uart_state);
+ }
+ btn_prev = btn;
}
}
diff --git a/examples/device/cdc_msc/src/msc_disk.c b/examples/device/cdc_msc/src/msc_disk.c
index 9645f4bfc..6fd42dd80 100644
--- a/examples/device/cdc_msc/src/msc_disk.c
+++ b/examples/device/cdc_msc/src/msc_disk.c
@@ -116,18 +116,20 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] = {
README_CONTENTS
};
-// Invoked when received SCSI_CMD_INQUIRY
-// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
-void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
+// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
+// Some inquiry_resp's fields are already filled with default values, application can update them
+// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
+uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
(void) lun;
-
const char vid[] = "TinyUSB";
const char pid[] = "Mass Storage";
const char rev[] = "1.0";
- memcpy(vendor_id, vid, strlen(vid));
- memcpy(product_id, pid, strlen(pid));
- memcpy(product_rev, rev, strlen(rev));
+ memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
+ memcpy(inquiry_resp->product_id, pid, strlen(pid));
+ memcpy(inquiry_resp->product_rev, rev, strlen(rev));
+
+ return sizeof(scsi_inquiry_resp_t); // 36 bytes
}
// Invoked when received Test Unit Ready command.
@@ -184,7 +186,7 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buff
}
// Check for overflow of offset + bufsize
- if (offset + bufsize > DISK_BLOCK_SIZE) {
+ if (lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE) {
return -1;
}
diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h
index 03e0e649c..811d464e9 100644
--- a/examples/device/cdc_msc/src/tusb_config.h
+++ b/examples/device/cdc_msc/src/tusb_config.h
@@ -87,7 +87,7 @@
//--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE
-#define CFG_TUD_ENDPOINT0_SIZE 64
+#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
//------------- CLASS -------------//
@@ -97,6 +97,8 @@
#define CFG_TUD_MIDI 0
#define CFG_TUD_VENDOR 0
+#define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint
+
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c
index 4b6b88041..edcee0462 100644
--- a/examples/device/cdc_msc/src/usb_descriptors.c
+++ b/examples/device/cdc_msc/src/usb_descriptors.c
@@ -52,7 +52,6 @@ tusb_desc_device_t const desc_device = {
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
-
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_VID,
@@ -131,7 +130,7 @@ uint8_t const desc_fs_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
@@ -146,7 +145,7 @@ uint8_t const desc_hs_configuration[] = {
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
@@ -197,7 +196,6 @@ uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {
#endif // highspeed
-
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
@@ -256,14 +254,14 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
- if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
+ if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; }
const char *str = string_desc_arr[index];
// Cap at max char
chr_count = strlen(str);
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
- if ( chr_count > max_count ) chr_count = max_count;
+ if ( chr_count > max_count ) { chr_count = max_count; }
// Convert ASCII string into UTF-16
for ( size_t i = 0; i < chr_count; i++ ) {
@@ -274,6 +272,5 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
// first byte is length (including header), second byte is string type
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
-
return _desc_str;
}
diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c
index c51e8ea81..09ccc9bf3 100644
--- a/examples/device/cdc_msc_freertos/src/main.c
+++ b/examples/device/cdc_msc_freertos/src/main.c
@@ -30,7 +30,7 @@
#include "bsp/board_api.h"
#include "tusb.h"
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define USBD_STACK_SIZE 4096
#else
// Increase stack size when debug log is enabled
@@ -72,7 +72,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
static void usb_device_task(void *param);
void led_blinking_task(void* param);
void cdc_task(void *params);
-
+extern void msc_disk_init(void);
//--------------------------------------------------------------------+
// Main
//--------------------------------------------------------------------+
@@ -91,15 +91,15 @@ int main(void) {
xTaskCreate(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL);
#endif
-#if !TUSB_MCU_VENDOR_ESPRESSIF
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
+#ifndef ESP_PLATFORM
+ // only start scheduler for non-espressif mcu
vTaskStartScheduler();
#endif
return 0;
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
void app_main(void) {
main();
}
@@ -123,6 +123,7 @@ static void usb_device_task(void *param) {
board_init_after_tusb();
}
+ msc_disk_init();
// RTOS forever loop
while (1) {
// put this thread to waiting state until there is new events
@@ -188,6 +189,16 @@ void cdc_task(void *params) {
}
tud_cdc_write_flush();
+
+ // Press on-board button to send Uart status notification
+ static uint32_t btn_prev = 0;
+ static cdc_notify_uart_state_t uart_state = { .value = 0 };
+ const uint32_t btn = board_button_read();
+ if (!btn_prev && btn) {
+ uart_state.dsr ^= 1;
+ tud_cdc_notify_uart_state(&uart_state);
+ }
+ btn_prev = btn;
}
// For ESP32-Sx this delay is essential to allow idle how to run and reset watchdog
diff --git a/examples/device/cdc_msc_freertos/src/msc_disk.c b/examples/device/cdc_msc_freertos/src/msc_disk.c
index d325d77fa..3a652103f 100644
--- a/examples/device/cdc_msc_freertos/src/msc_disk.c
+++ b/examples/device/cdc_msc_freertos/src/msc_disk.c
@@ -28,6 +28,37 @@
#if CFG_TUD_MSC
+// Use async IO in example or not
+#define CFG_EXAMPLE_MSC_ASYNC_IO 1
+
+// Simulate read/write operation delay
+#define CFG_EXAMPLE_MSC_IO_DELAY_MS 0
+
+#if CFG_EXAMPLE_MSC_ASYNC_IO
+#define IO_STACK_SIZE configMINIMAL_STACK_SIZE
+
+typedef struct {
+ uint8_t lun;
+ bool is_read;
+ uint32_t lba;
+ uint32_t offset;
+ void* buffer;
+ uint32_t bufsize;
+} io_ops_t;
+
+QueueHandle_t io_queue;
+#if configSUPPORT_STATIC_ALLOCATION
+uint8_t io_queue_buf[sizeof(io_ops_t)];
+StaticQueue_t io_queue_static;
+StackType_t io_stack[IO_STACK_SIZE];
+StaticTask_t io_taskdef;
+#endif
+
+static void io_task(void *params);
+#endif
+
+void msc_disk_init(void);
+
// whether host does safe-eject
static bool ejected = false;
@@ -40,8 +71,7 @@ static bool ejected = false;
If you find any bugs or get any questions, feel free to file an\r\n\
issue at github.com/hathach/tinyusb"
-enum
-{
+enum {
DISK_BLOCK_NUM = 16, // 8KB is the smallest size that windows allow to mount
DISK_BLOCK_SIZE = 512
};
@@ -119,25 +149,64 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
README_CONTENTS
};
-// Invoked when received SCSI_CMD_INQUIRY
-// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
-void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
-{
- (void) lun;
+#if CFG_EXAMPLE_MSC_ASYNC_IO
+void msc_disk_init() {
+#if configSUPPORT_STATIC_ALLOCATION
+ io_queue = xQueueCreateStatic(1, sizeof(io_ops_t), io_queue_buf, &io_queue_static);
+ xTaskCreateStatic(io_task, "io", IO_STACK_SIZE, NULL, 2, io_stack, &io_taskdef);
+#else
+ io_queue = xQueueCreate(1, sizeof(io_ops_t));
+ xTaskCreate(io_task, "io", IO_STACK_SIZE, NULL, 2, NULL);
+#endif
+}
+
+static void io_task(void *params) {
+ (void) params;
+ io_ops_t io_ops;
+ while (1) {
+ if (xQueueReceive(io_queue, &io_ops, portMAX_DELAY)) {
+ const uint8_t* addr = msc_disk[io_ops.lba] + io_ops.offset;
+ int32_t nbytes = io_ops.bufsize;
+ if (io_ops.is_read) {
+ memcpy(io_ops.buffer, addr, io_ops.bufsize);
+ } else {
+#ifndef CFG_EXAMPLE_MSC_READONLY
+ memcpy((uint8_t*) addr, io_ops.buffer, io_ops.bufsize);
+#else
+ nbytes = -1; // failed to write
+#endif
+ }
+
+ tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS);
+ tud_msc_async_io_done(nbytes, false);
+ }
+ }
+}
+
+#else
+void msc_disk_init() {}
+#endif
+
+// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
+// Some inquiry_resp's fields are already filled with default values, application can update them
+// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
+uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
+ (void) lun;
const char vid[] = "TinyUSB";
const char pid[] = "Mass Storage";
const char rev[] = "1.0";
- memcpy(vendor_id , vid, strlen(vid));
- memcpy(product_id , pid, strlen(pid));
- memcpy(product_rev, rev, strlen(rev));
+ memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
+ memcpy(inquiry_resp->product_id, pid, strlen(pid));
+ memcpy(inquiry_resp->product_rev, rev, strlen(rev));
+
+ return sizeof(scsi_inquiry_resp_t); // 36 bytes
}
// Invoked when received Test Unit Ready command.
// return true allowing host to read/write this LUN e.g SD card inserted
-bool tud_msc_test_unit_ready_cb(uint8_t lun)
-{
+bool tud_msc_test_unit_ready_cb(uint8_t lun) {
(void) lun;
// RAM disk is ready until ejected
@@ -152,10 +221,8 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun)
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
// Application update block count and block size
-void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
-{
+void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
(void) lun;
-
*block_count = DISK_BLOCK_NUM;
*block_size = DISK_BLOCK_SIZE;
}
@@ -163,18 +230,14 @@ void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_siz
// Invoked when received Start Stop Unit command
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
-bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
-{
+bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
(void) lun;
(void) power_condition;
- if ( load_eject )
- {
- if (start)
- {
+ if (load_eject) {
+ if (start) {
// load disk storage
- }else
- {
+ } else {
// unload disk storage
ejected = true;
}
@@ -185,90 +248,107 @@ bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, boo
// Callback invoked when received READ10 command.
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
-int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
-{
+int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
(void) lun;
// out of ramdisk
- if ( lba >= DISK_BLOCK_NUM ) {
- return -1;
+ if (lba >= DISK_BLOCK_NUM) {
+ return TUD_MSC_RET_ERROR;
}
// Check for overflow of offset + bufsize
- if ( offset + bufsize > DISK_BLOCK_SIZE ) {
- return -1;
+ if (lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE) {
+ return TUD_MSC_RET_ERROR;
}
- uint8_t const* addr = msc_disk[lba] + offset;
- memcpy(buffer, addr, bufsize);
+ #if CFG_EXAMPLE_MSC_ASYNC_IO
+ io_ops_t io_ops = {.is_read = true, .lun = lun, .lba = lba, .offset = offset, .buffer = buffer, .bufsize = bufsize};
- return (int32_t) bufsize;
+ // Send IO operation to IO task
+ TU_ASSERT(xQueueSend(io_queue, &io_ops, 0) == pdPASS);
+
+ return TUD_MSC_RET_ASYNC;
+ #else
+ uint8_t const *addr = msc_disk[lba] + offset;
+ memcpy(buffer, addr, bufsize);
+ return bufsize;
+ #endif
}
-bool tud_msc_is_writable_cb (uint8_t lun)
-{
+bool tud_msc_is_writable_cb (uint8_t lun) {
(void) lun;
-#ifdef CFG_EXAMPLE_MSC_READONLY
+ #ifdef CFG_EXAMPLE_MSC_READONLY
return false;
-#else
+ #else
return true;
-#endif
+ #endif
}
// Callback invoked when received WRITE10 command.
// Process data in buffer to disk's storage and return number of written bytes
-int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
-{
+int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
+ // out of ramdisk
+ if (lba >= DISK_BLOCK_NUM) {
+ return TUD_MSC_RET_ERROR;
+ }
+
+ // Check for overflow of offset + bufsize
+ if (lba * DISK_BLOCK_SIZE + offset + bufsize > DISK_BLOCK_NUM * DISK_BLOCK_SIZE) {
+ return TUD_MSC_RET_ERROR;
+ }
+
+ #ifdef CFG_EXAMPLE_MSC_READONLY
(void) lun;
+ (void) buffer;
+ return bufsize;
+ #endif
- // out of ramdisk
- if ( lba >= DISK_BLOCK_NUM ) return -1;
+ #if CFG_EXAMPLE_MSC_ASYNC_IO
+ io_ops_t io_ops = {.is_read = false, .lun = lun, .lba = lba, .offset = offset, .buffer = buffer, .bufsize = bufsize};
-#ifndef CFG_EXAMPLE_MSC_READONLY
- uint8_t* addr = msc_disk[lba] + offset;
+ // Send IO operation to IO task
+ TU_ASSERT(xQueueSend(io_queue, &io_ops, 0) == pdPASS);
+
+ return TUD_MSC_RET_ASYNC;
+ #else
+ uint8_t *addr = msc_disk[lba] + offset;
memcpy(addr, buffer, bufsize);
-#else
- (void) lba; (void) offset; (void) buffer;
-#endif
+ tusb_time_delay_ms_api(CFG_EXAMPLE_MSC_IO_DELAY_MS);
- return (int32_t) bufsize;
+ return bufsize;
+ #endif
}
// Callback invoked when received an SCSI command not in built-in list below
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
// - READ10 and WRITE10 has their own callbacks
-int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
-{
+int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize) {
// read10 & write10 has their own callback and MUST not be handled here
- void const* response = NULL;
+ void const *response = NULL;
int32_t resplen = 0;
// most scsi handled is input
bool in_xfer = true;
- switch (scsi_cmd[0])
- {
+ switch (scsi_cmd[0]) {
default:
// Set Sense = Invalid Command Operation
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
// negative means error -> tinyusb could stall and/or response with failed status
resplen = -1;
- break;
+ break;
}
// return resplen must not larger than bufsize
- if ( resplen > bufsize ) resplen = bufsize;
+ if (resplen > bufsize) { resplen = bufsize; }
- if ( response && (resplen > 0) )
- {
- if(in_xfer)
- {
+ if (response && (resplen > 0)) {
+ if (in_xfer) {
memcpy(buffer, response, (size_t) resplen);
- }else
- {
+ } else {
// SCSI output
}
}
diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h
index c3f2f7fb5..9cc3a18d1 100644
--- a/examples/device/cdc_msc_freertos/src/tusb_config.h
+++ b/examples/device/cdc_msc_freertos/src/tusb_config.h
@@ -59,7 +59,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
@@ -104,6 +104,8 @@
#define CFG_TUD_MIDI 0
#define CFG_TUD_VENDOR 0
+#define CFG_TUD_CDC_NOTIFY 1 // Enable use of notification endpoint
+
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c
index 405a57fe4..a55fa3675 100644
--- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c
+++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c
@@ -52,7 +52,6 @@ tusb_desc_device_t const desc_device = {
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
-
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_VID,
@@ -131,7 +130,7 @@ uint8_t const desc_fs_configuration[] =
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
@@ -147,7 +146,7 @@ uint8_t const desc_hs_configuration[] =
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
- TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
@@ -176,16 +175,14 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
// device_qualifier descriptor describes information about a high-speed capable device that would
// change if the device were operating at the other speed. If not highspeed capable stall this request.
-uint8_t const* tud_descriptor_device_qualifier_cb(void)
-{
+uint8_t const* tud_descriptor_device_qualifier_cb(void) {
return (uint8_t const*) &desc_device_qualifier;
}
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
-uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
-{
+uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index) {
(void) index; // for multiple configurations
// if link speed is high return fullspeed config, and vice versa
@@ -204,13 +201,12 @@ uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
-uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
-{
+uint8_t const * tud_descriptor_configuration_cb(uint8_t index) {
(void) index; // for multiple configurations
#if TUD_OPT_HIGH_SPEED
// Although we are highspeed, host may be fullspeed.
- return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
+ return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
#else
return desc_fs_configuration;
#endif
@@ -229,8 +225,7 @@ enum {
};
// array of pointer to string descriptors
-char const *string_desc_arr[] =
-{
+char const *string_desc_arr[] = {
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"TinyUSB", // 1: Manufacturer
"TinyUSB Device", // 2: Product
@@ -261,14 +256,14 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
- if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) return NULL;
+ if ( !(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) ) { return NULL; }
const char *str = string_desc_arr[index];
// Cap at max char
chr_count = strlen(str);
size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type
- if ( chr_count > max_count ) chr_count = max_count;
+ if ( chr_count > max_count ) { chr_count = max_count; }
// Convert ASCII string into UTF-16
for ( size_t i = 0; i < chr_count; i++ ) {
@@ -279,6 +274,5 @@ uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
// first byte is length (including header), second byte is string type
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
-
return _desc_str;
}
diff --git a/examples/device/cdc_uac2/skip.txt b/examples/device/cdc_uac2/skip.txt
new file mode 100644
index 000000000..a2a76af0e
--- /dev/null
+++ b/examples/device/cdc_uac2/skip.txt
@@ -0,0 +1,8 @@
+mcu:LPC11UXX
+mcu:LPC13XX
+mcu:NUC121
+mcu:SAMD11
+mcu:SAME5X
+mcu:SAMG
+board:stm32l052dap52
+family:espressif
diff --git a/examples/device/cdc_uac2/src/main.c b/examples/device/cdc_uac2/src/main.c
index b148593da..bc87f6e3c 100644
--- a/examples/device/cdc_uac2/src/main.c
+++ b/examples/device/cdc_uac2/src/main.c
@@ -39,6 +39,7 @@ extern uint32_t blink_interval_ms;
#endif
void led_blinking_task(void);
+void audio_task(void);
/*------------- MAIN -------------*/
int main(void)
@@ -62,7 +63,7 @@ int main(void)
{
tud_task(); // TinyUSB device task
led_blinking_task();
-
+ audio_task();
#if (CFG_TUSB_MCU == OPT_MCU_RP2040)
// printf("Hello, world!\r\n");
#endif
diff --git a/examples/device/cdc_uac2/src/tusb_config.h b/examples/device/cdc_uac2/src/tusb_config.h
index 93489cf62..2318ccf73 100644
--- a/examples/device/cdc_uac2/src/tusb_config.h
+++ b/examples/device/cdc_uac2/src/tusb_config.h
@@ -145,8 +145,8 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN)
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used
+#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device
// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1
@@ -154,8 +154,8 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX)
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX)
-#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT)
#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used
+#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device
// Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 2
@@ -164,8 +164,11 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64
// CDC FIFO size of TX and RX
-#define CFG_TUD_CDC_RX_BUFSIZE 64
-#define CFG_TUD_CDC_TX_BUFSIZE 64
+#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
+
+// CDC Endpoint transfer buffer size, more is faster
+#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#ifdef __cplusplus
}
diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c
index 70b0949a9..7d5da5ed0 100644
--- a/examples/device/cdc_uac2/src/uac2_app.c
+++ b/examples/device/cdc_uac2/src/uac2_app.c
@@ -49,17 +49,36 @@ uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
-// Buffer for microphone data
-int32_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ / 4];
// Buffer for speaker data
int32_t spk_buf[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 4];
// Speaker data size received in the last frame
-int spk_data_size;
+uint16_t spk_data_size;
// Resolution per format
const uint8_t resolutions_per_format[CFG_TUD_AUDIO_FUNC_1_N_FORMATS] = {CFG_TUD_AUDIO_FUNC_1_FORMAT_1_RESOLUTION_RX};
// Current resolution, update on format change
uint8_t current_resolution;
+//--------------------------------------------------------------------+
+// AUDIO Task
+//--------------------------------------------------------------------+
+
+// This task simulates an audio transfer callback, one frame is sent/received every 1ms.
+// In a real application, this would be replaced with actual I2S send/receive callback.
+void audio_task(void) {
+ static uint32_t start_ms = 0;
+ uint32_t curr_ms = board_millis();
+ if (start_ms == curr_ms) return;// not enough time
+ start_ms = curr_ms;
+ // When new data arrived, copy data from speaker buffer, to microphone buffer
+ // and send it over
+ // Only support speaker & headphone both have the same resolution
+ // If one is 16bit another is 24bit be care of LOUD noise !
+ spk_data_size = tud_audio_read(spk_buf, sizeof(spk_buf));
+ if (spk_data_size) {
+ tud_audio_write((uint8_t *) spk_buf, spk_data_size);
+ }
+}
+
// Helper for clock get requests
static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request)
{
@@ -265,8 +284,6 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_reque
blink_interval_ms = BLINK_STREAMING;
}
- // Clear buffer when streaming format is changed
- spk_data_size = 0;
if(alt != 0)
{
current_resolution = resolutions_per_format[alt-1];
@@ -275,30 +292,6 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_reque
return true;
}
-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)
-{
- (void)rhport;
- (void)func_id;
- (void)ep_out;
- (void)cur_alt_setting;
-
- spk_data_size = tud_audio_read(spk_buf, n_bytes_received);
- tud_audio_write(spk_buf, n_bytes_received);
-
- return true;
-}
-
-bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void)rhport;
- (void)itf;
- (void)ep_in;
- (void)cur_alt_setting;
-
- // This callback could be used to fill microphone data separately
- return true;
-}
-
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c
index 9f7255d8a..22d3cf05a 100644
--- a/examples/device/cdc_uac2/src/usb_descriptors.c
+++ b/examples/device/cdc_uac2/src/usb_descriptors.c
@@ -116,7 +116,7 @@ uint8_t const * tud_descriptor_device_cb(void)
#define EPNUM_CDC_IN 0x84
#endif
-uint8_t const desc_configuration[] =
+uint8_t const desc_fs_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
@@ -128,13 +128,78 @@ uint8_t const desc_configuration[] =
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 6, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64)
};
+#if TUD_OPT_HIGH_SPEED
+// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
+
+// high speed configuration
+uint8_t const desc_hs_configuration[] = {
+ // Config number, interface count, string index, total length, attribute, power in mA
+ TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
+
+ // Interface number, string index, EP Out & EP In address, EP size
+ TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR(2, EPNUM_AUDIO_OUT, EPNUM_AUDIO_IN | 0x80),
+
+ // CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 6, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512)
+};
+
+// other speed configuration
+uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
+
+// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
+tusb_desc_device_qualifier_t const desc_device_qualifier = {
+ .bLength = sizeof(tusb_desc_device_qualifier_t),
+ .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
+ .bcdUSB = 0x0100,
+
+ .bDeviceClass = TUSB_CLASS_MISC,
+ .bDeviceSubClass = MISC_SUBCLASS_COMMON,
+ .bDeviceProtocol = MISC_PROTOCOL_IAD,
+
+ .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
+ .bNumConfigurations = 0x01,
+ .bReserved = 0x00
+};
+
+// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request
+// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
+// device_qualifier descriptor describes information about a high-speed capable device that would
+// change if the device were operating at the other speed. If not highspeed capable stall this request.
+uint8_t const *tud_descriptor_device_qualifier_cb(void) {
+ return (uint8_t const *) &desc_device_qualifier;
+}
+
+// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
+// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
+// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
+uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {
+ (void) index; // for multiple configurations
+
+ // if link speed is high return fullspeed config, and vice versa
+ // Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG
+ memcpy(desc_other_speed_config,
+ (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration,
+ CONFIG_TOTAL_LEN);
+
+ desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG;
+
+ return desc_other_speed_config;
+}
+
+#endif // highspeed
+
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
{
(void)index; // for multiple configurations
- return desc_configuration;
+#if TUD_OPT_HIGH_SPEED
+ // Although we are highspeed, host may be fullspeed.
+ return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
+#else
+ return desc_fs_configuration;
+#endif
}
//--------------------------------------------------------------------+
diff --git a/examples/device/dynamic_configuration/src/msc_disk.c b/examples/device/dynamic_configuration/src/msc_disk.c
index 10c3ac6fe..8987c06be 100644
--- a/examples/device/dynamic_configuration/src/msc_disk.c
+++ b/examples/device/dynamic_configuration/src/msc_disk.c
@@ -116,19 +116,20 @@ uint8_t msc_disk[DISK_BLOCK_NUM][DISK_BLOCK_SIZE] =
README_CONTENTS
};
-// Invoked when received SCSI_CMD_INQUIRY
-// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
-void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
-{
+// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
+// Some inquiry_resp's fields are already filled with default values, application can update them
+// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
+uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
(void) lun;
-
const char vid[] = "TinyUSB";
const char pid[] = "Mass Storage";
const char rev[] = "1.0";
- memcpy(vendor_id , vid, strlen(vid));
- memcpy(product_id , pid, strlen(pid));
- memcpy(product_rev, rev, strlen(rev));
+ memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
+ memcpy(inquiry_resp->product_id, pid, strlen(pid));
+ memcpy(inquiry_resp->product_rev, rev, strlen(rev));
+
+ return sizeof(scsi_inquiry_resp_t); // 36 bytes
}
// Invoked when received Test Unit Ready command.
diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c
index 30c0331ef..3f5e8a91c 100644
--- a/examples/device/hid_composite_freertos/src/main.c
+++ b/examples/device/hid_composite_freertos/src/main.c
@@ -31,7 +31,7 @@
#include "tusb.h"
#include "usb_descriptors.h"
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
// ESP-IDF need "freertos/" prefix in include path.
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
#include "freertos/FreeRTOS.h"
@@ -112,17 +112,16 @@ int main(void)
xTimerStart(blinky_tm, 0);
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
-#if !TUSB_MCU_VENDOR_ESPRESSIF
+ // only start scheduler for non-espressif mcu
+#ifndef ESP_PLATFORM
vTaskStartScheduler();
#endif
return 0;
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
-void app_main(void)
-{
+#ifdef ESP_PLATFORM
+void app_main(void) {
main();
}
#endif
diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h
index 6ec38b95c..b28033a0c 100644
--- a/examples/device/hid_composite_freertos/src/tusb_config.h
+++ b/examples/device/hid_composite_freertos/src/tusb_config.h
@@ -59,7 +59,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
diff --git a/examples/device/midi_test_freertos/src/main.c b/examples/device/midi_test_freertos/src/main.c
index dbe89080c..3e406d38d 100644
--- a/examples/device/midi_test_freertos/src/main.c
+++ b/examples/device/midi_test_freertos/src/main.c
@@ -40,7 +40,7 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define USBD_STACK_SIZE 4096
#else
// Increase stack size when debug log is enabled
@@ -95,15 +95,15 @@ int main(void) {
xTaskCreate(midi_task, "midi", MIDI_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL);
#endif
-#if !TUSB_MCU_VENDOR_ESPRESSIF
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
+#ifndef ESP_PLATFORM
+ // only start scheduler for non-espressif mcu
vTaskStartScheduler();
#endif
return 0;
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
void app_main(void) {
main();
}
diff --git a/examples/device/msc_dual_lun/src/msc_disk_dual.c b/examples/device/msc_dual_lun/src/msc_disk_dual.c
index 1f7fb98c7..a1ad220b3 100644
--- a/examples/device/msc_dual_lun/src/msc_disk_dual.c
+++ b/examples/device/msc_dual_lun/src/msc_disk_dual.c
@@ -207,18 +207,20 @@ uint8_t tud_msc_get_maxlun_cb(void) {
return 2; // dual LUN
}
-// Invoked when received SCSI_CMD_INQUIRY
-// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
-void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
- (void) lun; // use same ID for both LUNs
-
+// Invoked when received SCSI_CMD_INQUIRY, v2 with full inquiry response
+// Some inquiry_resp's fields are already filled with default values, application can update them
+// Return length of inquiry response, typically sizeof(scsi_inquiry_resp_t) (36 bytes), can be longer if included vendor data.
+uint32_t tud_msc_inquiry2_cb(uint8_t lun, scsi_inquiry_resp_t* inquiry_resp) {
+ (void) lun;
const char vid[] = "TinyUSB";
const char pid[] = "Mass Storage";
const char rev[] = "1.0";
- memcpy(vendor_id , vid, strlen(vid));
- memcpy(product_id , pid, strlen(pid));
- memcpy(product_rev, rev, strlen(rev));
+ memcpy(inquiry_resp->vendor_id, vid, strlen(vid));
+ memcpy(inquiry_resp->product_id, pid, strlen(pid));
+ memcpy(inquiry_resp->product_rev, rev, strlen(rev));
+
+ return sizeof(scsi_inquiry_resp_t); // 36 bytes
}
// Invoked when received Test Unit Ready command.
diff --git a/examples/device/net_lwip_webserver/Makefile b/examples/device/net_lwip_webserver/Makefile
index 141532466..4ad110dec 100644
--- a/examples/device/net_lwip_webserver/Makefile
+++ b/examples/device/net_lwip_webserver/Makefile
@@ -1,5 +1,3 @@
-DEPS_SUBMODULES += lib/lwip
-
include ../../build_system/make/make.mk
# suppress warning caused by lwip
diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt
index 5ebe71612..20a264387 100644
--- a/examples/device/net_lwip_webserver/skip.txt
+++ b/examples/device/net_lwip_webserver/skip.txt
@@ -10,6 +10,8 @@ mcu:SAMD11
mcu:STM32L0
mcu:STM32F0
mcu:KINETIS_KL
+mcu:STM32H7RS
+mcu:STM32N6
family:broadcom_64bit
family:broadcom_32bit
family:espressif
diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h
index 41e8f0d67..04949cef9 100644
--- a/examples/device/net_lwip_webserver/src/lwipopts.h
+++ b/examples/device/net_lwip_webserver/src/lwipopts.h
@@ -58,6 +58,7 @@
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
#define LWIP_SINGLE_NETIF 1
+#define LWIP_NETIF_LINK_CALLBACK 1
#define PBUF_POOL_SIZE 4
diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c
index 36f402332..4bdddf6c5 100644
--- a/examples/device/net_lwip_webserver/src/main.c
+++ b/examples/device/net_lwip_webserver/src/main.c
@@ -31,6 +31,12 @@ this appears as either a RNDIS or CDC-ECM USB virtual network adapter; the OS pi
RNDIS should be valid on Linux and Windows hosts, and CDC-ECM should be valid on Linux and macOS hosts
The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server.
+
+Link State Control:
+- Press the user button to toggle the network link state (UP/DOWN)
+- This simulates "ethernet cable unplugged/plugged" events
+- The host OS will see the network interface as disconnected/connected accordingly
+- Use this to test network error handling and recovery in host applications
*/
/*
Some smartphones *may* work with this implementation as well, but likely have limited (broken) drivers,
@@ -63,9 +69,6 @@ try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00
/* lwip context */
static struct netif netif_data;
-/* shared between tud_network_recv_cb() and service_traffic() */
-static struct pbuf *received_frame;
-
/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */
/* ideally speaking, this should be generated from the hardware's unique ID (if available) */
/* it is suggested that the first byte is 0x02 to indicate a link-local address */
@@ -137,6 +140,12 @@ static err_t netif_init_cb(struct netif *netif) {
return ERR_OK;
}
+/* notifies the USB host about the link state change. */
+static void usbnet_netif_link_callback(struct netif *netif) {
+ bool link_up = netif_is_link_up(netif);
+ tud_network_link_state(BOARD_TUD_RHPORT, link_up);
+}
+
static void init_lwip(void) {
struct netif *netif = &netif_data;
@@ -147,11 +156,19 @@ static void init_lwip(void) {
memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address));
netif->hwaddr[5] ^= 0x01;
- netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input);
+ netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ethernet_input);
#if LWIP_IPV6
netif_create_ip6_linklocal_address(netif, 1);
#endif
netif_set_default(netif);
+
+#if LWIP_NETIF_LINK_CALLBACK
+ // Set the link callback to notify USB host about link state changes
+ netif_set_link_callback(netif, usbnet_netif_link_callback);
+ netif_set_link_up(netif);
+#else
+ tud_network_link_state(BOARD_TUD_RHPORT, true);
+#endif
}
/* handle any DNS requests from dns-server */
@@ -164,20 +181,29 @@ bool dns_query_proc(const char *name, ip4_addr_t *addr) {
}
bool tud_network_recv_cb(const uint8_t *src, uint16_t size) {
- /* this shouldn't happen, but if we get another packet before
- parsing the previous, we must signal our inability to accept it */
- if (received_frame) return false;
+ struct netif *netif = &netif_data;
if (size) {
struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL);
- if (p) {
- /* pbuf_alloc() has already initialized struct; all we need to do is copy the data */
- memcpy(p->payload, src, size);
+ if (p == NULL) {
+ printf("ERROR: Failed to allocate pbuf of size %d\n", size);
+ return false;
+ }
+
+ /* Copy buf to pbuf */
+ pbuf_take(p, src, size);
- /* store away the pointer for service_traffic() to later handle */
- received_frame = p;
+ // Surrender ownership of our pbuf unless there was an error
+ // Only call pbuf_free if not Ok else it will panic with "pbuf_free: p->ref > 0"
+ // or steal it from whatever took ownership of it with undefined consequences.
+ // See: https://savannah.nongnu.org/patch/index.php?10121
+ if (netif->input(p, netif) != ERR_OK) {
+ printf("ERROR: netif input failed\n");
+ pbuf_free(p);
}
+ // Signal tinyusb that the current frame has been processed.
+ tud_network_recv_renew();
}
return true;
@@ -191,29 +217,26 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
return pbuf_copy_partial(p, dst, p->tot_len, 0);
}
-static void service_traffic(void) {
- /* handle any packet received by tud_network_recv_cb() */
- if (received_frame) {
- // Surrender ownership of our pbuf unless there was an error
- // Only call pbuf_free if not Ok else it will panic with "pbuf_free: p->ref > 0"
- // or steal it from whatever took ownership of it with undefined consequences.
- // See: https://savannah.nongnu.org/patch/index.php?10121
- if (ethernet_input(received_frame, &netif_data)!=ERR_OK) {
- pbuf_free(received_frame);
+static void handle_link_state_switch(void) {
+ /* Check for button press to toggle link state */
+ static bool last_link_state = true;
+ static bool last_button_state = false;
+ bool current_button_state = board_button_read();
+
+ if (current_button_state && !last_button_state) {
+ /* Button pressed - toggle link state */
+ last_link_state = !last_link_state;
+ if (last_link_state) {
+ printf("Link state: UP\n");
+ netif_set_link_up(&netif_data);
+ } else {
+ printf("Link state: DOWN\n");
+ netif_set_link_down(&netif_data);
}
- received_frame = NULL;
- tud_network_recv_renew();
+ /* LWIP callback will notify USB host about the change */
}
+ last_button_state = current_button_state;
- sys_check_timeouts();
-}
-
-void tud_network_init_cb(void) {
- /* if the network is re-initializing and we have a leftover packet, we must do a cleanup */
- if (received_frame) {
- pbuf_free(received_frame);
- received_frame = NULL;
- }
}
int main(void) {
@@ -243,15 +266,23 @@ int main(void) {
lwiperf_start_tcp_server_default(NULL, NULL);
#endif
+#if CFG_TUD_NCM
+ printf("USB NCM network interface initialized\n");
+#elif CFG_TUD_ECM_RNDIS
+ printf("USB RNDIS/ECM network interface initialized\n");
+#endif
+
while (1) {
tud_task();
- service_traffic();
+ sys_check_timeouts(); // service lwip
+ handle_link_state_switch();
}
return 0;
}
/* lwip has provision for using a mutex, when applicable */
+/* This implementation is for single-threaded use only */
sys_prot_t sys_arch_protect(void) {
return 0;
}
diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h
index 22082fc81..c774f59ff 100644
--- a/examples/device/net_lwip_webserver/src/tusb_config.h
+++ b/examples/device/net_lwip_webserver/src/tusb_config.h
@@ -85,6 +85,7 @@ extern "C" {
#endif
// Use different configurations to test all net devices (also due to resource limitations)
+#ifndef USE_ECM
#if TU_CHECK_MCU(OPT_MCU_LPC15XX, OPT_MCU_LPC40XX, OPT_MCU_LPC51UXX, OPT_MCU_LPC54)
#define USE_ECM 1
#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAML21, OPT_MCU_SAML22)
@@ -97,6 +98,7 @@ extern "C" {
#define USE_ECM 0
#define INCLUDE_IPERF
#endif
+#endif
//--------------------------------------------------------------------
// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNING
diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c
index 6b2ab0973..33b8ea0ef 100644
--- a/examples/device/uac2_headset/src/main.c
+++ b/examples/device/uac2_headset/src/main.c
@@ -37,9 +37,9 @@
// List of supported sample rates
const uint32_t sample_rates[] = {44100, 48000};
-uint32_t current_sample_rate = 44100;
+uint32_t current_sample_rate = 44100;
-#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates)
+#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates)
/* Blink pattern
* - 25 ms : streaming data
@@ -47,16 +47,14 @@ uint32_t current_sample_rate = 44100;
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum
-{
+enum {
BLINK_STREAMING = 25,
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
};
-enum
-{
+enum {
VOLUME_CTRL_0_DB = 0,
VOLUME_CTRL_10_DB = 2560,
VOLUME_CTRL_20_DB = 5120,
@@ -75,8 +73,8 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
// Audio controls
// Current states
-int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
-int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
+int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
+int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];// +1 for master channel 0
// Buffer for microphone data
int32_t mic_buf[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ / 4];
@@ -95,15 +93,13 @@ void audio_task(void);
void audio_control_task(void);
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// init device stack on configured roothub port
tusb_rhport_init_t dev_init = {
- .role = TUSB_ROLE_DEVICE,
- .speed = TUSB_SPEED_AUTO
- };
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO};
tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
@@ -112,9 +108,8 @@ int main(void)
TU_LOG1("Headset running\r\n");
- while (1)
- {
- tud_task(); // TinyUSB device task
+ while (1) {
+ tud_task();// TinyUSB device task
audio_task();
audio_control_task();
led_blinking_task();
@@ -126,70 +121,57 @@ int main(void)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
- (void)remote_wakeup_en;
+void tud_suspend_cb(bool remote_wakeup_en) {
+ (void) remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
+void tud_resume_cb(void) {
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
}
// Helper for clock get requests
-static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request)
-{
+static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request) {
TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK);
- if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ)
- {
- if (request->bRequest == AUDIO_CS_REQ_CUR)
- {
+ if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) {
+ if (request->bRequest == AUDIO_CS_REQ_CUR) {
TU_LOG1("Clock get current freq %" PRIu32 "\r\n", current_sample_rate);
- audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) };
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf));
- }
- else if (request->bRequest == AUDIO_CS_REQ_RANGE)
- {
+ audio_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)};
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &curf, sizeof(curf));
+ } else if (request->bRequest == AUDIO_CS_REQ_RANGE) {
audio_control_range_4_n_t(N_SAMPLE_RATES) rangef =
- {
- .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)
- };
+ {
+ .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)};
TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES);
- for(uint8_t i = 0; i < N_SAMPLE_RATES; i++)
- {
+ for (uint8_t i = 0; i < N_SAMPLE_RATES; i++) {
rangef.subrange[i].bMin = (int32_t) sample_rates[i];
rangef.subrange[i].bMax = (int32_t) sample_rates[i];
rangef.subrange[i].bRes = 0;
- TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes);
+ TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int) rangef.subrange[i].bMin, (int) rangef.subrange[i].bMax, (int) rangef.subrange[i].bRes);
}
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &rangef, sizeof(rangef));
}
- }
- else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID &&
- request->bRequest == AUDIO_CS_REQ_CUR)
- {
- audio_control_cur_1_t cur_valid = { .bCur = 1 };
+ } else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID &&
+ request->bRequest == AUDIO_CS_REQ_CUR) {
+ audio_control_cur_1_t cur_valid = {.bCur = 1};
TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_valid, sizeof(cur_valid));
}
TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
@@ -197,25 +179,21 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t
}
// Helper for clock set requests
-static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf)
-{
- (void)rhport;
+static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) {
+ (void) rhport;
TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK);
TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR);
- if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ)
- {
+ if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) {
TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t));
- current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur;
+ current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *) buf)->bCur;
TU_LOG1("Clock set current freq: %" PRIu32 "\r\n", current_sample_rate);
return true;
- }
- else
- {
+ } else {
TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
return false;
@@ -223,33 +201,25 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t
}
// Helper for feature unit get requests
-static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request)
-{
+static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) {
TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT);
- if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR)
- {
- audio_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] };
+ if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) {
+ audio_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]};
TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1));
- }
- else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
- {
- if (request->bRequest == AUDIO_CS_REQ_RANGE)
- {
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &mute1, sizeof(mute1));
+ } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) {
+ if (request->bRequest == AUDIO_CS_REQ_RANGE) {
audio_control_range_2_n_t(1) range_vol = {
- .wNumSubRanges = tu_htole16(1),
- .subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) }
- };
+ .wNumSubRanges = tu_htole16(1),
+ .subrange[0] = {.bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256)}};
TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber,
range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol));
- }
- else if (request->bRequest == AUDIO_CS_REQ_CUR)
- {
- audio_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) };
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &range_vol, sizeof(range_vol));
+ } else if (request->bRequest == AUDIO_CS_REQ_CUR) {
+ audio_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])};
TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_vol, sizeof(cur_vol));
}
}
TU_LOG1("Feature unit get request not supported, entity = %u, selector = %u, request = %u\r\n",
@@ -259,35 +229,29 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req
}
// Helper for feature unit set requests
-static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf)
-{
- (void)rhport;
+static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) {
+ (void) rhport;
TU_ASSERT(request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT);
TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR);
- if (request->bControlSelector == AUDIO_FU_CTRL_MUTE)
- {
+ if (request->bControlSelector == AUDIO_FU_CTRL_MUTE) {
TU_VERIFY(request->wLength == sizeof(audio_control_cur_1_t));
- mute[request->bChannelNumber] = ((audio_control_cur_1_t const *)buf)->bCur;
+ mute[request->bChannelNumber] = ((audio_control_cur_1_t const *) buf)->bCur;
TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]);
return true;
- }
- else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
- {
+ } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) {
TU_VERIFY(request->wLength == sizeof(audio_control_cur_2_t));
- volume[request->bChannelNumber] = ((audio_control_cur_2_t const *)buf)->bCur;
+ volume[request->bChannelNumber] = ((audio_control_cur_2_t const *) buf)->bCur;
TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256);
return true;
- }
- else
- {
+ } else {
TU_LOG1("Feature unit set request not supported, entity = %u, selector = %u, request = %u\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
return false;
@@ -299,16 +263,14 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req
//--------------------------------------------------------------------+
// Invoked when audio class specific get request received for an entity
-bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request)
-{
- audio_control_request_t const *request = (audio_control_request_t const *)p_request;
+bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
+ audio_control_request_t const *request = (audio_control_request_t const *) p_request;
if (request->bEntityID == UAC2_ENTITY_CLOCK)
return tud_audio_clock_get_request(rhport, request);
if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT)
return tud_audio_feature_unit_get_request(rhport, request);
- else
- {
+ else {
TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
}
@@ -316,9 +278,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p
}
// Invoked when audio class specific set request received for an entity
-bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf)
-{
- audio_control_request_t const *request = (audio_control_request_t const *)p_request;
+bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) {
+ audio_control_request_t const *request = (audio_control_request_t const *) p_request;
if (request->bEntityID == UAC2_ENTITY_SPK_FEATURE_UNIT)
return tud_audio_feature_unit_set_request(rhport, request, buf);
@@ -330,108 +291,82 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p
return false;
}
-bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
- (void)rhport;
+bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
+ (void) rhport;
uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));
if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt == 0)
- blink_interval_ms = BLINK_MOUNTED;
+ blink_interval_ms = BLINK_MOUNTED;
return true;
}
-bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
- (void)rhport;
+bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
+ (void) rhport;
uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));
TU_LOG2("Set interface %d alt %d\r\n", itf, alt);
if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt != 0)
- blink_interval_ms = BLINK_STREAMING;
+ blink_interval_ms = BLINK_STREAMING;
// Clear buffer when streaming format is changed
spk_data_size = 0;
- if(alt != 0)
- {
- current_resolution = resolutions_per_format[alt-1];
+ if (alt != 0) {
+ current_resolution = resolutions_per_format[alt - 1];
}
return true;
}
-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)
-{
- (void)rhport;
- (void)func_id;
- (void)ep_out;
- (void)cur_alt_setting;
-
- spk_data_size = tud_audio_read(spk_buf, n_bytes_received);
- return true;
-}
-
-bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting)
-{
- (void)rhport;
- (void)itf;
- (void)ep_in;
- (void)cur_alt_setting;
-
- // This callback could be used to fill microphone data separately
- return true;
-}
-
//--------------------------------------------------------------------+
// AUDIO Task
//--------------------------------------------------------------------+
-void audio_task(void)
-{
+// This task simulates an audio transfer callback, one frame is sent/received every 1ms.
+// In a real application, this would be replaced with actual I2S send/receive callback.
+void audio_task(void) {
+ static uint32_t start_ms = 0;
+ uint32_t curr_ms = board_millis();
+ if (start_ms == curr_ms) return;// not enough time
+ start_ms = curr_ms;
// When new data arrived, copy data from speaker buffer, to microphone buffer
// and send it over
// Only support speaker & headphone both have the same resolution
// If one is 16bit another is 24bit be care of LOUD noise !
- if (spk_data_size)
- {
- if (current_resolution == 16)
- {
- int16_t *src = (int16_t*)spk_buf;
- int16_t *limit = (int16_t*)spk_buf + spk_data_size / 2;
- int16_t *dst = (int16_t*)mic_buf;
- while (src < limit)
- {
+ spk_data_size = tud_audio_read(spk_buf, sizeof(spk_buf));
+ if (spk_data_size) {
+ if (current_resolution == 16) {
+ int16_t *src = (int16_t *) spk_buf;
+ int16_t *limit = (int16_t *) spk_buf + spk_data_size / 2;
+ int16_t *dst = (int16_t *) mic_buf;
+ while (src < limit) {
// Combine two channels into one
int32_t left = *src++;
int32_t right = *src++;
*dst++ = (int16_t) ((left >> 1) + (right >> 1));
}
- tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2));
+ tud_audio_write((uint8_t *) mic_buf, (uint16_t) (spk_data_size / 2));
spk_data_size = 0;
- }
- else if (current_resolution == 24)
- {
+ } else if (current_resolution == 24) {
int32_t *src = spk_buf;
int32_t *limit = spk_buf + spk_data_size / 4;
int32_t *dst = mic_buf;
- while (src < limit)
- {
+ while (src < limit) {
// Combine two channels into one
int32_t left = *src++;
int32_t right = *src++;
*dst++ = (int32_t) ((uint32_t) ((left >> 1) + (right >> 1)) & 0xffffff00ul);
}
- tud_audio_write((uint8_t *)mic_buf, (uint16_t) (spk_data_size / 2));
+ tud_audio_write((uint8_t *) mic_buf, (uint16_t) (spk_data_size / 2));
spk_data_size = 0;
}
}
}
-void audio_control_task(void)
-{
+void audio_control_task(void) {
// Press on-board button to control volume
// Open host volume control, volume should switch between 10% and 100%
@@ -440,27 +375,25 @@ void audio_control_task(void)
static uint32_t start_ms = 0;
static uint32_t btn_prev = 0;
- if ( board_millis() - start_ms < interval_ms) return; // not enough time
+ if (board_millis() - start_ms < interval_ms) return;// not enough time
start_ms += interval_ms;
uint32_t btn = board_button_read();
- if (!btn_prev && btn)
- {
+ if (!btn_prev && btn) {
// Adjust volume between 0dB (100%) and -30dB (10%)
- for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++)
- {
+ for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) {
volume[i] = volume[i] == 0 ? -VOLUME_CTRL_30_DB : 0;
}
// 6.1 Interrupt Data Message
const audio_interrupt_data_t data = {
- .bInfo = 0, // Class-specific interrupt, originated from an interface
- .bAttribute = AUDIO_CS_REQ_CUR, // Caused by current settings
- .wValue_cn_or_mcn = 0, // CH0: master volume
- .wValue_cs = AUDIO_FU_CTRL_VOLUME, // Volume change
- .wIndex_ep_or_int = 0, // From the interface itself
- .wIndex_entity_id = UAC2_ENTITY_SPK_FEATURE_UNIT, // From feature unit
+ .bInfo = 0, // Class-specific interrupt, originated from an interface
+ .bAttribute = AUDIO_CS_REQ_CUR, // Caused by current settings
+ .wValue_cn_or_mcn = 0, // CH0: master volume
+ .wValue_cs = AUDIO_FU_CTRL_VOLUME, // Volume change
+ .wIndex_ep_or_int = 0, // From the interface itself
+ .wIndex_entity_id = UAC2_ENTITY_SPK_FEATURE_UNIT,// From feature unit
};
tud_audio_int_write(&data);
@@ -472,8 +405,7 @@ void audio_control_task(void)
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void)
-{
+void led_blinking_task(void) {
static uint32_t start_ms = 0;
static bool led_state = false;
diff --git a/examples/device/uac2_headset/src/tusb_config.h b/examples/device/uac2_headset/src/tusb_config.h
index c921a37ae..e738a09af 100644
--- a/examples/device/uac2_headset/src/tusb_config.h
+++ b/examples/device/uac2_headset/src/tusb_config.h
@@ -146,8 +146,8 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_TX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX)
-#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN)*4
#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_IN, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_IN) // Maximum EP IN size for all AS alternate settings used
+#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device
// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1
@@ -155,8 +155,8 @@ extern "C" {
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_1_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX)
#define CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT TUD_AUDIO_EP_SIZE(CFG_TUD_AUDIO_FUNC_1_MAX_SAMPLE_RATE, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_N_BYTES_PER_SAMPLE_RX, CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX)
-#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT)*2
#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TU_MAX(CFG_TUD_AUDIO_FUNC_1_FORMAT_1_EP_SZ_OUT, CFG_TUD_AUDIO_FUNC_1_FORMAT_2_EP_SZ_OUT) // Maximum EP IN size for all AS alternate settings used
+#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (TUD_OPT_HIGH_SPEED ? 32 : 4) * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX // Example read FIFO every 1ms, so it should be 8 times larger for HS device
// Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just wastes a few bytes)
#define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 2
diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c
index ea5a2941d..12425b919 100644
--- a/examples/device/uac2_speaker_fb/src/main.c
+++ b/examples/device/uac2_speaker_fb/src/main.c
@@ -27,12 +27,12 @@
#include <string.h>
#include "bsp/board_api.h"
+#include "common_types.h"
#include "tusb.h"
#include "usb_descriptors.h"
-#include "common_types.h"
#ifdef CFG_QUIRK_OS_GUESSING
-#include "quirk_os_guessing.h"
+ #include "quirk_os_guessing.h"
#endif
//--------------------------------------------------------------------+
@@ -41,14 +41,14 @@
// List of supported sample rates
#if defined(__RX__)
- const uint32_t sample_rates[] = {44100, 48000};
+const uint32_t sample_rates[] = {44100, 48000};
#else
- const uint32_t sample_rates[] = {44100, 48000, 88200, 96000};
+const uint32_t sample_rates[] = {44100, 48000, 88200, 96000};
#endif
-uint32_t current_sample_rate = 44100;
+uint32_t current_sample_rate = 44100;
-#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates)
+#define N_SAMPLE_RATES TU_ARRAY_SIZE(sample_rates)
/* Blink pattern
* - 25 ms : streaming data
@@ -56,16 +56,14 @@ uint32_t current_sample_rate = 44100;
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum
-{
+enum {
BLINK_STREAMING = 25,
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
};
-enum
-{
+enum {
VOLUME_CTRL_0_DB = 0,
VOLUME_CTRL_10_DB = 2560,
VOLUME_CTRL_20_DB = 5120,
@@ -84,11 +82,11 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
// Audio controls
// Current states
-int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
-int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
+int8_t mute[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1]; // +1 for master channel 0
+int16_t volume[CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1];// +1 for master channel 0
// Buffer for speaker data
-uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ/2];
+uint16_t i2s_dummy_buffer[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ / 2];
void led_blinking_task(void);
void audio_task(void);
@@ -96,20 +94,18 @@ void audio_task(void);
#if CFG_AUDIO_DEBUG
void audio_debug_task(void);
uint8_t current_alt_settings;
-uint16_t fifo_count;
-uint32_t fifo_count_avg;
+volatile uint16_t fifo_count;
+volatile uint32_t fifo_count_avg;
#endif
/*------------- MAIN -------------*/
-int main(void)
-{
+int main(void) {
board_init();
// init device stack on configured roothub port
tusb_rhport_init_t dev_init = {
- .role = TUSB_ROLE_DEVICE,
- .speed = TUSB_SPEED_AUTO
- };
+ .role = TUSB_ROLE_DEVICE,
+ .speed = TUSB_SPEED_AUTO};
tusb_init(BOARD_TUD_RHPORT, &dev_init);
if (board_init_after_tusb) {
@@ -118,9 +114,8 @@ int main(void)
TU_LOG1("Speaker running\r\n");
- while (1)
- {
- tud_task(); // TinyUSB device task
+ while (1) {
+ tud_task();// TinyUSB device task
led_blinking_task();
#if CFG_AUDIO_DEBUG
audio_debug_task();
@@ -134,29 +129,25 @@ int main(void)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
- (void)remote_wakeup_en;
+void tud_suspend_cb(bool remote_wakeup_en) {
+ (void) remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
+void tud_resume_cb(void) {
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
}
@@ -165,43 +156,34 @@ void tud_resume_cb(void)
//--------------------------------------------------------------------+
// Helper for clock get requests
-static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request)
-{
+static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t const *request) {
TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK);
- if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ)
- {
- if (request->bRequest == AUDIO_CS_REQ_CUR)
- {
+ if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) {
+ if (request->bRequest == AUDIO_CS_REQ_CUR) {
TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate);
- audio_control_cur_4_t curf = { (int32_t) tu_htole32(current_sample_rate) };
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf));
- }
- else if (request->bRequest == AUDIO_CS_REQ_RANGE)
- {
+ audio_control_cur_4_t curf = {(int32_t) tu_htole32(current_sample_rate)};
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &curf, sizeof(curf));
+ } else if (request->bRequest == AUDIO_CS_REQ_RANGE) {
audio_control_range_4_n_t(N_SAMPLE_RATES) rangef =
- {
- .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)
- };
+ {
+ .wNumSubRanges = tu_htole16(N_SAMPLE_RATES)};
TU_LOG1("Clock get %d freq ranges\r\n", N_SAMPLE_RATES);
- for(uint8_t i = 0; i < N_SAMPLE_RATES; i++)
- {
+ for (uint8_t i = 0; i < N_SAMPLE_RATES; i++) {
rangef.subrange[i].bMin = (int32_t) sample_rates[i];
rangef.subrange[i].bMax = (int32_t) sample_rates[i];
rangef.subrange[i].bRes = 0;
- TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int)rangef.subrange[i].bMin, (int)rangef.subrange[i].bMax, (int)rangef.subrange[i].bRes);
+ TU_LOG1("Range %d (%d, %d, %d)\r\n", i, (int) rangef.subrange[i].bMin, (int) rangef.subrange[i].bMax, (int) rangef.subrange[i].bRes);
}
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &rangef, sizeof(rangef));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &rangef, sizeof(rangef));
}
- }
- else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID &&
- request->bRequest == AUDIO_CS_REQ_CUR)
- {
- audio_control_cur_1_t cur_valid = { .bCur = 1 };
+ } else if (request->bControlSelector == AUDIO_CS_CTRL_CLK_VALID &&
+ request->bRequest == AUDIO_CS_REQ_CUR) {
+ audio_control_cur_1_t cur_valid = {.bCur = 1};
TU_LOG1("Clock get is valid %u\r\n", cur_valid.bCur);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_valid, sizeof(cur_valid));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_valid, sizeof(cur_valid));
}
TU_LOG1("Clock get request not supported, entity = %u, selector = %u, request = %u\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
@@ -209,25 +191,21 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t
}
// Helper for clock set requests
-static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf)
-{
- (void)rhport;
+static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) {
+ (void) rhport;
TU_ASSERT(request->bEntityID == UAC2_ENTITY_CLOCK);
TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR);
- if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ)
- {
+ if (request->bControlSelector == AUDIO_CS_CTRL_SAM_FREQ) {
TU_VERIFY(request->wLength == sizeof(audio_control_cur_4_t));
- current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *)buf)->bCur;
+ current_sample_rate = (uint32_t) ((audio_control_cur_4_t const *) buf)->bCur;
TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate);
return true;
- }
- else
- {
+ } else {
TU_LOG1("Clock set request not supported, entity = %u, selector = %u, request = %u\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
return false;
@@ -235,33 +213,25 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t
}
// Helper for feature unit get requests
-static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request)
-{
+static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_request_t const *request) {
TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT);
- if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR)
- {
- audio_control_cur_1_t mute1 = { .bCur = mute[request->bChannelNumber] };
+ if (request->bControlSelector == AUDIO_FU_CTRL_MUTE && request->bRequest == AUDIO_CS_REQ_CUR) {
+ audio_control_cur_1_t mute1 = {.bCur = mute[request->bChannelNumber]};
TU_LOG1("Get channel %u mute %d\r\n", request->bChannelNumber, mute1.bCur);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &mute1, sizeof(mute1));
- }
- else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
- {
- if (request->bRequest == AUDIO_CS_REQ_RANGE)
- {
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &mute1, sizeof(mute1));
+ } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) {
+ if (request->bRequest == AUDIO_CS_REQ_RANGE) {
audio_control_range_2_n_t(1) range_vol = {
- .wNumSubRanges = tu_htole16(1),
- .subrange[0] = { .bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256) }
- };
+ .wNumSubRanges = tu_htole16(1),
+ .subrange[0] = {.bMin = tu_htole16(-VOLUME_CTRL_50_DB), tu_htole16(VOLUME_CTRL_0_DB), tu_htole16(256)}};
TU_LOG1("Get channel %u volume range (%d, %d, %u) dB\r\n", request->bChannelNumber,
range_vol.subrange[0].bMin / 256, range_vol.subrange[0].bMax / 256, range_vol.subrange[0].bRes / 256);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &range_vol, sizeof(range_vol));
- }
- else if (request->bRequest == AUDIO_CS_REQ_CUR)
- {
- audio_control_cur_2_t cur_vol = { .bCur = tu_htole16(volume[request->bChannelNumber]) };
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &range_vol, sizeof(range_vol));
+ } else if (request->bRequest == AUDIO_CS_REQ_CUR) {
+ audio_control_cur_2_t cur_vol = {.bCur = tu_htole16(volume[request->bChannelNumber])};
TU_LOG1("Get channel %u volume %d dB\r\n", request->bChannelNumber, cur_vol.bCur / 256);
- return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &cur_vol, sizeof(cur_vol));
+ return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *) request, &cur_vol, sizeof(cur_vol));
}
}
TU_LOG1("Feature unit get request not supported, entity = %u, selector = %u, request = %u\r\n",
@@ -271,35 +241,29 @@ static bool tud_audio_feature_unit_get_request(uint8_t rhport, audio_control_req
}
// Helper for feature unit set requests
-static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf)
-{
- (void)rhport;
+static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_request_t const *request, uint8_t const *buf) {
+ (void) rhport;
TU_ASSERT(request->bEntityID == UAC2_ENTITY_FEATURE_UNIT);
TU_VERIFY(request->bRequest == AUDIO_CS_REQ_CUR);
- if (request->bControlSelector == AUDIO_FU_CTRL_MUTE)
- {
+ if (request->bControlSelector == AUDIO_FU_CTRL_MUTE) {
TU_VERIFY(request->wLength == sizeof(audio_control_cur_1_t));
- mute[request->bChannelNumber] = ((audio_control_cur_1_t const *)buf)->bCur;
+ mute[request->bChannelNumber] = ((audio_control_cur_1_t const *) buf)->bCur;
TU_LOG1("Set channel %d Mute: %d\r\n", request->bChannelNumber, mute[request->bChannelNumber]);
return true;
- }
- else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME)
- {
+ } else if (request->bControlSelector == AUDIO_FU_CTRL_VOLUME) {
TU_VERIFY(request->wLength == sizeof(audio_control_cur_2_t));
- volume[request->bChannelNumber] = ((audio_control_cur_2_t const *)buf)->bCur;
+ volume[request->bChannelNumber] = ((audio_control_cur_2_t const *) buf)->bCur;
TU_LOG1("Set channel %d volume: %d dB\r\n", request->bChannelNumber, volume[request->bChannelNumber] / 256);
return true;
- }
- else
- {
+ } else {
TU_LOG1("Feature unit set request not supported, entity = %u, selector = %u, request = %u\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
return false;
@@ -307,16 +271,14 @@ static bool tud_audio_feature_unit_set_request(uint8_t rhport, audio_control_req
}
// Invoked when audio class specific get request received for an entity
-bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request)
-{
- audio_control_request_t const *request = (audio_control_request_t const *)p_request;
+bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
+ audio_control_request_t const *request = (audio_control_request_t const *) p_request;
if (request->bEntityID == UAC2_ENTITY_CLOCK)
return tud_audio_clock_get_request(rhport, request);
if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT)
return tud_audio_feature_unit_get_request(rhport, request);
- else
- {
+ else {
TU_LOG1("Get request not handled, entity = %d, selector = %d, request = %d\r\n",
request->bEntityID, request->bControlSelector, request->bRequest);
}
@@ -324,9 +286,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p
}
// Invoked when audio class specific set request received for an entity
-bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf)
-{
- audio_control_request_t const *request = (audio_control_request_t const *)p_request;
+bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *buf) {
+ audio_control_request_t const *request = (audio_control_request_t const *) p_request;
if (request->bEntityID == UAC2_ENTITY_FEATURE_UNIT)
return tud_audio_feature_unit_set_request(rhport, request, buf);
@@ -338,28 +299,26 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p
return false;
}
-bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
- (void)rhport;
+bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
+ (void) rhport;
uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));
if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0)
- blink_interval_ms = BLINK_MOUNTED;
+ blink_interval_ms = BLINK_MOUNTED;
return true;
}
-bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
-{
- (void)rhport;
+bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) {
+ (void) rhport;
uint8_t const itf = tu_u16_low(tu_le16toh(p_request->wIndex));
uint8_t const alt = tu_u16_low(tu_le16toh(p_request->wValue));
TU_LOG2("Set interface %d alt %d\r\n", itf, alt);
if (ITF_NUM_AUDIO_STREAMING == itf && alt != 0)
- blink_interval_ms = BLINK_STREAMING;
+ blink_interval_ms = BLINK_STREAMING;
#if CFG_AUDIO_DEBUG
current_alt_settings = alt;
@@ -368,37 +327,34 @@ bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_reque
return true;
}
-void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param)
-{
- (void)func_id;
- (void)alt_itf;
+void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t *feedback_param) {
+ (void) func_id;
+ (void) alt_itf;
// Set feedback method to fifo counting
feedback_param->method = AUDIO_FEEDBACK_METHOD_FIFO_COUNT;
feedback_param->sample_freq = current_sample_rate;
}
#if CFG_AUDIO_DEBUG
-bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting)
-{
- (void)rhport;
- (void)n_bytes_received;
- (void)func_id;
- (void)ep_out;
- (void)cur_alt_setting;
+bool tud_audio_rx_done_isr(uint8_t rhport, uint16_t n_bytes_received, uint8_t func_id, uint8_t ep_out, uint8_t cur_alt_setting) {
+ (void) rhport;
+ (void) n_bytes_received;
+ (void) func_id;
+ (void) ep_out;
+ (void) cur_alt_setting;
fifo_count = tud_audio_available();
// Same averaging method used in UAC2 class
- fifo_count_avg = (uint32_t)(((uint64_t)fifo_count_avg * 63 + ((uint32_t)fifo_count << 16)) >> 6);
+ fifo_count_avg = (uint32_t) (((uint64_t) fifo_count_avg * 63 + ((uint32_t) fifo_count << 16)) >> 6);
return true;
}
#endif
#if CFG_QUIRK_OS_GUESSING
-bool tud_audio_feedback_format_correction_cb(uint8_t func_id)
-{
- (void)func_id;
- if(tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) {
+bool tud_audio_feedback_format_correction_cb(uint8_t func_id) {
+ (void) func_id;
+ if (tud_speed_get() == TUSB_SPEED_FULL && quirk_os_guessing_get() == QUIRK_OS_GUESSING_OSX) {
return true;
} else {
return false;
@@ -409,25 +365,21 @@ bool tud_audio_feedback_format_correction_cb(uint8_t func_id)
// AUDIO Task
//--------------------------------------------------------------------+
-void audio_task(void)
-{
- // Replace audio_task() with your I2S transmit callback.
- // Here we simulate a callback called every 1ms.
+// This task simulates an audio transmit callback, one frame is sent every 1ms.
+// In a real application, this would be replaced with actual I2S transmit callback.
+void audio_task(void) {
static uint32_t start_ms = 0;
uint32_t curr_ms = board_millis();
- if ( start_ms == curr_ms ) return; // not enough time
+ if (start_ms == curr_ms) return;// not enough time
start_ms = curr_ms;
- uint16_t length = (uint16_t) (current_sample_rate/1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX);
+ uint16_t length = (uint16_t) (current_sample_rate / 1000 * CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX);
- if (current_sample_rate == 44100 && (curr_ms % 10 == 0))
- {
+ if (current_sample_rate == 44100 && (curr_ms % 10 == 0)) {
// Take one more sample every 10 cycles, to have a average reading speed of 44.1
// This correction is not needed in real world cases
length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX;
- } else
- if (current_sample_rate == 88200 && (curr_ms % 5 == 0))
- {
+ } else if (current_sample_rate == 88200 && (curr_ms % 5 == 0)) {
// Take one more sample every 5 cycles, to have a average reading speed of 88.2
// This correction is not needed in real world cases
length += CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX;
@@ -439,8 +391,7 @@ void audio_task(void)
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinking_task(void)
-{
+void led_blinking_task(void) {
static uint32_t start_ms = 0;
static bool led_state = false;
@@ -457,33 +408,30 @@ void led_blinking_task(void)
// HID interface for audio debug
//--------------------------------------------------------------------+
// Every 1ms, we will sent 1 debug information report
-void audio_debug_task(void)
-{
+void audio_debug_task(void) {
static uint32_t start_ms = 0;
uint32_t curr_ms = board_millis();
- if ( start_ms == curr_ms ) return; // not enough time
+ if (start_ms == curr_ms) return;// not enough time
start_ms = curr_ms;
audio_debug_info_t debug_info;
- debug_info.sample_rate = current_sample_rate;
- debug_info.alt_settings = current_alt_settings;
- debug_info.fifo_size = CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ;
- debug_info.fifo_count = fifo_count;
+ debug_info.sample_rate = current_sample_rate;
+ debug_info.alt_settings = current_alt_settings;
+ debug_info.fifo_size = CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ;
+ debug_info.fifo_count = fifo_count;
debug_info.fifo_count_avg = (uint16_t) (fifo_count_avg >> 16);
- for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++)
- {
+ for (int i = 0; i < CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_RX + 1; i++) {
debug_info.mute[i] = mute[i];
debug_info.volume[i] = volume[i];
}
- if(tud_hid_ready())
+ if (tud_hid_ready())
tud_hid_report(0, &debug_info, sizeof(debug_info));
}
// Invoked when received GET_REPORT control request
// Unused here
-uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
-{
+uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) {
// TODO not Implemented
(void) itf;
(void) report_id;
@@ -496,8 +444,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
// Invoked when received SET_REPORT control request or
// Unused here
-void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
-{
+void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const *buffer, uint16_t bufsize) {
// This example doesn't use multiple report and report ID
(void) itf;
(void) report_id;
diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c
index 04d4af4e5..0406279fd 100644
--- a/examples/device/video_capture/src/main.c
+++ b/examples/device/video_capture/src/main.c
@@ -292,7 +292,7 @@ void led_blinking_task(void* param) {
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
#define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4)
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define USBD_STACK_SIZE 4096
int main(void);
void app_main(void) {
@@ -351,8 +351,8 @@ void freertos_init_task(void) {
xTaskCreate(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL);
#endif
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
- #if !TUSB_MCU_VENDOR_ESPRESSIF
+ // only start scheduler for non-espressif mcu
+ #ifndef ESP_PLATFORM
vTaskStartScheduler();
#endif
}
diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h
index 6dbd6f2a5..4ba86ca65 100644
--- a/examples/device/video_capture/src/tusb_config.h
+++ b/examples/device/video_capture/src/tusb_config.h
@@ -58,7 +58,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c
index 245e7abb8..dc616e3fa 100644
--- a/examples/device/video_capture_2ch/src/main.c
+++ b/examples/device/video_capture_2ch/src/main.c
@@ -300,7 +300,7 @@ void led_blinking_task(void* param) {
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
#define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4)
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define USBD_STACK_SIZE 4096
int main(void);
void app_main(void) {
@@ -359,8 +359,8 @@ void freertos_init_task(void) {
xTaskCreate(video_task, "video", VIDEO_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL);
#endif
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
- #if !TUSB_MCU_VENDOR_ESPRESSIF
+ // only start scheduler for non-espressif mcu
+ #ifndef ESP_PLATFORM
vTaskStartScheduler();
#endif
}
diff --git a/examples/device/video_capture_2ch/src/tusb_config.h b/examples/device/video_capture_2ch/src/tusb_config.h
index 91775a327..e84e49879 100644
--- a/examples/device/video_capture_2ch/src/tusb_config.h
+++ b/examples/device/video_capture_2ch/src/tusb_config.h
@@ -58,7 +58,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
diff --git a/examples/dual/host_hid_to_device_cdc/only.txt b/examples/dual/host_hid_to_device_cdc/only.txt
index 3f40b4e7c..35f896f1e 100644
--- a/examples/dual/host_hid_to_device_cdc/only.txt
+++ b/examples/dual/host_hid_to_device_cdc/only.txt
@@ -1,6 +1,7 @@
board:mimxrt1060_evk
board:mimxrt1064_evk
board:mcb1800
+mcu:CH32V20X
mcu:RP2040
mcu:ra6m5
mcu:MAX3421
diff --git a/examples/dual/host_hid_to_device_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c
index 633f7a6ac..6f30ca381 100644
--- a/examples/dual/host_hid_to_device_cdc/src/main.c
+++ b/examples/dual/host_hid_to_device_cdc/src/main.c
@@ -190,7 +190,9 @@ void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
// look up new key in previous keys
static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8_t keycode) {
for (uint8_t i = 0; i < 6; i++) {
- if (report->keycode[i] == keycode) return true;
+ if (report->keycode[i] == keycode) {
+ return true;
+ }
}
return false;
@@ -230,7 +232,9 @@ static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const* re
// TODO example skips key released
}
- if (flush) tud_cdc_write_flush();
+ if (flush) {
+ tud_cdc_write_flush();
+ }
prev_report = *report;
}
diff --git a/examples/dual/host_info_to_device_cdc/only.txt b/examples/dual/host_info_to_device_cdc/only.txt
index 3f40b4e7c..35f896f1e 100644
--- a/examples/dual/host_info_to_device_cdc/only.txt
+++ b/examples/dual/host_info_to_device_cdc/only.txt
@@ -1,6 +1,7 @@
board:mimxrt1060_evk
board:mimxrt1064_evk
board:mcb1800
+mcu:CH32V20X
mcu:RP2040
mcu:ra6m5
mcu:MAX3421
diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c
index 7e593f234..a2a505952 100644
--- a/examples/dual/host_info_to_device_cdc/src/main.c
+++ b/examples/dual/host_info_to_device_cdc/src/main.c
@@ -78,6 +78,22 @@ static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_devi
void led_blinking_task(void);
void cdc_task(void);
+#define cdc_printf(...) \
+ do { \
+ char _tempbuf[256]; \
+ char* _bufptr = _tempbuf; \
+ uint32_t count = (uint32_t) sprintf(_tempbuf, __VA_ARGS__); \
+ while (count > 0) { \
+ uint32_t wr_count = tud_cdc_write(_bufptr, count); \
+ count -= wr_count; \
+ _bufptr += wr_count; \
+ if (count > 0){ \
+ tud_task(); \
+ tud_cdc_write_flush(); \
+ } \
+ } \
+ } while(0)
+
/*------------- MAIN -------------*/
int main(void) {
board_init();
@@ -160,22 +176,6 @@ void cdc_task(void) {
//--------------------------------------------------------------------+
// Host Get device information
//--------------------------------------------------------------------+
-#define cdc_printf(...) \
- do { \
- char _tempbuf[256]; \
- char* _bufptr = _tempbuf; \
- uint32_t count = (uint32_t) sprintf(_tempbuf, __VA_ARGS__); \
- while (count > 0) { \
- uint32_t wr_count = tud_cdc_write(_bufptr, count); \
- count -= wr_count; \
- _bufptr += wr_count; \
- if (count > 0){ \
- tud_task();\
- tud_cdc_write_flush(); \
- } \
- } \
- } while(0)
-
static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_device) {
// Get String descriptor using Sync API
uint16_t serial[64];
@@ -232,12 +232,14 @@ void tuh_enum_descriptor_device_cb(uint8_t daddr, tusb_desc_device_t const* desc
}
void tuh_mount_cb(uint8_t daddr) {
- printf("mounted device %u\r\n", daddr);
+ cdc_printf("mounted device %u\r\n", daddr);
+ tud_cdc_write_flush();
is_print[daddr] = true;
}
void tuh_umount_cb(uint8_t daddr) {
- printf("unmounted device %u\r\n", daddr);
+ cdc_printf("unmounted device %u\r\n", daddr);
+ tud_cdc_write_flush();
is_print[daddr] = false;
}
@@ -249,7 +251,9 @@ void led_blinking_task(void) {
static bool led_state = false;
// Blink every interval ms
- if (board_millis() - start_ms < blink_interval_ms) return; // not enough time
+ if (board_millis() - start_ms < blink_interval_ms) {
+ return;// not enough time
+ }
start_ms += blink_interval_ms;
board_led_write(led_state);
@@ -300,7 +304,9 @@ static int _count_utf8_bytes(const uint16_t *buf, size_t len) {
}
static void print_utf16(uint16_t *temp_buf, size_t buf_len) {
- if ((temp_buf[0] & 0xff) == 0) return; // empty
+ if ((temp_buf[0] & 0xff) == 0) {
+ return;// empty
+ }
size_t utf16_len = ((temp_buf[0] & 0xff) - 2) / sizeof(uint16_t);
size_t utf8_len = (size_t) _count_utf8_bytes(temp_buf + 1, utf16_len);
_convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len);
diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt
index 95f9f1d82..cba58f8e8 100644
--- a/examples/host/bare_api/only.txt
+++ b/examples/host/bare_api/only.txt
@@ -1,3 +1,4 @@
+mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
@@ -15,3 +16,7 @@ mcu:MAX3421
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
+mcu:STM32H7RS
+mcu:STM32N6
+family:samd21
+family:samd5x_e5x
diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt
index 95f9f1d82..cba58f8e8 100644
--- a/examples/host/cdc_msc_hid/only.txt
+++ b/examples/host/cdc_msc_hid/only.txt
@@ -1,3 +1,4 @@
+mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
@@ -15,3 +16,7 @@ mcu:MAX3421
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
+mcu:STM32H7RS
+mcu:STM32N6
+family:samd21
+family:samd5x_e5x
diff --git a/examples/host/cdc_msc_hid/src/cdc_app.c b/examples/host/cdc_msc_hid/src/cdc_app.c
index e68ec383b..97f1a96d6 100644
--- a/examples/host/cdc_msc_hid/src/cdc_app.c
+++ b/examples/host/cdc_msc_hid/src/cdc_app.c
@@ -31,8 +31,7 @@ static size_t get_console_inputs(uint8_t* buf, size_t bufsize) {
size_t count = 0;
while (count < bufsize) {
int ch = board_getchar();
- if (ch <= 0) break;
-
+ if (ch <= 0) { break; }
buf[count] = (uint8_t) ch;
count++;
}
@@ -69,10 +68,15 @@ void tuh_cdc_rx_cb(uint8_t idx) {
uint32_t const bufsize = sizeof(buf) - 1;
// forward cdc interfaces -> console
- uint32_t count = tuh_cdc_read(idx, buf, bufsize);
- buf[count] = 0;
+ const uint32_t count = tuh_cdc_read(idx, buf, bufsize);
+ if (count) {
+ buf[count] = 0;
+ printf("%s", (char*) buf);
- printf("%s", (char*) buf);
+ #ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
+ fflush(stdout);// flush right away, else nanolib will wait for newline
+ #endif
+ }
}
// Invoked when a device with CDC interface is mounted
@@ -88,7 +92,7 @@ void tuh_cdc_mount_cb(uint8_t idx) {
// If CFG_TUH_CDC_LINE_CODING_ON_ENUM is defined, line coding will be set by tinyusb stack
// while eneumerating new cdc device
cdc_line_coding_t line_coding = {0};
- if (tuh_cdc_get_local_line_coding(idx, &line_coding)) {
+ if (tuh_cdc_get_line_coding_local(idx, &line_coding)) {
printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits);
}
diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c
index a751c9c80..6f01d6f45 100644
--- a/examples/host/cdc_msc_hid/src/hid_app.c
+++ b/examples/host/cdc_msc_hid/src/hid_app.c
@@ -29,14 +29,9 @@
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
+#define MAX_REPORT 4
-// If your host terminal support ansi escape code such as TeraTerm
-// it can be use to simulate mouse cursor movement within terminal
-#define USE_ANSI_ESCAPE 0
-
-#define MAX_REPORT 4
-
-static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII };
+static uint8_t const keycode2ascii[128][2] = {HID_KEYCODE_TO_ASCII};
// Each HID instance can has multiple reports
static struct {
@@ -45,8 +40,8 @@ static struct {
} hid_info[CFG_TUH_HID];
static void process_kbd_report(hid_keyboard_report_t const *report);
-static void process_mouse_report(hid_mouse_report_t const * report);
-static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len);
+static void process_mouse_report(hid_mouse_report_t const *report);
+static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len);
void hid_app_task(void) {
// nothing to do
@@ -70,7 +65,7 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_re
printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]);
- // By default host stack will use activate boot protocol on supported interface.
+ // By default, host stack will use boot protocol on supported interface.
// Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser)
if (itf_protocol == HID_ITF_PROTOCOL_NONE) {
hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len);
@@ -121,7 +116,7 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
//--------------------------------------------------------------------+
// look up new key in previous keys
-static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8_t keycode) {
+static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) {
for (uint8_t i = 0; i < 6; i++) {
if (report->keycode[i] == keycode) {
return true;
@@ -130,28 +125,25 @@ static inline bool find_key_in_report(hid_keyboard_report_t const* report, uint8
return false;
}
-static void process_kbd_report(hid_keyboard_report_t const *report)
-{
- static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released
+static void process_kbd_report(hid_keyboard_report_t const *report) {
+ static hid_keyboard_report_t prev_report = {0, 0, {0}};// previous report to check key released
//------------- example code ignore control (non-printable) key affects -------------//
- for(uint8_t i=0; i<6; i++)
- {
- if ( report->keycode[i] )
- {
- if ( find_key_in_report(&prev_report, report->keycode[i]) )
- {
+ for (uint8_t i = 0; i < 6; i++) {
+ if (report->keycode[i]) {
+ if (find_key_in_report(&prev_report, report->keycode[i])) {
// exist in previous report means the current key is holding
- }else
- {
+ } else {
// not existed in previous report means the current key is pressed
bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0];
putchar(ch);
- if ( ch == '\r' ) putchar('\n'); // added new line for enter key
+ if (ch == '\r') {
+ putchar('\n');
+ }
- #ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
- fflush(stdout); // flush right away, else nanolib will wait for newline
+ #ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
+ fflush(stdout);// flush right away, else nanolib will wait for newline
#endif
}
}
@@ -166,55 +158,22 @@ static void process_kbd_report(hid_keyboard_report_t const *report)
//--------------------------------------------------------------------+
static void cursor_movement(int8_t x, int8_t y, int8_t wheel) {
-#if USE_ANSI_ESCAPE
- // Move X using ansi escape
- if ( x < 0)
- {
- printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left
- }else if ( x > 0)
- {
- printf(ANSI_CURSOR_FORWARD(%d), x); // move right
- }
-
- // Move Y using ansi escape
- if ( y < 0)
- {
- printf(ANSI_CURSOR_UP(%d), (-y)); // move up
- }else if ( y > 0)
- {
- printf(ANSI_CURSOR_DOWN(%d), y); // move down
- }
-
- // Scroll using ansi escape
- if (wheel < 0)
- {
- printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up
- }else if (wheel > 0)
- {
- printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down
- }
-
- printf("\r\n");
-#else
printf("(%d %d %d)\r\n", x, y, wheel);
-#endif
}
-static void process_mouse_report(hid_mouse_report_t const * report)
-{
- static hid_mouse_report_t prev_report = { 0 };
+static void process_mouse_report(hid_mouse_report_t const *report) {
+ static hid_mouse_report_t prev_report = {0};
- //------------- button state -------------//
+ // button state
uint8_t button_changed_mask = report->buttons ^ prev_report.buttons;
- if ( button_changed_mask & report->buttons)
- {
+ if (button_changed_mask & report->buttons) {
printf(" %c%c%c ",
- report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-',
- report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-',
- report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-');
+ report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-',
+ report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-',
+ report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-');
}
- //------------- cursor movement -------------//
+ // cursor movement
cursor_movement(report->x, report->y, report->wheel);
}
@@ -263,18 +222,23 @@ static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t c
if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) {
switch (rpt_info->usage) {
case HID_USAGE_DESKTOP_KEYBOARD:
- TU_LOG1("HID receive keyboard report\r\n");
+ TU_LOG2("HID receive keyboard report\r\n");
// Assume keyboard follow boot report layout
process_kbd_report((hid_keyboard_report_t const *) report);
break;
case HID_USAGE_DESKTOP_MOUSE:
- TU_LOG1("HID receive mouse report\r\n");
+ TU_LOG2("HID receive mouse report\r\n");
// Assume mouse follow boot report layout
process_mouse_report((hid_mouse_report_t const *) report);
break;
default:
+ printf("report[%u] ", rpt_info->report_id);
+ for (uint8_t i = 0; i < len; i++) {
+ printf("%02X ", report[i]);
+ }
+ printf("\r\n");
break;
}
}
diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h
index cc8d6e5c4..2f8cb5e03 100644
--- a/examples/host/cdc_msc_hid/src/tusb_config.h
+++ b/examples/host/cdc_msc_hid/src/tusb_config.h
@@ -103,10 +103,11 @@
#define CFG_TUH_ENUMERATION_BUFSIZE 256
#define CFG_TUH_HUB 1 // number of supported hubs
-#define CFG_TUH_CDC 1 // CDC ACM
+#define CFG_TUH_CDC 2 // number of supported CDC devices. also activates CDC ACM
#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API
+#define CFG_TUH_CDC_PL2303 1 // PL2303 Serial. PL2303 is not part of CDC class, only to re-use CDC driver API
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
#define CFG_TUH_MSC 1
#define CFG_TUH_VENDOR 0
@@ -122,7 +123,7 @@
// Set Line Control state on enumeration/mounted:
// DTR ( bit 0), RTS (bit 1)
-#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03
+#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM (CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS)
// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt
index e3ae25260..576271aff 100644
--- a/examples/host/cdc_msc_hid_freertos/only.txt
+++ b/examples/host/cdc_msc_hid_freertos/only.txt
@@ -13,3 +13,7 @@ mcu:MAX3421
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
+mcu:STM32H7RS
+mcu:STM32N6
+family:samd21
+family:samd5x_e5x
diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
index e279ad509..d99760a02 100644
--- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
+++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
@@ -27,7 +27,7 @@
#include "tusb.h"
#include "bsp/board_api.h"
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CDC_STACK_SZIE 2048
#else
#define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2)
diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c
index 64a108254..0bcb355ec 100644
--- a/examples/host/cdc_msc_hid_freertos/src/main.c
+++ b/examples/host/cdc_msc_hid_freertos/src/main.c
@@ -30,7 +30,7 @@
#include "bsp/board_api.h"
#include "tusb.h"
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define USBH_STACK_SIZE 4096
#else
// Increase stack size when debug log is enabled
@@ -86,15 +86,15 @@ int main(void) {
xTimerStart(blinky_tm, 0);
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
-#if !TUSB_MCU_VENDOR_ESPRESSIF
+ // only start scheduler for non-espressif mcu
+#ifndef ESP_PLATFORM
vTaskStartScheduler();
#endif
return 0;
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
void app_main(void) {
main();
}
diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
index 682265f59..3cdb227e2 100644
--- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
+++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
@@ -44,7 +44,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
@@ -108,10 +108,11 @@
#define CFG_TUH_ENUMERATION_BUFSIZE 256
#define CFG_TUH_HUB 1 // number of supported hubs
-#define CFG_TUH_CDC 1 // CDC ACM
+#define CFG_TUH_CDC 1 // number of supported CDC devices. also activates CDC ACM
#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
#define CFG_TUH_CDC_CH34X 1 // CH340 or CH341 Serial. CH34X is not part of CDC class, only to re-use CDC driver API
+#define CFG_TUH_CDC_PL2303 1 // PL2303 Serial. PL2303 is not part of CDC class, only to re-use CDC driver API
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
#define CFG_TUH_MSC 1
#define CFG_TUH_VENDOR 0
@@ -127,7 +128,7 @@
// Set Line Control state on enumeration/mounted:
// DTR ( bit 0), RTS (bit 1)
-#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03
+#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM (CDC_CONTROL_LINE_STATE_DTR | CDC_CONTROL_LINE_STATE_RTS)
// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt
index b6f87f423..133a7c9a0 100644
--- a/examples/host/device_info/only.txt
+++ b/examples/host/device_info/only.txt
@@ -1,3 +1,4 @@
+mcu:CH32V20X
mcu:ESP32S2
mcu:ESP32S3
mcu:ESP32P4
@@ -18,3 +19,7 @@ mcu:RAXXX
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
+mcu:STM32H7RS
+mcu:STM32N6
+family:samd21
+family:samd5x_e5x
diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c
index e924a137b..7189972d6 100644
--- a/examples/host/device_info/src/main.c
+++ b/examples/host/device_info/src/main.c
@@ -268,7 +268,7 @@ void led_blinking_task(void* param) {
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define USB_STACK_SIZE 4096
#else
// Increase stack size when debug log is enabled
@@ -285,7 +285,7 @@ StackType_t usb_stack[USB_STACK_SIZE];
StaticTask_t usb_taskdef;
#endif
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
void app_main(void) {
main();
}
@@ -308,8 +308,8 @@ void init_freertos_task(void) {
xTaskCreate(usb_host_task, "usbh", USB_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
#endif
- // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
-#if !TUSB_MCU_VENDOR_ESPRESSIF
+ // only start scheduler for non-espressif mcu
+#ifndef ESP_PLATFORM
vTaskStartScheduler();
#endif
}
diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h
index e12970c12..e4ca2528e 100644
--- a/examples/host/device_info/src/tusb_config.h
+++ b/examples/host/device_info/src/tusb_config.h
@@ -40,7 +40,7 @@
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt
index 95f9f1d82..cba58f8e8 100644
--- a/examples/host/hid_controller/only.txt
+++ b/examples/host/hid_controller/only.txt
@@ -1,3 +1,4 @@
+mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
@@ -15,3 +16,7 @@ mcu:MAX3421
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
+mcu:STM32H7RS
+mcu:STM32N6
+family:samd21
+family:samd5x_e5x
diff --git a/examples/host/midi_rx/only.txt b/examples/host/midi_rx/only.txt
index b6f87f423..133a7c9a0 100644
--- a/examples/host/midi_rx/only.txt
+++ b/examples/host/midi_rx/only.txt
@@ -1,3 +1,4 @@
+mcu:CH32V20X
mcu:ESP32S2
mcu:ESP32S3
mcu:ESP32P4
@@ -18,3 +19,7 @@ mcu:RAXXX
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
+mcu:STM32H7RS
+mcu:STM32N6
+family:samd21
+family:samd5x_e5x
diff --git a/examples/host/midi_rx/src/tusb_config.h b/examples/host/midi_rx/src/tusb_config.h
index c9b430388..76bdf87f3 100644
--- a/examples/host/midi_rx/src/tusb_config.h
+++ b/examples/host/midi_rx/src/tusb_config.h
@@ -40,7 +40,7 @@ extern "C" {
#endif
// Espressif IDF requires "freertos/" prefix in include path
-#if TUSB_MCU_VENDOR_ESPRESSIF
+#ifdef ESP_PLATFORM
#define CFG_TUSB_OS_INC_PATH freertos/
#endif
diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt
index 95f9f1d82..cba58f8e8 100644
--- a/examples/host/msc_file_explorer/only.txt
+++ b/examples/host/msc_file_explorer/only.txt
@@ -1,3 +1,4 @@
+mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
@@ -15,3 +16,7 @@ mcu:MAX3421
mcu:STM32F4
mcu:STM32F7
mcu:STM32H7
+mcu:STM32H7RS
+mcu:STM32N6
+family:samd21
+family:samd5x_e5x
diff --git a/examples/typec/power_delivery/src/main.c b/examples/typec/power_delivery/src/main.c
index 068dbbeb1..de0db4721 100644
--- a/examples/typec/power_delivery/src/main.c
+++ b/examples/typec/power_delivery/src/main.c
@@ -71,9 +71,8 @@ int main(void)
}
}
-#if TUSB_MCU_VENDOR_ESPRESSIF
-void app_main(void)
-{
+#ifdef ESP_PLATFORM
+void app_main(void) {
main();
}
#endif