Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
宁楠萍
rt-thread
提交
bd566e6a
R
rt-thread
项目概览
宁楠萍
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bd566e6a
编写于
11月 21, 2017
作者:
lymzzyh
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[Components][Drivers][USB] Add CDC-ECM class (LWIP on USB)
Windows下没驱动 linux和mac下免驱
上级
334da974
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
686 addition
and
2 deletion
+686
-2
components/drivers/KConfig
components/drivers/KConfig
+8
-0
components/drivers/usb/usbdevice/SConscript
components/drivers/usb/usbdevice/SConscript
+3
-0
components/drivers/usb/usbdevice/class/cdc.h
components/drivers/usb/usbdevice/class/cdc.h
+62
-2
components/drivers/usb/usbdevice/class/ecm.c
components/drivers/usb/usbdevice/class/ecm.c
+602
-0
components/drivers/usb/usbdevice/core/usbdevice.c
components/drivers/usb/usbdevice/core/usbdevice.c
+11
-0
未找到文件。
components/drivers/KConfig
浏览文件 @
bd566e6a
...
...
@@ -132,6 +132,10 @@ menu "Using USB"
config _RT_USB_DEVICE_HID
bool "Enable to use device as HID device"
select RT_USB_DEVICE_HID
config _RT_USB_DEVICE_ECM
bool "Enable to use device as ecm device"
select RT_USB_DEVICE_ECM
depends on RT_USING_LWIP
endchoice
if RT_USB_DEVICE_COMPOSITE
config RT_USB_DEVICE_CDC
...
...
@@ -143,6 +147,10 @@ menu "Using USB"
config RT_USB_DEVICE_HID
bool "Enable to use device as HID device"
default n
config RT_USB_DEVICE_ECM
bool "Enable to use device as ecm device"
default n
depends on RT_USING_LWIP
endif
if RT_USB_DEVICE_HID
...
...
components/drivers/usb/usbdevice/SConscript
浏览文件 @
bd566e6a
...
...
@@ -16,6 +16,9 @@ if GetDepend('RT_USB_DEVICE_HID'):
if
GetDepend
(
'RT_USB_DEVICE_MSTORAGE'
):
src
+=
Glob
(
'class/mstorage.c'
)
if
GetDepend
(
'RT_USB_DEVICE_ECM'
):
src
+=
Glob
(
'class/ecm.c'
)
CPPPATH
=
[
cwd
]
group
=
DefineGroup
(
'rt_usbd'
,
src
,
depend
=
[
'RT_USING_USB_DEVICE'
],
CPPPATH
=
CPPPATH
)
...
...
components/drivers/usb/usbdevice/class/cdc.h
浏览文件 @
bd566e6a
...
...
@@ -31,6 +31,7 @@
#define USB_CDC_CLASS_COMM 0x02
#define USB_CDC_CLASS_DATA 0x0A
#define USB_CDC_SUBCLASS_NONE 0x00
#define USB_CDC_SUBCLASS_DLCM 0x01
#define USB_CDC_SUBCLASS_ACM 0x02
#define USB_CDC_SUBCLASS_TCM 0x03
...
...
@@ -38,9 +39,10 @@
#define USB_CDC_SUBCLASS_CCM 0x05
#define USB_CDC_SUBCLASS_ETH 0x06
#define USB_CDC_SUBCLASS_ATM 0x07
#define USB_CDC_SUBCLASS_EEM 0x0C
#define USB_CDC_PROTOCOL_NONE 0x00
#define USB_CDC_PROTOCOL_V25TER 0x01
#define USB_CDC_PROTOCOL_I430 0x30
#define USB_CDC_PROTOCOL_HDLC 0x31
#define USB_CDC_PROTOCOL_TRANS 0x32
...
...
@@ -54,6 +56,7 @@
#define USB_CDC_PROTOCOL_HOST 0xFD
#define USB_CDC_PROTOCOL_PUFD 0xFE
#define USB_CDC_PROTOCOL_VENDOR 0xFF
#define USB_CDC_PROTOCOL_EEM 0x07
#define USB_CDC_CS_INTERFACE 0x24
#define USB_CDC_CS_ENDPOINT 0x25
...
...
@@ -62,6 +65,7 @@
#define USB_CDC_SCS_CALL_MGMT 0x01
#define USB_CDC_SCS_ACM 0x02
#define USB_CDC_SCS_UNION 0x06
#define USB_CDC_SCS_ETH 0x0F
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
...
...
@@ -153,6 +157,30 @@ struct ucdc_comm_descriptor
};
typedef
struct
ucdc_comm_descriptor
*
ucdc_comm_desc_t
;
struct
ucdc_enet_descriptor
{
rt_uint8_t
bFunctionLength
;
rt_uint8_t
bDescriptorType
;
rt_uint8_t
bDescriptorSubtype
;
rt_uint8_t
iMACAddress
;
rt_uint8_t
bmEthernetStatistics
[
4
];
rt_uint16_t
wMaxSegmentSize
;
rt_uint16_t
wMCFilters
;
rt_uint8_t
bNumberPowerFilters
;
};
struct
ucdc_eth_descriptor
{
#ifdef RT_USB_DEVICE_COMPOSITE
struct
uiad_descriptor
iad_desc
;
#endif
struct
uinterface_descriptor
intf_desc
;
struct
ucdc_header_descriptor
hdr_desc
;
struct
ucdc_union_descriptor
union_desc
;
struct
ucdc_enet_descriptor
enet_desc
;
struct
uendpoint_descriptor
ep_desc
;
};
typedef
struct
ucdc_eth_descriptor
*
ucdc_eth_desc_t
;
struct
ucdc_data_descriptor
{
struct
uinterface_descriptor
intf_desc
;
...
...
@@ -177,7 +205,39 @@ struct cdc_eps
uep_t
ep_cmd
;
};
typedef
struct
cdc_eps
*
cdc_eps_t
;
struct
ucdc_management_element_notifications
{
rt_uint8_t
bmRequestType
;
rt_uint8_t
bNotificatinCode
;
rt_uint16_t
wValue
;
rt_uint16_t
wIndex
;
rt_uint16_t
wLength
;
};
typedef
struct
ucdc_management_element_notifications
*
ucdc_mg_notifications_t
;
struct
ucdc_connection_speed_change_data
{
rt_uint32_t
down_bit_rate
;
rt_uint32_t
up_bit_rate
;
};
typedef
struct
connection_speed_change_data
*
connect_speed_data_t
;
enum
ucdc_notification_code
{
UCDC_NOTIFI_NETWORK_CONNECTION
=
0x00
,
UCDC_NOTIFI_RESPONSE_AVAILABLE
=
0x01
,
UCDC_NOTIFI_AUX_JACK_HOOK_STATE
=
0x08
,
UCDC_NOTIFI_RING_DETECT
=
0x09
,
UCDC_NOTIFI_SERIAL_STATE
=
0x20
,
UCDC_NOTIFI_CALL_STATE_CHANGE
=
0x28
,
UCDC_NOTIFI_LINE_STATE_CHANGE
=
0x29
,
UCDC_NOTIFI_CONNECTION_SPEED_CHANGE
=
0x2A
,
};
typedef
enum
ucdc_notification_code
ucdc_notification_code_t
;
#pragma pack()
#endif
components/drivers/usb/usbdevice/class/ecm.c
0 → 100644
浏览文件 @
bd566e6a
/*
* File : ecm.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006-2013, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2017-11-19 ZYH first version
*/
#include <rtdevice.h>
#include "cdc.h"
#ifdef ECM_DEBUG
#define ECM_PRINTF rt_kprintf("[ECM] "); rt_kprintf
#else
#define ECM_PRINTF(...)
#endif
/* ECM_DEBUG */
/* RT-Thread LWIP ethernet interface */
#include <netif/ethernetif.h>
#ifndef USB_ETH_MTU
#define USB_ETH_MTU 1514
#endif
#define MAX_ADDR_LEN 6
struct
rt_ecm_eth
{
/* inherit from ethernet device */
struct
eth_device
parent
;
struct
ufunction
*
func
;
struct
cdc_eps
eps
;
/* interface address info */
rt_uint8_t
host_addr
[
MAX_ADDR_LEN
];
rt_uint8_t
dev_addr
[
MAX_ADDR_LEN
];
ALIGN
(
4
)
rt_uint8_t
rx_pool
[
64
];
ALIGN
(
4
)
rt_size_t
rx_size
;
ALIGN
(
4
)
rt_size_t
rx_offset
;
ALIGN
(
4
)
char
rx_buffer
[
USB_ETH_MTU
];
char
tx_buffer
[
USB_ETH_MTU
];
struct
rt_semaphore
tx_buffer_free
;
};
typedef
struct
rt_ecm_eth
*
rt_ecm_eth_t
;
ALIGN
(
4
)
static
struct
udevice_descriptor
_dev_desc
=
{
USB_DESC_LENGTH_DEVICE
,
/* bLength */
USB_DESC_TYPE_DEVICE
,
/* type */
USB_BCD_VERSION
,
/* bcdUSB */
USB_CLASS_CDC
,
/* bDeviceClass */
USB_CDC_SUBCLASS_ETH
,
/* bDeviceSubClass */
USB_CDC_PROTOCOL_NONE
,
/* bDeviceProtocol */
0x40
,
/* bMaxPacketSize0 */
_VENDOR_ID
,
/* idVendor */
_PRODUCT_ID
,
/* idProduct */
USB_BCD_DEVICE
,
/* bcdDevice */
USB_STRING_MANU_INDEX
,
/* iManufacturer */
USB_STRING_PRODUCT_INDEX
,
/* iProduct */
USB_STRING_SERIAL_INDEX
,
/* iSerialNumber */
USB_DYNAMIC
/* bNumConfigurations */
};
/* communcation interface descriptor */
ALIGN
(
4
)
const
static
struct
ucdc_eth_descriptor
_comm_desc
=
{
#ifdef RT_USB_DEVICE_COMPOSITE
/* Interface Association Descriptor */
USB_DESC_LENGTH_IAD
,
USB_DESC_TYPE_IAD
,
USB_DYNAMIC
,
0x02
,
USB_CDC_CLASS_COMM
,
USB_CDC_SUBCLASS_ETH
,
USB_CDC_PROTOCOL_NONE
,
0x00
,
#endif
/* Interface Descriptor */
USB_DESC_LENGTH_INTERFACE
,
USB_DESC_TYPE_INTERFACE
,
USB_DYNAMIC
,
0x00
,
0x01
,
USB_CDC_CLASS_COMM
,
USB_CDC_SUBCLASS_ETH
,
USB_CDC_PROTOCOL_NONE
,
0x00
,
/* Header Functional Descriptor */
sizeof
(
struct
ucdc_header_descriptor
),
USB_CDC_CS_INTERFACE
,
USB_CDC_SCS_HEADER
,
0x0110
,
/* Union Functional Descriptor */
sizeof
(
struct
ucdc_union_descriptor
),
USB_CDC_CS_INTERFACE
,
USB_CDC_SCS_UNION
,
USB_DYNAMIC
,
USB_DYNAMIC
,
/* Abstract Control Management Functional Descriptor */
sizeof
(
struct
ucdc_enet_descriptor
),
USB_CDC_CS_INTERFACE
,
USB_CDC_SCS_ETH
,
USB_STRING_SERIAL_INDEX
,
{
0
,
0
,
0
,
0
},
USB_ETH_MTU
,
0x00
,
0x00
,
/* Endpoint Descriptor */
USB_DESC_LENGTH_ENDPOINT
,
USB_DESC_TYPE_ENDPOINT
,
USB_DIR_IN
|
USB_DYNAMIC
,
USB_EP_ATTR_INT
,
0x08
,
0xFF
,
};
/* data interface descriptor */
ALIGN
(
4
)
const
static
struct
ucdc_data_descriptor
_data_desc
=
{
/* interface descriptor */
USB_DESC_LENGTH_INTERFACE
,
USB_DESC_TYPE_INTERFACE
,
USB_DYNAMIC
,
0x00
,
0x02
,
USB_CDC_CLASS_DATA
,
USB_CDC_SUBCLASS_ETH
,
0x00
,
0x00
,
/* endpoint, bulk out */
USB_DESC_LENGTH_ENDPOINT
,
USB_DESC_TYPE_ENDPOINT
,
USB_DIR_OUT
|
USB_DYNAMIC
,
USB_EP_ATTR_BULK
,
USB_CDC_BUFSIZE
,
0x00
,
/* endpoint, bulk in */
USB_DESC_LENGTH_ENDPOINT
,
USB_DESC_TYPE_ENDPOINT
,
USB_DYNAMIC
|
USB_DIR_IN
,
USB_EP_ATTR_BULK
,
USB_CDC_BUFSIZE
,
0x00
,
};
ALIGN
(
4
)
const
static
char
*
_ustring
[]
=
{
"Language"
,
/* LANGID */
"RT-Thread Team."
,
/* MANU */
"RT-Thread ECM device"
,
/* PRODUCT */
"3497F694ECAB"
,
/* SERIAL (MAC)*/
"Configuration"
,
/* CONFIG */
"Interface"
,
/* INTERFACE */
};
ALIGN
(
4
)
static
struct
usb_qualifier_descriptor
dev_qualifier
=
{
sizeof
(
dev_qualifier
),
USB_DESC_TYPE_DEVICEQUALIFIER
,
0x0200
,
USB_CLASS_CDC
,
0x00
,
64
,
0x01
,
0
,
};
static
rt_err_t
_cdc_send_notifi
(
ufunction_t
func
,
ucdc_notification_code_t
notifi
,
rt_uint16_t
wValue
,
rt_uint16_t
wLength
)
{
static
struct
ucdc_management_element_notifications
_notifi
;
cdc_eps_t
eps
;
RT_ASSERT
(
func
!=
RT_NULL
)
eps
=
&
((
rt_ecm_eth_t
)
func
->
user_data
)
->
eps
;
_notifi
.
bmRequestType
=
0xA1
;
_notifi
.
bNotificatinCode
=
notifi
;
_notifi
.
wValue
=
wValue
;
_notifi
.
wLength
=
wLength
;
eps
->
ep_cmd
->
request
.
buffer
=
(
void
*
)
&
_notifi
;
eps
->
ep_cmd
->
request
.
size
=
8
;
eps
->
ep_cmd
->
request
.
req_type
=
UIO_REQUEST_WRITE
;
rt_usbd_io_request
(
func
->
device
,
eps
->
ep_cmd
,
&
eps
->
ep_cmd
->
request
);
return
RT_EOK
;
}
static
rt_err_t
_ecm_set_eth_packet_filter
(
ufunction_t
func
,
ureq_t
setup
)
{
rt_ecm_eth_t
_ecm_eth
=
(
rt_ecm_eth_t
)
func
->
user_data
;
dcd_ep0_send_status
(
func
->
device
->
dcd
);
/* send link up. */
eth_device_linkchange
(
&
_ecm_eth
->
parent
,
RT_TRUE
);
_cdc_send_notifi
(
func
,
UCDC_NOTIFI_NETWORK_CONNECTION
,
1
,
0
);
return
RT_EOK
;
}
/**
* This function will handle rndis interface request.
*
* @param device the usb device object.
* @param setup the setup request.
*
* @return RT_EOK on successful.
*/
static
rt_err_t
_interface_handler
(
ufunction_t
func
,
ureq_t
setup
)
{
RT_ASSERT
(
func
!=
RT_NULL
);
RT_ASSERT
(
setup
!=
RT_NULL
);
switch
(
setup
->
bRequest
)
{
case
CDC_SET_ETH_PACKET_FILTER
:
_ecm_set_eth_packet_filter
(
func
,
setup
);
break
;
default:
rt_kprintf
(
"setup->bRequest:0x%02X"
,
setup
->
bRequest
);
break
;
}
return
RT_EOK
;
}
/**
* This function will handle rndis bulk in endpoint request.
*
* @param device the usb device object.
* @param size request size.
*
* @return RT_EOK.
*/
static
rt_err_t
_ep_in_handler
(
ufunction_t
func
,
rt_size_t
size
)
{
rt_ecm_eth_t
ecm_device
=
(
rt_ecm_eth_t
)
func
->
user_data
;
rt_sem_release
(
&
ecm_device
->
tx_buffer_free
);
return
RT_EOK
;
}
/**
* This function will handle RNDIS bulk out endpoint request.
*
* @param device the usb device object.
* @param size request size.
*
* @return RT_EOK.
*/
static
rt_err_t
_ep_out_handler
(
ufunction_t
func
,
rt_size_t
size
)
{
rt_ecm_eth_t
ecm_device
=
(
rt_ecm_eth_t
)
func
->
user_data
;
rt_memcpy
((
void
*
)(
ecm_device
->
rx_buffer
+
ecm_device
->
rx_offset
),
ecm_device
->
rx_pool
,
size
);
ecm_device
->
rx_offset
+=
size
;
if
(
size
<
EP_MAXPACKET
(
ecm_device
->
eps
.
ep_out
))
{
ecm_device
->
rx_size
=
ecm_device
->
rx_offset
;
ecm_device
->
rx_offset
=
0
;
eth_device_ready
(
&
ecm_device
->
parent
);
}
else
{
ecm_device
->
eps
.
ep_out
->
request
.
buffer
=
ecm_device
->
eps
.
ep_out
->
buffer
;
ecm_device
->
eps
.
ep_out
->
request
.
size
=
EP_MAXPACKET
(
ecm_device
->
eps
.
ep_out
);
ecm_device
->
eps
.
ep_out
->
request
.
req_type
=
UIO_REQUEST_READ_BEST
;
rt_usbd_io_request
(
ecm_device
->
func
->
device
,
ecm_device
->
eps
.
ep_out
,
&
ecm_device
->
eps
.
ep_out
->
request
);
}
return
RT_EOK
;
}
static
rt_err_t
rt_ecm_eth_init
(
rt_device_t
dev
)
{
return
RT_EOK
;
}
static
rt_err_t
rt_ecm_eth_open
(
rt_device_t
dev
,
rt_uint16_t
oflag
)
{
return
RT_EOK
;
}
static
rt_err_t
rt_ecm_eth_close
(
rt_device_t
dev
)
{
return
RT_EOK
;
}
static
rt_size_t
rt_ecm_eth_read
(
rt_device_t
dev
,
rt_off_t
pos
,
void
*
buffer
,
rt_size_t
size
)
{
rt_set_errno
(
-
RT_ENOSYS
);
return
0
;
}
static
rt_size_t
rt_ecm_eth_write
(
rt_device_t
dev
,
rt_off_t
pos
,
const
void
*
buffer
,
rt_size_t
size
)
{
rt_set_errno
(
-
RT_ENOSYS
);
return
0
;
}
static
rt_err_t
rt_ecm_eth_control
(
rt_device_t
dev
,
int
cmd
,
void
*
args
)
{
rt_ecm_eth_t
ecm_eth_dev
=
(
rt_ecm_eth_t
)
dev
;
switch
(
cmd
)
{
case
NIOCTL_GADDR
:
/* get mac address */
if
(
args
)
rt_memcpy
(
args
,
ecm_eth_dev
->
dev_addr
,
MAX_ADDR_LEN
);
else
return
-
RT_ERROR
;
break
;
default
:
break
;
}
return
RT_EOK
;
}
struct
pbuf
*
rt_ecm_eth_rx
(
rt_device_t
dev
)
{
struct
pbuf
*
p
=
RT_NULL
;
rt_uint32_t
offset
=
0
;
rt_ecm_eth_t
ecm_eth_dev
=
(
rt_ecm_eth_t
)
dev
;
if
(
ecm_eth_dev
->
rx_size
!=
0
)
{
/* allocate buffer */
p
=
pbuf_alloc
(
PBUF_RAW
,
ecm_eth_dev
->
rx_size
,
PBUF_RAM
);
if
(
p
!=
RT_NULL
)
{
struct
pbuf
*
q
;
for
(
q
=
p
;
q
!=
RT_NULL
;
q
=
q
->
next
)
{
/* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */
rt_memcpy
(
q
->
payload
,
(
rt_uint8_t
*
)((
ecm_eth_dev
->
rx_buffer
)
+
offset
),
q
->
len
);
offset
+=
q
->
len
;
}
}
}
{
if
(
ecm_eth_dev
->
func
->
device
->
state
==
USB_STATE_CONFIGURED
)
{
ecm_eth_dev
->
rx_size
=
0
;
ecm_eth_dev
->
rx_offset
=
0
;
ecm_eth_dev
->
eps
.
ep_out
->
request
.
buffer
=
ecm_eth_dev
->
eps
.
ep_out
->
buffer
;
ecm_eth_dev
->
eps
.
ep_out
->
request
.
size
=
EP_MAXPACKET
(
ecm_eth_dev
->
eps
.
ep_out
);
ecm_eth_dev
->
eps
.
ep_out
->
request
.
req_type
=
UIO_REQUEST_READ_BEST
;
rt_usbd_io_request
(
ecm_eth_dev
->
func
->
device
,
ecm_eth_dev
->
eps
.
ep_out
,
&
ecm_eth_dev
->
eps
.
ep_out
->
request
);
}
}
return
p
;
}
rt_err_t
rt_ecm_eth_tx
(
rt_device_t
dev
,
struct
pbuf
*
p
)
{
struct
pbuf
*
q
;
char
*
pbuffer
;
rt_err_t
result
=
RT_EOK
;
rt_ecm_eth_t
ecm_eth_dev
=
(
rt_ecm_eth_t
)
dev
;
if
(
!
ecm_eth_dev
->
parent
.
link_status
)
{
ECM_PRINTF
(
"linkdown, drop pkg
\r\n
"
);
return
RT_EOK
;
}
// RT_ASSERT(p->tot_len < USB_ETH_MTU);
if
(
p
->
tot_len
>
USB_ETH_MTU
)
{
ECM_PRINTF
(
"RNDIS MTU is:%d, but the send packet size is %d
\r\n
"
,
USB_ETH_MTU
,
p
->
tot_len
);
p
->
tot_len
=
USB_ETH_MTU
;
}
result
=
rt_sem_take
(
&
ecm_eth_dev
->
tx_buffer_free
,
RT_WAITING_FOREVER
);
if
(
result
!=
RT_EOK
)
{
return
result
;
}
pbuffer
=
(
char
*
)
&
ecm_eth_dev
->
tx_buffer
;
for
(
q
=
p
;
q
!=
NULL
;
q
=
q
->
next
)
{
rt_memcpy
(
pbuffer
,
q
->
payload
,
q
->
len
);
pbuffer
+=
q
->
len
;
}
{
if
(
ecm_eth_dev
->
func
->
device
->
state
==
USB_STATE_CONFIGURED
)
{
ecm_eth_dev
->
eps
.
ep_in
->
request
.
buffer
=
(
void
*
)
&
ecm_eth_dev
->
tx_buffer
;
ecm_eth_dev
->
eps
.
ep_in
->
request
.
size
=
p
->
tot_len
;
ecm_eth_dev
->
eps
.
ep_in
->
request
.
req_type
=
UIO_REQUEST_WRITE
;
rt_usbd_io_request
(
ecm_eth_dev
->
func
->
device
,
ecm_eth_dev
->
eps
.
ep_in
,
&
ecm_eth_dev
->
eps
.
ep_in
->
request
);
}
}
return
result
;
}
/**
* This function will handle RNDIS interrupt in endpoint request.
*
* @param device the usb device object.
* @param size request size.
*
* @return RT_EOK.
*/
static
rt_err_t
_ep_cmd_handler
(
ufunction_t
func
,
rt_size_t
size
)
{
return
RT_EOK
;
}
/**
* This function will run cdc class, it will be called on handle set configuration request.
*
* @param device the usb device object.
*
* @return RT_EOK on successful.
*/
static
rt_err_t
_function_enable
(
ufunction_t
func
)
{
cdc_eps_t
eps
;
rt_ecm_eth_t
ecm_device
=
(
rt_ecm_eth_t
)
func
->
user_data
;
eps
=
(
cdc_eps_t
)
&
ecm_device
->
eps
;
eps
->
ep_out
->
buffer
=
ecm_device
->
rx_pool
;
ecm_device
->
rx_size
=
0
;
ecm_device
->
rx_offset
=
0
;
eps
->
ep_out
->
request
.
buffer
=
(
void
*
)
eps
->
ep_out
->
buffer
;
eps
->
ep_out
->
request
.
size
=
EP_MAXPACKET
(
eps
->
ep_out
);
eps
->
ep_out
->
request
.
req_type
=
UIO_REQUEST_READ_BEST
;
rt_usbd_io_request
(
func
->
device
,
eps
->
ep_out
,
&
eps
->
ep_out
->
request
);
return
RT_EOK
;
}
/**
* This function will stop cdc class, it will be called on handle set configuration request.
*
* @param device the usb device object.
*
* @return RT_EOK on successful.
*/
static
rt_err_t
_function_disable
(
ufunction_t
func
)
{
eth_device_linkchange
(
&
((
rt_ecm_eth_t
)
func
->
user_data
)
->
parent
,
RT_FALSE
);
return
RT_EOK
;
}
static
struct
ufunction_ops
ops
=
{
_function_enable
,
_function_disable
,
RT_NULL
,
};
/**
* This function will configure cdc descriptor.
*
* @param comm the communication interface number.
* @param data the data interface number.
*
* @return RT_EOK on successful.
*/
static
rt_err_t
_cdc_descriptor_config
(
ucdc_comm_desc_t
comm
,
rt_uint8_t
cintf_nr
,
ucdc_data_desc_t
data
,
rt_uint8_t
dintf_nr
)
{
comm
->
call_mgmt_desc
.
data_interface
=
dintf_nr
;
comm
->
union_desc
.
master_interface
=
cintf_nr
;
comm
->
union_desc
.
slave_interface0
=
dintf_nr
;
#ifdef RT_USB_DEVICE_COMPOSITE
comm
->
iad_desc
.
bFirstInterface
=
cintf_nr
;
#endif
return
RT_EOK
;
}
/**
* This function will create a cdc ecm class instance.
*
* @param device the usb device object.
*
* @return RT_EOK on successful.
*/
ufunction_t
rt_usbd_function_ecm_create
(
udevice_t
device
)
{
ufunction_t
cdc
;
rt_ecm_eth_t
_ecm_eth
;
cdc_eps_t
eps
;
uintf_t
intf_comm
,
intf_data
;
ualtsetting_t
comm_setting
,
data_setting
;
ucdc_data_desc_t
data_desc
;
ucdc_eth_desc_t
comm_desc
;
/* parameter check */
RT_ASSERT
(
device
!=
RT_NULL
);
/* set usb device string description */
rt_usbd_device_set_string
(
device
,
_ustring
);
/* create a cdc class */
cdc
=
rt_usbd_function_new
(
device
,
&
_dev_desc
,
&
ops
);
rt_usbd_device_set_qualifier
(
device
,
&
dev_qualifier
);
_ecm_eth
=
rt_malloc
(
sizeof
(
struct
rt_ecm_eth
));
rt_memset
(
_ecm_eth
,
0
,
sizeof
(
struct
rt_ecm_eth
));
cdc
->
user_data
=
_ecm_eth
;
_ecm_eth
->
func
=
cdc
;
/* create a cdc class endpoints collection */
eps
=
&
_ecm_eth
->
eps
;
/* create a cdc communication interface and a cdc data interface */
intf_comm
=
rt_usbd_interface_new
(
device
,
_interface_handler
);
intf_data
=
rt_usbd_interface_new
(
device
,
_interface_handler
);
/* create a communication alternate setting and a data alternate setting */
comm_setting
=
rt_usbd_altsetting_new
(
sizeof
(
struct
ucdc_eth_descriptor
));
data_setting
=
rt_usbd_altsetting_new
(
sizeof
(
struct
ucdc_data_descriptor
));
/* config desc in alternate setting */
rt_usbd_altsetting_config_descriptor
(
comm_setting
,
&
_comm_desc
,
(
rt_off_t
)
&
((
ucdc_eth_desc_t
)
0
)
->
intf_desc
);
rt_usbd_altsetting_config_descriptor
(
data_setting
,
&
_data_desc
,
0
);
/* configure the cdc interface descriptor */
_cdc_descriptor_config
(
comm_setting
->
desc
,
intf_comm
->
intf_num
,
data_setting
->
desc
,
intf_data
->
intf_num
);
/* create a command endpoint */
comm_desc
=
(
ucdc_eth_desc_t
)
comm_setting
->
desc
;
eps
->
ep_cmd
=
rt_usbd_endpoint_new
(
&
comm_desc
->
ep_desc
,
_ep_cmd_handler
);
/* add the command endpoint to the cdc communication interface */
rt_usbd_altsetting_add_endpoint
(
comm_setting
,
eps
->
ep_cmd
);
/* add the communication alternate setting to the communication interface,
then set default setting of the interface */
rt_usbd_interface_add_altsetting
(
intf_comm
,
comm_setting
);
rt_usbd_set_altsetting
(
intf_comm
,
0
);
/* add the communication interface to the cdc class */
rt_usbd_function_add_interface
(
cdc
,
intf_comm
);
/* create a bulk in and a bulk out endpoint */
data_desc
=
(
ucdc_data_desc_t
)
data_setting
->
desc
;
eps
->
ep_out
=
rt_usbd_endpoint_new
(
&
data_desc
->
ep_out_desc
,
_ep_out_handler
);
eps
->
ep_in
=
rt_usbd_endpoint_new
(
&
data_desc
->
ep_in_desc
,
_ep_in_handler
);
/* add the bulk out and bulk in endpoints to the data alternate setting */
rt_usbd_altsetting_add_endpoint
(
data_setting
,
eps
->
ep_in
);
rt_usbd_altsetting_add_endpoint
(
data_setting
,
eps
->
ep_out
);
/* add the data alternate setting to the data interface
then set default setting of the interface */
rt_usbd_interface_add_altsetting
(
intf_data
,
data_setting
);
rt_usbd_set_altsetting
(
intf_data
,
0
);
/* add the cdc data interface to cdc class */
rt_usbd_function_add_interface
(
cdc
,
intf_data
);
rt_sem_init
(
&
_ecm_eth
->
tx_buffer_free
,
"ue_tx"
,
1
,
RT_IPC_FLAG_FIFO
);
/* OUI 00-00-00, only for test. */
_ecm_eth
->
dev_addr
[
0
]
=
0x34
;
_ecm_eth
->
dev_addr
[
1
]
=
0x97
;
_ecm_eth
->
dev_addr
[
2
]
=
0xF6
;
/* generate random MAC. */
_ecm_eth
->
dev_addr
[
3
]
=
0x94
;
//*(const rt_uint8_t *)(0x1fff7a10);
_ecm_eth
->
dev_addr
[
4
]
=
0xEC
;
//*(const rt_uint8_t *)(0x1fff7a14);
_ecm_eth
->
dev_addr
[
5
]
=
0xAC
;
//(const rt_uint8_t *)(0x1fff7a18);
/* OUI 00-00-00, only for test. */
_ecm_eth
->
host_addr
[
0
]
=
0x34
;
_ecm_eth
->
host_addr
[
1
]
=
0x97
;
_ecm_eth
->
host_addr
[
2
]
=
0xF6
;
/* generate random MAC. */
_ecm_eth
->
host_addr
[
3
]
=
0x94
;
//*(const rt_uint8_t *)(0x1fff7a10);
_ecm_eth
->
host_addr
[
4
]
=
0xEC
;
//*(const rt_uint8_t *)(0x1fff7a14);
_ecm_eth
->
host_addr
[
5
]
=
0xAB
;
//*(const rt_uint8_t *)(0x1fff7a18);
_ecm_eth
->
parent
.
parent
.
init
=
rt_ecm_eth_init
;
_ecm_eth
->
parent
.
parent
.
open
=
rt_ecm_eth_open
;
_ecm_eth
->
parent
.
parent
.
close
=
rt_ecm_eth_close
;
_ecm_eth
->
parent
.
parent
.
read
=
rt_ecm_eth_read
;
_ecm_eth
->
parent
.
parent
.
write
=
rt_ecm_eth_write
;
_ecm_eth
->
parent
.
parent
.
control
=
rt_ecm_eth_control
;
_ecm_eth
->
parent
.
parent
.
user_data
=
device
;
_ecm_eth
->
parent
.
eth_rx
=
rt_ecm_eth_rx
;
_ecm_eth
->
parent
.
eth_tx
=
rt_ecm_eth_tx
;
/* register eth device */
eth_device_init
(
&
_ecm_eth
->
parent
,
"u0"
);
/* send link up. */
eth_device_linkchange
(
&
_ecm_eth
->
parent
,
RT_FALSE
);
return
cdc
;
}
components/drivers/usb/usbdevice/core/usbdevice.c
浏览文件 @
bd566e6a
...
...
@@ -132,6 +132,17 @@ rt_err_t rt_usb_device_init(void)
}
#endif
#ifdef RT_USB_DEVICE_ECM
{
extern
ufunction_t
rt_usbd_function_ecm_create
(
udevice_t
device
);
/* create a rndis function object */
func
=
rt_usbd_function_ecm_create
(
udevice
);
/* add the function to the configuration */
rt_usbd_config_add_function
(
cfg
,
func
);
}
#endif
/* set device descriptor to the device */
#ifdef RT_USB_DEVICE_COMPOSITE
rt_usbd_device_set_descriptor
(
udevice
,
&
compsit_desc
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录