mirror of
https://github.com/sakumisu/CherryUSB.git
synced 2025-05-09 00:21:44 +08:00
refactor(platform): update platform support
This commit is contained in:
parent
3336919e0d
commit
865d2f5d96
@ -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
|
||||
|
||||
|
17
README.md
17
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 |
|
||||
|
15
README_zh.md
15
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 | 工具链接 |
|
||||
|
||||
|
15
SConscript
15
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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
71
class/vendor/net/usbh_asix.c
vendored
71
class/vendor/net/usbh_asix.c
vendored
@ -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)
|
||||
|
10
class/vendor/net/usbh_asix.h
vendored
10
class/vendor/net/usbh_asix.h
vendored
@ -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
|
||||
}
|
||||
|
53
class/vendor/net/usbh_rtl8152.c
vendored
53
class/vendor/net/usbh_rtl8152.c
vendored
@ -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)
|
||||
|
10
class/vendor/net/usbh_rtl8152.h
vendored
10
class/vendor/net/usbh_rtl8152.h
vendored
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
14
platform/README.md
Normal file
14
platform/README.md
Normal file
@ -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.
|
@ -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;
|
||||
}
|
||||
}
|
504
platform/none/usbh_lwip.c
Normal file
504
platform/none/usbh_lwip.c
Normal file
@ -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
|
189
platform/nuttx/usbh_fs.c
Normal file
189
platform/nuttx/usbh_fs.c
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/scsi.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/mutex.h>
|
||||
|
||||
#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);
|
||||
}
|
165
platform/nuttx/usbh_net.c
Normal file
165
platform/nuttx/usbh_net.c
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <semaphore.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/net/ip.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#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
|
17
platform/rtthread/usb_check.c
Normal file
17
platform/rtthread/usb_check.c
Normal file
@ -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
|
@ -238,4 +238,4 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
|
||||
dfs_unmount(mount_point);
|
||||
rt_device_unregister(rt_device_find(name));
|
||||
}
|
||||
}
|
415
platform/rtthread/usbh_lwip.c
Normal file
415
platform/rtthread/usbh_lwip.c
Normal file
@ -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 <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <netif/ethernetif.h>
|
||||
|
||||
#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
|
0
platform/threadx/.gitkeep
Normal file
0
platform/threadx/.gitkeep
Normal file
43
third_party/rt-thread-5.0/usb_check.c
vendored
43
third_party/rt-thread-5.0/usb_check.c
vendored
@ -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
|
Loading…
x
Reference in New Issue
Block a user