From c6204620f42faa0d4fd9d24f51f36cc0baa5020d Mon Sep 17 00:00:00 2001 From: ranchuan Date: Fri, 26 Sep 2025 16:45:54 +0800 Subject: [PATCH] =?UTF-8?q?usb=5Fnet=E7=BC=96=E8=AF=91=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/device/cdc_dual_ports/src/main.c | 56 ++++++- .../device/net_lwip_webserver/src/arch/cc.h | 2 +- .../device/net_lwip_webserver/src/lwipopts.h | 8 +- examples/device/net_lwip_webserver/src/main.c | 138 +++++++++++++++--- .../net_lwip_webserver/src/tusb_config.h | 20 ++- .../net_lwip_webserver/src/usb_descriptors.c | 1 + src/class/net/ncm_device.c | 4 +- 7 files changed, 196 insertions(+), 33 deletions(-) diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index 5a3e18358..745f9a616 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -23,6 +23,13 @@ * */ +#include +#include "bsp_init.h" +#include "stm32f4xx.h" +#include "dcd.h" +#include + + #include #include #include @@ -47,8 +54,55 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; static void led_blinking_task(void); static void cdc_task(void); + + +int tusb_board_init(void) { + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_OTG_HS, ENABLE); + + GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_OTG2_FS); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_OTG2_FS); + + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + // no need enable irq, it will be enabled in dwc2_dcd_int_enable() + return 0; +} + +void usb_irq_enable(){ + NVIC_InitTypeDef NVIC_InitStructure; + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + +static void tusb_thread_entry(void *parameter) +{ + (void) parameter; + while (1) + { +#if CFG_TUH_ENABLED + tuh_task(); +#endif +#if CFG_TUD_ENABLED + tud_task(); +#endif + } +} + + + /*------------- MAIN -------------*/ -int main(void) { +int main_task(void) { board_init(); // init device stack on configured roothub port diff --git a/examples/device/net_lwip_webserver/src/arch/cc.h b/examples/device/net_lwip_webserver/src/arch/cc.h index 9f30b91cb..9caec339e 100644 --- a/examples/device/net_lwip_webserver/src/arch/cc.h +++ b/examples/device/net_lwip_webserver/src/arch/cc.h @@ -34,7 +34,7 @@ //#include "cpu.h" -typedef int sys_prot_t; +// typedef int sys_prot_t; diff --git a/examples/device/net_lwip_webserver/src/lwipopts.h b/examples/device/net_lwip_webserver/src/lwipopts.h index 04949cef9..09fc44d96 100644 --- a/examples/device/net_lwip_webserver/src/lwipopts.h +++ b/examples/device/net_lwip_webserver/src/lwipopts.h @@ -32,12 +32,14 @@ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ +#include "rtdef.h" + /* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ -#define NO_SYS 1 +#define NO_SYS 0 #define MEM_ALIGNMENT 4 #define LWIP_RAW 0 #define LWIP_NETCONN 0 -#define LWIP_SOCKET 0 +#define LWIP_SOCKET 1 #define LWIP_DHCP 0 #define LWIP_ICMP 1 #define LWIP_UDP 1 @@ -68,5 +70,7 @@ #define LWIP_BROADCAST_PING 1 #define LWIP_IPV6_MLD 0 #define LWIP_IPV6_SEND_ROUTER_SOLICIT 0 +#define LWIP_TIMEVAL_PRIVATE 0 +// #define _TIMEVAL_DEFINED 1 #endif /* __LWIPOPTS_H__ */ diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 4bdddf6c5..7a15c727f 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -49,12 +49,18 @@ The smartphone may be artificially picky about which Ethernet MAC address to rec try changing the first byte of tud_network_mac_address[] below from 0x02 to 0x00 (clearing bit 1). */ +#include +#include "bsp_init.h" +#include "stm32f4xx.h" +#include "dcd.h" + + #include "bsp/board_api.h" #include "tusb.h" #include "dhserver.h" #include "dnserver.h" -#include "httpd.h" +#include "lwip/apps/httpd.h" #include "lwip/ethip6.h" #include "lwip/init.h" #include "lwip/timeouts.h" @@ -187,7 +193,7 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { struct pbuf *p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); if (p == NULL) { - printf("ERROR: Failed to allocate pbuf of size %d\n", size); + TU_LOG(2,"ERROR: Failed to allocate pbuf of size %d\n", size); return false; } @@ -199,7 +205,7 @@ bool tud_network_recv_cb(const uint8_t *src, uint16_t size) { // 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"); + TU_LOG(2,"ERROR: netif input failed\n"); pbuf_free(p); } // Signal tinyusb that the current frame has been processed. @@ -227,10 +233,10 @@ static void handle_link_state_switch(void) { /* Button pressed - toggle link state */ last_link_state = !last_link_state; if (last_link_state) { - printf("Link state: UP\n"); + TU_LOG(2,"Link state: UP\n"); netif_set_link_up(&netif_data); } else { - printf("Link state: DOWN\n"); + TU_LOG(2,"Link state: DOWN\n"); netif_set_link_down(&netif_data); } /* LWIP callback will notify USB host about the change */ @@ -239,9 +245,72 @@ static void handle_link_state_switch(void) { } -int main(void) { + + +int tusb_board_init(void) { + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_OTG_HS, ENABLE); + + GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_OTG2_FS); + GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_OTG2_FS); + + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + // no need enable irq, it will be enabled in dwc2_dcd_int_enable() + return 0; +} + +void usb_irq_enable(){ + NVIC_InitTypeDef NVIC_InitStructure; + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); + NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + + + + + +static void tusb_thread_entry(void *parameter) +{ + (void) parameter; + while (1) + { +#if CFG_TUH_ENABLED + tuh_task(); +#endif +#if CFG_TUD_ENABLED + tud_task(); +#endif + } +} + + + + + + +int init_tinyusb(void) { /* initialize TinyUSB */ - board_init(); + 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(); // init device stack on configured roothub port tusb_rhport_init_t dev_init = { @@ -249,6 +318,7 @@ int main(void) { .speed = TUSB_SPEED_AUTO }; tusb_init(BOARD_TUD_RHPORT, &dev_init); + usb_irq_enable(); if (board_init_after_tusb) { board_init_after_tusb(); @@ -267,30 +337,50 @@ int main(void) { #endif #if CFG_TUD_NCM - printf("USB NCM network interface initialized\n"); + TU_LOG(2,"USB NCM network interface initialized\n"); #elif CFG_TUD_ECM_RNDIS - printf("USB RNDIS/ECM network interface initialized\n"); + TU_LOG(2,"USB RNDIS/ECM network interface initialized\n"); #endif - while (1) { - tud_task(); - sys_check_timeouts(); // service lwip - handle_link_state_switch(); - } + #ifdef RT_USING_HEAP + tid = rt_thread_create("tusb", tusb_thread_entry, RT_NULL, + 2048, + 1, 10); + if (tid == RT_NULL) + #else + rt_err_t result; + + tid = &tusb_thread; + result = rt_thread_init(tid, "tusb", tusb_thread_entry, RT_NULL, + tusb_stack, sizeof(tusb_stack), 4, 10); + if (result != RT_EOK) +#endif /* RT_USING_HEAP */ + { + TU_LOG(2,"Fail to create TinyUSB thread"); + return -1; + } + + rt_thread_startup(tid); + // while (1) { + // tud_task(); + // // sys_check_timeouts(); // service lwip + // // handle_link_state_switch(); + // } return 0; } +extern_init(tinyusb, init_tinyusb); /* 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; -} -void sys_arch_unprotect(sys_prot_t pval) { - (void) pval; -} +// sys_prot_t sys_arch_protect(void) { +// return 0; +// } +// void sys_arch_unprotect(sys_prot_t pval) { +// (void) pval; +// } -/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ -uint32_t sys_now(void) { - return board_millis(); -} +// /* lwip needs a millisecond time source, and the TinyUSB board support code has one available */ +// uint32_t sys_now(void) { +// return board_millis(); +// } diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index c774f59ff..0befbb365 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -38,7 +38,7 @@ extern "C" { // RHPort number used for device can be defined by board.mk, default to port 0 #ifndef BOARD_TUD_RHPORT - #define BOARD_TUD_RHPORT 0 + #define BOARD_TUD_RHPORT 1 #endif // RHPort max operational speed can defined by board.mk @@ -50,17 +50,19 @@ extern "C" { // Common Configuration //-------------------------------------------------------------------- + +#define CFG_TUSB_MCU OPT_MCU_STM32F4 // defined by compiler flags for flexibility #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif #ifndef CFG_TUSB_OS - #define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_OS OPT_OS_RTTHREAD #endif #ifndef CFG_TUSB_DEBUG - #define CFG_TUSB_DEBUG 0 + #define CFG_TUSB_DEBUG 3 #endif // Enable Device stack @@ -68,6 +70,18 @@ extern "C" { // Default is max speed that hardware controller could support with on-chip PHY #define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED + // fs is 0; hs is 1 + #ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 1 + #endif + + #if BOARD_DEVICE_RHPORT_NUM == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) + #elif BOARD_DEVICE_RHPORT_NUM == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) + #else + #error "Incorrect RHPort configuration" + #endif /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. * Tinyusb use follows macros to declare transferring memory so that they can be put diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index cd800f521..de7b89953 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -25,6 +25,7 @@ #include "bsp/board_api.h" #include "tusb.h" +#include "net_device.h" /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 02833c5f1..858a0f4c3 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -368,7 +368,7 @@ static void xmit_start_if_possible(uint8_t rhport) { #if CFG_TUD_NCM_LOG_LEVEL >= 3 { uint16_t len = ncm_interface.xmit_tinyusb_ntb->nth.wBlockLength; - TU_LOG_BUF(3, ncm_interface.xmit_tinyusb_ntb->data[i], len); + TU_LOG_BUF(3, ncm_interface.xmit_tinyusb_ntb->data, len); } #endif @@ -612,7 +612,7 @@ static bool recv_validate_datagram(const recv_ntb_t *ntb, uint32_t len) { } #if CFG_TUD_NCM_LOG_LEVEL >= 3 - TU_LOG_BUF(3, ntb->data[i], len); + TU_LOG_BUF(3, ntb->data, len); #endif // -> ntb contains a valid packet structure