diff --git a/Kconfig.cherryusb b/Kconfig.cherryusb index c559fa83..aae7cb00 100644 --- a/Kconfig.cherryusb +++ b/Kconfig.cherryusb @@ -197,19 +197,22 @@ if CHERRYUSB prompt "Enable usb msc driver" default n - config CHERRYUSB_HOST_CDC_RNDIS - bool - prompt "Enable usb rndis driver" - default n - config CHERRYUSB_HOST_CDC_ECM bool prompt "Enable usb cdc ecm driver" + select USBHOST_PLATFORM_CDC_ECM + default n + + config CHERRYUSB_HOST_CDC_RNDIS + bool + prompt "Enable usb rndis driver" + select USBHOST_PLATFORM_CDC_RNDIS default n config CHERRYUSB_HOST_CDC_NCM bool prompt "Enable usb cdc ncm driver" + select USBHOST_PLATFORM_CDC_NCM default n config CHERRYUSB_HOST_VIDEO @@ -230,11 +233,13 @@ if CHERRYUSB config CHERRYUSB_HOST_ASIX bool prompt "Enable usb asix driver" + select USBHOST_PLATFORM_ASIX default n config CHERRYUSB_HOST_RTL8152 bool prompt "Enable usb rtl8152 driver" + select USBHOST_PLATFORM_RTL8152 default n config CHERRYUSB_HOST_FTDI @@ -252,6 +257,26 @@ if CHERRYUSB prompt "Enable usb cp210x driver" default n + config CHERRYUSB_HOST_PL2303 + bool + prompt "Enable usb pl2303 driver" + default n + + config USBHOST_PLATFORM_CDC_ECM + bool + + config USBHOST_PLATFORM_CDC_RNDIS + bool + + config USBHOST_PLATFORM_CDC_NCM + bool + + config USBHOST_PLATFORM_ASIX + bool + + config USBHOST_PLATFORM_RTL152 + bool + config CHERRYUSB_HOST_TEMPLATE bool prompt "Use usb host template" @@ -270,34 +295,9 @@ if CHERRYUSB depends on CHERRYUSB_HOST_HID config TEST_USBH_MSC int - prompt "demo for test msc, do not enable because it has used dfs instead" + prompt "demo for test msc" default 0 depends on CHERRYUSB_HOST_MSC - config TEST_USBH_CDC_ECM - int - prompt "demo for test cdc ecm" - default 0 - depends on CHERRYUSB_HOST_CDC_ECM - config TEST_USBH_CDC_NCM - int - prompt "demo for test cdc ncm" - default 0 - depends on CHERRYUSB_HOST_CDC_NCM - config TEST_USBH_RNDIS - int - prompt "demo for test cdc rndis" - default 0 - depends on CHERRYUSB_HOST_CDC_RNDIS - config TEST_USBH_ASIX - int - prompt "demo for test asix" - default 0 - depends on CHERRYUSB_HOST_ASIX - config TEST_USBH_RTL8152 - int - prompt "demo for test rtl8152" - default 0 - depends on CHERRYUSB_HOST_RTL8152 endif endif diff --git a/README.md b/README.md index 2c3f2900..77daee4b 100644 --- a/README.md +++ b/README.md @@ -36,27 +36,14 @@ Taking into account USB performance issues and trying to achieve the theoretical ## Directoy Structure -``` -. -├── class -├── common -├── core -├── demo -├── docs -├── osal -├── packet capture -└── port -└── tools - -``` - | Directory | Description | |:-------------:|:---------------------------:| |class | usb class driver | |common | usb spec macros and utils | |core | usb core implementation | -|demo | different chips demo | +|demo | usb device and host demo | |osal | os wrapper | +|platform | class support for other os | |docs | doc for guiding | |port | usb dcd and hcd porting | |tools | tool url | diff --git a/README_zh.md b/README_zh.md index b6b26c1e..a59649e0 100644 --- a/README_zh.md +++ b/README_zh.md @@ -36,26 +36,15 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 ## 目录结构 -``` -. -├── class -├── common -├── core -├── demo -├── docs -├── osal -└── port -└── tools -``` - | 目录名 | 描述 | |:-------------:|:-------------------------------:| |class | usb class 类主从驱动 | |common | usb spec 定义、常用宏、标准接口定义 | |core | usb 主从协议栈核心实现 | -|demo | 示例 | +|demo | 主从 class demo | |docs | 文档 | |osal | os 封装层 | +|platform | 其他 os 全家桶适配 | |port | usb 主从需要实现的 porting 接口 | |tools | 工具链接 | diff --git a/SConscript b/SConscript index c4998332..ee49e272 100644 --- a/SConscript +++ b/SConscript @@ -191,11 +191,18 @@ if GetDepend(['PKG_CHERRYUSB_HOST']): if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']): src += Glob('demo/usb_host.c') - if GetDepend('RT_USING_DFS'): - src += Glob('third_party/rt-thread-5.0/dfs_usbh_msc.c') + if GetDepend('RT_USING_DFS') and GetDepend(['PKG_CHERRYUSB_HOST_MSC']): + src += Glob('platform/rtthread/usbh_dfs.c') -src += Glob('third_party/rt-thread-5.0/usb_msh.c') -src += Glob('third_party/rt-thread-5.0/usb_check.c') + if GetDepend('PKG_CHERRYUSB_HOST_CDC_ECM') \ + or GetDepend('PKG_CHERRYUSB_HOST_CDC_RNDIS') \ + or GetDepend('PKG_CHERRYUSB_HOST_CDC_NCM') \ + or GetDepend('PKG_CHERRYUSB_HOST_CDC_ASIX') \ + or GetDepend('PKG_CHERRYUSB_HOST_CDC_RTL8152'): + src += Glob('platform/rtthread/usbh_lwip.c') + +src += Glob('platform/rtthread/usb_msh.c') +src += Glob('platform/rtthread/usb_check.c') group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES) diff --git a/class/cdc/usbh_cdc_ecm.c b/class/cdc/usbh_cdc_ecm.c index b115bcf8..5e3ae7bc 100644 --- a/class/cdc/usbh_cdc_ecm.c +++ b/class/cdc/usbh_cdc_ecm.c @@ -230,14 +230,6 @@ void usbh_cdc_ecm_rx_thread(void *argument) { uint32_t g_cdc_ecm_rx_length; int ret; - err_t err; - struct pbuf *p; -#if LWIP_TCPIP_CORE_LOCKING_INPUT - pbuf_type type = PBUF_ROM; -#else - pbuf_type type = PBUF_POOL; -#endif - struct netif *netif = (struct netif *)argument; USB_LOG_INFO("Create cdc ecm rx thread\r\n"); // clang-format off @@ -269,23 +261,9 @@ find_class: if (g_cdc_ecm_rx_length % USB_GET_MAXPACKETSIZE(g_cdc_ecm_class.bulkin->wMaxPacketSize)) { USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_length); - p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_length, type); - if (p != NULL) { -#if LWIP_TCPIP_CORE_LOCKING_INPUT - p->payload = g_cdc_ecm_rx_buffer; -#else - memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length); -#endif - g_cdc_ecm_rx_length = 0; + usbh_cdc_ecm_eth_input(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length); - err = netif->input(p, netif); - if (err != ERR_OK) { - pbuf_free(p); - } - } else { - g_cdc_ecm_rx_length = 0; - USB_LOG_ERR("No memory to alloc pbuf for cdc ecm rx\r\n"); - } + g_cdc_ecm_rx_length = 0; } else { /* read continue util read short packet */ if (g_cdc_ecm_rx_length > CONFIG_USBHOST_CDC_ECM_ETH_MAX_SIZE) { @@ -301,30 +279,20 @@ delete: // clang-format on } -err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p) +int usbh_cdc_ecm_eth_output(uint8_t *buf, uint32_t buflen) { - int ret; - struct pbuf *q; uint8_t *buffer = g_cdc_ecm_tx_buffer; if (g_cdc_ecm_class.connect_status == false) { - return ERR_BUF; + return -USB_ERR_NOTCONN; } - for (q = p; q != NULL; q = q->next) { - memcpy(buffer, q->payload, q->len); - buffer += q->len; - } + memcpy(buffer, buf, buflen); - USB_LOG_DBG("txlen:%d\r\n", p->tot_len); + USB_LOG_DBG("txlen:%d\r\n", buflen); - usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, p->tot_len, USB_OSAL_WAITING_FOREVER, NULL, NULL); - ret = usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb); - if (ret < 0) { - return ERR_BUF; - } - - return ERR_OK; + usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.hport, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, buflen, USB_OSAL_WAITING_FOREVER, NULL, NULL); + return usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb); } __WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) diff --git a/class/cdc/usbh_cdc_ecm.h b/class/cdc/usbh_cdc_ecm.h index 6066bd05..d965ac88 100644 --- a/class/cdc/usbh_cdc_ecm.h +++ b/class/cdc/usbh_cdc_ecm.h @@ -8,9 +8,6 @@ #include "usb_cdc.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" - struct usbh_cdc_ecm { struct usbh_hubport *hport; struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ @@ -29,10 +26,6 @@ struct usbh_cdc_ecm { uint16_t max_segment_size; uint32_t speed[2]; - ip_addr_t ipaddr; - ip_addr_t netmask; - ip_addr_t gateway; - void *user_data; }; @@ -45,7 +38,8 @@ int usbh_cdc_ecm_get_connect_status(struct usbh_cdc_ecm *cdc_ecm_class); void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class); void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class); -err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p); +int usbh_cdc_ecm_eth_output(uint8_t *buf, uint32_t buflen); +void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen); void usbh_cdc_ecm_rx_thread(void *argument); #ifdef __cplusplus diff --git a/class/cdc/usbh_cdc_ncm.c b/class/cdc/usbh_cdc_ncm.c index f6e43af3..4f13f791 100644 --- a/class/cdc/usbh_cdc_ncm.c +++ b/class/cdc/usbh_cdc_ncm.c @@ -248,14 +248,6 @@ void usbh_cdc_ncm_rx_thread(void *argument) { uint32_t g_cdc_ncm_rx_length; int ret; - err_t err; - struct pbuf *p; -#if LWIP_TCPIP_CORE_LOCKING_INPUT - pbuf_type type = PBUF_ROM; -#else - pbuf_type type = PBUF_POOL; -#endif - struct netif *netif = (struct netif *)argument; USB_LOG_INFO("Create cdc ncm rx thread\r\n"); // clang-format off @@ -311,20 +303,8 @@ find_class: if (ndp16_datagram->wDatagramIndex && ndp16_datagram->wDatagramLength) { USB_LOG_DBG("ndp16_datagram index:%02x, length:%02x\r\n", ndp16_datagram->wDatagramIndex, ndp16_datagram->wDatagramLength); - p = pbuf_alloc(PBUF_RAW, ndp16_datagram->wDatagramLength, type); - if (p != NULL) { -#if LWIP_TCPIP_CORE_LOCKING_INPUT - p->payload = (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex]; -#else - memcpy(p->payload, (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex], ndp16_datagram->wDatagramLength); -#endif - err = netif->input(p, netif); - if (err != ERR_OK) { - pbuf_free(p); - } - } else { - USB_LOG_ERR("No memory to alloc pbuf for cdc ncm rx\r\n"); - } + uint8_t *buf = (uint8_t *)&g_cdc_ncm_rx_buffer[ndp16_datagram->wDatagramIndex]; + usbh_cdc_ncm_eth_input(buf, ndp16_datagram->wDatagramLength); } } @@ -344,15 +324,13 @@ delete: // clang-format on } -err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p) +int usbh_cdc_ncm_eth_output(uint8_t *buf, uint32_t buflen) { - int ret; - struct pbuf *q; uint8_t *buffer; struct cdc_ncm_ndp16_datagram *ndp16_datagram; if (g_cdc_ncm_class.connect_status == false) { - return ERR_BUF; + return -USB_ERR_NOTCONN; } struct cdc_ncm_nth16 *nth16 = (struct cdc_ncm_nth16 *)&g_cdc_ncm_tx_buffer[0]; @@ -360,8 +338,8 @@ err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p) nth16->dwSignature = CDC_NCM_NTH16_SIGNATURE; nth16->wHeaderLength = 12; nth16->wSequence = g_cdc_ncm_class.bulkout_sequence++; - nth16->wBlockLength = 16 + 16 + USB_ALIGN_UP(p->tot_len, 4); - nth16->wNdpIndex = 16 + USB_ALIGN_UP(p->tot_len, 4); + nth16->wBlockLength = 16 + 16 + USB_ALIGN_UP(buflen, 4); + nth16->wNdpIndex = 16 + USB_ALIGN_UP(buflen, 4); struct cdc_ncm_ndp16 *ndp16 = (struct cdc_ncm_ndp16 *)&g_cdc_ncm_tx_buffer[nth16->wNdpIndex]; @@ -371,28 +349,19 @@ err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p) ndp16_datagram = (struct cdc_ncm_ndp16_datagram *)&g_cdc_ncm_tx_buffer[nth16->wNdpIndex + 8 + 4 * 0]; ndp16_datagram->wDatagramIndex = 16; - ndp16_datagram->wDatagramLength = p->tot_len; + ndp16_datagram->wDatagramLength = buflen; ndp16_datagram = (struct cdc_ncm_ndp16_datagram *)&g_cdc_ncm_tx_buffer[nth16->wNdpIndex + 8 + 4 * 1]; ndp16_datagram->wDatagramIndex = 0; ndp16_datagram->wDatagramLength = 0; buffer = &g_cdc_ncm_tx_buffer[16]; - - for (q = p; q != NULL; q = q->next) { - memcpy(buffer, q->payload, q->len); - buffer += q->len; - } + memcpy(buffer, buf, buflen); USB_LOG_DBG("txlen:%d\r\n", nth16->wBlockLength); usbh_bulk_urb_fill(&g_cdc_ncm_class.bulkout_urb, g_cdc_ncm_class.hport, g_cdc_ncm_class.bulkout, g_cdc_ncm_tx_buffer, nth16->wBlockLength, USB_OSAL_WAITING_FOREVER, NULL, NULL); - ret = usbh_submit_urb(&g_cdc_ncm_class.bulkout_urb); - if (ret < 0) { - return ERR_BUF; - } - - return ERR_OK; + return usbh_submit_urb(&g_cdc_ncm_class.bulkout_urb); } __WEAK void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class) diff --git a/class/cdc/usbh_cdc_ncm.h b/class/cdc/usbh_cdc_ncm.h index b3cc7d49..5f069401 100644 --- a/class/cdc/usbh_cdc_ncm.h +++ b/class/cdc/usbh_cdc_ncm.h @@ -8,9 +8,6 @@ #include "usb_cdc.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" - struct usbh_cdc_ncm { struct usbh_hubport *hport; struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ @@ -33,10 +30,6 @@ struct usbh_cdc_ncm { uint16_t max_segment_size; uint32_t speed[2]; - ip_addr_t ipaddr; - ip_addr_t netmask; - ip_addr_t gateway; - void *user_data; }; @@ -49,7 +42,8 @@ int usbh_cdc_ncm_get_connect_status(struct usbh_cdc_ncm *cdc_ncm_class); void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class); void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class); -err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p); +int usbh_cdc_ncm_eth_output(uint8_t *buf, uint32_t buflen); +void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen); void usbh_cdc_ncm_rx_thread(void *argument); #ifdef __cplusplus diff --git a/class/vendor/net/usbh_asix.c b/class/vendor/net/usbh_asix.c index a820f4da..62d78ec3 100644 --- a/class/vendor/net/usbh_asix.c +++ b/class/vendor/net/usbh_asix.c @@ -653,16 +653,8 @@ void usbh_asix_rx_thread(void *argument) { uint32_t g_asix_rx_length; int ret; - err_t err; uint16_t len; uint16_t len_crc; - struct pbuf *p; -#if LWIP_TCPIP_CORE_LOCKING_INPUT - pbuf_type type = PBUF_ROM; -#else - pbuf_type type = PBUF_POOL; -#endif - struct netif *netif = (struct netif *)argument; USB_LOG_INFO("Create asix rx thread\r\n"); // clang-format off @@ -702,23 +694,9 @@ find_class: USB_LOG_DBG("rxlen:%d\r\n", g_asix_rx_length); - p = pbuf_alloc(PBUF_RAW, len, type); - if (p != NULL) { -#if LWIP_TCPIP_CORE_LOCKING_INPUT - p->payload = (uint8_t *)&g_asix_rx_buffer[4]; -#else - memcpy(p->payload, (uint8_t *)&g_asix_rx_buffer[4], len); -#endif - g_asix_rx_length = 0; - - err = netif->input(p, netif); - if (err != ERR_OK) { - pbuf_free(p); - } - } else { - g_asix_rx_length = 0; - USB_LOG_ERR("No memory to alloc pbuf for asix rx\r\n"); - } + uint8_t *buf = (uint8_t *)&g_asix_rx_buffer[4]; + usbh_asix_eth_input(buf, len); + g_asix_rx_length = 0; } else { if (g_asix_rx_length > CONFIG_USBHOST_ASIX_ETH_MAX_SIZE) { USB_LOG_ERR("Rx packet is overflow\r\n"); @@ -733,46 +711,37 @@ delete: // clang-format on } -err_t usbh_asix_linkoutput(struct netif *netif, struct pbuf *p) +int usbh_asix_eth_output(uint8_t *buf, uint32_t buflen) { - int ret; - struct pbuf *q; uint16_t actual_len; - uint8_t *buffer = &g_asix_tx_buffer[4]; + uint8_t *buffer; if (g_asix_class.connect_status == false) { - return ERR_BUF; + return -USB_ERR_NOTCONN; } - for (q = p; q != NULL; q = q->next) { - memcpy(buffer, q->payload, q->len); - buffer += q->len; - } + buffer = &g_asix_tx_buffer[4]; + memcpy(buffer, buf, buflen); - g_asix_tx_buffer[0] = p->tot_len & 0xff; - g_asix_tx_buffer[1] = (p->tot_len >> 8) & 0xff; + g_asix_tx_buffer[0] = buflen & 0xff; + g_asix_tx_buffer[1] = (buflen >> 8) & 0xff; g_asix_tx_buffer[2] = ~g_asix_tx_buffer[0]; g_asix_tx_buffer[3] = ~g_asix_tx_buffer[1]; - if (!(p->tot_len + 4) % USB_GET_MAXPACKETSIZE(g_asix_class.bulkout->wMaxPacketSize)) { - USB_LOG_DBG("txlen:%d\r\n", p->tot_len + 8); - g_asix_tx_buffer[p->tot_len + 4 + 0] = 0x00; - g_asix_tx_buffer[p->tot_len + 4 + 1] = 0x00; - g_asix_tx_buffer[p->tot_len + 4 + 2] = 0xff; - g_asix_tx_buffer[p->tot_len + 4 + 3] = 0xff; - actual_len = p->tot_len + 8; + if (!(buflen + 4) % USB_GET_MAXPACKETSIZE(g_asix_class.bulkout->wMaxPacketSize)) { + USB_LOG_DBG("txlen:%d\r\n", buflen + 8); + g_asix_tx_buffer[buflen + 4 + 0] = 0x00; + g_asix_tx_buffer[buflen + 4 + 1] = 0x00; + g_asix_tx_buffer[buflen + 4 + 2] = 0xff; + g_asix_tx_buffer[buflen + 4 + 3] = 0xff; + actual_len = buflen + 8; } else { - USB_LOG_DBG("txlen:%d\r\n", p->tot_len + 4); - actual_len = p->tot_len + 4; + USB_LOG_DBG("txlen:%d\r\n", buflen + 4); + actual_len = buflen + 4; } usbh_bulk_urb_fill(&g_asix_class.bulkout_urb, g_asix_class.hport, g_asix_class.bulkout, g_asix_tx_buffer, actual_len, USB_OSAL_WAITING_FOREVER, NULL, NULL); - ret = usbh_submit_urb(&g_asix_class.bulkout_urb); - if (ret < 0) { - return ERR_BUF; - } - - return ERR_OK; + return usbh_submit_urb(&g_asix_class.bulkout_urb); } __WEAK void usbh_asix_run(struct usbh_asix *asix_class) diff --git a/class/vendor/net/usbh_asix.h b/class/vendor/net/usbh_asix.h index 0642578b..9f34e570 100644 --- a/class/vendor/net/usbh_asix.h +++ b/class/vendor/net/usbh_asix.h @@ -6,9 +6,6 @@ #ifndef USBH_ASIX_H #define USBH_ASIX_H -#include "lwip/netif.h" -#include "lwip/pbuf.h" - /* ASIX AX8817X based USB 2.0 Ethernet Devices */ #define AX_CMD_SET_SW_MII 0x06 @@ -156,10 +153,6 @@ struct usbh_asix { bool connect_status; uint8_t mac[6]; - ip_addr_t ipaddr; - ip_addr_t netmask; - ip_addr_t gateway; - void *user_data; }; @@ -172,8 +165,9 @@ int usbh_asix_get_connect_status(struct usbh_asix *asix_class); void usbh_asix_run(struct usbh_asix *asix_class); void usbh_asix_stop(struct usbh_asix *asix_class); +int usbh_asix_eth_output(uint8_t *buf, uint32_t buflen); +void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen); void usbh_asix_rx_thread(void *argument); -err_t usbh_asix_linkoutput(struct netif *netif, struct pbuf *p); #ifdef __cplusplus } diff --git a/class/vendor/net/usbh_rtl8152.c b/class/vendor/net/usbh_rtl8152.c index 8def54fb..3bd68a1d 100644 --- a/class/vendor/net/usbh_rtl8152.c +++ b/class/vendor/net/usbh_rtl8152.c @@ -2122,16 +2122,8 @@ void usbh_rtl8152_rx_thread(void *argument) { uint32_t g_rtl8152_rx_length; int ret; - err_t err; uint16_t len; uint16_t data_offset; - struct pbuf *p; -#if LWIP_TCPIP_CORE_LOCKING_INPUT - pbuf_type type = PBUF_ROM; -#else - pbuf_type type = PBUF_POOL; -#endif - struct netif *netif = (struct netif *)argument; USB_LOG_INFO("Create rtl8152 rx thread\r\n"); // clang-format off @@ -2181,20 +2173,9 @@ find_class: USB_LOG_DBG("data_offset:%d, eth len:%d\r\n", data_offset, len); - p = pbuf_alloc(PBUF_RAW, len, type); - if (p != NULL) { -#if LWIP_TCPIP_CORE_LOCKING_INPUT - p->payload = (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)]; -#else - memcpy(p->payload, (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)], len); -#endif - err = netif->input(p, netif); - if (err != ERR_OK) { - pbuf_free(p); - } - } else { - USB_LOG_ERR("No memory to alloc pbuf for rtl8152 rx\r\n"); - } + uint8_t *buf = (uint8_t *)&g_rtl8152_rx_buffer[data_offset + sizeof(struct rx_desc)]; + usbh_rtl8152_eth_input(buf, len); + data_offset += (len + sizeof(struct rx_desc)); g_rtl8152_rx_length -= (len + sizeof(struct rx_desc)); @@ -2217,36 +2198,26 @@ delete: // clang-format on } -err_t usbh_rtl8152_linkoutput(struct netif *netif, struct pbuf *p) +int usbh_rtl8152_eth_output(uint8_t *buf, uint32_t buflen) { - int ret; - struct pbuf *q; uint8_t *buffer; - struct tx_desc *tx_desc = (struct tx_desc *)g_rtl8152_tx_buffer; + struct tx_desc *tx_desc; if (g_rtl8152_class.connect_status == false) { - return ERR_BUF; + return -USB_ERR_NOTCONN; } - tx_desc->opts1 = p->tot_len | TX_FS | TX_LS; + tx_desc = (struct tx_desc *)g_rtl8152_tx_buffer; + tx_desc->opts1 = buflen | TX_FS | TX_LS; tx_desc->opts2 = 0; buffer = g_rtl8152_tx_buffer + sizeof(struct tx_desc); + memcpy(buffer, buf, buflen); - for (q = p; q != NULL; q = q->next) { - memcpy(buffer, q->payload, q->len); - buffer += q->len; - } + USB_LOG_DBG("txlen:%d\r\n", buflen + sizeof(struct tx_desc)); - USB_LOG_DBG("txlen:%d\r\n", p->tot_len + sizeof(struct tx_desc)); - - usbh_bulk_urb_fill(&g_rtl8152_class.bulkout_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkout, g_rtl8152_tx_buffer, p->tot_len + sizeof(struct tx_desc), USB_OSAL_WAITING_FOREVER, NULL, NULL); - ret = usbh_submit_urb(&g_rtl8152_class.bulkout_urb); - if (ret < 0) { - return ERR_BUF; - } - - return ERR_OK; + usbh_bulk_urb_fill(&g_rtl8152_class.bulkout_urb, g_rtl8152_class.hport, g_rtl8152_class.bulkout, g_rtl8152_tx_buffer, buflen + sizeof(struct tx_desc), USB_OSAL_WAITING_FOREVER, NULL, NULL); + return usbh_submit_urb(&g_rtl8152_class.bulkout_urb); } __WEAK void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class) diff --git a/class/vendor/net/usbh_rtl8152.h b/class/vendor/net/usbh_rtl8152.h index 4386ebb7..a9aa7943 100644 --- a/class/vendor/net/usbh_rtl8152.h +++ b/class/vendor/net/usbh_rtl8152.h @@ -6,9 +6,6 @@ #ifndef USBH_RTL8152_H #define USBH_RTL8152_H -#include "lwip/netif.h" -#include "lwip/pbuf.h" - struct usbh_rtl8152 { struct usbh_hubport *hport; struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ @@ -24,10 +21,6 @@ struct usbh_rtl8152 { bool connect_status; uint32_t speed[2]; - ip_addr_t ipaddr; - ip_addr_t netmask; - ip_addr_t gateway; - uint8_t version; uint8_t eee_adv; uint8_t eee_en; @@ -63,8 +56,9 @@ int usbh_rtl8152_get_connect_status(struct usbh_rtl8152 *rtl8152_class); void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class); void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class); +int usbh_rtl8152_eth_output(uint8_t *buf, uint32_t buflen); +void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen); void usbh_rtl8152_rx_thread(void *argument); -err_t usbh_rtl8152_linkoutput(struct netif *netif, struct pbuf *p); #ifdef __cplusplus } diff --git a/class/wireless/usbh_rndis.c b/class/wireless/usbh_rndis.c index ab99855d..969e6e53 100644 --- a/class/wireless/usbh_rndis.c +++ b/class/wireless/usbh_rndis.c @@ -425,18 +425,10 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf) void usbh_rndis_rx_thread(void *argument) { uint32_t g_rndis_rx_length; - uint32_t pmg_offset; int ret; - err_t err; - struct pbuf *p; + uint32_t pmg_offset; rndis_data_packet_t *pmsg; rndis_data_packet_t temp; -#if LWIP_TCPIP_CORE_LOCKING_INPUT - pbuf_type type = PBUF_ROM; -#else - pbuf_type type = PBUF_POOL; -#endif - struct netif *netif = (struct netif *)argument; USB_LOG_INFO("Create rndis rx thread\r\n"); // clang-format off @@ -481,28 +473,15 @@ find_class: } if (pmsg->MessageType == REMOTE_NDIS_PACKET_MSG) { - p = pbuf_alloc(PBUF_RAW, pmsg->DataLength, type); - if (p != NULL) { - void *src = (void *)(g_rndis_rx_buffer + pmg_offset + sizeof(rndis_generic_msg_t) + pmsg->DataOffset); -#if LWIP_TCPIP_CORE_LOCKING_INPUT - p->payload = src; -#else - memcpy(p->payload, src, pmsg->DataLength); -#endif - err = netif->input(p, netif); - if (err != ERR_OK) { - pbuf_free(p); - } - pmg_offset += pmsg->MessageLength; - g_rndis_rx_length -= pmsg->MessageLength; + uint8_t *buf = (uint8_t *)(g_rndis_rx_buffer + pmg_offset + sizeof(rndis_generic_msg_t) + pmsg->DataOffset); - /* drop the last dummy byte, it is a short packet to tell us we have received a multiple of wMaxPacketSize */ - if (g_rndis_rx_length < 4) { - g_rndis_rx_length = 0; - } - } else { + usbh_rndis_eth_input(buf, pmsg->DataLength); + pmg_offset += pmsg->MessageLength; + g_rndis_rx_length -= pmsg->MessageLength; + + /* drop the last dummy byte, it is a short packet to tell us we have received a multiple of wMaxPacketSize */ + if (g_rndis_rx_length < 4) { g_rndis_rx_length = 0; - USB_LOG_ERR("No memory to alloc pbuf for rndis rx\r\n"); } } else { USB_LOG_ERR("offset:%d,remain:%d,total:%d\r\n", pmg_offset, g_rndis_rx_length, total_len); @@ -525,31 +504,26 @@ delete: // clang-format on } -err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p) +int usbh_rndis_eth_output(uint8_t *buf, uint32_t buflen) { - int ret; - struct pbuf *q; uint8_t *buffer; rndis_data_packet_t *hdr; uint32_t len; if (g_rndis_class.connect_status == false) { - return ERR_BUF; + return -USB_ERR_NOTCONN; } hdr = (rndis_data_packet_t *)g_rndis_tx_buffer; memset(hdr, 0, sizeof(rndis_data_packet_t)); hdr->MessageType = REMOTE_NDIS_PACKET_MSG; - hdr->MessageLength = sizeof(rndis_data_packet_t) + p->tot_len; + hdr->MessageLength = sizeof(rndis_data_packet_t) + buflen; hdr->DataOffset = sizeof(rndis_data_packet_t) - sizeof(rndis_generic_msg_t); - hdr->DataLength = p->tot_len; + hdr->DataLength = buflen; buffer = (uint8_t *)(g_rndis_tx_buffer + sizeof(rndis_data_packet_t)); - for (q = p; q != NULL; q = q->next) { - memcpy(buffer, q->payload, q->len); - buffer += q->len; - } + memcpy(buffer, buf, buflen); len = hdr->MessageLength; /* if message length is the multiple of wMaxPacketSize, we should add a short packet to tell device transfer is over. */ @@ -560,12 +534,7 @@ err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p) USB_LOG_DBG("txlen:%d\r\n", len); usbh_bulk_urb_fill(&g_rndis_class.bulkout_urb, g_rndis_class.hport, g_rndis_class.bulkout, g_rndis_tx_buffer, len, USB_OSAL_WAITING_FOREVER, NULL, NULL); - ret = usbh_submit_urb(&g_rndis_class.bulkout_urb); - if (ret < 0) { - return ERR_BUF; - } - - return ERR_OK; + return usbh_submit_urb(&g_rndis_class.bulkout_urb); } __WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class) diff --git a/class/wireless/usbh_rndis.h b/class/wireless/usbh_rndis.h index b4e99c3d..be56e400 100644 --- a/class/wireless/usbh_rndis.h +++ b/class/wireless/usbh_rndis.h @@ -8,9 +8,6 @@ #include "usb_cdc.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" - struct usbh_rndis { struct usbh_hubport *hport; struct usb_endpoint_descriptor *bulkin; /* Bulk IN endpoint */ @@ -30,10 +27,6 @@ struct usbh_rndis { bool connect_status; uint8_t mac[6]; - ip_addr_t ipaddr; - ip_addr_t netmask; - ip_addr_t gateway; - void *user_data; }; @@ -47,7 +40,8 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class); void usbh_rndis_run(struct usbh_rndis *rndis_class); void usbh_rndis_stop(struct usbh_rndis *rndis_class); -err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p); +int usbh_rndis_eth_output(uint8_t *buf, uint32_t buflen); +void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen); void usbh_rndis_rx_thread(void *argument); #ifdef __cplusplus diff --git a/platform/README.md b/platform/README.md new file mode 100644 index 00000000..a6afc93e --- /dev/null +++ b/platform/README.md @@ -0,0 +1,14 @@ +# Platform Support + +This is a platform support for other os with their own components. + +| Platform | fs | net | serial | +|:---------:|:------------:|:------------:|:------------:| +|none | fatfs | lwip | none | +|rtthread | dfs | lwip | rt_device | +|nuttx | nuttx block driver | nuttx net | nuttx char driver| +|threadx | filex | netx | none | + +- **fs** is for usbd_msc and usbh_msc +- **net** is for cdc_ecm, cdc_rndis, cdc_ncm, asix, rtl8152 and so on. +- **serial** is for cdc_acm, ch340, ftdi, cp210x, pl2303 and so on. \ No newline at end of file diff --git a/third_party/fatfs-0.14/source/port/fatfs_usbh.c b/platform/none/usbh_fatfs.c similarity index 94% rename from third_party/fatfs-0.14/source/port/fatfs_usbh.c rename to platform/none/usbh_fatfs.c index feab07e4..ba76c12c 100644 --- a/third_party/fatfs-0.14/source/port/fatfs_usbh.c +++ b/platform/none/usbh_fatfs.c @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ #include "ff.h" #include "diskio.h" #include "usbh_core.h" @@ -9,6 +14,7 @@ int USB_disk_status(void) { return 0; } + int USB_disk_initialize(void) { active_msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda"); @@ -59,4 +65,4 @@ int USB_disk_ioctl(BYTE cmd, void *buff) } return result; -} \ No newline at end of file +} diff --git a/platform/none/usbh_lwip.c b/platform/none/usbh_lwip.c new file mode 100644 index 00000000..f6091378 --- /dev/null +++ b/platform/none/usbh_lwip.c @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "netif/etharp.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" +#include "lwip/tcpip.h" +#if LWIP_DHCP +#include "lwip/dhcp.h" +#include "lwip/prot/dhcp.h" +#endif + +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "timers.h" + +#include "usbh_core.h" + +#if LWIP_TCPIP_CORE_LOCKING_INPUT !=1 +#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread +#endif + +#if LWIP_TCPIP_CORE_LOCKING !=1 +#error must set LWIP_TCPIP_CORE_LOCKING to 1 +#endif + +#if PBUF_POOL_BUFSIZE < 1600 +#error PBUF_POOL_BUFSIZE must be larger than 1600 +#endif + +#define CONFIG_USBHOST_PLATFORM_CDC_ECM +#define CONFIG_USBHOST_PLATFORM_CDC_RNDIS +#define CONFIG_USBHOST_PLATFORM_CDC_NCM +#define CONFIG_USBHOST_PLATFORM_ASIX +#define CONFIG_USBHOST_PLATFORM_RTL8152 + +ip_addr_t g_ipaddr; +ip_addr_t g_netmask; +ip_addr_t g_gateway; + +void usbh_lwip_eth_input_common(struct netif *netif, uint8_t *buf, uint32_t len) +{ +#if LWIP_TCPIP_CORE_LOCKING_INPUT + pbuf_type type = PBUF_REF; +#else + pbuf_type type = PBUF_POOL; +#endif + err_t err; + struct pbuf *p; + + p = pbuf_alloc(PBUF_RAW, len, type); + if (p != NULL) { +#if LWIP_TCPIP_CORE_LOCKING_INPUT + p->payload = buf; +#else + memcpy(p->payload, buf, len); +#endif + err = netif->input(p, netif); + if (err != ERR_OK) { + pbuf_free(p); + } + } else { + USB_LOG_ERR("No memory to alloc pbuf\r\n"); + } +} + +TimerHandle_t dhcp_handle; + +static void dhcp_timeout(TimerHandle_t xTimer) +{ + struct netif *netif = (struct netif *)pvTimerGetTimerID(xTimer); + struct dhcp *dhcp; + + if (netif_is_up(netif)) { + dhcp = netif_dhcp_data(netif); + + if (dhcp && (dhcp->state == DHCP_STATE_BOUND)) { + USB_LOG_INFO("IPv4 Address : %s\r\n", ipaddr_ntoa(&netif->ip_addr)); + USB_LOG_INFO("IPv4 Subnet mask : %s\r\n", ipaddr_ntoa(&netif->netmask)); + USB_LOG_INFO("IPv4 Gateway : %s\r\n\r\n", ipaddr_ntoa(&netif->gw)); + + xTimerStop(xTimer, 0); + } + } +} + +#ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM +#include "usbh_cdc_ecm.h" + +struct netif g_cdc_ecm_netif; + +static err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p) +{ + int ret = usbh_cdc_ecm_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return ERR_BUF; + } else { + return ERR_OK; + } +} + +void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(&g_cdc_ecm_netif, buf, buflen); +} + +static err_t usbh_cdc_ecm_if_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->output = etharp_output; + netif->linkoutput = usbh_cdc_ecm_linkoutput; + return ERR_OK; +} + +void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) +{ + struct netif *netif = &g_cdc_ecm_netif; + + netif->hwaddr_len = 6; + memcpy(netif->hwaddr, cdc_ecm_class->mac, 6); + + IP4_ADDR(&g_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&g_netmask, 0, 0, 0, 0); + IP4_ADDR(&g_gateway, 0, 0, 0, 0); + + netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_cdc_ecm_if_init, tcpip_input); + netif_set_default(netif); + while (!netif_is_up(netif)) { + } + + dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout); + if (dhcp_handle == NULL) { + USB_LOG_ERR("timer creation failed! \r\n"); + while (1) { + } + } + + usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL); +#if LWIP_DHCP + dhcp_start(netif); + xTimerStart(dhcp_handle, 0); +#endif +} + +void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class) +{ + struct netif *netif = &g_cdc_ecm_netif; +#if LWIP_DHCP + dhcp_stop(netif); + dhcp_cleanup(netif); + xTimerStop(dhcp_handle, 0); + xTimerDelete(dhcp_handle, 0); +#endif + netif_set_down(netif); + netif_remove(netif); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS +#include "usbh_rndis.h" + +TimerHandle_t timer_handle; + +static void rndis_dev_keepalive_timeout(TimerHandle_t xTimer) +{ + struct usbh_rndis *rndis_class = (struct usbh_rndis *)pvTimerGetTimerID(xTimer); + usbh_rndis_keepalive(rndis_class); +} + +void timer_init(struct usbh_rndis *rndis_class) +{ + timer_handle = xTimerCreate((const char *)NULL, (TickType_t)5000, (UBaseType_t)pdTRUE, (void *const)rndis_class, (TimerCallbackFunction_t)rndis_dev_keepalive_timeout); + if (NULL != timer_handle) { + xTimerStart(timer_handle, 0); + } else { + USB_LOG_ERR("timer creation failed! \r\n"); + for (;;) { + ; + } + } +} + +struct netif g_rndis_netif; + +static err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p) +{ + int ret = usbh_rndis_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return ERR_BUF; + } else { + return ERR_OK; + } +} + +void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(&g_rndis_netif, buf, buflen); +} + +static err_t usbh_rndis_if_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->output = etharp_output; + netif->linkoutput = usbh_rndis_linkoutput; + return ERR_OK; +} + +void usbh_rndis_run(struct usbh_rndis *rndis_class) +{ + struct netif *netif = &g_rndis_netif; + + netif->hwaddr_len = 6; + memcpy(netif->hwaddr, rndis_class->mac, 6); + + IP4_ADDR(&g_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&g_netmask, 0, 0, 0, 0); + IP4_ADDR(&g_gateway, 0, 0, 0, 0); + + netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_rndis_if_init, tcpip_input); + netif_set_default(netif); + while (!netif_is_up(netif)) { + } + + dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout); + if (dhcp_handle == NULL) { + USB_LOG_ERR("timer creation failed! \r\n"); + while (1) { + } + } + + usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL); + + //timer_init(rndis_class); + +#if LWIP_DHCP + dhcp_start(netif); + xTimerStart(dhcp_handle, 0); +#endif +} + +void usbh_rndis_stop(struct usbh_rndis *rndis_class) +{ + struct netif *netif = &g_rndis_netif; +#if LWIP_DHCP + dhcp_stop(netif); + dhcp_cleanup(netif); + xTimerStop(dhcp_handle, 0); + xTimerDelete(dhcp_handle, 0); +#endif + netif_set_down(netif); + netif_remove(netif); + // xTimerStop(timer_handle, 0); + // xTimerDelete(timer_handle, 0); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM +#include "usbh_cdc_ncm.h" + +struct netif g_cdc_ncm_netif; + +static err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p) +{ + int ret = usbh_cdc_ncm_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return ERR_BUF; + } else { + return ERR_OK; + } +} + +void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(&g_cdc_ncm_netif, buf, buflen); +} + +static err_t usbh_cdc_ncm_if_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->output = etharp_output; + netif->linkoutput = usbh_cdc_ncm_linkoutput; + return ERR_OK; +} + +void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class) +{ + struct netif *netif = &g_cdc_ncm_netif; + + netif->hwaddr_len = 6; + memcpy(netif->hwaddr, cdc_ncm_class->mac, 6); + + IP4_ADDR(&g_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&g_netmask, 0, 0, 0, 0); + IP4_ADDR(&g_gateway, 0, 0, 0, 0); + + netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_cdc_ncm_if_init, tcpip_input); + netif_set_default(netif); + while (!netif_is_up(netif)) { + } + + dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout); + if (dhcp_handle == NULL) { + USB_LOG_ERR("timer creation failed! \r\n"); + while (1) { + } + } + + usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL); +#if LWIP_DHCP + dhcp_start(netif); + xTimerStart(dhcp_handle, 0); +#endif +} + +void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class) +{ + struct netif *netif = &g_cdc_ncm_netif; +#if LWIP_DHCP + dhcp_stop(netif); + dhcp_cleanup(netif); + xTimerStop(dhcp_handle, 0); + xTimerDelete(dhcp_handle, 0); +#endif + netif_set_down(netif); + netif_remove(netif); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_ASIX +#include "usbh_asix.h" + +struct netif g_asix_netif; + +static err_t usbh_asix_linkoutput(struct netif *netif, struct pbuf *p) +{ + int ret = usbh_asix_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return ERR_BUF; + } else { + return ERR_OK; + } +} + +void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(&g_asix_netif, buf, buflen); +} + +static err_t usbh_asix_if_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->output = etharp_output; + netif->linkoutput = usbh_asix_linkoutput; + return ERR_OK; +} + +void usbh_asix_run(struct usbh_asix *asix_class) +{ + struct netif *netif = &g_asix_netif; + + netif->hwaddr_len = 6; + memcpy(netif->hwaddr, asix_class->mac, 6); + + IP4_ADDR(&g_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&g_netmask, 0, 0, 0, 0); + IP4_ADDR(&g_gateway, 0, 0, 0, 0); + + netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_asix_if_init, tcpip_input); + netif_set_default(netif); + while (!netif_is_up(netif)) { + } + + dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout); + if (dhcp_handle == NULL) { + USB_LOG_ERR("timer creation failed! \r\n"); + while (1) { + } + } + + usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL); +#if LWIP_DHCP + dhcp_start(netif); + xTimerStart(dhcp_handle, 0); +#endif +} + +void usbh_asix_stop(struct usbh_asix *asix_class) +{ + struct netif *netif = &g_asix_netif; +#if LWIP_DHCP + dhcp_stop(netif); + dhcp_cleanup(netif); + xTimerStop(dhcp_handle, 0); + xTimerDelete(dhcp_handle, 0); +#endif + netif_set_down(netif); + netif_remove(netif); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_RTL8152 +#include "usbh_rtl8152.h" + +struct netif g_rtl8152_netif; + +static err_t usbh_rtl8152_linkoutput(struct netif *netif, struct pbuf *p) +{ + int ret = usbh_rtl8152_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return ERR_BUF; + } else { + return ERR_OK; + } +} + +void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(&g_rtl8152_netif, buf, buflen); +} + +static err_t usbh_rtl8152_if_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + netif->mtu = 1500; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; + netif->state = NULL; + netif->name[0] = 'E'; + netif->name[1] = 'X'; + netif->output = etharp_output; + netif->linkoutput = usbh_rtl8152_linkoutput; + return ERR_OK; +} + +void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class) +{ + struct netif *netif = &g_rtl8152_netif; + + netif->hwaddr_len = 6; + memcpy(netif->hwaddr, rtl8152_class->mac, 6); + + IP4_ADDR(&g_ipaddr, 0, 0, 0, 0); + IP4_ADDR(&g_netmask, 0, 0, 0, 0); + IP4_ADDR(&g_gateway, 0, 0, 0, 0); + + netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_rtl8152_if_init, tcpip_input); + netif_set_default(netif); + while (!netif_is_up(netif)) { + } + + dhcp_handle = xTimerCreate((const char *)"dhcp", (TickType_t)200, (UBaseType_t)pdTRUE, (void *const)netif, (TimerCallbackFunction_t)dhcp_timeout); + if (dhcp_handle == NULL) { + USB_LOG_ERR("timer creation failed! \r\n"); + while (1) { + } + } + + usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL); +#if LWIP_DHCP + dhcp_start(netif); + xTimerStart(dhcp_handle, 0); +#endif +} + +void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class) +{ + struct netif *netif = &g_rtl8152_netif; +#if LWIP_DHCP + dhcp_stop(netif); + dhcp_cleanup(netif); + xTimerStop(dhcp_handle, 0); + xTimerDelete(dhcp_handle, 0); +#endif + netif_set_down(netif); + netif_remove(netif); +} +#endif diff --git a/platform/nuttx/usbh_fs.c b/platform/nuttx/usbh_fs.c new file mode 100644 index 00000000..94920323 --- /dev/null +++ b/platform/nuttx/usbh_fs.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "usbh_core.h" +#include "usbh_msc.h" + +#ifdef CONFIG_ARCH_CHIP_HPMICRO +#include "hpm_misc.h" +#define usbhmsc_phy2sysaddr(a) core_local_mem_to_sys_address(0, a) +#else +#define usbhmsc_phy2sysaddr(a) (a) +#endif + +static int usbhost_open(FAR struct inode *inode); +static int usbhost_close(FAR struct inode *inode); +static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer, + blkcnt_t startsector, unsigned int nsectors); +static ssize_t usbhost_write(FAR struct inode *inode, + FAR const unsigned char *buffer, + blkcnt_t startsector, unsigned int nsectors); +static int usbhost_geometry(FAR struct inode *inode, + FAR struct geometry *geometry); +static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg); +/* Block driver operations. This is the interface exposed to NuttX by the + * class that permits it to behave like a block driver. + */ + +static const struct block_operations g_bops = { + usbhost_open, /* open */ + usbhost_close, /* close */ + usbhost_read, /* read */ + usbhost_write, /* write */ + usbhost_geometry, /* geometry */ + usbhost_ioctl /* ioctl */ +}; + +static int usbhost_open(FAR struct inode *inode) +{ + struct usbh_msc *msc_class; + + DEBUGASSERT(inode->i_private); + msc_class = (struct usbh_msc *)inode->i_private; + + if (msc_class->hport && msc_class->hport->connected) { + return OK; + } else { + return -ENODEV; + } +} + +static int usbhost_close(FAR struct inode *inode) +{ + DEBUGASSERT(inode->i_private); + return 0; +} + +static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer, + blkcnt_t startsector, unsigned int nsectors) +{ + struct usbh_msc *msc_class; + int ret; + + DEBUGASSERT(inode->i_private); + msc_class = (struct usbh_msc *)inode->i_private; + + if (msc_class->hport && msc_class->hport->connected) { + ret = usbh_msc_scsi_read10(msc_class, startsector, (uint8_t *)usbhmsc_phy2sysaddr((uint32_t)buffer), nsectors); + if (ret < 0) { + return ret; + } else { +#ifdef CONFIG_USBHOST_MSC_DCACHE + up_invalidate_dcache((uintptr_t)buffer, (uintptr_t)(buffer + nsectors * msc_class->blocksize)); +#endif + return nsectors; + } + } else { + return -ENODEV; + } +} + +static ssize_t usbhost_write(FAR struct inode *inode, + FAR const unsigned char *buffer, + blkcnt_t startsector, unsigned int nsectors) +{ + struct usbh_msc *msc_class; + int ret; + + DEBUGASSERT(inode->i_private); + msc_class = (struct usbh_msc *)inode->i_private; + + if (msc_class->hport && msc_class->hport->connected) { +#ifdef CONFIG_USBHOST_MSC_DCACHE + up_flush_dcache((uintptr_t)buffer, (uintptr_t)(buffer + nsectors * msc_class->blocksize)); +#endif + ret = usbh_msc_scsi_write10(msc_class, startsector, (uint8_t *)usbhmsc_phy2sysaddr((uint32_t)buffer), nsectors); + if (ret < 0) { + return ret; + } else { + return nsectors; + } + } else { + return -ENODEV; + } +} + +static int usbhost_geometry(FAR struct inode *inode, + FAR struct geometry *geometry) +{ + struct usbh_msc *msc_class; + + DEBUGASSERT(inode->i_private); + msc_class = (struct usbh_msc *)inode->i_private; + + if (msc_class->hport && msc_class->hport->connected) { + memset(geometry, 0, sizeof(*geometry)); + + geometry->geo_available = true; + geometry->geo_mediachanged = false; + geometry->geo_writeenabled = true; + geometry->geo_nsectors = msc_class->blocknum; + geometry->geo_sectorsize = msc_class->blocksize; + + uinfo("nsectors: %" PRIdOFF " sectorsize: %" PRIi16 "\n", + geometry->geo_nsectors, geometry->geo_sectorsize); + return OK; + } else { + return -ENODEV; + } + + return 0; +} + +static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg) +{ + struct usbh_msc *msc_class; + + DEBUGASSERT(inode->i_private); + msc_class = (struct usbh_msc *)inode->i_private; + + if (msc_class->hport && msc_class->hport->connected) { + return -ENOTTY; + } else { + return -ENODEV; + } + + return 0; +} + +#define DEV_FORMAT "/dev/sd%c" + +void usbh_msc_run(struct usbh_msc *msc_class) +{ + char devname[32]; + + snprintf(devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar); + + register_blockdriver(devname, &g_bops, 0, msc_class); +} + +void usbh_msc_stop(struct usbh_msc *msc_class) +{ + char devname[32]; + + snprintf(devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar); + + unregister_blockdriver(devname); +} \ No newline at end of file diff --git a/platform/nuttx/usbh_net.c b/platform/nuttx/usbh_net.c new file mode 100644 index 00000000..b034ecc8 --- /dev/null +++ b/platform/nuttx/usbh_net.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "usbh_core.h" + +#define CONFIG_USBHOST_PLATFORM_CDC_ECM +#define CONFIG_USBHOST_PLATFORM_CDC_RNDIS +#define CONFIG_USBHOST_PLATFORM_CDC_NCM +#define CONFIG_USBHOST_PLATFORM_ASIX +#define CONFIG_USBHOST_PLATFORM_RTL8152 + +struct usbh_net { + struct net_driver_s netdev; + struct work_s txpollwork; + bool linkup; +}; + +void usbh_net_eth_input_common(struct net_driver_s *dev, uint8_t *buf, size_t len, int (*eth_output)(uint8_t *buf, uint32_t buflen)) +{ + FAR struct eth_hdr_s *hdr; + + net_lock(); + + NETDEV_RXPACKETS(dev); + + /* Any ACK or other response packet generated by the network stack + * will always be shorter than the received packet, therefore it is + * safe to pass the received frame buffer directly. + */ + + dev->d_buf = buf; + dev->d_len = len; + + hdr = (FAR struct eth_hdr_s *)dev->d_buf; +#ifdef CONFIG_NET_IPv4 + if (hdr->type == HTONS(ETHTYPE_IP)) { + NETDEV_RXIPV4(dev); + + /* Receive an IPv4 packet from the network device */ + + ipv4_input(dev); + if (dev->d_len > 0) { + /* And send the packet */ + eth_output(dev->d_buf, dev->d_len); + } + } else +#endif +#ifdef CONFIG_NET_IPv6 + if (hdr->type == HTONS(ETHTYPE_IP6)) { + NETDEV_RXIPV6(dev); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(dev); + + if (dev->d_len > 0) { + /* And send the packet */ + eth_output(dev->d_buf, dev->d_len); + } + } else +#endif +#ifdef CONFIG_NET_ARP + if (hdr->type == HTONS(ETHTYPE_ARP)) { + NETDEV_RXARP(dev); + + arp_input(dev); + if (dev->d_len > 0) { + eth_output(dev->d_buf, dev->d_len); + } + } else +#endif + { + NETDEV_RXDROPPED(dev); + } + + net_unlock(); +} + +#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS +#include "usbh_rndis.h" + +struct usbh_net g_rndis_dev; + +static int rndis_ifup(struct net_driver_s *dev) +{ + printf("rndis if up\r\n"); + g_rndis_dev.linkup = true; + usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL); + return OK; +} + +static int rndis_ifdown(struct net_driver_s *dev) +{ + printf("rndis if down\r\n"); + g_rndis_dev.linkup = false; + return OK; +} + +static int rndis_txpoll(struct net_driver_s *dev) +{ + return usbh_rndis_eth_output(g_rndis_dev.netdev.d_buf, g_rndis_dev.netdev.d_len); +} + +static void rndis_txavail_work(void *arg) +{ + net_lock(); + + if (g_rndis_dev.linkup) { + devif_poll(&g_rndis_dev.netdev, rndis_txpoll); + } else { + } + + net_unlock(); +} + +static int rndis_txavail(struct net_driver_s *dev) +{ + if (work_available(&g_rndis_dev.txpollwork)) { + work_queue(LPWORK, &g_rndis_dev.txpollwork, rndis_txavail_work, NULL, 0); + } else { + return -1; + } + + return OK; +} + +void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_net_eth_input_common(&g_rndis_dev.netdev, buf, buflen, usbh_rndis_eth_output); +} + +void usbh_rndis_run(struct usbh_rndis *rndis_class) +{ + memset(&g_rndis_dev.netdev, 0, sizeof(struct net_driver_s)); + + g_rndis_dev.netdev.d_ifup = rndis_ifup; + g_rndis_dev.netdev.d_ifdown = rndis_ifdown; + g_rndis_dev.netdev.d_txavail = rndis_txavail; + g_rndis_dev.netdev.d_private = rndis_class; + + for (uint8_t j = 0; j < 6; j++) { + g_rndis_dev.netdev.d_mac.ether.ether_addr_octet[j] = rndis_class->mac[j]; + } + netdev_register(&g_rndis_dev.netdev, NET_LL_ETHERNET); +} + +void usbh_rndis_stop(struct usbh_rndis *rndis_class) +{ +} +#endif \ No newline at end of file diff --git a/platform/rtthread/usb_check.c b/platform/rtthread/usb_check.c new file mode 100644 index 00000000..d4baf03e --- /dev/null +++ b/platform/rtthread/usb_check.c @@ -0,0 +1,17 @@ +#include "rtthread.h" + +#ifdef PKG_CHERRYUSB_HOST + +#ifndef RT_USING_TIMER_SOFT +#error must enable RT_USING_TIMER_SOFT to support timer callback in thread +#endif + +#if IDLE_THREAD_STACK_SIZE < 2048 +#error "IDLE_THREAD_STACK_SIZE must be greater than 2048" +#endif + +#if RT_TIMER_THREAD_STACK_SIZE < 2048 +#error "RT_TIMER_THREAD_STACK_SIZE must be greater than 2048" +#endif + +#endif diff --git a/third_party/rt-thread-5.0/usb_msh.c b/platform/rtthread/usb_msh.c similarity index 100% rename from third_party/rt-thread-5.0/usb_msh.c rename to platform/rtthread/usb_msh.c diff --git a/third_party/rt-thread-5.0/dfs_usbh_msc.c b/platform/rtthread/usbh_dfs.c similarity index 99% rename from third_party/rt-thread-5.0/dfs_usbh_msc.c rename to platform/rtthread/usbh_dfs.c index cdb9e80b..968064a6 100644 --- a/third_party/rt-thread-5.0/dfs_usbh_msc.c +++ b/platform/rtthread/usbh_dfs.c @@ -238,4 +238,4 @@ void usbh_msc_stop(struct usbh_msc *msc_class) dfs_unmount(mount_point); rt_device_unregister(rt_device_find(name)); -} \ No newline at end of file +} diff --git a/platform/rtthread/usbh_lwip.c b/platform/rtthread/usbh_lwip.c new file mode 100644 index 00000000..2c0c7eaf --- /dev/null +++ b/platform/rtthread/usbh_lwip.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2024, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "netif/etharp.h" +#include "lwip/netif.h" +#include "lwip/pbuf.h" +#include "lwip/tcpip.h" +#if LWIP_DHCP +#include "lwip/dhcp.h" +#include "lwip/prot/dhcp.h" +#endif + +#include +#include +#include + +#include "usbh_core.h" + +#include "lwip/opt.h" + +#ifndef RT_USING_LWIP212 +#error must enable RT_USING_LWIP212 +#endif + +#ifndef LWIP_NO_RX_THREAD +#error must enable LWIP_NO_RX_THREAD, we do not use rtthread eth rx thread +#endif + +#ifndef LWIP_NO_TX_THREAD +#warning suggest you to enable LWIP_NO_TX_THREAD, we do not use rtthread eth tx thread +#endif + +#if LWIP_TCPIP_CORE_LOCKING_INPUT !=1 +#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread +#endif + +#if LWIP_TCPIP_CORE_LOCKING !=1 +#error must set LWIP_TCPIP_CORE_LOCKING to 1 +#endif + +#if PBUF_POOL_BUFSIZE < 1600 +#error PBUF_POOL_BUFSIZE must be larger than 1600 +#endif + +// #define CONFIG_USBHOST_PLATFORM_CDC_ECM +// #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS +// #define CONFIG_USBHOST_PLATFORM_CDC_NCM +// #define CONFIG_USBHOST_PLATFORM_ASIX +// #define CONFIG_USBHOST_PLATFORM_RTL8152 + +void usbh_lwip_eth_input_common(struct netif *netif, uint8_t *buf, uint32_t len) +{ +#if LWIP_TCPIP_CORE_LOCKING_INPUT + pbuf_type type = PBUF_REF; +#else + pbuf_type type = PBUF_POOL; +#endif + err_t err; + struct pbuf *p; + + p = pbuf_alloc(PBUF_RAW, len, type); + if (p != NULL) { +#if LWIP_TCPIP_CORE_LOCKING_INPUT + p->payload = buf; +#else + memcpy(p->payload, buf, len); +#endif + err = netif->input(p, netif); + if (err != ERR_OK) { + pbuf_free(p); + } + } else { + USB_LOG_ERR("No memory to alloc pbuf\r\n"); + } +} + +#ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM +#include "usbh_cdc_ecm.h" + +static struct eth_device g_cdc_ecm_dev; + +static rt_err_t rt_usbh_cdc_ecm_control(rt_device_t dev, int cmd, void *args) +{ + struct usbh_cdc_ecm *cdc_ecm_class = (struct usbh_cdc_ecm *)dev->user_data; + + switch (cmd) { + case NIOCTL_GADDR: + + /* get mac address */ + if (args) + rt_memcpy(args, cdc_ecm_class->mac, 6); + else + return -RT_ERROR; + + break; + + default: + break; + } + + return RT_EOK; +} + +static rt_err_t rt_usbh_cdc_ecm_eth_tx(rt_device_t dev, struct pbuf *p) +{ + int ret = usbh_cdc_ecm_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return -RT_ERROR; + } else { + return RT_EOK; + } +} + +void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(g_cdc_ecm_dev.netif, buf, buflen); +} + +void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class) +{ + memset(&g_cdc_ecm_dev, 0, sizeof(struct eth_device)); + + g_cdc_ecm_dev.parent.control = rt_usbh_cdc_ecm_control; + g_cdc_ecm_dev.eth_rx = NULL; + g_cdc_ecm_dev.eth_tx = rt_usbh_cdc_ecm_eth_tx; + g_cdc_ecm_dev.parent.user_data = cdc_ecm_class; + + eth_device_init(&g_cdc_ecm_dev, "u0"); + eth_device_linkchange(&g_cdc_ecm_dev, RT_TRUE); + + usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL); +} + +void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class) +{ + eth_device_deinit(&g_cdc_ecm_dev); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS +#include "usbh_rndis.h" + +static struct eth_device g_rndis_dev; + +static rt_timer_t keep_timer = RT_NULL; + +static void rndis_dev_keepalive_timeout(void *parameter) +{ + struct usbh_rndis *rndis_class = (struct usbh_rndis *)parameter; + usbh_rndis_keepalive(rndis_class); +} + +static void timer_init(struct usbh_rndis *rndis_class) +{ + keep_timer = rt_timer_create("keep", + rndis_dev_keepalive_timeout, + rndis_class, + 5000, + RT_TIMER_FLAG_PERIODIC | + RT_TIMER_FLAG_SOFT_TIMER); + + rt_timer_start(keep_timer); +} + +static rt_err_t rt_usbh_rndis_control(rt_device_t dev, int cmd, void *args) +{ + struct usbh_rndis *rndis_class = (struct usbh_rndis *)dev->user_data; + + switch (cmd) { + case NIOCTL_GADDR: + + /* get mac address */ + if (args) + rt_memcpy(args, rndis_class->mac, 6); + else + return -RT_ERROR; + + break; + + default: + break; + } + + return RT_EOK; +} + +static rt_err_t rt_usbh_rndis_eth_tx(rt_device_t dev, struct pbuf *p) +{ + int ret = usbh_rndis_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return -RT_ERROR; + } else { + return RT_EOK; + } +} + +void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(g_rndis_dev.netif, buf, buflen); +} + +void usbh_rndis_run(struct usbh_rndis *rndis_class) +{ + memset(&g_rndis_dev, 0, sizeof(struct eth_device)); + + g_rndis_dev.parent.control = rt_usbh_rndis_control; + g_rndis_dev.eth_rx = NULL; + g_rndis_dev.eth_tx = rt_usbh_rndis_eth_tx; + g_rndis_dev.parent.user_data = rndis_class; + + eth_device_init(&g_rndis_dev, "u2"); + eth_device_linkchange(&g_rndis_dev, RT_TRUE); + + usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL); + //timer_init(rndis_class); +} + +void usbh_rndis_stop(struct usbh_rndis *rndis_class) +{ + eth_device_deinit(&g_rndis_dev); + // rt_timer_stop(keep_timer); + // rt_timer_delete(keep_timer); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM +#include "usbh_cdc_ncm.h" + +static struct eth_device g_cdc_ncm_dev; + +static rt_err_t rt_usbh_cdc_ncm_control(rt_device_t dev, int cmd, void *args) +{ + struct usbh_cdc_ncm *cdc_ncm_class = (struct usbh_cdc_ncm *)dev->user_data; + + switch (cmd) { + case NIOCTL_GADDR: + + /* get mac address */ + if (args) + rt_memcpy(args, cdc_ncm_class->mac, 6); + else + return -RT_ERROR; + + break; + + default: + break; + } + + return RT_EOK; +} + +static rt_err_t rt_usbh_cdc_ncm_eth_tx(rt_device_t dev, struct pbuf *p) +{ + int ret = usbh_cdc_ncm_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return -RT_ERROR; + } else { + return RT_EOK; + } +} + +void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(g_cdc_ncm_dev.netif, buf, buflen); +} + +void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class) +{ + memset(&g_cdc_ncm_dev, 0, sizeof(struct eth_device)); + + g_cdc_ncm_dev.parent.control = rt_usbh_cdc_ncm_control; + g_cdc_ncm_dev.eth_rx = NULL; + g_cdc_ncm_dev.eth_tx = rt_usbh_cdc_ncm_eth_tx; + g_cdc_ncm_dev.parent.user_data = cdc_ncm_class; + + eth_device_init(&g_cdc_ncm_dev, "u1"); + eth_device_linkchange(&g_cdc_ncm_dev, RT_TRUE); + + usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL); +} + +void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class) +{ + eth_device_deinit(&g_cdc_ncm_dev); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_ASIX +#include "usbh_asix.h" + +static struct eth_device g_asix_dev; + +static rt_err_t rt_usbh_asix_control(rt_device_t dev, int cmd, void *args) +{ + struct usbh_asix *asix_class = (struct usbh_asix *)dev->user_data; + + switch (cmd) { + case NIOCTL_GADDR: + + /* get mac address */ + if (args) + rt_memcpy(args, asix_class->mac, 6); + else + return -RT_ERROR; + + break; + + default: + break; + } + + return RT_EOK; +} + +static rt_err_t rt_usbh_asix_eth_tx(rt_device_t dev, struct pbuf *p) +{ + int ret = usbh_asix_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return -RT_ERROR; + } else { + return RT_EOK; + } +} + +void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(g_asix_dev.netif, buf, buflen); +} + +void usbh_asix_run(struct usbh_asix *asix_class) +{ + memset(&g_asix_dev, 0, sizeof(struct eth_device)); + + g_asix_dev.parent.control = rt_usbh_asix_control; + g_asix_dev.eth_rx = NULL; + g_asix_dev.eth_tx = rt_usbh_asix_eth_tx; + g_asix_dev.parent.user_data = asix_class; + + eth_device_init(&g_asix_dev, "u3"); + eth_device_linkchange(&g_asix_dev, RT_TRUE); + + usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL); +} + +void usbh_asix_stop(struct usbh_asix *asix_class) +{ + eth_device_deinit(&g_asix_dev); +} +#endif + +#ifdef CONFIG_USBHOST_PLATFORM_RTL8152 +#include "usbh_rtl8152.h" + +static struct eth_device g_rtl8152_dev; + +static rt_err_t rt_usbh_rtl8152_control(rt_device_t dev, int cmd, void *args) +{ + struct usbh_rtl8152 *rtl8152_class = (struct usbh_rtl8152 *)dev->user_data; + + switch (cmd) { + case NIOCTL_GADDR: + + /* get mac address */ + if (args) + rt_memcpy(args, rtl8152_class->mac, 6); + else + return -RT_ERROR; + + break; + + default: + break; + } + + return RT_EOK; +} + +static rt_err_t rt_usbh_rtl8152_eth_tx(rt_device_t dev, struct pbuf *p) +{ + int ret = usbh_rtl8152_eth_output(p->payload, p->tot_len); + if (ret < 0) { + return -RT_ERROR; + } else { + return RT_EOK; + } +} + +void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen) +{ + usbh_lwip_eth_input_common(g_rtl8152_dev.netif, buf, buflen); +} + +void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class) +{ + memset(&g_rtl8152_dev, 0, sizeof(struct eth_device)); + + g_rtl8152_dev.parent.control = rt_usbh_rtl8152_control; + g_rtl8152_dev.eth_rx = NULL; + g_rtl8152_dev.eth_tx = rt_usbh_rtl8152_eth_tx; + g_rtl8152_dev.parent.user_data = rtl8152_class; + + eth_device_init(&g_rtl8152_dev, "u4"); + eth_device_linkchange(&g_rtl8152_dev, RT_TRUE); + + usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL); +} + +void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class) +{ + eth_device_deinit(&g_rtl8152_dev); +} +#endif diff --git a/platform/threadx/.gitkeep b/platform/threadx/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/third_party/rt-thread-5.0/usb_check.c b/third_party/rt-thread-5.0/usb_check.c deleted file mode 100644 index 13d178fb..00000000 --- a/third_party/rt-thread-5.0/usb_check.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "rtthread.h" - -#ifdef PKG_CHERRYUSB_HOST - -#ifndef RT_USING_TIMER_SOFT -#error must enable RT_USING_TIMER_SOFT to support timer callback in thread -#endif - -#if IDLE_THREAD_STACK_SIZE < 2048 -#error "IDLE_THREAD_STACK_SIZE must be greater than 2048" -#endif - -#if RT_TIMER_THREAD_STACK_SIZE < 2048 -#error "RT_TIMER_THREAD_STACK_SIZE must be greater than 2048" -#endif - -#ifdef RT_USING_LWIP - -#include "lwip/opt.h" - -#ifndef RT_USING_LWIP212 -#error must enable RT_USING_LWIP212 -#endif - -#ifndef LWIP_NO_RX_THREAD -#error must enable LWIP_NO_RX_THREAD, we do not use rtthread eth rx thread -#endif - -#if LWIP_TCPIP_CORE_LOCKING_INPUT !=1 -#warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread -#endif - -#if LWIP_TCPIP_CORE_LOCKING !=1 -#error must set LWIP_TCPIP_CORE_LOCKING to 1 -#endif - -#if PBUF_POOL_BUFSIZE < 1514 -#error PBUF_POOL_BUFSIZE must be larger than 1514 -#endif - -#endif - -#endif