diff options
| author | Zixun LI <[email protected]> | 2025-11-25 10:59:43 +0100 |
|---|---|---|
| committer | Zixun LI <[email protected]> | 2025-11-25 10:59:43 +0100 |
| commit | dc083e4d9c87658498a3bd0b527d25bc88dd1ed6 (patch) | |
| tree | 0523e934e5a1b1fe8331b28990ddf2e2f4478077 /examples/dual | |
| parent | e59b2c40fc9e655918629d73cc8c54b86b4a70c1 (diff) | |
| parent | fee2d2a034d65aa625bc1a8b32c3b7a51292a39f (diff) | |
Merge remote-tracking branch 'tinyusb/master' into n6_build
Signed-off-by: Zixun LI <[email protected]>
Diffstat (limited to 'examples/dual')
9 files changed, 171 insertions, 51 deletions
diff --git a/examples/dual/host_hid_to_device_cdc/Makefile b/examples/dual/host_hid_to_device_cdc/Makefile index 474ae9814..a51251bf9 100644 --- a/examples/dual/host_hid_to_device_cdc/Makefile +++ b/examples/dual/host_hid_to_device_cdc/Makefile @@ -1,12 +1,12 @@ -include ../../build_system/make/make.mk +include ../../../hw/bsp/family_support.mk INC += \ src \ - $(TOP)/hw \ + # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) -SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) +SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) CFLAGS_GCC += -Wno-error=cast-align -Wno-error=null-dereference @@ -15,4 +15,4 @@ SRC_C += \ src/host/hub.c \ src/host/usbh.c -include ../../build_system/make/rules.mk +include ../../../hw/bsp/family_rules.mk diff --git a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c index 9d57737fb..3efa30e20 100644 --- a/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c +++ b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 @@ -42,7 +42,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -122,7 +122,7 @@ enum { #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) // full speed configuration -uint8_t const desc_fs_configuration[] = { +static 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), @@ -134,7 +134,7 @@ uint8_t const desc_fs_configuration[] = { // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration -uint8_t const desc_hs_configuration[] = { +static 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), @@ -143,10 +143,10 @@ uint8_t const desc_hs_configuration[] = { }; // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static 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 = { +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, @@ -175,7 +175,7 @@ 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 + // Note: the descriptor type is OTHER_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); diff --git a/examples/dual/host_info_to_device_cdc/CMakeLists.txt b/examples/dual/host_info_to_device_cdc/CMakeLists.txt index 6ae5b5766..ad3c5ddf0 100644 --- a/examples/dual/host_info_to_device_cdc/CMakeLists.txt +++ b/examples/dual/host_info_to_device_cdc/CMakeLists.txt @@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM) # Checks this example is valid for the family and initializes the project family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}) +# Espressif has its own cmake build system +if(FAMILY STREQUAL "espressif") + return() +endif() + add_executable(${PROJECT}) # Example source @@ -25,7 +30,7 @@ target_include_directories(${PROJECT} PUBLIC # Configure compilation flags and libraries for the example without RTOS. # See the corresponding function in hw/bsp/FAMILY/family.cmake for details. -family_configure_dual_usb_example(${PROJECT} noos) +family_configure_dual_usb_example(${PROJECT} ${RTOS}) # due to warnings from Pico-PIO-USB if (FAMILY STREQUAL rp2040) diff --git a/examples/dual/host_info_to_device_cdc/Makefile b/examples/dual/host_info_to_device_cdc/Makefile index 083c9169a..659cf6ff9 100644 --- a/examples/dual/host_info_to_device_cdc/Makefile +++ b/examples/dual/host_info_to_device_cdc/Makefile @@ -1,12 +1,12 @@ -include ../../build_system/make/make.mk +include ../../../hw/bsp/family_support.mk INC += \ src \ - $(TOP)/hw \ + # Example source EXAMPLE_SOURCE += $(wildcard src/*.c) -SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) +SRC_C += $(addprefix $(EXAMPLE_PATH)/, $(EXAMPLE_SOURCE)) CFLAGS_GCC += -Wno-error=cast-align -Wno-error=null-dereference @@ -14,4 +14,4 @@ SRC_C += \ src/host/hub.c \ src/host/usbh.c -include ../../build_system/make/rules.mk +include ../../../hw/bsp/family_rules.mk diff --git a/examples/dual/host_info_to_device_cdc/only.txt b/examples/dual/host_info_to_device_cdc/only.txt index 35f896f1e..4431065ba 100644 --- a/examples/dual/host_info_to_device_cdc/only.txt +++ b/examples/dual/host_info_to_device_cdc/only.txt @@ -8,3 +8,4 @@ mcu:MAX3421 mcu:STM32F4 mcu:STM32F7 mcu:STM32H7 +mcu:ESP32P4 diff --git a/examples/dual/host_info_to_device_cdc/src/CMakeLists.txt b/examples/dual/host_info_to_device_cdc/src/CMakeLists.txt new file mode 100644 index 000000000..cef2b46ee --- /dev/null +++ b/examples/dual/host_info_to_device_cdc/src/CMakeLists.txt @@ -0,0 +1,4 @@ +# This file is for ESP-IDF only +idf_component_register(SRCS "main.c" "usb_descriptors.c" + INCLUDE_DIRS "." + REQUIRES boards tinyusb_src) 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 67e905b9d..00d059b66 100644 --- a/examples/dual/host_info_to_device_cdc/src/main.c +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -69,14 +69,18 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -static bool is_print[CFG_TUH_DEVICE_MAX+1] = { 0 }; +static bool is_printable[CFG_TUH_DEVICE_MAX + 1] = {0}; static tusb_desc_device_t descriptor_device[CFG_TUH_DEVICE_MAX+1]; static void print_utf16(uint16_t *temp_buf, size_t buf_len); static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_device); -void led_blinking_task(void); -void cdc_task(void); +static void led_blinking_task(void); +static void cdc_task(void); + +#if CFG_TUSB_OS == OPT_OS_FREERTOS +static void freertos_init(void); +#endif #define cdc_printf(...) \ do { \ @@ -94,37 +98,90 @@ void cdc_task(void); } \ } while(0) -/*------------- MAIN -------------*/ -int main(void) { - board_init(); - - printf("TinyUSB Host Information -> Device CDC Example\r\n"); +static void usb_device_init(void) { // init device and host stack on configured roothub port tusb_rhport_init_t dev_init = { .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); + tud_cdc_configure_t cdc_cfg = TUD_CDC_CONFIGURE_DEFAULT(); + cdc_cfg.tx_persistent = true; + cdc_cfg.tx_overwritabe_if_not_connected = false; + tud_cdc_configure(&cdc_cfg); + board_init_after_tusb(); +} +static void usb_host_init(void) { + // init host stack on configured roothub port tusb_rhport_init_t host_init = { .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUH_RHPORT, &host_init); - board_init_after_tusb(); +} + +//--------------------------------------------------------------------+ +// Main +//--------------------------------------------------------------------+ +static void main_task(void* param) { + (void) param; while (1) { - tud_task(); // tinyusb device task - tuh_task(); // tinyusb host task cdc_task(); led_blinking_task(); + + // preempted RTOS run device/host stack in its own task +#if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO + tud_task(); // tinyusb device task + tuh_task(); // tinyusb host task +#endif } +} + +int main(void) { + board_init(); + +#if CFG_TUSB_OS == OPT_OS_NONE || CFG_TUSB_OS == OPT_OS_PICO + printf("TinyUSB Host Information -> Device CDC Example\r\n"); + + usb_device_init(); + usb_host_init(); + + main_task(NULL); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + freertos_init(); // create RTOS tasks for device, host stack and main_task() +#else + #error RTOS not supported +#endif return 0; } +#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO +// USB Device Driver task for RTOS +static void usb_device_task(void *param) { + (void) param; + usb_device_init(); + while (1) { + // put this thread to waiting state until there is new events + tud_task(); + } +} + +static void usb_host_task(void *param) { + (void) param; + usb_host_init(); + while (1) { + // put this thread to waiting state until there is new events + tuh_task(); + } +} +#endif + + //--------------------------------------------------------------------+ // Device CDC //--------------------------------------------------------------------+ @@ -153,17 +210,23 @@ void tud_resume_cb(void) { } void cdc_task(void) { + static uint32_t connected_ms = 0; + if (!tud_cdc_connected()) { - // delay a bit otherwise we can outpace host's terminal. Linux will set LineState (DTR) then Line Coding. - // If we send data before Linux's terminal set Line Coding, it can be ignored --> missing data with hardware test loop - board_delay(20); + connected_ms = board_millis(); return; } + // delay a bit otherwise we can outpace host's terminal. Linux will set LineState (DTR) then Line Coding. + // If we send data before Linux's terminal set Line Coding, it can be ignored --> missing data with hardware test loop + if (board_millis() - connected_ms < 100) { + return; // wait for stable connection + } + for (uint8_t daddr = 1; daddr <= CFG_TUH_DEVICE_MAX; daddr++) { if (tuh_mounted(daddr)) { - if (is_print[daddr]) { - is_print[daddr] = false; + if (is_printable[daddr]) { + is_printable[daddr] = false; print_device_info(daddr, &descriptor_device[daddr]); tud_cdc_write_flush(); } @@ -218,9 +281,7 @@ static void print_device_info(uint8_t daddr, const tusb_desc_device_t* desc_devi cdc_printf("\r\n"); cdc_printf(" iSerialNumber %u " , desc_device->iSerialNumber); - cdc_printf((char*)serial); // serial is already to UTF-8 - cdc_printf("\r\n"); - + cdc_printf("%s \r\n", (char*)serial); // serial is already to UTF-8 cdc_printf(" bNumConfigurations %u\r\n" , desc_device->bNumConfigurations); } @@ -232,13 +293,13 @@ void tuh_enum_descriptor_device_cb(uint8_t daddr, tusb_desc_device_t const* desc void tuh_mount_cb(uint8_t daddr) { cdc_printf("mounted device %u\r\n", daddr); tud_cdc_write_flush(); - is_print[daddr] = true; + is_printable[daddr] = true; } void tuh_umount_cb(uint8_t daddr) { cdc_printf("unmounted device %u\r\n", daddr); tud_cdc_write_flush(); - is_print[daddr] = false; + is_printable[daddr] = false; } //--------------------------------------------------------------------+ @@ -261,7 +322,6 @@ void led_blinking_task(void) { //--------------------------------------------------------------------+ // String Descriptor Helper //--------------------------------------------------------------------+ - static void _convert_utf16le_to_utf8(const uint16_t *utf16, size_t utf16_len, uint8_t *utf8, size_t utf8_len) { // TODO: Check for runover. (void)utf8_len; @@ -310,5 +370,55 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len) { _convert_utf16le_to_utf8(temp_buf + 1, utf16_len, (uint8_t *) temp_buf, sizeof(uint16_t) * buf_len); ((uint8_t*) temp_buf)[utf8_len] = '\0'; - cdc_printf((char*) temp_buf); + cdc_printf("%s", (char*) temp_buf); } + +//--------------------------------------------------------------------+ +// FreeRTOS +//--------------------------------------------------------------------+ +#if CFG_TUSB_OS == OPT_OS_FREERTOS + +#ifdef ESP_PLATFORM + #define USBD_STACK_SIZE 4096 + #define USBH_STACK_SIZE 4096 + void app_main(void) { + main(); + } +#else + // Increase stack size when debug log is enabled + #define USBD_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 4 : 2)) + #define USBH_STACK_SIZE (configMINIMAL_STACK_SIZE * (CFG_TUSB_DEBUG ? 4 : 2)) +#endif + +#define MAIN_STACK_SIZE (configMINIMAL_STACK_SIZE*4) + +// static task +#if configSUPPORT_STATIC_ALLOCATION +StackType_t main_stack[MAIN_STACK_SIZE]; +StaticTask_t main_taskdef; + +StackType_t usb_device_stack[USBD_STACK_SIZE]; +StaticTask_t usb_device_taskdef; + +StackType_t usb_host_stack[USBH_STACK_SIZE]; +StaticTask_t usb_host_taskdef; +#endif + +void freertos_init(void) { + #if configSUPPORT_STATIC_ALLOCATION + xTaskCreateStatic(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_device_stack, &usb_device_taskdef); + xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef); + xTaskCreateStatic(main_task, "main", MAIN_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, main_stack, &main_taskdef); + #else + xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(main_task, "main", MAIN_STACK_SIZE, NULL, configMAX_PRIORITIES - 2, NULL); + #endif + + // only start scheduler for non-espressif mcu + #ifndef ESP_PLATFORM + vTaskStartScheduler(); + #endif +} + +#endif diff --git a/examples/dual/host_info_to_device_cdc/src/tusb_config.h b/examples/dual/host_info_to_device_cdc/src/tusb_config.h index bb47fbf4a..601c27dae 100644 --- a/examples/dual/host_info_to_device_cdc/src/tusb_config.h +++ b/examples/dual/host_info_to_device_cdc/src/tusb_config.h @@ -112,7 +112,7 @@ // 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) +#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 256) // CDC Endpoint transfer buffer size, more is faster #define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c b/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c index 9d57737fb..3efa30e20 100644 --- a/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c +++ b/examples/dual/host_info_to_device_cdc/src/usb_descriptors.c @@ -32,9 +32,9 @@ * Auto ProductID layout's Bitmap: * [MSB] HID | MSC | CDC [LSB] */ -#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) -#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ - _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) +#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) +#define USB_PID (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | \ + PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) ) #define USB_VID 0xCafe #define USB_BCD 0x0200 @@ -42,7 +42,7 @@ //--------------------------------------------------------------------+ // Device Descriptors //--------------------------------------------------------------------+ -tusb_desc_device_t const desc_device = { +static tusb_desc_device_t const desc_device = { .bLength = sizeof(tusb_desc_device_t), .bDescriptorType = TUSB_DESC_DEVICE, .bcdUSB = USB_BCD, @@ -122,7 +122,7 @@ enum { #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) // full speed configuration -uint8_t const desc_fs_configuration[] = { +static 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), @@ -134,7 +134,7 @@ uint8_t const desc_fs_configuration[] = { // Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration // high speed configuration -uint8_t const desc_hs_configuration[] = { +static 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), @@ -143,10 +143,10 @@ uint8_t const desc_hs_configuration[] = { }; // other speed configuration -uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN]; +static 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 = { +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, @@ -175,7 +175,7 @@ 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 + // Note: the descriptor type is OTHER_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); |
