summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorZixun LI <[email protected]>2026-05-03 14:36:25 +0200
committerGitHub <[email protected]>2026-05-03 14:36:25 +0200
commitea2de8be7e939fdffd73efd75cc2e2051ca495a9 (patch)
treef2801e76d9643eb277ba49498f0fedeee9aa2e6b /examples
parent5c0c1662464e48681533e8ecc1217613fb6e3820 (diff)
parent939c2f91c200db2bf9874c2e6c50b3530f8a6725 (diff)
Merge branch 'master' into copilot/upgrade-net-lwip-webserver-descriptors
Diffstat (limited to 'examples')
-rw-r--r--examples/device/CMakeLists.txt1
-rw-r--r--examples/device/audio_4_channel_mic/src/usb_descriptors.c4
-rw-r--r--examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c4
-rw-r--r--examples/device/audio_test/src/usb_descriptors.c4
-rw-r--r--examples/device/audio_test_freertos/src/usb_descriptors.c4
-rw-r--r--examples/device/audio_test_multi_rate/src/main.c2
-rw-r--r--examples/device/audio_test_multi_rate/src/usb_descriptors.c4
-rw-r--r--examples/device/cdc_dual_ports/src/usb_descriptors.c25
-rw-r--r--examples/device/cdc_msc/src/usb_descriptors.c22
-rw-r--r--examples/device/cdc_msc_freertos/src/main.c4
-rw-r--r--examples/device/cdc_msc_freertos/src/usb_descriptors.c22
-rw-r--r--examples/device/cdc_msc_throughput/CMakeLists.txt35
-rw-r--r--examples/device/cdc_msc_throughput/Makefile11
-rw-r--r--examples/device/cdc_msc_throughput/src/main.c151
-rw-r--r--examples/device/cdc_msc_throughput/src/tusb_config.h103
-rw-r--r--examples/device/cdc_msc_throughput/src/usb_descriptors.c186
-rw-r--r--examples/device/cdc_uac2/src/uac2_app.c8
-rw-r--r--examples/device/cdc_uac2/src/usb_descriptors.c22
-rw-r--r--examples/device/dfu/skip.txt1
-rw-r--r--examples/device/dynamic_configuration/src/usb_descriptors.c2
-rw-r--r--examples/device/hid_generic_inout/src/usb_descriptors.c2
-rw-r--r--examples/device/midi_test/src/usb_descriptors.c2
-rw-r--r--examples/device/midi_test_freertos/src/usb_descriptors.c2
-rw-r--r--examples/device/msc_dual_lun/src/usb_descriptors.c12
-rw-r--r--examples/device/mtp/src/usb_descriptors.c2
-rw-r--r--examples/device/net_lwip_webserver/src/lwipopts.h20
-rw-r--r--examples/device/net_lwip_webserver/src/tusb_config.h33
-rw-r--r--examples/device/net_lwip_webserver/src/usb_descriptors.c12
-rw-r--r--examples/device/printer_to_cdc/src/usb_descriptors.c21
-rw-r--r--examples/device/uac2_headset/src/main.c8
-rw-r--r--examples/device/uac2_headset/src/usb_descriptors.c15
-rw-r--r--examples/device/uac2_speaker_fb/src/main.c8
-rw-r--r--examples/device/uac2_speaker_fb/src/usb_descriptors.c15
-rw-r--r--examples/device/webusb_serial/src/usb_descriptors.c22
-rw-r--r--examples/dual/dynamic_switch/src/usb_descriptors.c2
35 files changed, 710 insertions, 81 deletions
diff --git a/examples/device/CMakeLists.txt b/examples/device/CMakeLists.txt
index 7173f455e..088872711 100644
--- a/examples/device/CMakeLists.txt
+++ b/examples/device/CMakeLists.txt
@@ -16,6 +16,7 @@ set(EXAMPLE_LIST
cdc_dual_ports
cdc_msc
cdc_msc_freertos
+ cdc_msc_throughput
cdc_uac2
dfu
dfu_runtime
diff --git a/examples/device/audio_4_channel_mic/src/usb_descriptors.c b/examples/device/audio_4_channel_mic/src/usb_descriptors.c
index 00337eee7..2380ea0ae 100644
--- a/examples/device/audio_4_channel_mic/src/usb_descriptors.c
+++ b/examples/device/audio_4_channel_mic/src/usb_descriptors.c
@@ -91,6 +91,10 @@ enum
// nRF5x ISO can only be endpoint 8
#define EPNUM_AUDIO 0x08
+#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put audio iso on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO 0x0A
+
#else
#define EPNUM_AUDIO 0x01
#endif
diff --git a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c
index 3bb93f67d..216cd062a 100644
--- a/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c
+++ b/examples/device/audio_4_channel_mic_freertos/src/usb_descriptors.c
@@ -91,6 +91,10 @@ enum
// nRF5x ISO can only be endpoint 8
#define EPNUM_AUDIO 0x08
+#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put audio iso on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO 0x0A
+
#else
#define EPNUM_AUDIO 0x01
#endif
diff --git a/examples/device/audio_test/src/usb_descriptors.c b/examples/device/audio_test/src/usb_descriptors.c
index ad161939e..37ebf84d3 100644
--- a/examples/device/audio_test/src/usb_descriptors.c
+++ b/examples/device/audio_test/src/usb_descriptors.c
@@ -91,6 +91,10 @@ enum
// nRF5x ISO can only be endpoint 8
#define EPNUM_AUDIO 0x08
+#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put audio iso on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO 0x0A
+
#else
#define EPNUM_AUDIO 0x01
#endif
diff --git a/examples/device/audio_test_freertos/src/usb_descriptors.c b/examples/device/audio_test_freertos/src/usb_descriptors.c
index ad161939e..37ebf84d3 100644
--- a/examples/device/audio_test_freertos/src/usb_descriptors.c
+++ b/examples/device/audio_test_freertos/src/usb_descriptors.c
@@ -91,6 +91,10 @@ enum
// nRF5x ISO can only be endpoint 8
#define EPNUM_AUDIO 0x08
+#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put audio iso on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO 0x0A
+
#else
#define EPNUM_AUDIO 0x01
#endif
diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c
index 952176997..a86beb415 100644
--- a/examples/device/audio_test_multi_rate/src/main.c
+++ b/examples/device/audio_test_multi_rate/src/main.c
@@ -532,7 +532,7 @@ static bool audio20_get_req_entity(uint8_t rhport, tusb_control_request_t const
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));
+ uint8_t const alt = tu_u16_low(p_request->wValue);
// Clear buffer when streaming format is changed
if (alt != 0) {
diff --git a/examples/device/audio_test_multi_rate/src/usb_descriptors.c b/examples/device/audio_test_multi_rate/src/usb_descriptors.c
index 505936fdb..31333dcd3 100644
--- a/examples/device/audio_test_multi_rate/src/usb_descriptors.c
+++ b/examples/device/audio_test_multi_rate/src/usb_descriptors.c
@@ -88,6 +88,10 @@ enum {
// nRF5x ISO can only be endpoint 8
#define EPNUM_AUDIO 0x08
+#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put audio iso on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO 0x0A
+
#else
#define EPNUM_AUDIO 0x01
#endif
diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c
index e6011c35a..adfd8cf9d 100644
--- a/examples/device/cdc_dual_ports/src/usb_descriptors.c
+++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c
@@ -106,16 +106,27 @@ enum {
#define EPNUM_CDC_1_OUT 0x05
#define EPNUM_CDC_1_IN 0x84
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_CDC_0_NOTIF 0x81
- #define EPNUM_CDC_0_OUT 0x02
- #define EPNUM_CDC_0_IN 0x83
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put bulk on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_CDC_0_NOTIF 0x81
+ #define EPNUM_CDC_0_OUT 0x08
+ #define EPNUM_CDC_0_IN 0x89
- #define EPNUM_CDC_1_NOTIF 0x84
- #define EPNUM_CDC_1_OUT 0x05
- #define EPNUM_CDC_1_IN 0x86
+ #define EPNUM_CDC_1_NOTIF 0x82
+ #define EPNUM_CDC_1_OUT 0x0A
+ #define EPNUM_CDC_1_IN 0x8B
+ #else
+ #define EPNUM_CDC_0_NOTIF 0x81
+ #define EPNUM_CDC_0_OUT 0x02
+ #define EPNUM_CDC_0_IN 0x83
+
+ #define EPNUM_CDC_1_NOTIF 0x84
+ #define EPNUM_CDC_1_OUT 0x05
+ #define EPNUM_CDC_1_IN 0x86
+ #endif
#else
#define EPNUM_CDC_0_NOTIF 0x81
diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c
index c668ea3a7..5dc80dee3 100644
--- a/examples/device/cdc_msc/src/usb_descriptors.c
+++ b/examples/device/cdc_msc/src/usb_descriptors.c
@@ -102,15 +102,25 @@ enum {
#define EPNUM_MSC_OUT 0x05
#define EPNUM_MSC_IN 0x84
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_CDC_NOTIF 0x81
- #define EPNUM_CDC_OUT 0x02
- #define EPNUM_CDC_IN 0x83
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put bulk on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x08
+ #define EPNUM_CDC_IN 0x89
- #define EPNUM_MSC_OUT 0x04
- #define EPNUM_MSC_IN 0x85
+ #define EPNUM_MSC_OUT 0x0A
+ #define EPNUM_MSC_IN 0x8B
+ #else
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x83
+
+ #define EPNUM_MSC_OUT 0x04
+ #define EPNUM_MSC_IN 0x85
+ #endif
#else
#define EPNUM_CDC_NOTIF 0x81
diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c
index 4fb209fd0..f2f71d089 100644
--- a/examples/device/cdc_msc_freertos/src/main.c
+++ b/examples/device/cdc_msc_freertos/src/main.c
@@ -34,10 +34,10 @@
#define USBD_STACK_SIZE 4096
#else
// Increase stack size when debug log is enabled
- #define USBD_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
+ #define USBD_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 4 : 2))
#endif
-#define CDC_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 2 : 1))
+#define CDC_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 3 : 2))
#define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE
//--------------------------------------------------------------------+
diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c
index 4950f02e0..f5b015051 100644
--- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c
+++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c
@@ -102,15 +102,25 @@ enum {
#define EPNUM_MSC_OUT 0x05
#define EPNUM_MSC_IN 0x84
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_CDC_NOTIF 0x81
- #define EPNUM_CDC_OUT 0x02
- #define EPNUM_CDC_IN 0x83
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put bulk on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x08
+ #define EPNUM_CDC_IN 0x89
- #define EPNUM_MSC_OUT 0x04
- #define EPNUM_MSC_IN 0x85
+ #define EPNUM_MSC_OUT 0x0A
+ #define EPNUM_MSC_IN 0x8B
+ #else
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x83
+
+ #define EPNUM_MSC_OUT 0x04
+ #define EPNUM_MSC_IN 0x85
+ #endif
#else
#define EPNUM_CDC_NOTIF 0x81
diff --git a/examples/device/cdc_msc_throughput/CMakeLists.txt b/examples/device/cdc_msc_throughput/CMakeLists.txt
new file mode 100644
index 000000000..69c1caa6a
--- /dev/null
+++ b/examples/device/cdc_msc_throughput/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.20)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
+
+project(cdc_msc_throughput C CXX ASM)
+
+# Checks this example is valid for the family and initializes the project
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
+
+# Espressif has its own cmake build system
+if(FAMILY STREQUAL "espressif")
+ return()
+endif()
+
+if (RTOS STREQUAL zephyr)
+ set(EXE_NAME app)
+else()
+ set(EXE_NAME ${PROJECT_NAME})
+ add_executable(${EXE_NAME})
+endif()
+
+# Example source
+target_sources(${EXE_NAME} PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
+ )
+
+# Example include
+target_include_directories(${EXE_NAME} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ )
+
+# Configure compilation flags and libraries for the example without RTOS.
+# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
+family_configure_device_example(${EXE_NAME} ${RTOS})
diff --git a/examples/device/cdc_msc_throughput/Makefile b/examples/device/cdc_msc_throughput/Makefile
new file mode 100644
index 000000000..035e90308
--- /dev/null
+++ b/examples/device/cdc_msc_throughput/Makefile
@@ -0,0 +1,11 @@
+include ../../../hw/bsp/family_support.mk
+
+INC += \
+ src \
+
+
+# Example source
+EXAMPLE_SOURCE += $(wildcard src/*.c)
+SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE))
+
+include ../../../hw/bsp/family_rules.mk
diff --git a/examples/device/cdc_msc_throughput/src/main.c b/examples/device/cdc_msc_throughput/src/main.c
new file mode 100644
index 000000000..116cbe13f
--- /dev/null
+++ b/examples/device/cdc_msc_throughput/src/main.c
@@ -0,0 +1,151 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include "bsp/board_api.h"
+#include "tusb.h"
+
+// cdc_msc_throughput: minimal CDC+MSC device aimed at measuring pure USB bulk throughput.
+// MSC read/write callbacks don't touch any backing storage - write discards the
+// data and read only zero-fills the low LBAs the host scans during enumeration
+// (partition table, GPT header). Higher LBAs return whatever is already in the
+// transfer buffer, so `dd` numbers reflect the USB/driver ceiling, not any
+// simulated storage or per-byte memset cost.
+// CDC path drains RX in tud_cdc_rx_cb and sources TX from a static filler in the
+// main loop so `dd` can target /dev/ttyACMx in either direction.
+
+static void cdc_throughput_task(void);
+
+//--------------------------------------------------------------------+
+// Main
+//--------------------------------------------------------------------+
+int main(void) {
+ board_init();
+
+ tusb_rhport_init_t dev_init = {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO};
+ tusb_init(BOARD_TUD_RHPORT, &dev_init);
+
+ board_init_after_tusb();
+
+ while (1) {
+ tud_task();
+ cdc_throughput_task();
+ }
+}
+
+//--------------------------------------------------------------------+
+// CDC callbacks + tasks
+//--------------------------------------------------------------------+
+void tud_cdc_rx_cb(uint8_t itf) {
+ (void) itf;
+ tud_cdc_read_flush(); // Drain RX
+}
+
+static void cdc_throughput_task(void) {
+ if (!tud_cdc_connected()) return;
+
+ // Source TX: fill whatever write room is free.
+ static uint8_t const filler[CFG_TUD_CDC_TX_EPSIZE] = {0};
+ uint32_t room = tud_cdc_write_available();
+ while (room > 0) {
+ uint32_t n = tud_cdc_write(filler, tu_min32(room, sizeof(filler)));
+ if (n == 0) {
+ break;
+ }
+ room -= n;
+ }
+ tud_cdc_write_flush();
+}
+
+//--------------------------------------------------------------------+
+// MSC callbacks
+//--------------------------------------------------------------------+
+
+// 1 GiB logical capacity so `dd` can run long enough for stable numbers.
+// No real backing store - block content is synthesised on read, discarded on write.
+enum {
+ DISK_BLOCK_SIZE = 512,
+ DISK_BLOCK_COUNT = 0x00200000u, // 2 Mi blocks = 1 GiB
+ // Kernel probes partition-table / filesystem-superblock locations near the
+ // start of the disk during enumeration. Zero-fill only this head range so the
+ // block layer sees "no partition, no filesystem" and leaves us alone; higher
+ // LBAs skip the memset so `dd` measures pure USB/driver throughput.
+ DISK_ZEROFILL_LBA = 64, // 32 KiB
+};
+
+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;
+ const char vid[] = "TinyUSB";
+ const char pid[] = "Mass Storage";
+ const char rev[] = "1.0";
+ (void) strncpy((char*) vendor_id, vid, 8);
+ (void) strncpy((char*) product_id, pid, 16);
+ (void) strncpy((char*) product_rev, rev, 4);
+}
+
+bool tud_msc_test_unit_ready_cb(uint8_t lun) {
+ (void) lun;
+ return true;
+}
+
+void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) {
+ (void) lun;
+ *block_count = DISK_BLOCK_COUNT;
+ *block_size = DISK_BLOCK_SIZE;
+}
+
+bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
+ (void) lun; (void) power_condition; (void) start; (void) load_eject;
+ return true;
+}
+
+bool tud_msc_is_writable_cb(uint8_t lun) {
+ (void) lun;
+ return true;
+}
+
+// READ10: zero-fill only the head range the kernel inspects, skip memset everywhere
+// else so we measure the USB / driver path rather than memset cost.
+int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
+ (void) lun; (void) offset;
+ if (lba < DISK_ZEROFILL_LBA) {
+ memset(buffer, 0, bufsize);
+ } else {
+ (void) buffer;
+ }
+ return (int32_t) bufsize;
+}
+
+// WRITE10: discard the received data entirely - this is the pure USB-speed test.
+int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) {
+ (void) lun; (void) lba; (void) offset; (void) buffer;
+ return (int32_t) bufsize;
+}
+
+// Unknown SCSI commands: stall with Invalid Command sense.
+int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) {
+ (void) scsi_cmd; (void) buffer; (void) bufsize;
+ tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
+ return -1;
+}
diff --git a/examples/device/cdc_msc_throughput/src/tusb_config.h b/examples/device/cdc_msc_throughput/src/tusb_config.h
new file mode 100644
index 000000000..6c8655719
--- /dev/null
+++ b/examples/device/cdc_msc_throughput/src/tusb_config.h
@@ -0,0 +1,103 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef TUSB_CONFIG_H_
+#define TUSB_CONFIG_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//--------------------------------------------------------------------
+// Board Specific Configuration
+//--------------------------------------------------------------------
+
+#ifndef BOARD_TUD_RHPORT
+ #define BOARD_TUD_RHPORT 0
+#endif
+
+#ifndef BOARD_TUD_MAX_SPEED
+ #define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
+#endif
+
+//--------------------------------------------------------------------
+// Common Configuration
+//--------------------------------------------------------------------
+
+#ifndef CFG_TUSB_MCU
+ #error CFG_TUSB_MCU must be defined
+#endif
+
+#ifndef CFG_TUSB_OS
+ #define CFG_TUSB_OS OPT_OS_NONE
+#endif
+
+#ifndef CFG_TUSB_DEBUG
+ #define CFG_TUSB_DEBUG 0
+#endif
+
+// Enable Device stack
+#define CFG_TUD_ENABLED 1
+#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
+
+#ifndef CFG_TUSB_MEM_SECTION
+ #define CFG_TUSB_MEM_SECTION
+#endif
+
+#ifndef CFG_TUSB_MEM_ALIGN
+ #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
+#endif
+
+//--------------------------------------------------------------------
+// DEVICE CONFIGURATION
+//--------------------------------------------------------------------
+
+#ifndef CFG_TUD_ENDPOINT0_SIZE
+ #define CFG_TUD_ENDPOINT0_SIZE 64
+#endif
+
+//------------- CLASS -------------//
+#define CFG_TUD_CDC 1
+#define CFG_TUD_MSC 1
+
+// Large MSC bulk buffer: host transfers big CBW payloads (e.g. dd bs=1M does 64KiB
+// chunks). A 4K per-bulk-IO buffer lets the class driver amortise the per-CBW
+// overhead across many USB packets, approximating the maximum USB bulk throughput.
+#define CFG_TUD_MSC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 4096 : 1024)
+
+// #define CFG_TUD_CDC_TX_PERSISTENT 1
+
+// CDC throughput: size for HS; tinyusb will auto-scale for FS via TUD_OPT_HIGH_SPEED.
+#define CFG_TUD_CDC_RX_EPSIZE (TUD_OPT_HIGH_SPEED ? 2*512 : 2*64)
+#define CFG_TUD_CDC_TX_EPSIZE CFG_TUD_CDC_RX_EPSIZE
+
+#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 2*512 : 2*64)
+#define CFG_TUD_CDC_TX_BUFSIZE CFG_TUD_CDC_RX_BUFSIZE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TUSB_CONFIG_H_ */
diff --git a/examples/device/cdc_msc_throughput/src/usb_descriptors.c b/examples/device/cdc_msc_throughput/src/usb_descriptors.c
new file mode 100644
index 000000000..3b0ff6e17
--- /dev/null
+++ b/examples/device/cdc_msc_throughput/src/usb_descriptors.c
@@ -0,0 +1,186 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include "bsp/board_api.h"
+#include "tusb.h"
+
+#define USB_PID (0x4000 | ((CFG_TUD_CDC) ? (1 << 0) : 0) | ((CFG_TUD_MSC) ? (1 << 1) : 0))
+#define USB_VID 0xCafe
+#define USB_BCD 0x0200
+
+static tusb_desc_device_t const desc_device = {
+ .bLength = sizeof(tusb_desc_device_t),
+ .bDescriptorType = TUSB_DESC_DEVICE,
+ .bcdUSB = USB_BCD,
+
+ // IAD required for composite CDC + MSC
+ .bDeviceClass = TUSB_CLASS_MISC,
+ .bDeviceSubClass = MISC_SUBCLASS_COMMON,
+ .bDeviceProtocol = MISC_PROTOCOL_IAD,
+ .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
+
+ .idVendor = USB_VID,
+ .idProduct = USB_PID,
+ .bcdDevice = 0x0100,
+
+ .iManufacturer = 0x01,
+ .iProduct = 0x02,
+ .iSerialNumber = 0x03,
+
+ .bNumConfigurations = 0x01,
+};
+
+uint8_t const *tud_descriptor_device_cb(void) {
+ return (uint8_t const *) &desc_device;
+}
+
+enum {
+ ITF_NUM_CDC = 0,
+ ITF_NUM_CDC_DATA,
+ ITF_NUM_MSC,
+ ITF_NUM_TOTAL,
+};
+
+// Place bulk endpoints on EP>=8 for MAX32690 class parts (bigger FIFO, DPB-capable).
+#if CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put bulk on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x08
+ #define EPNUM_CDC_IN 0x89
+ #define EPNUM_MSC_OUT 0x0A
+ #define EPNUM_MSC_IN 0x8B
+ #else
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x83
+ #define EPNUM_MSC_OUT 0x04
+ #define EPNUM_MSC_IN 0x85
+ #endif
+#else
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x82
+ #define EPNUM_MSC_OUT 0x03
+ #define EPNUM_MSC_IN 0x83
+#endif
+
+#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN)
+
+static uint8_t const desc_fs_configuration[] = {
+ TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
+ TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
+};
+
+#if TUD_OPT_HIGH_SPEED
+static uint8_t const desc_hs_configuration[] = {
+ TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
+ TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 16, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
+ TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
+};
+
+static uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
+
+static tusb_desc_device_qualifier_t const desc_device_qualifier = {
+ .bLength = sizeof(tusb_desc_device_qualifier_t),
+ .bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
+ .bcdUSB = USB_BCD,
+ .bDeviceClass = 0x00,
+ .bDeviceSubClass = 0x00,
+ .bDeviceProtocol = 0x00,
+ .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
+ .bNumConfigurations = 0x01,
+ .bReserved = 0x00,
+};
+
+uint8_t const *tud_descriptor_device_qualifier_cb(void) {
+ return (uint8_t const *) &desc_device_qualifier;
+}
+
+uint8_t const *tud_descriptor_other_speed_configuration_cb(uint8_t index) {
+ (void) index;
+ 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
+
+uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
+ (void) index;
+#if TUD_OPT_HIGH_SPEED
+ return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
+#else
+ return desc_fs_configuration;
+#endif
+}
+
+enum {
+ STRID_LANGID = 0,
+ STRID_MANUFACTURER,
+ STRID_PRODUCT,
+ STRID_SERIAL,
+};
+
+static char const *string_desc_arr[] = {
+ (const char[]) { 0x09, 0x04 },
+ "TinyUSB",
+ "Throughput",
+ NULL,
+ "TinyUSB CDC",
+ "TinyUSB MSC",
+};
+
+static uint16_t _desc_str[32 + 1];
+
+uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
+ (void) langid;
+ size_t chr_count;
+
+ switch (index) {
+ case STRID_LANGID:
+ memcpy(&_desc_str[1], string_desc_arr[0], 2);
+ chr_count = 1;
+ break;
+
+ case STRID_SERIAL:
+ chr_count = board_usb_get_serial(_desc_str + 1, 32);
+ break;
+
+ default:
+ if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL;
+ const char *str = string_desc_arr[index];
+ chr_count = strlen(str);
+ size_t const max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1;
+ if (chr_count > max_count) chr_count = max_count;
+ for (size_t i = 0; i < chr_count; i++) _desc_str[1 + i] = str[i];
+ break;
+ }
+
+ _desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8) | (2 * chr_count + 2));
+ return _desc_str;
+}
diff --git a/examples/device/cdc_uac2/src/uac2_app.c b/examples/device/cdc_uac2/src/uac2_app.c
index 7760c402b..6e9d1d9e3 100644
--- a/examples/device/cdc_uac2/src/uac2_app.c
+++ b/examples/device/cdc_uac2/src/uac2_app.c
@@ -263,8 +263,8 @@ bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const
{
(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));
+ uint8_t const itf = tu_u16_low(p_request->wIndex);
+ uint8_t const alt = tu_u16_low(p_request->wValue);
if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt == 0) {
// Audio streaming stop
@@ -277,8 +277,8 @@ bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const
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));
+ uint8_t const itf = tu_u16_low(p_request->wIndex);
+ uint8_t const alt = tu_u16_low(p_request->wValue);
TU_LOG2("Set interface %d alt %d\r\n", itf, alt);
if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt != 0) {
diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c
index e6caaa971..fdffc761e 100644
--- a/examples/device/cdc_uac2/src/usb_descriptors.c
+++ b/examples/device/cdc_uac2/src/usb_descriptors.c
@@ -97,15 +97,25 @@ uint8_t const * tud_descriptor_device_cb(void)
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x82
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_AUDIO_IN 0x01
- #define EPNUM_AUDIO_OUT 0x02
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put CDC bulk on EP>=8 and audio iso on EP10/11 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO_OUT 0x0A
+ #define EPNUM_AUDIO_IN 0x0B
- #define EPNUM_CDC_NOTIF 0x83
- #define EPNUM_CDC_OUT 0x04
- #define EPNUM_CDC_IN 0x85
+ #define EPNUM_CDC_NOTIF 0x83
+ #define EPNUM_CDC_OUT 0x08
+ #define EPNUM_CDC_IN 0x89
+ #else
+ #define EPNUM_AUDIO_IN 0x01
+ #define EPNUM_AUDIO_OUT 0x02
+
+ #define EPNUM_CDC_NOTIF 0x83
+ #define EPNUM_CDC_OUT 0x04
+ #define EPNUM_CDC_IN 0x85
+ #endif
#else
#define EPNUM_AUDIO_IN 0x01
diff --git a/examples/device/dfu/skip.txt b/examples/device/dfu/skip.txt
index 79d3da9d2..ccff857ac 100644
--- a/examples/device/dfu/skip.txt
+++ b/examples/device/dfu/skip.txt
@@ -1,3 +1,2 @@
-mcu:TM4C
mcu:BCM2835
family:espressif
diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c
index 458b7c2a5..c4049414f 100644
--- a/examples/device/dynamic_configuration/src/usb_descriptors.c
+++ b/examples/device/dynamic_configuration/src/usb_descriptors.c
@@ -132,7 +132,7 @@ enum
#define EPNUM_1_MSC_OUT 0x02
#define EPNUM_1_MSC_IN 0x82
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_0_CDC_NOTIF 0x81
diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c
index 929b2fd3a..93e718461 100644
--- a/examples/device/hid_generic_inout/src/usb_descriptors.c
+++ b/examples/device/hid_generic_inout/src/usb_descriptors.c
@@ -97,7 +97,7 @@ enum
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
-#if defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#if CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_HID_OUT 0x01
diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c
index e969f33a3..99c798ce1 100644
--- a/examples/device/midi_test/src/usb_descriptors.c
+++ b/examples/device/midi_test/src/usb_descriptors.c
@@ -87,7 +87,7 @@ enum {
#define EPNUM_MIDI_OUT 0x02
#define EPNUM_MIDI_IN 0x81
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_MIDI_OUT 0x01
diff --git a/examples/device/midi_test_freertos/src/usb_descriptors.c b/examples/device/midi_test_freertos/src/usb_descriptors.c
index e969f33a3..99c798ce1 100644
--- a/examples/device/midi_test_freertos/src/usb_descriptors.c
+++ b/examples/device/midi_test_freertos/src/usb_descriptors.c
@@ -87,7 +87,7 @@ enum {
#define EPNUM_MIDI_OUT 0x02
#define EPNUM_MIDI_IN 0x81
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_MIDI_OUT 0x01
diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c
index f73935ee0..b328cf17f 100644
--- a/examples/device/msc_dual_lun/src/usb_descriptors.c
+++ b/examples/device/msc_dual_lun/src/usb_descriptors.c
@@ -91,11 +91,17 @@ enum
#define EPNUM_MSC_OUT 0x02
#define EPNUM_MSC_IN 0x81
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_MSC_OUT 0x01
- #define EPNUM_MSC_IN 0x82
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put bulk on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_MSC_OUT 0x08
+ #define EPNUM_MSC_IN 0x89
+ #else
+ #define EPNUM_MSC_OUT 0x01
+ #define EPNUM_MSC_IN 0x82
+ #endif
#else
#define EPNUM_MSC_OUT 0x01
diff --git a/examples/device/mtp/src/usb_descriptors.c b/examples/device/mtp/src/usb_descriptors.c
index f0aa3de6b..4c840560e 100644
--- a/examples/device/mtp/src/usb_descriptors.c
+++ b/examples/device/mtp/src/usb_descriptors.c
@@ -94,7 +94,7 @@ enum
#define EPNUM_MTP_OUT 0x02
#define EPNUM_MTP_IN 0x81
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_MTP_EVT 0x81
diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h
index 11686ce2a..350120423 100644
--- a/examples/device/net_lwip_webserver/src/lwipopts.h
+++ b/examples/device/net_lwip_webserver/src/lwipopts.h
@@ -32,6 +32,14 @@
#ifndef LWIPOPTS_H__
#define LWIPOPTS_H__
+// Pulls in tusb_option.h → tusb_config.h, which defines LWIP_HIGH_THROUGHPUT
+// based on the target MCU's SRAM tier.
+#include "tusb_option.h"
+
+#ifndef LWIP_HIGH_THROUGHPUT
+ #define LWIP_HIGH_THROUGHPUT 0
+#endif
+
/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
#define NO_SYS 1
#define MEM_ALIGNMENT 4
@@ -49,7 +57,15 @@
#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/)
#define TCP_SND_BUF (4 * TCP_MSS)
-#define TCP_WND (4 * TCP_MSS)
+#if LWIP_HIGH_THROUGHPUT
+ #define TCP_WND (8 * TCP_MSS)
+ #define PBUF_POOL_SIZE 8
+ // Must grow in step with TCP_SND_BUF (default MEMP_NUM_TCP_SEG=16 caps TCP_SND_BUF at 4*MSS).
+ #define MEMP_NUM_TCP_SEG 16
+#else
+ #define TCP_WND (4 * TCP_MSS)
+ #define PBUF_POOL_SIZE 4
+#endif
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
@@ -60,8 +76,6 @@
#define LWIP_SINGLE_NETIF 1
#define LWIP_NETIF_LINK_CALLBACK 1
-#define PBUF_POOL_SIZE 4
-
#define HTTPD_USE_CUSTOM_FSDATA 0
#define LWIP_MULTICAST_PING 1
diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h
index 3285ea52c..24082fe25 100644
--- a/examples/device/net_lwip_webserver/src/tusb_config.h
+++ b/examples/device/net_lwip_webserver/src/tusb_config.h
@@ -92,32 +92,53 @@ extern "C" {
#define USE_ECM 1
#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1)
#define USE_ECM 1
-#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002)
- #define USE_ECM 1
#else
#define USE_ECM 0
- #define INCLUDE_IPERF
#endif
#endif
+// MCU SRAM tier — drives the bigger lwIP buffers in lwipopts.h, the larger
+// NCM OUT NTB size below, and whether iperf is built. Small-RAM MCUs
+// (stm32c0/f1/wb, lpc11/13, samd11) keep modest defaults to fit.
+#ifndef LWIP_HIGH_THROUGHPUT
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) || \
+ TU_CHECK_MCU(OPT_MCU_STM32F2, OPT_MCU_STM32F4, OPT_MCU_STM32F7) || \
+ TU_CHECK_MCU(OPT_MCU_STM32H5, OPT_MCU_STM32H7, OPT_MCU_STM32H7RS) || \
+ TU_CHECK_MCU(OPT_MCU_STM32U5, OPT_MCU_STM32N6) || \
+ TU_CHECK_MCU(OPT_MCU_RP2040) || \
+ TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX) || \
+ TU_CHECK_MCU(OPT_MCU_NRF5X)
+ #define LWIP_HIGH_THROUGHPUT 1
+ #else
+ #define LWIP_HIGH_THROUGHPUT 0
+ #endif
+#endif
+
+#if LWIP_HIGH_THROUGHPUT && !defined(INCLUDE_IPERF)
+ #define INCLUDE_IPERF
+#endif
+
//--------------------------------------------------------------------
// NCM CLASS CONFIGURATION, SEE "ncm.h" FOR PERFORMANCE TUNING
//--------------------------------------------------------------------
// Must be >> MTU
// Can be set to 2048 without impact
-#define CFG_TUD_NCM_IN_NTB_MAX_SIZE (2 * TCP_MSS + 100)
+#define CFG_TUD_NCM_IN_NTB_MAX_SIZE (1 * TCP_MSS + 100)
// Must be >> MTU
// Can be set to smaller values if wNtbOutMaxDatagrams==1
-#define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100)
+#if LWIP_HIGH_THROUGHPUT
+ #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (3 * TCP_MSS + 100)
+#else
+ #define CFG_TUD_NCM_OUT_NTB_MAX_SIZE (2 * TCP_MSS + 100)
+#endif
// Number of NCM transfer blocks for reception side
#ifndef CFG_TUD_NCM_OUT_NTB_N
#define CFG_TUD_NCM_OUT_NTB_N 1
#endif
-// Number of NCM transfer blocks for transmission side
#ifndef CFG_TUD_NCM_IN_NTB_N
#define CFG_TUD_NCM_IN_NTB_N 1
#endif
diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c
index 80594fdeb..1aa223eb9 100644
--- a/examples/device/net_lwip_webserver/src/usb_descriptors.c
+++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c
@@ -123,12 +123,20 @@ const uint8_t *tud_descriptor_device_cb(void) {
#define EPNUM_NET_OUT 0x02
#define EPNUM_NET_IN 0x81
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
-// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
+// MCUs that don't support the same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
+
+#if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+// endpoint 8,9 has FIFO of 2048 bytes
+#define EPNUM_NET_NOTIF 0x81
+#define EPNUM_NET_OUT 0x08
+#define EPNUM_NET_IN 0x89
+#else
#define EPNUM_NET_NOTIF 0x81
#define EPNUM_NET_OUT 0x02
#define EPNUM_NET_IN 0x83
+#endif
#else
#define EPNUM_NET_NOTIF 0x81
diff --git a/examples/device/printer_to_cdc/src/usb_descriptors.c b/examples/device/printer_to_cdc/src/usb_descriptors.c
index 30d309ed4..db7bfe97a 100644
--- a/examples/device/printer_to_cdc/src/usb_descriptors.c
+++ b/examples/device/printer_to_cdc/src/usb_descriptors.c
@@ -67,12 +67,21 @@ uint8_t const *tud_descriptor_device_cb(void) {
//--------------------------------------------------------------------+
// Endpoint numbers
-#if defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
- #define EPNUM_CDC_NOTIF 0x81
- #define EPNUM_CDC_OUT 0x02
- #define EPNUM_CDC_IN 0x83
- #define EPNUM_PRINTER_OUT 0x04
- #define EPNUM_PRINTER_IN 0x85
+#if CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put bulk on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x08
+ #define EPNUM_CDC_IN 0x89
+ #define EPNUM_PRINTER_OUT 0x0A
+ #define EPNUM_PRINTER_IN 0x8B
+ #else
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x83
+ #define EPNUM_PRINTER_OUT 0x04
+ #define EPNUM_PRINTER_IN 0x85
+ #endif
#else
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02
diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c
index 0ea63d8f7..779e927bc 100644
--- a/examples/device/uac2_headset/src/main.c
+++ b/examples/device/uac2_headset/src/main.c
@@ -522,8 +522,8 @@ bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p
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));
+ uint8_t const itf = tu_u16_low(p_request->wIndex);
+ uint8_t const alt = tu_u16_low(p_request->wValue);
if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt == 0) {
blink_interval_ms = BLINK_MOUNTED;
@@ -534,8 +534,8 @@ bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const
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));
+ uint8_t const itf = tu_u16_low(p_request->wIndex);
+ uint8_t const alt = tu_u16_low(p_request->wValue);
TU_LOG2("Set interface %d alt %d\r\n", itf, alt);
if (ITF_NUM_AUDIO_STREAMING_SPK == itf && alt != 0) {
diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c
index e4fbbf8a5..b554e7195 100644
--- a/examples/device/uac2_headset/src/usb_descriptors.c
+++ b/examples/device/uac2_headset/src/usb_descriptors.c
@@ -97,12 +97,19 @@ uint8_t const * tud_descriptor_device_cb(void)
#define EPNUM_AUDIO_OUT 0x08
#define EPNUM_AUDIO_INT 0x01
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_AUDIO_IN 0x01
- #define EPNUM_AUDIO_OUT 0x02
- #define EPNUM_AUDIO_INT 0x03
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put audio iso on EP10/11 so the 4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO_OUT 0x0A
+ #define EPNUM_AUDIO_IN 0x0B
+ #define EPNUM_AUDIO_INT 0x01
+ #else
+ #define EPNUM_AUDIO_IN 0x01
+ #define EPNUM_AUDIO_OUT 0x02
+ #define EPNUM_AUDIO_INT 0x03
+ #endif
#else
#define EPNUM_AUDIO_IN 0x01
diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c
index c3e97bb28..402642162 100644
--- a/examples/device/uac2_speaker_fb/src/main.c
+++ b/examples/device/uac2_speaker_fb/src/main.c
@@ -457,8 +457,8 @@ static bool audio20_set_req_entity(tusb_control_request_t const *p_request, uint
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));
+ uint8_t const itf = tu_u16_low(p_request->wIndex);
+ uint8_t const alt = tu_u16_low(p_request->wValue);
TU_LOG2("Set interface %d alt %d\r\n", itf, alt);
if (ITF_NUM_AUDIO_STREAMING == itf && alt != 0)
@@ -531,8 +531,8 @@ bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p
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));
+ uint8_t const itf = tu_u16_low(p_request->wIndex);
+ uint8_t const alt = tu_u16_low(p_request->wValue);
if (ITF_NUM_AUDIO_STREAMING == itf && alt == 0) {
blink_interval_ms = BLINK_MOUNTED;
diff --git a/examples/device/uac2_speaker_fb/src/usb_descriptors.c b/examples/device/uac2_speaker_fb/src/usb_descriptors.c
index c5a161a1e..f0c780e38 100644
--- a/examples/device/uac2_speaker_fb/src/usb_descriptors.c
+++ b/examples/device/uac2_speaker_fb/src/usb_descriptors.c
@@ -115,12 +115,19 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf) {
#define EPNUM_AUDIO_FB 0x08
#define EPNUM_DEBUG 0x01
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_AUDIO 0x02
- #define EPNUM_AUDIO_FB 0x01
- #define EPNUM_DEBUG 0x03
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put audio iso on EP10/11 so the 4096-byte FIFOs can back double packet buffering
+ #define EPNUM_AUDIO 0x0A
+ #define EPNUM_AUDIO_FB 0x0B
+ #define EPNUM_DEBUG 0x01
+ #else
+ #define EPNUM_AUDIO 0x02
+ #define EPNUM_AUDIO_FB 0x01
+ #define EPNUM_DEBUG 0x03
+ #endif
#else
#define EPNUM_AUDIO 0x01
diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c
index 0ef41a68e..527837161 100644
--- a/examples/device/webusb_serial/src/usb_descriptors.c
+++ b/examples/device/webusb_serial/src/usb_descriptors.c
@@ -104,15 +104,25 @@ enum
#define EPNUM_VENDOR_OUT 0x05
#define EPNUM_VENDOR_IN 0x84
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
- #define EPNUM_CDC_NOTIF 0x81
- #define EPNUM_CDC_OUT 0x02
- #define EPNUM_CDC_IN 0x83
+ #if TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002)
+ // Put bulk on EP>=8 so the 2048/4096-byte FIFOs can back double packet buffering
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x08
+ #define EPNUM_CDC_IN 0x89
+
+ #define EPNUM_VENDOR_OUT 0x0A
+ #define EPNUM_VENDOR_IN 0x8B
+ #else
+ #define EPNUM_CDC_NOTIF 0x81
+ #define EPNUM_CDC_OUT 0x02
+ #define EPNUM_CDC_IN 0x83
- #define EPNUM_VENDOR_OUT 0x04
- #define EPNUM_VENDOR_IN 0x85
+ #define EPNUM_VENDOR_OUT 0x04
+ #define EPNUM_VENDOR_IN 0x85
+ #endif
#else
#define EPNUM_CDC_NOTIF 0x81
diff --git a/examples/dual/dynamic_switch/src/usb_descriptors.c b/examples/dual/dynamic_switch/src/usb_descriptors.c
index 54ffc2c18..ef6d795b7 100644
--- a/examples/dual/dynamic_switch/src/usb_descriptors.c
+++ b/examples/dual/dynamic_switch/src/usb_descriptors.c
@@ -86,7 +86,7 @@ enum {
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x82
-#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY)
+#elif CFG_TUD_ENDPOINT_ONE_DIRECTION_ONLY
// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_CDC_NOTIF 0x81