update(class/cdc/usbd_cdc_ecm): support transfer api for enet & wireless without lwip

This commit is contained in:
sakumisu
2024-11-11 21:48:13 +08:00
parent d0edc30c11
commit 58d552d03d
4 changed files with 69 additions and 49 deletions

View File

@@ -524,7 +524,7 @@ struct cdc_ncm_ndp16 {
int_ep, /* bEndpointAddress */ \ int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \ 0x03, /* bmAttributes */ \
0x08, 0x00, /* wMaxPacketSize */ \ 0x08, 0x00, /* wMaxPacketSize */ \
0x10, /* bInterval */ \ 0x05, /* bInterval */ \
0x09, /* bLength */ \ 0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
@@ -596,7 +596,7 @@ eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx)
int_ep, /* bEndpointAddress */ \ int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \ 0x03, /* bmAttributes */ \
0x10, 0x00, /* wMaxPacketSize */ \ 0x10, 0x00, /* wMaxPacketSize */ \
0x10, /* bInterval */ \ 0x05, /* bInterval */ \
0x09, /* bLength */ \ 0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \

View File

@@ -7,17 +7,21 @@
#include "usbd_cdc_ecm.h" #include "usbd_cdc_ecm.h"
#define CDC_ECM_OUT_EP_IDX 0 #define CDC_ECM_OUT_EP_IDX 0
#define CDC_ECM_IN_EP_IDX 1 #define CDC_ECM_IN_EP_IDX 1
#define CDC_ECM_INT_EP_IDX 2 #define CDC_ECM_INT_EP_IDX 2
/* Ethernet Maximum Segment size, typically 1514 bytes */
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1536U
/* Describe EndPoints configuration */ /* Describe EndPoints configuration */
static struct usbd_endpoint cdc_ecm_ep_data[3]; static struct usbd_endpoint cdc_ecm_ep_data[3];
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE]; static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
#endif
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16]; static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16];
volatile uint8_t *g_cdc_ecm_rx_data_buffer = NULL;
volatile uint32_t g_cdc_ecm_rx_data_length = 0; volatile uint32_t g_cdc_ecm_rx_data_length = 0;
volatile uint32_t g_cdc_ecm_tx_data_length = 0; volatile uint32_t g_cdc_ecm_tx_data_length = 0;
@@ -68,8 +72,10 @@ void usbd_cdc_ecm_send_notify(uint8_t notifycode, uint8_t value, uint32_t *speed
break; break;
} }
if (bytes2send) { if (usb_device_is_configured(0)) {
usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send); if (bytes2send) {
usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send);
}
} }
} }
@@ -93,11 +99,11 @@ static int cdc_ecm_class_interface_request_handler(uint8_t busid, struct usb_set
* bit3 Broadcast * bit3 Broadcast
* bit4 Multicast * bit4 Multicast
*/ */
if (g_current_net_status == 0) { #ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
g_current_net_status = 1; g_connect_speed_table[0] = 100000000; /* 100 Mbps */
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL); g_connect_speed_table[1] = 100000000; /* 100 Mbps */
} usbd_cdc_ecm_set_connect(true, g_connect_speed_table);
#endif
break; break;
default: default:
USB_LOG_WRN("Unhandled CDC ECM Class bRequest 0x%02x\r\n", setup->bRequest); USB_LOG_WRN("Unhandled CDC ECM Class bRequest 0x%02x\r\n", setup->bRequest);
@@ -117,10 +123,11 @@ void cdc_ecm_notify_handler(uint8_t busid, uint8_t event, void *arg)
g_current_net_status = 0; g_current_net_status = 0;
g_cdc_ecm_rx_data_length = 0; g_cdc_ecm_rx_data_length = 0;
g_cdc_ecm_tx_data_length = 0; g_cdc_ecm_tx_data_length = 0;
g_cdc_ecm_rx_data_buffer = NULL;
break; break;
case USBD_EVENT_CONFIGURED: case USBD_EVENT_CONFIGURED:
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(busid, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr)); #ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
#endif
break; break;
default: default:
@@ -132,14 +139,8 @@ void cdc_ecm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{ {
(void)busid; (void)busid;
g_cdc_ecm_rx_data_length += nbytes; g_cdc_ecm_rx_data_length = nbytes;
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_data_length);
if (nbytes < usbd_get_ep_mps(0, ep)) {
g_cdc_ecm_rx_data_buffer = g_cdc_ecm_rx_buffer;
usbd_cdc_ecm_data_recv_done(g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
} else {
usbd_ep_start_read(0, ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], usbd_get_ep_mps(0, ep));
}
} }
void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
@@ -150,6 +151,7 @@ void cdc_ecm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
/* send zlp */ /* send zlp */
usbd_ep_start_write(0, ep, NULL, 0); usbd_ep_start_write(0, ep, NULL, 0);
} else { } else {
usbd_cdc_ecm_data_send_done(g_cdc_ecm_tx_data_length);
g_cdc_ecm_tx_data_length = 0; g_cdc_ecm_tx_data_length = 0;
} }
} }
@@ -160,14 +162,20 @@ void cdc_ecm_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
(void)ep; (void)ep;
(void)nbytes; (void)nbytes;
if (g_current_net_status == 1) { if (g_current_net_status == 2) {
g_current_net_status = 2; g_current_net_status = 3;
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, g_connect_speed_table); usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE, 0, g_connect_speed_table);
} else {
g_current_net_status = 0;
} }
} }
int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len) int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len)
{ {
if (!usb_device_is_configured(0)) {
return -USB_ERR_NODEV;
}
if (g_cdc_ecm_tx_data_length > 0) { if (g_cdc_ecm_tx_data_length > 0) {
return -USB_ERR_BUSY; return -USB_ERR_BUSY;
} }
@@ -175,14 +183,17 @@ int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len)
g_cdc_ecm_tx_data_length = len; g_cdc_ecm_tx_data_length = len;
USB_LOG_DBG("txlen:%d\r\n", g_cdc_ecm_tx_data_length); USB_LOG_DBG("txlen:%d\r\n", g_cdc_ecm_tx_data_length);
return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, g_cdc_ecm_tx_data_length); return usbd_ep_start_write(0, cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, buf, len);
} }
void usbd_cdc_ecm_start_read_next(void) int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len)
{ {
if (!usb_device_is_configured(0)) {
return -USB_ERR_NODEV;
}
g_cdc_ecm_rx_data_length = 0; g_cdc_ecm_rx_data_length = 0;
g_cdc_ecm_rx_data_buffer = NULL; usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, buf, len);
usbd_ep_start_read(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, g_cdc_ecm_rx_buffer, usbd_get_ep_mps(0, cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr));
} }
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP #ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
@@ -190,19 +201,19 @@ struct pbuf *usbd_cdc_ecm_eth_rx(void)
{ {
struct pbuf *p; struct pbuf *p;
if (g_cdc_ecm_rx_data_buffer == NULL) { if (g_cdc_ecm_rx_data_length == 0) {
return NULL; return NULL;
} }
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_data_length, PBUF_POOL); p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_data_length, PBUF_POOL);
if (p == NULL) { if (p == NULL) {
usbd_cdc_ecm_start_read_next(); usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
return NULL; return NULL;
} }
usb_memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length); usb_memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
p->len = g_cdc_ecm_rx_data_length; p->len = g_cdc_ecm_rx_data_length;
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_data_length); USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_data_length);
usbd_cdc_ecm_start_read_next(); usbd_cdc_ecm_start_read(g_cdc_ecm_rx_buffer, CONFIG_CDC_ECM_ETH_MAX_SEGSZE);
return p; return p;
} }
@@ -250,13 +261,24 @@ struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const
return intf; return intf;
} }
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2]) void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2])
{ {
memcpy(g_connect_speed_table, speed, 8); if (connect) {
g_current_net_status = 2;
memcpy(g_connect_speed_table, speed, 8);
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL);
} else {
g_current_net_status = 1;
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_DISCONNECTED, NULL);
}
} }
__WEAK void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len) __WEAK void usbd_cdc_ecm_data_recv_done(uint32_t len)
{
(void)len;
}
__WEAK void usbd_cdc_ecm_data_send_done(uint32_t len)
{ {
(void)buf;
(void)len; (void)len;
} }

View File

@@ -12,21 +12,15 @@
extern "C" { extern "C" {
#endif #endif
/* Ethernet Maximum Segment size, typically 1514 bytes */
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U
/* Init cdc ecm interface driver */ /* Init cdc ecm interface driver */
struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const uint8_t int_ep, const uint8_t out_ep, const uint8_t in_ep); struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const uint8_t int_ep, const uint8_t out_ep, const uint8_t in_ep);
/* Setup request command callback api */ void usbd_cdc_ecm_set_connect(bool connect, uint32_t speed[2]);
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2]);
/* Api for eth only without any net stack */ void usbd_cdc_ecm_data_recv_done(uint32_t len);
uint8_t *usbd_cdc_ecm_get_tx_buffer(void); void usbd_cdc_ecm_data_send_done(uint32_t len);
void usbd_cdc_ecm_send_done(void);
int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len); int usbd_cdc_ecm_start_write(uint8_t *buf, uint32_t len);
void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len); int usbd_cdc_ecm_start_read(uint8_t *buf, uint32_t len);
void usbd_cdc_ecm_start_read_next(void);
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP #ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
#include "lwip/netif.h" #include "lwip/netif.h"

View File

@@ -6,6 +6,10 @@
#include "usbd_core.h" #include "usbd_core.h"
#include "usbd_cdc_ecm.h" #include "usbd_cdc_ecm.h"
#ifndef CONFIG_USBDEV_CDC_ECM_USING_LWIP
#error "Please enable CONFIG_USBDEV_CDC_ECM_USING_LWIP for this demo"
#endif
/*!< endpoint address */ /*!< endpoint address */
#define CDC_IN_EP 0x81 #define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02 #define CDC_OUT_EP 0x02
@@ -222,12 +226,12 @@ void cdc_ecm_lwip_init(void)
while (!netif_is_up(netif)) { while (!netif_is_up(netif)) {
} }
// while (dhserv_init(&dhcp_config)) {} while (dhserv_init(&dhcp_config)) {}
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {} while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
} }
void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len) void usbd_cdc_ecm_data_recv_done(uint32_t len)
{ {
} }