From 65c35de215df7bd4a190d2f94f5f6e2ca34e9614 Mon Sep 17 00:00:00 2001 From: andy <1414772332@qq.com> Date: Wed, 24 Sep 2025 00:05:38 +0800 Subject: [PATCH] =?UTF-8?q?usb=E9=80=9A=E4=BF=A1=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cdc_dual_ports/src/usb_descriptors.c | 4 +- lib/rt-thread/tusb_rt_thread_port.c | 82 ++++++++++++++++++- src/class/cdc/cdc_device.c | 1 + src/osal/osal_rtthread.h | 24 ++++-- src/portable/synopsys/dwc2/dwc2_common.c | 4 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 2 +- 6 files changed, 103 insertions(+), 14 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index 15b0f053c..67ebff2d2 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -36,7 +36,7 @@ #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 0x0843 +#define USB_VID 0xcafe #define USB_BCD 0x0200 //--------------------------------------------------------------------+ @@ -217,7 +217,7 @@ char const *string_desc_arr[] = { (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) "TinyUSB", // 1: Manufacturer "TinyUSB Device", // 2: Product - NULL, // 3: Serials will use unique ID if possible + "20250922", // 3: Serials will use unique ID if possible "TinyUSB CDC", // 4: CDC Interface }; diff --git a/lib/rt-thread/tusb_rt_thread_port.c b/lib/rt-thread/tusb_rt_thread_port.c index d123a1007..d2244b6ef 100644 --- a/lib/rt-thread/tusb_rt_thread_port.c +++ b/lib/rt-thread/tusb_rt_thread_port.c @@ -28,6 +28,7 @@ #include "bsp_init.h" #include "stm32f4xx.h" #include "dcd.h" +#include #define DBG_TAG "TinyUSB" #define DBG_LVL DBG_INFO @@ -40,6 +41,10 @@ static rt_uint8_t tusb_stack[PKG_TINYUSB_STACK_SIZE]; static struct rt_thread tusb_thread; #endif /* RT_USING_HEAP */ + +struct rt_semaphore g_dcd_sem; + + int tusb_board_init(void) { GPIO_InitTypeDef GPIO_InitStructure; @@ -83,12 +88,21 @@ static void tusb_thread_entry(void *parameter) #endif } } +static void cdc_task(void *parameter); static int init_tinyusb(void) { rt_thread_t tid; - + RCC_ClocksTypeDef rcc = {0}; + RCC_GetClocksFreq(&rcc); + rt_kprintf("TinyUSB init... \r\n"); + rt_kprintf("rcc.SYSCLK_Frequency=%d Hz\r\n", rcc.SYSCLK_Frequency); + rt_kprintf("rcc.HCLK_Frequency=%d Hz\r\n", rcc.HCLK_Frequency); + rt_kprintf("rcc.PCLK1_Frequency=%d Hz\r\n", rcc.PCLK1_Frequency); + rt_kprintf("rcc.PCLK2_Frequency=%d Hz\r\n", rcc.PCLK2_Frequency); + rt_kprintf("rcc.USBCLK_Frequency=%d Hz\r\n", rcc.USBCLK_Frequency); tusb_board_init(); + rt_sem_init(&g_dcd_sem, "tusb_cdc", 0, RT_IPC_FLAG_PRIO); //call tusb_rhport_init() tusb_init(); @@ -99,7 +113,7 @@ static int init_tinyusb(void) #ifdef RT_USING_HEAP tid = rt_thread_create("tusb", tusb_thread_entry, RT_NULL, 2048, - 5, 10); + 1, 10); if (tid == RT_NULL) #else rt_err_t result; @@ -116,8 +130,72 @@ static int init_tinyusb(void) rt_thread_startup(tid); + tid = rt_thread_create("tusb_cdc", cdc_task, RT_NULL, + 2048, + 6, 10); + rt_thread_startup(tid); + return 0; } // INIT_APP_EXPORT(init_tinyusb); extern_init(tinyusb, init_tinyusb); + + + +static void echo_serial_port(uint8_t itf, uint8_t buf[], uint32_t count) { + uint8_t const case_diff = 'a' - 'A'; + + for (uint32_t i = 0; i < count; i++) { + if (itf == 0) { + // echo back 1st port as lower case + if (isupper(buf[i])) buf[i] += case_diff; + } else { + // echo back 2nd port as upper case + if (islower(buf[i])) buf[i] -= case_diff; + } + + tud_cdc_n_write_char(itf, buf[i]); + } + tud_cdc_n_write_flush(itf); +} + + + + +// notify cdc task recv data +void tud_cdc_rx_cb(uint8_t itf){ + TU_LOG(2, "tud_cdc_rx_cb\r\n"); + rt_sem_release(&g_dcd_sem); +} + + +static void cdc_task(void *parameter) { + TU_LOG(2, "CDC task started\r\n"); + while(1){ + rt_sem_take(&g_dcd_sem, RT_WAITING_FOREVER); + TU_LOG(2, "tud_cdc_rx_take\r\n"); + 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); + } + + } + } + } +} + + + + + + #endif /*__RTTHREAD__*/ diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 4e4e01eaf..4677ffaa3 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -340,6 +340,7 @@ uint16_t cdcd_open(uint8_t rhport, const tusb_desc_interface_t* itf_desc, uint16 // Only support ACM subclass TU_VERIFY( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass, 0); + TU_LOG(2,"CDC Interface %u\r\n", itf_desc->bInterfaceNumber); // Find available interface cdcd_interface_t* p_cdc; diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h index 2336fd090..3f3f4d53e 100644 --- a/src/osal/osal_rtthread.h +++ b/src/osal/osal_rtthread.h @@ -35,6 +35,14 @@ extern "C" { #endif + +// Enable device interrupt +extern void dcd_int_enable (uint8_t rhport); + +// Disable device interrupt +extern void dcd_int_disable(uint8_t rhport); + + //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ @@ -51,24 +59,21 @@ typedef struct rt_mutex osal_spinlock_t; osal_spinlock_t _name TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { - // rt_spin_lock_init(ctx); - rt_mutex_init(ctx, "tusb", RT_IPC_FLAG_PRIO); + } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } - // rt_spin_lock(ctx); - rt_mutex_take(ctx, RT_WAITING_FOREVER); + dcd_int_disable(1); } TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { if (!TUP_MCU_MULTIPLE_CORE && in_isr) { return; // single core MCU does not need to lock in ISR } - // rt_spin_unlock(ctx); - rt_mutex_release(ctx); + dcd_int_enable(1); } //--------------------------------------------------------------------+ @@ -163,7 +168,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { (void) in_isr; - return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; + int ret; + ret = rt_mq_send(qhdl, (void *) data, qhdl->msg_size); + if (ret != RT_EOK) { + rt_kprintf("osal_queue_send failed ret=%d\n", ret); + } + return ret == RT_EOK; } TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 57ad7545f..73e6767ef 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -85,9 +85,9 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~GUSBCFG_TRDT_Msk; gusbcfg |= 5u << GUSBCFG_TRDT_Pos; // force to device mode - gusbcfg |= GUSBCFG_FDMOD; + // gusbcfg |= GUSBCFG_FDMOD; dwc2->gusbcfg = gusbcfg; - osal_task_delay(50); + // osal_task_delay(50); // MCU specific PHY update post reset dwc2_phy_update(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index e4f5363fb..55475cfd7 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -273,7 +273,7 @@ static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { turnaround = 0xCu; } else if (SystemCoreClock >= 16000000u) { - turnaround = 0xfu; + turnaround = 0xdu; } else if (SystemCoreClock >= 15000000u) { turnaround = 0xEu;