Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
在你之后
rt-thread
提交
c8932cda
R
rt-thread
项目概览
在你之后
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
c8932cda
编写于
11月 30, 2017
作者:
B
bernard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[BSP] Add SDIO/EMAC drivers for VExpress A9 bsp
上级
02106c0b
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
1553 addition
and
15 deletion
+1553
-15
bsp/qemu-vexpress-a9/.config
bsp/qemu-vexpress-a9/.config
+37
-9
bsp/qemu-vexpress-a9/applications/mnt.c
bsp/qemu-vexpress-a9/applications/mnt.c
+19
-0
bsp/qemu-vexpress-a9/drivers/drv_sdio.c
bsp/qemu-vexpress-a9/drivers/drv_sdio.c
+456
-0
bsp/qemu-vexpress-a9/drivers/drv_sdio.h
bsp/qemu-vexpress-a9/drivers/drv_sdio.h
+47
-0
bsp/qemu-vexpress-a9/drivers/drv_smc911x.c
bsp/qemu-vexpress-a9/drivers/drv_smc911x.c
+551
-0
bsp/qemu-vexpress-a9/drivers/drv_smc911x.h
bsp/qemu-vexpress-a9/drivers/drv_smc911x.h
+402
-0
bsp/qemu-vexpress-a9/drivers/realview.h
bsp/qemu-vexpress-a9/drivers/realview.h
+8
-0
bsp/qemu-vexpress-a9/rtconfig.h
bsp/qemu-vexpress-a9/rtconfig.h
+33
-6
未找到文件。
bsp/qemu-vexpress-a9/.config
浏览文件 @
c8932cda
...
...
@@ -8,6 +8,9 @@
#
CONFIG_RT_NAME_MAX
=
8
CONFIG_RT_ALIGN_SIZE
=
4
# CONFIG_RT_THREAD_PRIORITY_8 is not set
CONFIG_RT_THREAD_PRIORITY_32
=
y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX
=
32
CONFIG_RT_TICK_PER_SECOND
=
100
CONFIG_RT_DEBUG
=
y
...
...
@@ -33,9 +36,11 @@ CONFIG_RT_USING_SIGNALS=y
#
CONFIG_RT_USING_MEMPOOL
=
y
CONFIG_RT_USING_MEMHEAP
=
y
CONFIG_RT_USING_HEAP
=
y
# CONFIG_RT_USING_NOHEAP is not set
CONFIG_RT_USING_SMALL_MEM
=
y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
CONFIG_RT_USING_HEAP
=
y
#
# Kernel Device Object
...
...
@@ -79,6 +84,7 @@ CONFIG_FINSH_USING_MSH_DEFAULT=y
CONFIG_RT_USING_DFS
=
y
CONFIG_DFS_USING_WORKDIR
=
y
CONFIG_DFS_FILESYSTEMS_MAX
=
2
CONFIG_DFS_FILESYSTEM_TYPES_MAX
=
2
CONFIG_DFS_FD_MAX
=
4
CONFIG_RT_USING_DFS_ELMFAT
=
y
...
...
@@ -131,6 +137,11 @@ CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y
# CONFIG_RT_USING_ENC28J60 is not set
# CONFIG_RT_USING_SPI_WIFI is not set
CONFIG_RT_USING_WDT
=
y
# CONFIG_RT_USING_WIFI is not set
#
# Using USB
#
# CONFIG_RT_USING_USB_HOST is not set
# CONFIG_RT_USING_USB_DEVICE is not set
...
...
@@ -153,6 +164,7 @@ CONFIG_RT_USING_POSIX_TERMIOS=y
CONFIG_RT_USING_LWIP
=
y
# CONFIG_RT_USING_LWIP141 is not set
CONFIG_RT_USING_LWIP202
=
y
# CONFIG_RT_USING_LWIP_IPV6 is not set
# CONFIG_RT_LWIP_IGMP is not set
CONFIG_RT_LWIP_ICMP
=
y
# CONFIG_RT_LWIP_SNMP is not set
...
...
@@ -233,6 +245,7 @@ CONFIG_RTGUI_IMAGE_CONTAINER=y
#
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
#
# IoT - internet of things
...
...
@@ -243,21 +256,19 @@ CONFIG_RTGUI_IMAGE_CONTAINER=y
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_EZXML is not set
#
# Marvell WiFi
#
# CONFIG_PKG_USING_MARVELLWIFI is not set
# CONFIG_PKG_USING_NANOPB is not set
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_libsodium is not set
#
# language packages
#
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
#
# multimedia packages
...
...
@@ -268,13 +279,30 @@ CONFIG_RTGUI_IMAGE_CONTAINER=y
#
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
#
# miscellaneous packages
#
CONFIG_PKG_USING_HELLO
=
y
CONFIG_PKG_HELLO_PATH
=
"/packages/misc/hello"
CONFIG_PKG_HELLO_VER
=
"v1.0.0"
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
#
# example package: hello
#
# CONFIG_PKG_USING_HELLO is not set
#
# Privated Packages of RealThread
#
# CONFIG_PKG_USING_CODEC is not set
# CONFIG_PKG_USING_PLAYER is not set
#
# Network Utilities
#
# CONFIG_PKG_USING_MDNS is not set
# CONFIG_PKG_USING_UPNP is not set
CONFIG_RT_USING_UART0
=
y
CONFIG_RT_USING_UART1
=
y
CONFIG_BSP_DRV_CLCD
=
y
...
...
bsp/qemu-vexpress-a9/applications/mnt.c
0 → 100644
浏览文件 @
c8932cda
#include <rtthread.h>
#ifdef RT_USING_DFS
#include <dfs_fs.h>
int
mnt_init
(
void
)
{
rt_thread_delay
(
RT_TICK_PER_SECOND
);
if
(
dfs_mount
(
"sd0"
,
"/"
,
"elm"
,
0
,
0
)
==
0
)
{
rt_kprintf
(
"file system initialization done!
\n
"
);
}
return
0
;
}
INIT_ENV_EXPORT
(
mnt_init
);
#endif
bsp/qemu-vexpress-a9/drivers/drv_sdio.c
0 → 100644
浏览文件 @
c8932cda
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/mmcsd_core.h>
#include <stdint.h>
#include <stdio.h>
#include "drv_sdio.h"
#ifdef RT_USING_SDIO
#define MMC_BASE_ADDR (0x10005000)
#define PL180_POWER (0x00)
#define PL180_CLOCK (0x04)
#define PL180_ARGUMENT (0x08)
#define PL180_COMMAND (0x0c)
#define PL180_RESPCMD (0x10)
#define PL180_RESP0 (0x14)
#define PL180_RESP1 (0x18)
#define PL180_RESP2 (0x1c)
#define PL180_RESP3 (0x20)
#define PL180_DATA_TIMER (0x24)
#define PL180_DATA_LENGTH (0x28)
#define PL180_DATA_CTRL (0x2c)
#define PL180_DATA_CNT (0x30)
#define PL180_STATUS (0x34)
#define PL180_CLEAR (0x38)
#define PL180_MASK0 (0x3c)
#define PL180_MASK1 (0x40)
#define PL180_SELECT (0x44)
#define PL180_FIFO_CNT (0x48)
#define PL180_FIFO (0x80)
#define PL180_RSP_NONE (0 << 0)
#define PL180_RSP_PRESENT (1 << 0)
#define PL180_RSP_136BIT (1 << 1)
#define PL180_RSP_CRC (1 << 2)
#define PL180_CMD_WAITRESP (1 << 6)
#define PL180_CMD_LONGRSP (1 << 7)
#define PL180_CMD_WAITINT (1 << 8)
#define PL180_CMD_WAITPEND (1 << 9)
#define PL180_CMD_ENABLE (1 << 10)
#define PL180_STAT_CMD_CRC_FAIL (1 << 0)
#define PL180_STAT_DAT_CRC_FAIL (1 << 1)
#define PL180_STAT_CMD_TIME_OUT (1 << 2)
#define PL180_STAT_DAT_TIME_OUT (1 << 3)
#define PL180_STAT_TX_UNDERRUN (1 << 4)
#define PL180_STAT_RX_OVERRUN (1 << 5)
#define PL180_STAT_CMD_RESP_END (1 << 6)
#define PL180_STAT_CMD_SENT (1 << 7)
#define PL180_STAT_DAT_END (1 << 8)
#define PL180_STAT_DAT_BLK_END (1 << 10)
#define PL180_STAT_CMD_ACT (1 << 11)
#define PL180_STAT_TX_ACT (1 << 12)
#define PL180_STAT_RX_ACT (1 << 13)
#define PL180_STAT_TX_FIFO_HALF (1 << 14)
#define PL180_STAT_RX_FIFO_HALF (1 << 15)
#define PL180_STAT_TX_FIFO_FULL (1 << 16)
#define PL180_STAT_RX_FIFO_FULL (1 << 17)
#define PL180_STAT_TX_FIFO_ZERO (1 << 18)
#define PL180_STAT_RX_DAT_ZERO (1 << 19)
#define PL180_STAT_TX_DAT_AVL (1 << 20)
#define PL180_STAT_RX_FIFO_AVL (1 << 21)
#define PL180_CLR_CMD_CRC_FAIL (1 << 0)
#define PL180_CLR_DAT_CRC_FAIL (1 << 1)
#define PL180_CLR_CMD_TIMEOUT (1 << 2)
#define PL180_CLR_DAT_TIMEOUT (1 << 3)
#define PL180_CLR_TX_UNDERRUN (1 << 4)
#define PL180_CLR_RX_OVERRUN (1 << 5)
#define PL180_CLR_CMD_RESP_END (1 << 6)
#define PL180_CLR_CMD_SENT (1 << 7)
#define PL180_CLR_DAT_END (1 << 8)
#define PL180_CLR_DAT_BLK_END (1 << 10)
#define DBG_LEVEL DBG_LOG
// #define DBG_ENABLE
#define DBG_COLOR
#include "rtdbg.h"
struct
sdhci_pl180_pdata_t
{
rt_uint32_t
virt
;
};
static
inline
rt_uint32_t
read32
(
uint32_t
addr
)
{
return
(
*
((
volatile
rt_uint32_t
*
)(
addr
))
);
}
static
inline
void
write32
(
uint32_t
addr
,
rt_uint32_t
value
)
{
*
((
volatile
rt_uint32_t
*
)(
addr
))
=
value
;
}
static
rt_err_t
pl180_transfer_command
(
struct
sdhci_pl180_pdata_t
*
pdat
,
struct
sdhci_cmd_t
*
cmd
)
{
rt_uint32_t
cmdidx
;
rt_uint32_t
status
;
rt_err_t
ret
=
RT_EOK
;
if
(
read32
(
pdat
->
virt
+
PL180_COMMAND
)
&
PL180_CMD_ENABLE
)
write32
(
pdat
->
virt
+
PL180_COMMAND
,
0x0
);
cmdidx
=
(
cmd
->
cmdidx
&
0xff
)
|
PL180_CMD_ENABLE
;
if
(
cmd
->
resptype
)
{
cmdidx
|=
PL180_CMD_WAITRESP
;
if
(
cmd
->
resptype
&
PL180_RSP_136BIT
)
cmdidx
|=
PL180_CMD_LONGRSP
;
}
write32
(
pdat
->
virt
+
PL180_ARGUMENT
,
cmd
->
cmdarg
);
write32
(
pdat
->
virt
+
PL180_COMMAND
,
cmdidx
);
do
{
status
=
read32
(
pdat
->
virt
+
PL180_STATUS
);
}
while
(
!
(
status
&
(
PL180_STAT_CMD_SENT
|
PL180_STAT_CMD_RESP_END
|
PL180_STAT_CMD_TIME_OUT
|
PL180_STAT_CMD_CRC_FAIL
)));
dbg_log
(
DBG_LOG
,
"mmc status done!
\n
"
);
if
(
cmd
->
resptype
&
PL180_RSP_PRESENT
)
{
cmd
->
response
[
0
]
=
read32
(
pdat
->
virt
+
PL180_RESP0
);
if
(
cmd
->
resptype
&
PL180_RSP_136BIT
)
{
dbg_log
(
DBG_LOG
,
"136bit response
\n
"
);
cmd
->
response
[
1
]
=
read32
(
pdat
->
virt
+
PL180_RESP1
);
cmd
->
response
[
2
]
=
read32
(
pdat
->
virt
+
PL180_RESP2
);
cmd
->
response
[
3
]
=
read32
(
pdat
->
virt
+
PL180_RESP3
);
}
}
if
(
status
&
PL180_STAT_CMD_TIME_OUT
)
{
ret
=
-
RT_ETIMEOUT
;
}
else
if
((
status
&
PL180_STAT_CMD_CRC_FAIL
)
&&
(
cmd
->
resptype
&
PL180_RSP_CRC
))
{
ret
=
-
RT_ERROR
;
}
write32
(
pdat
->
virt
+
PL180_CLEAR
,
(
PL180_CLR_CMD_SENT
|
PL180_CLR_CMD_RESP_END
|
PL180_CLR_CMD_TIMEOUT
|
PL180_CLR_CMD_CRC_FAIL
));
return
ret
;
}
static
rt_err_t
read_bytes
(
struct
sdhci_pl180_pdata_t
*
pdat
,
rt_uint32_t
*
buf
,
rt_uint32_t
blkcount
,
rt_uint32_t
blksize
)
{
rt_uint32_t
*
tmp
=
buf
;
rt_uint32_t
count
=
blkcount
*
blksize
;
rt_uint32_t
status
,
err
;
status
=
read32
(
pdat
->
virt
+
PL180_STATUS
);
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
|
PL180_STAT_RX_OVERRUN
);
while
((
!
err
)
&&
(
count
>=
sizeof
(
rt_uint32_t
)))
{
if
(
status
&
PL180_STAT_RX_FIFO_AVL
)
{
*
(
tmp
)
=
read32
(
pdat
->
virt
+
PL180_FIFO
);
tmp
++
;
count
-=
sizeof
(
rt_uint32_t
);
}
status
=
read32
(
pdat
->
virt
+
PL180_STATUS
);
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
|
PL180_STAT_RX_OVERRUN
);
}
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
|
PL180_STAT_DAT_BLK_END
|
PL180_STAT_RX_OVERRUN
);
while
(
!
err
)
{
status
=
read32
(
pdat
->
virt
+
PL180_STATUS
);
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
|
PL180_STAT_DAT_BLK_END
|
PL180_STAT_RX_OVERRUN
);
}
if
(
status
&
PL180_STAT_DAT_TIME_OUT
)
return
-
RT_ERROR
;
else
if
(
status
&
PL180_STAT_DAT_CRC_FAIL
)
return
-
RT_ERROR
;
else
if
(
status
&
PL180_STAT_RX_OVERRUN
)
return
-
RT_ERROR
;
write32
(
pdat
->
virt
+
PL180_CLEAR
,
0x1DC007FF
);
if
(
count
)
return
-
RT_ERROR
;
return
RT_EOK
;
}
static
rt_err_t
write_bytes
(
struct
sdhci_pl180_pdata_t
*
pdat
,
rt_uint32_t
*
buf
,
rt_uint32_t
blkcount
,
rt_uint32_t
blksize
)
{
rt_uint32_t
*
tmp
=
buf
;
rt_uint32_t
count
=
blkcount
*
blksize
;
rt_uint32_t
status
,
err
;
int
i
;
status
=
read32
(
pdat
->
virt
+
PL180_STATUS
);
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
);
while
(
!
err
&&
count
)
{
if
(
status
&
PL180_STAT_TX_FIFO_HALF
)
{
if
(
count
>=
8
*
sizeof
(
rt_uint32_t
))
{
for
(
i
=
0
;
i
<
8
;
i
++
)
write32
(
pdat
->
virt
+
PL180_FIFO
,
*
(
tmp
+
i
));
tmp
+=
8
;
count
-=
8
*
sizeof
(
rt_uint32_t
);
}
else
{
while
(
count
>=
sizeof
(
rt_uint32_t
))
{
write32
(
pdat
->
virt
+
PL180_FIFO
,
*
tmp
);
tmp
++
;
count
-=
sizeof
(
rt_uint32_t
);
}
}
}
status
=
read32
(
pdat
->
virt
+
PL180_STATUS
);
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
);
}
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
|
PL180_STAT_DAT_BLK_END
);
while
(
!
err
)
{
status
=
read32
(
pdat
->
virt
+
PL180_STATUS
);
err
=
status
&
(
PL180_STAT_DAT_CRC_FAIL
|
PL180_STAT_DAT_TIME_OUT
|
PL180_STAT_DAT_BLK_END
);
}
if
(
status
&
PL180_STAT_DAT_TIME_OUT
)
return
-
RT_ERROR
;
else
if
(
status
&
PL180_STAT_DAT_CRC_FAIL
)
return
-
RT_ERROR
;
write32
(
pdat
->
virt
+
PL180_CLEAR
,
0x1DC007FF
);
if
(
count
)
return
-
RT_ERROR
;
return
RT_EOK
;
}
static
rt_err_t
pl180_transfer_data
(
struct
sdhci_pl180_pdata_t
*
pdat
,
struct
sdhci_cmd_t
*
cmd
,
struct
sdhci_data_t
*
dat
)
{
rt_uint32_t
dlen
=
(
rt_uint32_t
)(
dat
->
blkcnt
*
dat
->
blksz
);
rt_uint32_t
blksz_bits
=
dat
->
blksz
-
1
;
rt_uint32_t
dctrl
=
(
blksz_bits
<<
4
)
|
(
0x1
<<
0
)
|
(
0x1
<<
14
);
rt_err_t
ret
=
-
RT_ERROR
;
write32
(
pdat
->
virt
+
PL180_DATA_TIMER
,
0xffff
);
write32
(
pdat
->
virt
+
PL180_DATA_LENGTH
,
dlen
);
if
(
dat
->
flag
&
DATA_DIR_READ
)
{
dctrl
|=
(
0x1
<<
1
);
write32
(
pdat
->
virt
+
PL180_DATA_CTRL
,
dctrl
);
ret
=
pl180_transfer_command
(
pdat
,
cmd
);
if
(
ret
<
0
)
return
ret
;
ret
=
read_bytes
(
pdat
,
(
rt_uint32_t
*
)
dat
->
buf
,
dat
->
blkcnt
,
dat
->
blksz
);
}
else
if
(
dat
->
flag
&
DATA_DIR_WRITE
)
{
ret
=
pl180_transfer_command
(
pdat
,
cmd
);
if
(
ret
<
0
)
return
ret
;
write32
(
pdat
->
virt
+
PL180_DATA_CTRL
,
dctrl
);
ret
=
write_bytes
(
pdat
,
(
rt_uint32_t
*
)
dat
->
buf
,
dat
->
blkcnt
,
dat
->
blksz
);
}
return
ret
;
}
static
rt_err_t
sdhci_pl180_detect
(
struct
sdhci_t
*
sdhci
)
{
return
RT_EOK
;
}
static
rt_err_t
sdhci_pl180_setwidth
(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
width
)
{
return
RT_EOK
;
}
static
rt_err_t
sdhci_pl180_setclock
(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
clock
)
{
rt_uint32_t
temp
=
0
;
struct
sdhci_pl180_pdata_t
*
pdat
=
(
struct
sdhci_pl180_pdata_t
*
)
sdhci
->
priv
;
if
(
clock
)
{
temp
=
read32
(
pdat
->
virt
+
PL180_CLOCK
)
|
(
0x1
<<
8
);
temp
=
temp
;
// skip warning
write32
(
pdat
->
virt
+
PL180_CLOCK
,
0x100
);
}
else
{
//write32(pdat->virt + PL180_CLOCK, read32(pdat->virt + PL180_CLOCK) & (~(0x1<<8)));
}
return
RT_EOK
;
}
static
rt_err_t
sdhci_pl180_transfer
(
struct
sdhci_t
*
sdhci
,
struct
sdhci_cmd_t
*
cmd
,
struct
sdhci_data_t
*
dat
)
{
struct
sdhci_pl180_pdata_t
*
pdat
=
(
struct
sdhci_pl180_pdata_t
*
)
sdhci
->
priv
;
if
(
!
dat
)
return
pl180_transfer_command
(
pdat
,
cmd
);
return
pl180_transfer_data
(
pdat
,
cmd
,
dat
);
}
static
void
mmc_request_send
(
struct
rt_mmcsd_host
*
host
,
struct
rt_mmcsd_req
*
req
)
{
struct
sdhci_t
*
sdhci
=
(
struct
sdhci_t
*
)
host
->
private_data
;
struct
sdhci_cmd_t
cmd
;
struct
sdhci_data_t
dat
;
rt_memset
(
&
cmd
,
0
,
sizeof
(
struct
sdhci_cmd_t
));
rt_memset
(
&
dat
,
0
,
sizeof
(
struct
sdhci_data_t
));
cmd
.
cmdidx
=
req
->
cmd
->
cmd_code
;
cmd
.
cmdarg
=
req
->
cmd
->
arg
;
if
(
req
->
cmd
->
flags
&
RESP_MASK
)
{
cmd
.
resptype
=
PL180_RSP_PRESENT
;
if
(
resp_type
(
req
->
cmd
)
==
RESP_R2
)
cmd
.
resptype
|=
PL180_RSP_136BIT
;
}
else
cmd
.
resptype
=
0
;
if
(
req
->
data
)
{
dat
.
buf
=
(
rt_uint8_t
*
)
req
->
data
->
buf
;
dat
.
flag
=
req
->
data
->
flags
;
dat
.
blksz
=
req
->
data
->
blksize
;
dat
.
blkcnt
=
req
->
data
->
blks
;
req
->
cmd
->
err
=
sdhci_pl180_transfer
(
sdhci
,
&
cmd
,
&
dat
);
}
else
{
req
->
cmd
->
err
=
sdhci_pl180_transfer
(
sdhci
,
&
cmd
,
RT_NULL
);
}
dbg_log
(
DBG_INFO
,
"cmdarg:%d
\n
"
,
cmd
.
cmdarg
);
dbg_log
(
DBG_INFO
,
"[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x
\n
"
,
cmd
.
response
[
0
],
cmd
.
response
[
1
],
cmd
.
response
[
2
],
cmd
.
response
[
3
]);
req
->
cmd
->
resp
[
3
]
=
cmd
.
response
[
3
];
req
->
cmd
->
resp
[
2
]
=
cmd
.
response
[
2
];
req
->
cmd
->
resp
[
1
]
=
cmd
.
response
[
1
];
req
->
cmd
->
resp
[
0
]
=
cmd
.
response
[
0
];
if
(
req
->
cmd
->
err
)
dbg_log
(
DBG_ERROR
,
"transfer cmd err
\n
"
);
mmcsd_req_complete
(
host
);
}
static
void
mmc_set_iocfg
(
struct
rt_mmcsd_host
*
host
,
struct
rt_mmcsd_io_cfg
*
io_cfg
)
{
struct
sdhci_t
*
sdhci
=
(
struct
sdhci_t
*
)
host
->
private_data
;
sdhci_pl180_setclock
(
sdhci
,
io_cfg
->
clock
);
sdhci_pl180_setwidth
(
sdhci
,
io_cfg
->
bus_width
);
dbg_log
(
DBG_INFO
,
"clock:%d bus_width:%d
\n
"
,
io_cfg
->
clock
,
io_cfg
->
bus_width
);
}
static
const
struct
rt_mmcsd_host_ops
ops
=
{
mmc_request_send
,
mmc_set_iocfg
,
RT_NULL
,
RT_NULL
,
};
int
pl180_init
(
void
)
{
rt_uint32_t
virt
;
rt_uint32_t
id
;
struct
rt_mmcsd_host
*
host
=
RT_NULL
;
struct
sdhci_pl180_pdata_t
*
pdat
=
RT_NULL
;
struct
sdhci_t
*
sdhci
=
RT_NULL
;
host
=
mmcsd_alloc_host
();
if
(
!
host
)
{
dbg_log
(
DBG_ERROR
,
"alloc host failed
\n
"
);
goto
err
;
}
sdhci
=
rt_malloc
(
sizeof
(
struct
sdhci_t
));
if
(
!
sdhci
)
{
dbg_log
(
DBG_ERROR
,
"alloc sdhci failed
\n
"
);
goto
err
;
}
rt_memset
(
sdhci
,
0
,
sizeof
(
struct
sdhci_t
));
virt
=
MMC_BASE_ADDR
;
id
=
(((
read32
((
virt
+
0xfec
))
&
0xff
)
<<
24
)
|
((
read32
((
virt
+
0xfe8
))
&
0xff
)
<<
16
)
|
((
read32
((
virt
+
0xfe4
))
&
0xff
)
<<
8
)
|
((
read32
((
virt
+
0xfe0
))
&
0xff
)
<<
0
));
dbg_log
(
DBG_LOG
,
"id=0x%08x
\n
"
,
id
);
if
(((
id
>>
12
)
&
0xff
)
!=
0x41
||
(
id
&
0xfff
)
!=
0x181
)
{
dbg_log
(
DBG_ERROR
,
"check id failed
\n
"
);
goto
err
;
}
pdat
=
(
struct
sdhci_pl180_pdata_t
*
)
rt_malloc
(
sizeof
(
struct
sdhci_pl180_pdata_t
));
RT_ASSERT
(
pdat
!=
RT_NULL
);
pdat
->
virt
=
(
uint32_t
)
virt
;
sdhci
->
name
=
"sd0"
;
sdhci
->
voltages
=
VDD_33_34
;
sdhci
->
width
=
MMCSD_BUSWIDTH_4
;
sdhci
->
clock
=
26
*
1000
*
1000
;
sdhci
->
removeable
=
RT_TRUE
;
sdhci
->
detect
=
sdhci_pl180_detect
;
sdhci
->
setwidth
=
sdhci_pl180_setwidth
;
sdhci
->
setclock
=
sdhci_pl180_setclock
;
sdhci
->
transfer
=
sdhci_pl180_transfer
;
sdhci
->
priv
=
pdat
;
write32
(
pdat
->
virt
+
PL180_POWER
,
0xbf
);
// rt_kprintf("power:0x%08x\n", read32(pdat->virt + PL180_POWER));
host
->
ops
=
&
ops
;
host
->
freq_min
=
400000
;
host
->
freq_max
=
50000000
;
host
->
valid_ocr
=
VDD_32_33
|
VDD_33_34
;
// host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
host
->
flags
=
MMCSD_MUTBLKWRITE
|
MMCSD_SUP_HIGHSPEED
|
MMCSD_SUP_SDIO_IRQ
;
host
->
max_seg_size
=
2048
;
host
->
max_dma_segs
=
10
;
host
->
max_blk_size
=
512
;
host
->
max_blk_count
=
4096
;
host
->
private_data
=
sdhci
;
mmcsd_change
(
host
);
return
RT_EOK
;
err:
if
(
host
)
rt_free
(
host
);
if
(
sdhci
)
rt_free
(
sdhci
);
return
-
RT_EIO
;
}
INIT_DEVICE_EXPORT
(
pl180_init
);
#endif
bsp/qemu-vexpress-a9/drivers/drv_sdio.h
0 → 100644
浏览文件 @
c8932cda
#ifndef __DRV_SDIO_H__
#define __DRV_SDIO_H__
#ifdef __cplusplus
extern
"C"
{
#endif
#include <rtthread.h>
struct
sdhci_cmd_t
{
rt_uint32_t
cmdidx
;
rt_uint32_t
cmdarg
;
rt_uint32_t
resptype
;
rt_uint32_t
response
[
4
];
};
struct
sdhci_data_t
{
rt_uint8_t
*
buf
;
rt_uint32_t
flag
;
rt_uint32_t
blksz
;
rt_uint32_t
blkcnt
;
};
struct
sdhci_t
{
char
*
name
;
rt_uint32_t
voltages
;
rt_uint32_t
width
;
rt_uint32_t
clock
;
rt_err_t
removeable
;
void
*
sdcard
;
rt_err_t
(
*
detect
)(
struct
sdhci_t
*
sdhci
);
rt_err_t
(
*
setwidth
)(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
width
);
rt_err_t
(
*
setclock
)(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
clock
);
rt_err_t
(
*
transfer
)(
struct
sdhci_t
*
sdhci
,
struct
sdhci_cmd_t
*
cmd
,
struct
sdhci_data_t
*
dat
);
void
*
priv
;
};
#ifdef __cplusplus
}
#endif
#endif
bsp/qemu-vexpress-a9/drivers/drv_smc911x.c
0 → 100644
浏览文件 @
c8932cda
#include <board.h>
#include <rtthread.h>
#include <netif/ethernetif.h>
#include <lwipopts.h>
#define MAX_ADDR_LEN 6
#define SMC911X_EMAC_DEVICE(eth) (struct eth_device_smc911x*)(eth)
#include "drv_smc911x.h"
#define DRIVERNAME "EMAC"
struct
eth_device_smc911x
{
/* inherit from Ethernet device */
struct
eth_device
parent
;
/* interface address info. */
rt_uint8_t
enetaddr
[
MAX_ADDR_LEN
];
/* MAC address */
uint32_t
iobase
;
uint32_t
irqno
;
};
static
struct
eth_device_smc911x
_emac
;
int
udelay
(
int
value
)
{
return
0
;
}
int
mdelay
(
int
value
)
{
return
0
;
}
#if defined (CONFIG_SMC911X_32_BIT)
rt_inline
uint32_t
smc911x_reg_read
(
struct
eth_device_smc911x
*
dev
,
uint32_t
offset
)
{
return
*
(
volatile
uint32_t
*
)(
dev
->
iobase
+
offset
);
}
rt_inline
void
smc911x_reg_write
(
struct
eth_device_smc911x
*
dev
,
uint32_t
offset
,
uint32_t
val
)
{
*
(
volatile
uint32_t
*
)(
dev
->
iobase
+
offset
)
=
val
;
}
#elif defined (CONFIG_SMC911X_16_BIT)
rt_inline
uint32_t
smc911x_reg_read
(
struct
eth_device_smc911x
*
dev
,
uint32_t
offset
)
{
volatile
uint16_t
*
addr_16
=
(
uint16_t
*
)(
dev
->
iobase
+
offset
);
return
((
*
addr_16
&
0x0000ffff
)
|
(
*
(
addr_16
+
1
)
<<
16
));
}
rt_inline
void
smc911x_reg_write
(
struct
eth_device_smc911x
*
dev
,
uint32_t
offset
,
uint32_t
val
)
{
*
(
volatile
uint16_t
*
)(
dev
->
iobase
+
offset
)
=
(
uint16_t
)
val
;
*
(
volatile
uint16_t
*
)(
dev
->
iobase
+
offset
+
2
)
=
(
uint16_t
)(
val
>>
16
);
}
#else
#error "SMC911X: undefined bus width"
#endif
/* CONFIG_SMC911X_16_BIT */
struct
chip_id
{
uint16_t
id
;
char
*
name
;
};
static
const
struct
chip_id
chip_ids
[]
=
{
{
CHIP_89218
,
"LAN89218"
},
{
CHIP_9115
,
"LAN9115"
},
{
CHIP_9116
,
"LAN9116"
},
{
CHIP_9117
,
"LAN9117"
},
{
CHIP_9118
,
"LAN9118"
},
{
CHIP_9211
,
"LAN9211"
},
{
CHIP_9215
,
"LAN9215"
},
{
CHIP_9216
,
"LAN9216"
},
{
CHIP_9217
,
"LAN9217"
},
{
CHIP_9218
,
"LAN9218"
},
{
CHIP_9220
,
"LAN9220"
},
{
CHIP_9221
,
"LAN9221"
},
{
0
,
RT_NULL
},
};
static
uint32_t
smc911x_get_mac_csr
(
struct
eth_device_smc911x
*
dev
,
uint8_t
reg
)
{
while
(
smc911x_reg_read
(
dev
,
MAC_CSR_CMD
)
&
MAC_CSR_CMD_CSR_BUSY
)
;
smc911x_reg_write
(
dev
,
MAC_CSR_CMD
,
MAC_CSR_CMD_CSR_BUSY
|
MAC_CSR_CMD_R_NOT_W
|
reg
);
while
(
smc911x_reg_read
(
dev
,
MAC_CSR_CMD
)
&
MAC_CSR_CMD_CSR_BUSY
)
;
return
smc911x_reg_read
(
dev
,
MAC_CSR_DATA
);
}
static
void
smc911x_set_mac_csr
(
struct
eth_device_smc911x
*
dev
,
uint8_t
reg
,
uint32_t
data
)
{
while
(
smc911x_reg_read
(
dev
,
MAC_CSR_CMD
)
&
MAC_CSR_CMD_CSR_BUSY
)
;
smc911x_reg_write
(
dev
,
MAC_CSR_DATA
,
data
);
smc911x_reg_write
(
dev
,
MAC_CSR_CMD
,
MAC_CSR_CMD_CSR_BUSY
|
reg
);
while
(
smc911x_reg_read
(
dev
,
MAC_CSR_CMD
)
&
MAC_CSR_CMD_CSR_BUSY
)
;
}
static
int
smc911x_detect_chip
(
struct
eth_device_smc911x
*
dev
)
{
unsigned
long
val
,
i
;
val
=
smc911x_reg_read
(
dev
,
BYTE_TEST
);
if
(
val
==
0xffffffff
)
{
/* Special case -- no chip present */
return
-
1
;
}
else
if
(
val
!=
0x87654321
)
{
rt_kprintf
(
DRIVERNAME
": Invalid chip endian 0x%08lx
\n
"
,
val
);
return
-
1
;
}
val
=
smc911x_reg_read
(
dev
,
ID_REV
)
>>
16
;
for
(
i
=
0
;
chip_ids
[
i
].
id
!=
0
;
i
++
)
{
if
(
chip_ids
[
i
].
id
==
val
)
break
;
}
if
(
!
chip_ids
[
i
].
id
)
{
rt_kprintf
(
DRIVERNAME
": Unknown chip ID %04lx
\n
"
,
val
);
return
-
1
;
}
return
0
;
}
static
void
smc911x_reset
(
struct
eth_device_smc911x
*
dev
)
{
int
timeout
;
/*
* Take out of PM setting first
* Device is already wake up if PMT_CTRL_READY bit is set
*/
if
((
smc911x_reg_read
(
dev
,
PMT_CTRL
)
&
PMT_CTRL_READY
)
==
0
)
{
/* Write to the bytetest will take out of powerdown */
smc911x_reg_write
(
dev
,
BYTE_TEST
,
0x0
);
timeout
=
10
;
while
(
timeout
--
&&
!
(
smc911x_reg_read
(
dev
,
PMT_CTRL
)
&
PMT_CTRL_READY
))
udelay
(
10
);
if
(
timeout
<
0
)
{
rt_kprintf
(
DRIVERNAME
": timeout waiting for PM restore
\n
"
);
return
;
}
}
/* Disable interrupts */
smc911x_reg_write
(
dev
,
INT_EN
,
0
);
smc911x_reg_write
(
dev
,
HW_CFG
,
HW_CFG_SRST
);
timeout
=
1000
;
while
(
timeout
--
&&
smc911x_reg_read
(
dev
,
E2P_CMD
)
&
E2P_CMD_EPC_BUSY
)
udelay
(
10
);
if
(
timeout
<
0
)
{
rt_kprintf
(
DRIVERNAME
": reset timeout
\n
"
);
return
;
}
/* Reset the FIFO level and flow control settings */
smc911x_set_mac_csr
(
dev
,
FLOW
,
FLOW_FCPT
|
FLOW_FCEN
);
smc911x_reg_write
(
dev
,
AFC_CFG
,
0x0050287F
);
/* Set to LED outputs */
smc911x_reg_write
(
dev
,
GPIO_CFG
,
0x70070000
);
}
static
void
smc911x_handle_mac_address
(
struct
eth_device_smc911x
*
dev
)
{
unsigned
long
addrh
,
addrl
;
uint8_t
*
m
=
dev
->
enetaddr
;
addrl
=
m
[
0
]
|
(
m
[
1
]
<<
8
)
|
(
m
[
2
]
<<
16
)
|
(
m
[
3
]
<<
24
);
addrh
=
m
[
4
]
|
(
m
[
5
]
<<
8
);
smc911x_set_mac_csr
(
dev
,
ADDRL
,
addrl
);
smc911x_set_mac_csr
(
dev
,
ADDRH
,
addrh
);
}
static
int
smc911x_eth_phy_read
(
struct
eth_device_smc911x
*
dev
,
uint8_t
phy
,
uint8_t
reg
,
uint16_t
*
val
)
{
while
(
smc911x_get_mac_csr
(
dev
,
MII_ACC
)
&
MII_ACC_MII_BUSY
)
;
smc911x_set_mac_csr
(
dev
,
MII_ACC
,
phy
<<
11
|
reg
<<
6
|
MII_ACC_MII_BUSY
);
while
(
smc911x_get_mac_csr
(
dev
,
MII_ACC
)
&
MII_ACC_MII_BUSY
)
;
*
val
=
smc911x_get_mac_csr
(
dev
,
MII_DATA
);
return
0
;
}
static
int
smc911x_eth_phy_write
(
struct
eth_device_smc911x
*
dev
,
uint8_t
phy
,
uint8_t
reg
,
uint16_t
val
)
{
while
(
smc911x_get_mac_csr
(
dev
,
MII_ACC
)
&
MII_ACC_MII_BUSY
)
;
smc911x_set_mac_csr
(
dev
,
MII_DATA
,
val
);
smc911x_set_mac_csr
(
dev
,
MII_ACC
,
phy
<<
11
|
reg
<<
6
|
MII_ACC_MII_BUSY
|
MII_ACC_MII_WRITE
);
while
(
smc911x_get_mac_csr
(
dev
,
MII_ACC
)
&
MII_ACC_MII_BUSY
)
;
return
0
;
}
static
int
smc911x_phy_reset
(
struct
eth_device_smc911x
*
dev
)
{
uint32_t
reg
;
reg
=
smc911x_reg_read
(
dev
,
PMT_CTRL
);
reg
&=
~
0xfffff030
;
reg
|=
PMT_CTRL_PHY_RST
;
smc911x_reg_write
(
dev
,
PMT_CTRL
,
reg
);
mdelay
(
100
);
return
0
;
}
static
void
smc911x_phy_configure
(
struct
eth_device_smc911x
*
dev
)
{
int
timeout
;
uint16_t
status
;
smc911x_phy_reset
(
dev
);
smc911x_eth_phy_write
(
dev
,
1
,
MII_BMCR
,
BMCR_RESET
);
mdelay
(
1
);
smc911x_eth_phy_write
(
dev
,
1
,
MII_ADVERTISE
,
0x01e1
);
smc911x_eth_phy_write
(
dev
,
1
,
MII_BMCR
,
BMCR_ANENABLE
|
BMCR_ANRESTART
);
timeout
=
5000
;
do
{
mdelay
(
1
);
if
((
timeout
--
)
==
0
)
goto
err_out
;
if
(
smc911x_eth_phy_read
(
dev
,
1
,
MII_BMSR
,
&
status
)
!=
0
)
goto
err_out
;
}
while
(
!
(
status
&
BMSR_LSTATUS
));
return
;
err_out:
rt_kprintf
(
DRIVERNAME
": autonegotiation timed out
\n
"
);
}
static
void
smc911x_enable
(
struct
eth_device_smc911x
*
dev
)
{
/* Enable TX */
smc911x_reg_write
(
dev
,
HW_CFG
,
8
<<
16
|
HW_CFG_SF
);
smc911x_reg_write
(
dev
,
GPT_CFG
,
GPT_CFG_TIMER_EN
|
10000
);
smc911x_reg_write
(
dev
,
TX_CFG
,
TX_CFG_TX_ON
);
/* no padding to start of packets */
smc911x_reg_write
(
dev
,
RX_CFG
,
0
);
smc911x_set_mac_csr
(
dev
,
MAC_CR
,
MAC_CR_TXEN
|
MAC_CR_RXEN
|
MAC_CR_HBDIS
);
}
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
/* wrapper for smc911x_eth_phy_read */
static
int
smc911x_miiphy_read
(
struct
mii_dev
*
bus
,
int
phy
,
int
devad
,
int
reg
)
{
uint16_t
val
=
0
;
struct
eth_device_smc911x
*
dev
=
eth_get_dev_by_name
(
bus
->
name
);
if
(
dev
)
{
int
retval
=
smc911x_eth_phy_read
(
dev
,
phy
,
reg
,
&
val
);
if
(
retval
<
0
)
return
retval
;
return
val
;
}
return
-
ENODEV
;
}
/* wrapper for smc911x_eth_phy_write */
static
int
smc911x_miiphy_write
(
struct
mii_dev
*
bus
,
int
phy
,
int
devad
,
int
reg
,
uint16_t
val
)
{
struct
eth_device_smc911x
*
dev
=
eth_get_dev_by_name
(
bus
->
name
);
if
(
dev
)
return
smc911x_eth_phy_write
(
dev
,
phy
,
reg
,
val
);
return
-
ENODEV
;
}
#endif
static
void
smc911x_isr
(
int
vector
,
void
*
param
)
{
uint32_t
status
;
struct
eth_device_smc911x
*
emac
;
emac
=
SMC911X_EMAC_DEVICE
(
param
);
status
=
smc911x_reg_read
(
emac
,
INT_STS
);
if
(
status
&
INT_STS_RSFL
)
{
eth_device_ready
(
&
emac
->
parent
);
}
smc911x_reg_write
(
emac
,
INT_STS
,
status
);
return
;
}
static
rt_err_t
smc911x_emac_init
(
rt_device_t
dev
)
{
// uint32_t value;
struct
eth_device_smc911x
*
emac
;
emac
=
SMC911X_EMAC_DEVICE
(
dev
);
RT_ASSERT
(
emac
!=
RT_NULL
);
smc911x_reset
(
emac
);
/* Configure the PHY, initialize the link state */
smc911x_phy_configure
(
emac
);
smc911x_handle_mac_address
(
emac
);
/* Turn on Tx + Rx */
smc911x_enable
(
emac
);
#if 1
/* Interrupt on every received packet */
smc911x_reg_write
(
emac
,
FIFO_INT
,
0x01
<<
8
);
smc911x_reg_write
(
emac
,
INT_EN
,
INT_EN_RDFL_EN
|
INT_EN_RSFL_EN
);
/* enable interrupt */
smc911x_reg_write
(
emac
,
INT_CFG
,
INT_CFG_IRQ_EN
|
INT_CFG_IRQ_POL
|
INT_CFG_IRQ_TYPE
);
#else
/* disable interrupt */
smc911x_reg_write
(
emac
,
INT_EN
,
0
);
value
=
smc911x_reg_read
(
emac
,
INT_CFG
);
value
&=
~
INT_CFG_IRQ_EN
;
smc911x_reg_write
(
emac
,
INT_CFG
,
value
);
#endif
rt_hw_interrupt_install
(
emac
->
irqno
,
smc911x_isr
,
emac
,
"smc911x"
);
rt_hw_interrupt_umask
(
emac
->
irqno
);
return
RT_EOK
;
}
static
rt_err_t
smc911x_emac_control
(
rt_device_t
dev
,
int
cmd
,
void
*
args
)
{
struct
eth_device_smc911x
*
emac
;
emac
=
SMC911X_EMAC_DEVICE
(
dev
);
RT_ASSERT
(
emac
!=
RT_NULL
);
switch
(
cmd
)
{
case
NIOCTL_GADDR
:
/* get MAC address */
if
(
args
)
rt_memcpy
(
args
,
emac
->
enetaddr
,
6
);
else
return
-
RT_ERROR
;
break
;
default
:
break
;
}
return
RT_EOK
;
}
/* Ethernet device interface */
/* transmit packet. */
static
uint8_t
tx_buf
[
2048
];
rt_err_t
smc911x_emac_tx
(
rt_device_t
dev
,
struct
pbuf
*
p
)
{
struct
eth_device_smc911x
*
emac
;
uint32_t
*
data
;
uint32_t
tmplen
;
uint32_t
status
;
uint32_t
length
;
emac
=
SMC911X_EMAC_DEVICE
(
dev
);
RT_ASSERT
(
emac
!=
RT_NULL
);
/* copy pbuf to a whole ETH frame */
pbuf_copy_partial
(
p
,
tx_buf
,
p
->
tot_len
,
0
);
/* send it out */
data
=
(
uint32_t
*
)
tx_buf
;
length
=
p
->
tot_len
;
smc911x_reg_write
(
emac
,
TX_DATA_FIFO
,
TX_CMD_A_INT_FIRST_SEG
|
TX_CMD_A_INT_LAST_SEG
|
length
);
smc911x_reg_write
(
emac
,
TX_DATA_FIFO
,
length
);
tmplen
=
(
length
+
3
)
/
4
;
while
(
tmplen
--
)
{
smc911x_reg_write
(
emac
,
TX_DATA_FIFO
,
*
data
++
);
}
/* wait for transmission */
while
(
!
((
smc911x_reg_read
(
emac
,
TX_FIFO_INF
)
&
TX_FIFO_INF_TSUSED
)
>>
16
));
/* get status. Ignore 'no carrier' error, it has no meaning for
* full duplex operation
*/
status
=
smc911x_reg_read
(
emac
,
TX_STATUS_FIFO
)
&
(
TX_STS_LOC
|
TX_STS_LATE_COLL
|
TX_STS_MANY_COLL
|
TX_STS_MANY_DEFER
|
TX_STS_UNDERRUN
);
if
(
!
status
)
return
0
;
rt_kprintf
(
DRIVERNAME
": failed to send packet: %s%s%s%s%s
\n
"
,
status
&
TX_STS_LOC
?
"TX_STS_LOC "
:
""
,
status
&
TX_STS_LATE_COLL
?
"TX_STS_LATE_COLL "
:
""
,
status
&
TX_STS_MANY_COLL
?
"TX_STS_MANY_COLL "
:
""
,
status
&
TX_STS_MANY_DEFER
?
"TX_STS_MANY_DEFER "
:
""
,
status
&
TX_STS_UNDERRUN
?
"TX_STS_UNDERRUN"
:
""
);
return
-
RT_EIO
;
}
/* reception packet. */
struct
pbuf
*
smc911x_emac_rx
(
rt_device_t
dev
)
{
struct
pbuf
*
p
=
RT_NULL
;
struct
eth_device_smc911x
*
emac
;
emac
=
SMC911X_EMAC_DEVICE
(
dev
);
RT_ASSERT
(
emac
!=
RT_NULL
);
/* take the emac buffer to the pbuf */
if
((
smc911x_reg_read
(
emac
,
RX_FIFO_INF
)
&
RX_FIFO_INF_RXSUSED
)
>>
16
)
{
uint32_t
status
;
uint32_t
pktlen
,
tmplen
;
status
=
smc911x_reg_read
(
emac
,
RX_STATUS_FIFO
);
/* get frame length */
pktlen
=
(
status
&
RX_STS_PKT_LEN
)
>>
16
;
smc911x_reg_write
(
emac
,
RX_CFG
,
0
);
tmplen
=
(
pktlen
+
3
)
/
4
;
/* allocate pbuf */
p
=
pbuf_alloc
(
PBUF_LINK
,
tmplen
*
4
,
PBUF_RAM
);
if
(
p
)
{
uint32_t
*
data
=
(
uint32_t
*
)
p
->
payload
;
while
(
tmplen
--
)
{
*
data
++
=
smc911x_reg_read
(
emac
,
RX_DATA_FIFO
);
}
}
if
(
status
&
RX_STS_ES
)
{
rt_kprintf
(
DRIVERNAME
": dropped bad packet. Status: 0x%08x
\n
"
,
status
);
}
}
return
p
;
}
int
smc911x_emac_hw_init
(
void
)
{
_emac
.
iobase
=
VEXPRESS_ETH_BASE
;
_emac
.
irqno
=
IRQ_VEXPRESS_A9_ETH
;
if
(
smc911x_detect_chip
(
&
_emac
))
{
rt_kprintf
(
"no smc911x network interface found!
\n
"
);
return
-
1
;
}
/* set INT CFG */
smc911x_reg_write
(
&
_emac
,
INT_CFG
,
INT_CFG_IRQ_POL
|
INT_CFG_IRQ_TYPE
);
/* test MAC address */
_emac
.
enetaddr
[
0
]
=
0x52
;
_emac
.
enetaddr
[
1
]
=
0x54
;
_emac
.
enetaddr
[
2
]
=
0x00
;
_emac
.
enetaddr
[
3
]
=
0x11
;
_emac
.
enetaddr
[
4
]
=
0x22
;
_emac
.
enetaddr
[
5
]
=
0x33
;
_emac
.
parent
.
parent
.
init
=
smc911x_emac_init
;
_emac
.
parent
.
parent
.
open
=
RT_NULL
;
_emac
.
parent
.
parent
.
close
=
RT_NULL
;
_emac
.
parent
.
parent
.
read
=
RT_NULL
;
_emac
.
parent
.
parent
.
write
=
RT_NULL
;
_emac
.
parent
.
parent
.
control
=
smc911x_emac_control
;
_emac
.
parent
.
parent
.
user_data
=
RT_NULL
;
_emac
.
parent
.
eth_rx
=
smc911x_emac_rx
;
_emac
.
parent
.
eth_tx
=
smc911x_emac_tx
;
/* register ETH device */
eth_device_init
(
&
(
_emac
.
parent
),
"e0"
);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
{
int
retval
;
struct
mii_dev
*
mdiodev
=
mdio_alloc
();
if
(
!
mdiodev
)
return
-
ENOMEM
;
strncpy
(
mdiodev
->
name
,
dev
->
name
,
MDIO_NAME_LEN
);
mdiodev
->
read
=
smc911x_miiphy_read
;
mdiodev
->
write
=
smc911x_miiphy_write
;
retval
=
mdio_register
(
mdiodev
);
if
(
retval
<
0
)
return
retval
;
}
#endif
eth_device_linkchange
(
&
_emac
.
parent
,
RT_TRUE
);
return
0
;
}
INIT_APP_EXPORT
(
smc911x_emac_hw_init
);
#include <finsh.h>
int
emac
(
int
argc
,
char
**
argv
)
{
rt_hw_interrupt_umask
(
_emac
.
irqno
);
return
0
;
}
MSH_CMD_EXPORT
(
emac
,
emac
dump
);
bsp/qemu-vexpress-a9/drivers/drv_smc911x.h
0 → 100644
浏览文件 @
c8932cda
/*
* SMSC LAN9[12]1[567] Network driver
*
* (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _SMC911X_H_
#define _SMC911X_H_
#include <stdint.h>
#define CONFIG_SMC911X_32_BIT
/* Below are the register offsets and bit definitions
* of the Lan911x memory space
*/
#define RX_DATA_FIFO 0x00
#define TX_DATA_FIFO 0x20
#define TX_CMD_A_INT_ON_COMP 0x80000000
#define TX_CMD_A_INT_BUF_END_ALGN 0x03000000
#define TX_CMD_A_INT_4_BYTE_ALGN 0x00000000
#define TX_CMD_A_INT_16_BYTE_ALGN 0x01000000
#define TX_CMD_A_INT_32_BYTE_ALGN 0x02000000
#define TX_CMD_A_INT_DATA_OFFSET 0x001F0000
#define TX_CMD_A_INT_FIRST_SEG 0x00002000
#define TX_CMD_A_INT_LAST_SEG 0x00001000
#define TX_CMD_A_BUF_SIZE 0x000007FF
#define TX_CMD_B_PKT_TAG 0xFFFF0000
#define TX_CMD_B_ADD_CRC_DISABLE 0x00002000
#define TX_CMD_B_DISABLE_PADDING 0x00001000
#define TX_CMD_B_PKT_BYTE_LENGTH 0x000007FF
#define RX_STATUS_FIFO 0x40
#define RX_STS_PKT_LEN 0x3FFF0000
#define RX_STS_ES 0x00008000
#define RX_STS_BCST 0x00002000
#define RX_STS_LEN_ERR 0x00001000
#define RX_STS_RUNT_ERR 0x00000800
#define RX_STS_MCAST 0x00000400
#define RX_STS_TOO_LONG 0x00000080
#define RX_STS_COLL 0x00000040
#define RX_STS_ETH_TYPE 0x00000020
#define RX_STS_WDOG_TMT 0x00000010
#define RX_STS_MII_ERR 0x00000008
#define RX_STS_DRIBBLING 0x00000004
#define RX_STS_CRC_ERR 0x00000002
#define RX_STATUS_FIFO_PEEK 0x44
#define TX_STATUS_FIFO 0x48
#define TX_STS_TAG 0xFFFF0000
#define TX_STS_ES 0x00008000
#define TX_STS_LOC 0x00000800
#define TX_STS_NO_CARR 0x00000400
#define TX_STS_LATE_COLL 0x00000200
#define TX_STS_MANY_COLL 0x00000100
#define TX_STS_COLL_CNT 0x00000078
#define TX_STS_MANY_DEFER 0x00000004
#define TX_STS_UNDERRUN 0x00000002
#define TX_STS_DEFERRED 0x00000001
#define TX_STATUS_FIFO_PEEK 0x4C
#define ID_REV 0x50
#define ID_REV_CHIP_ID 0xFFFF0000
/* RO */
#define ID_REV_REV_ID 0x0000FFFF
/* RO */
#define INT_CFG 0x54
#define INT_CFG_INT_DEAS 0xFF000000
/* R/W */
#define INT_CFG_INT_DEAS_CLR 0x00004000
#define INT_CFG_INT_DEAS_STS 0x00002000
#define INT_CFG_IRQ_INT 0x00001000
/* RO */
#define INT_CFG_IRQ_EN 0x00000100
/* R/W */
/* R/W Not Affected by SW Reset */
#define INT_CFG_IRQ_POL 0x00000010
/* R/W Not Affected by SW Reset */
#define INT_CFG_IRQ_TYPE 0x00000001
#define INT_STS 0x58
#define INT_STS_SW_INT 0x80000000
/* R/WC */
#define INT_STS_TXSTOP_INT 0x02000000
/* R/WC */
#define INT_STS_RXSTOP_INT 0x01000000
/* R/WC */
#define INT_STS_RXDFH_INT 0x00800000
/* R/WC */
#define INT_STS_RXDF_INT 0x00400000
/* R/WC */
#define INT_STS_TX_IOC 0x00200000
/* R/WC */
#define INT_STS_RXD_INT 0x00100000
/* R/WC */
#define INT_STS_GPT_INT 0x00080000
/* R/WC */
#define INT_STS_PHY_INT 0x00040000
/* RO */
#define INT_STS_PME_INT 0x00020000
/* R/WC */
#define INT_STS_TXSO 0x00010000
/* R/WC */
#define INT_STS_RWT 0x00008000
/* R/WC */
#define INT_STS_RXE 0x00004000
/* R/WC */
#define INT_STS_TXE 0x00002000
/* R/WC */
/*#define INT_STS_ERX 0x00001000*/
/* R/WC */
#define INT_STS_TDFU 0x00000800
/* R/WC */
#define INT_STS_TDFO 0x00000400
/* R/WC */
#define INT_STS_TDFA 0x00000200
/* R/WC */
#define INT_STS_TSFF 0x00000100
/* R/WC */
#define INT_STS_TSFL 0x00000080
/* R/WC */
/*#define INT_STS_RXDF 0x00000040*/
/* R/WC */
#define INT_STS_RDFO 0x00000040
/* R/WC */
#define INT_STS_RDFL 0x00000020
/* R/WC */
#define INT_STS_RSFF 0x00000010
/* R/WC */
#define INT_STS_RSFL 0x00000008
/* R/WC */
#define INT_STS_GPIO2_INT 0x00000004
/* R/WC */
#define INT_STS_GPIO1_INT 0x00000002
/* R/WC */
#define INT_STS_GPIO0_INT 0x00000001
/* R/WC */
#define INT_EN 0x5C
#define INT_EN_SW_INT_EN 0x80000000
/* R/W */
#define INT_EN_TXSTOP_INT_EN 0x02000000
/* R/W */
#define INT_EN_RXSTOP_INT_EN 0x01000000
/* R/W */
#define INT_EN_RXDFH_INT_EN 0x00800000
/* R/W */
/*#define INT_EN_RXDF_INT_EN 0x00400000*/
/* R/W */
#define INT_EN_TIOC_INT_EN 0x00200000
/* R/W */
#define INT_EN_RXD_INT_EN 0x00100000
/* R/W */
#define INT_EN_GPT_INT_EN 0x00080000
/* R/W */
#define INT_EN_PHY_INT_EN 0x00040000
/* R/W */
#define INT_EN_PME_INT_EN 0x00020000
/* R/W */
#define INT_EN_TXSO_EN 0x00010000
/* R/W */
#define INT_EN_RWT_EN 0x00008000
/* R/W */
#define INT_EN_RXE_EN 0x00004000
/* R/W */
#define INT_EN_TXE_EN 0x00002000
/* R/W */
/*#define INT_EN_ERX_EN 0x00001000*/
/* R/W */
#define INT_EN_TDFU_EN 0x00000800
/* R/W */
#define INT_EN_TDFO_EN 0x00000400
/* R/W */
#define INT_EN_TDFA_EN 0x00000200
/* R/W */
#define INT_EN_TSFF_EN 0x00000100
/* R/W */
#define INT_EN_TSFL_EN 0x00000080
/* R/W */
/*#define INT_EN_RXDF_EN 0x00000040*/
/* R/W */
#define INT_EN_RDFO_EN 0x00000040
/* R/W */
#define INT_EN_RDFL_EN 0x00000020
/* R/W */
#define INT_EN_RSFF_EN 0x00000010
/* R/W */
#define INT_EN_RSFL_EN 0x00000008
/* R/W */
#define INT_EN_GPIO2_INT 0x00000004
/* R/W */
#define INT_EN_GPIO1_INT 0x00000002
/* R/W */
#define INT_EN_GPIO0_INT 0x00000001
/* R/W */
#define BYTE_TEST 0x64
#define FIFO_INT 0x68
#define FIFO_INT_TX_AVAIL_LEVEL 0xFF000000
/* R/W */
#define FIFO_INT_TX_STS_LEVEL 0x00FF0000
/* R/W */
#define FIFO_INT_RX_AVAIL_LEVEL 0x0000FF00
/* R/W */
#define FIFO_INT_RX_STS_LEVEL 0x000000FF
/* R/W */
#define RX_CFG 0x6C
#define RX_CFG_RX_END_ALGN 0xC0000000
/* R/W */
#define RX_CFG_RX_END_ALGN4 0x00000000
/* R/W */
#define RX_CFG_RX_END_ALGN16 0x40000000
/* R/W */
#define RX_CFG_RX_END_ALGN32 0x80000000
/* R/W */
#define RX_CFG_RX_DMA_CNT 0x0FFF0000
/* R/W */
#define RX_CFG_RX_DUMP 0x00008000
/* R/W */
#define RX_CFG_RXDOFF 0x00001F00
/* R/W */
/*#define RX_CFG_RXBAD 0x00000001*/
/* R/W */
#define TX_CFG 0x70
/*#define TX_CFG_TX_DMA_LVL 0xE0000000*/
/* R/W */
/* R/W Self Clearing */
/*#define TX_CFG_TX_DMA_CNT 0x0FFF0000*/
#define TX_CFG_TXS_DUMP 0x00008000
/* Self Clearing */
#define TX_CFG_TXD_DUMP 0x00004000
/* Self Clearing */
#define TX_CFG_TXSAO 0x00000004
/* R/W */
#define TX_CFG_TX_ON 0x00000002
/* R/W */
#define TX_CFG_STOP_TX 0x00000001
/* Self Clearing */
#define HW_CFG 0x74
#define HW_CFG_TTM 0x00200000
/* R/W */
#define HW_CFG_SF 0x00100000
/* R/W */
#define HW_CFG_TX_FIF_SZ 0x000F0000
/* R/W */
#define HW_CFG_TR 0x00003000
/* R/W */
#define HW_CFG_PHY_CLK_SEL 0x00000060
/* R/W */
#define HW_CFG_PHY_CLK_SEL_INT_PHY 0x00000000
/* R/W */
#define HW_CFG_PHY_CLK_SEL_EXT_PHY 0x00000020
/* R/W */
#define HW_CFG_PHY_CLK_SEL_CLK_DIS 0x00000040
/* R/W */
#define HW_CFG_SMI_SEL 0x00000010
/* R/W */
#define HW_CFG_EXT_PHY_DET 0x00000008
/* RO */
#define HW_CFG_EXT_PHY_EN 0x00000004
/* R/W */
#define HW_CFG_32_16_BIT_MODE 0x00000004
/* RO */
#define HW_CFG_SRST_TO 0x00000002
/* RO */
#define HW_CFG_SRST 0x00000001
/* Self Clearing */
#define RX_DP_CTRL 0x78
#define RX_DP_CTRL_RX_FFWD 0x80000000
/* R/W */
#define RX_DP_CTRL_FFWD_BUSY 0x80000000
/* RO */
#define RX_FIFO_INF 0x7C
#define RX_FIFO_INF_RXSUSED 0x00FF0000
/* RO */
#define RX_FIFO_INF_RXDUSED 0x0000FFFF
/* RO */
#define TX_FIFO_INF 0x80
#define TX_FIFO_INF_TSUSED 0x00FF0000
/* RO */
#define TX_FIFO_INF_TDFREE 0x0000FFFF
/* RO */
#define PMT_CTRL 0x84
#define PMT_CTRL_PM_MODE 0x00003000
/* Self Clearing */
#define PMT_CTRL_PHY_RST 0x00000400
/* Self Clearing */
#define PMT_CTRL_WOL_EN 0x00000200
/* R/W */
#define PMT_CTRL_ED_EN 0x00000100
/* R/W */
/* R/W Not Affected by SW Reset */
#define PMT_CTRL_PME_TYPE 0x00000040
#define PMT_CTRL_WUPS 0x00000030
/* R/WC */
#define PMT_CTRL_WUPS_NOWAKE 0x00000000
/* R/WC */
#define PMT_CTRL_WUPS_ED 0x00000010
/* R/WC */
#define PMT_CTRL_WUPS_WOL 0x00000020
/* R/WC */
#define PMT_CTRL_WUPS_MULTI 0x00000030
/* R/WC */
#define PMT_CTRL_PME_IND 0x00000008
/* R/W */
#define PMT_CTRL_PME_POL 0x00000004
/* R/W */
/* R/W Not Affected by SW Reset */
#define PMT_CTRL_PME_EN 0x00000002
#define PMT_CTRL_READY 0x00000001
/* RO */
#define GPIO_CFG 0x88
#define GPIO_CFG_LED3_EN 0x40000000
/* R/W */
#define GPIO_CFG_LED2_EN 0x20000000
/* R/W */
#define GPIO_CFG_LED1_EN 0x10000000
/* R/W */
#define GPIO_CFG_GPIO2_INT_POL 0x04000000
/* R/W */
#define GPIO_CFG_GPIO1_INT_POL 0x02000000
/* R/W */
#define GPIO_CFG_GPIO0_INT_POL 0x01000000
/* R/W */
#define GPIO_CFG_EEPR_EN 0x00700000
/* R/W */
#define GPIO_CFG_GPIOBUF2 0x00040000
/* R/W */
#define GPIO_CFG_GPIOBUF1 0x00020000
/* R/W */
#define GPIO_CFG_GPIOBUF0 0x00010000
/* R/W */
#define GPIO_CFG_GPIODIR2 0x00000400
/* R/W */
#define GPIO_CFG_GPIODIR1 0x00000200
/* R/W */
#define GPIO_CFG_GPIODIR0 0x00000100
/* R/W */
#define GPIO_CFG_GPIOD4 0x00000010
/* R/W */
#define GPIO_CFG_GPIOD3 0x00000008
/* R/W */
#define GPIO_CFG_GPIOD2 0x00000004
/* R/W */
#define GPIO_CFG_GPIOD1 0x00000002
/* R/W */
#define GPIO_CFG_GPIOD0 0x00000001
/* R/W */
#define GPT_CFG 0x8C
#define GPT_CFG_TIMER_EN 0x20000000
/* R/W */
#define GPT_CFG_GPT_LOAD 0x0000FFFF
/* R/W */
#define GPT_CNT 0x90
#define GPT_CNT_GPT_CNT 0x0000FFFF
/* RO */
#define ENDIAN 0x98
#define FREE_RUN 0x9C
#define RX_DROP 0xA0
#define MAC_CSR_CMD 0xA4
#define MAC_CSR_CMD_CSR_BUSY 0x80000000
/* Self Clearing */
#define MAC_CSR_CMD_R_NOT_W 0x40000000
/* R/W */
#define MAC_CSR_CMD_CSR_ADDR 0x000000FF
/* R/W */
#define MAC_CSR_DATA 0xA8
#define AFC_CFG 0xAC
#define AFC_CFG_AFC_HI 0x00FF0000
/* R/W */
#define AFC_CFG_AFC_LO 0x0000FF00
/* R/W */
#define AFC_CFG_BACK_DUR 0x000000F0
/* R/W */
#define AFC_CFG_FCMULT 0x00000008
/* R/W */
#define AFC_CFG_FCBRD 0x00000004
/* R/W */
#define AFC_CFG_FCADD 0x00000002
/* R/W */
#define AFC_CFG_FCANY 0x00000001
/* R/W */
#define E2P_CMD 0xB0
#define E2P_CMD_EPC_BUSY 0x80000000
/* Self Clearing */
#define E2P_CMD_EPC_CMD 0x70000000
/* R/W */
#define E2P_CMD_EPC_CMD_READ 0x00000000
/* R/W */
#define E2P_CMD_EPC_CMD_EWDS 0x10000000
/* R/W */
#define E2P_CMD_EPC_CMD_EWEN 0x20000000
/* R/W */
#define E2P_CMD_EPC_CMD_WRITE 0x30000000
/* R/W */
#define E2P_CMD_EPC_CMD_WRAL 0x40000000
/* R/W */
#define E2P_CMD_EPC_CMD_ERASE 0x50000000
/* R/W */
#define E2P_CMD_EPC_CMD_ERAL 0x60000000
/* R/W */
#define E2P_CMD_EPC_CMD_RELOAD 0x70000000
/* R/W */
#define E2P_CMD_EPC_TIMEOUT 0x00000200
/* RO */
#define E2P_CMD_MAC_ADDR_LOADED 0x00000100
/* RO */
#define E2P_CMD_EPC_ADDR 0x000000FF
/* R/W */
#define E2P_DATA 0xB4
#define E2P_DATA_EEPROM_DATA 0x000000FF
/* R/W */
/* end of LAN register offsets and bit definitions */
/* MAC Control and Status registers */
#define MAC_CR 0x01
/* R/W */
/* MAC_CR - MAC Control Register */
#define MAC_CR_RXALL 0x80000000
/* TODO: delete this bit? It is not described in the data sheet. */
#define MAC_CR_HBDIS 0x10000000
#define MAC_CR_RCVOWN 0x00800000
#define MAC_CR_LOOPBK 0x00200000
#define MAC_CR_FDPX 0x00100000
#define MAC_CR_MCPAS 0x00080000
#define MAC_CR_PRMS 0x00040000
#define MAC_CR_INVFILT 0x00020000
#define MAC_CR_PASSBAD 0x00010000
#define MAC_CR_HFILT 0x00008000
#define MAC_CR_HPFILT 0x00002000
#define MAC_CR_LCOLL 0x00001000
#define MAC_CR_BCAST 0x00000800
#define MAC_CR_DISRTY 0x00000400
#define MAC_CR_PADSTR 0x00000100
#define MAC_CR_BOLMT_MASK 0x000000C0
#define MAC_CR_DFCHK 0x00000020
#define MAC_CR_TXEN 0x00000008
#define MAC_CR_RXEN 0x00000004
#define ADDRH 0x02
/* R/W mask 0x0000FFFFUL */
#define ADDRL 0x03
/* R/W mask 0xFFFFFFFFUL */
#define HASHH 0x04
/* R/W */
#define HASHL 0x05
/* R/W */
#define MII_ACC 0x06
/* R/W */
#define MII_ACC_PHY_ADDR 0x0000F800
#define MII_ACC_MIIRINDA 0x000007C0
#define MII_ACC_MII_WRITE 0x00000002
#define MII_ACC_MII_BUSY 0x00000001
#define MII_DATA 0x07
/* R/W mask 0x0000FFFFUL */
#define FLOW 0x08
/* R/W */
#define FLOW_FCPT 0xFFFF0000
#define FLOW_FCPASS 0x00000004
#define FLOW_FCEN 0x00000002
#define FLOW_FCBSY 0x00000001
#define VLAN1 0x09
/* R/W mask 0x0000FFFFUL */
#define VLAN1_VTI1 0x0000ffff
#define VLAN2 0x0A
/* R/W mask 0x0000FFFFUL */
#define VLAN2_VTI2 0x0000ffff
#define WUFF 0x0B
/* WO */
#define WUCSR 0x0C
/* R/W */
#define WUCSR_GUE 0x00000200
#define WUCSR_WUFR 0x00000040
#define WUCSR_MPR 0x00000020
#define WUCSR_WAKE_EN 0x00000004
#define WUCSR_MPEN 0x00000002
/* Chip ID values */
#define CHIP_89218 0x218a
#define CHIP_9115 0x115
#define CHIP_9116 0x116
#define CHIP_9117 0x117
#define CHIP_9118 0x118
#define CHIP_9211 0x9211
#define CHIP_9215 0x115a
#define CHIP_9216 0x116a
#define CHIP_9217 0x117a
#define CHIP_9218 0x118a
#define CHIP_9220 0x9220
#define CHIP_9221 0x9221
/* Generic MII registers. */
#define MII_BMCR 0x00
/* Basic mode control register */
#define MII_BMSR 0x01
/* Basic mode status register */
#define MII_PHYSID1 0x02
/* PHYS ID 1 */
#define MII_PHYSID2 0x03
/* PHYS ID 2 */
#define MII_ADVERTISE 0x04
/* Advertisement control reg */
#define MII_LPA 0x05
/* Link partner ability reg */
#define MII_EXPANSION 0x06
/* Expansion register */
#define MII_CTRL1000 0x09
/* 1000BASE-T control */
#define MII_STAT1000 0x0a
/* 1000BASE-T status */
#define MII_ESTATUS 0x0f
/* Extended Status */
#define MII_DCOUNTER 0x12
/* Disconnect counter */
#define MII_FCSCOUNTER 0x13
/* False carrier counter */
#define MII_NWAYTEST 0x14
/* N-way auto-neg test reg */
#define MII_RERRCOUNTER 0x15
/* Receive error counter */
#define MII_SREVISION 0x16
/* Silicon revision */
#define MII_RESV1 0x17
/* Reserved... */
#define MII_LBRERROR 0x18
/* Lpback, rx, bypass error */
#define MII_PHYADDR 0x19
/* PHY address */
#define MII_RESV2 0x1a
/* Reserved... */
#define MII_TPISTATUS 0x1b
/* TPI status for 10mbps */
#define MII_NCONFIG 0x1c
/* Network interface config */
/* Basic mode control register. */
#define BMCR_RESV 0x003f
/* Unused... */
#define BMCR_SPEED1000 0x0040
/* MSB of Speed (1000) */
#define BMCR_CTST 0x0080
/* Collision test */
#define BMCR_FULLDPLX 0x0100
/* Full duplex */
#define BMCR_ANRESTART 0x0200
/* Auto negotiation restart */
#define BMCR_ISOLATE 0x0400
/* Disconnect DP83840 from MII */
#define BMCR_PDOWN 0x0800
/* Powerdown the DP83840 */
#define BMCR_ANENABLE 0x1000
/* Enable auto negotiation */
#define BMCR_SPEED100 0x2000
/* Select 100Mbps */
#define BMCR_LOOPBACK 0x4000
/* TXD loopback bits */
#define BMCR_RESET 0x8000
/* Reset the DP83840 */
/* Basic mode status register. */
#define BMSR_ERCAP 0x0001
/* Ext-reg capability */
#define BMSR_JCD 0x0002
/* Jabber detected */
#define BMSR_LSTATUS 0x0004
/* Link status */
#define BMSR_ANEGCAPABLE 0x0008
/* Able to do auto-negotiation */
#define BMSR_RFAULT 0x0010
/* Remote fault detected */
#define BMSR_ANEGCOMPLETE 0x0020
/* Auto-negotiation complete */
#define BMSR_RESV 0x00c0
/* Unused... */
#define BMSR_ESTATEN 0x0100
/* Extended Status in R15 */
#define BMSR_100HALF2 0x0200
/* Can do 100BASE-T2 HDX */
#define BMSR_100FULL2 0x0400
/* Can do 100BASE-T2 FDX */
#define BMSR_10HALF 0x0800
/* Can do 10mbps, half-duplex */
#define BMSR_10FULL 0x1000
/* Can do 10mbps, full-duplex */
#define BMSR_100HALF 0x2000
/* Can do 100mbps, half-duplex */
#define BMSR_100FULL 0x4000
/* Can do 100mbps, full-duplex */
#define BMSR_100BASE4 0x8000
/* Can do 100mbps, 4k packets */
#endif
bsp/qemu-vexpress-a9/drivers/realview.h
浏览文件 @
c8932cda
...
...
@@ -35,6 +35,8 @@
#define VEXPRESS_SRAM_BASE 0x48000000
#define REALVIEW_ETH_BASE 0x4E000000
/* Ethernet */
#define VEXPRESS_ETH_BASE 0x4E000000
/* Ethernet */
#define REALVIEW_USB_BASE 0x4F000000
/* USB */
#define REALVIEW_GIC_DIST_BASE 0x1E001000
/* Generic interrupt controller distributor */
#define REALVIEW_LT_BASE 0xC0000000
/* Logic Tile expansion */
...
...
@@ -84,12 +86,18 @@
#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 2)
/* Timer 0/1 (default timer) */
#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 3)
/* Timer 2/3 */
#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 4)
/* Timer 2/3 */
#define IRQ_VEXPRESS_A9_RTC (IRQ_PBA8_GIC_START + 4)
#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 5)
/* UART 0 on development chip */
#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 6)
/* UART 1 on development chip */
#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 7)
/* UART 2 on development chip */
#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 8)
/* UART 3 on development chip */
#define IRQ_VEXPRESS_A9_KBD (IRQ_PBA8_GIC_START + 12)
#define IRQ_VEXPRESS_A9_MOUSE (IRQ_PBA8_GIC_START + 13)
#define IRQ_VEXPRESS_A9_CLCD (IRQ_PBA8_GIC_START + 14)
#define IRQ_VEXPRESS_A9_ETH (IRQ_PBA8_GIC_START + 15)
/* 9 reserved */
#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11)
/* Synchronous Serial Port */
#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16)
/* Smart Card Interface */
...
...
bsp/qemu-vexpress-a9/rtconfig.h
浏览文件 @
c8932cda
...
...
@@ -8,6 +8,9 @@
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 4
/* RT_THREAD_PRIORITY_8 is not set */
#define RT_THREAD_PRIORITY_32
/* RT_THREAD_PRIORITY_256 is not set */
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 100
#define RT_DEBUG
...
...
@@ -31,9 +34,11 @@
#define RT_USING_MEMPOOL
#define RT_USING_MEMHEAP
#define RT_USING_HEAP
/* RT_USING_NOHEAP is not set */
#define RT_USING_SMALL_MEM
/* RT_USING_SLAB is not set */
/* RT_USING_MEMHEAP_AS_HEAP is not set */
#define RT_USING_HEAP
/* Kernel Device Object */
...
...
@@ -72,6 +77,7 @@
#define RT_USING_DFS
#define DFS_USING_WORKDIR
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FD_MAX 4
#define RT_USING_DFS_ELMFAT
...
...
@@ -122,6 +128,10 @@
/* RT_USING_ENC28J60 is not set */
/* RT_USING_SPI_WIFI is not set */
#define RT_USING_WDT
/* RT_USING_WIFI is not set */
/* Using USB */
/* RT_USING_USB_HOST is not set */
/* RT_USING_USB_DEVICE is not set */
...
...
@@ -140,6 +150,7 @@
#define RT_USING_LWIP
/* RT_USING_LWIP141 is not set */
#define RT_USING_LWIP202
/* RT_USING_LWIP_IPV6 is not set */
/* RT_LWIP_IGMP is not set */
#define RT_LWIP_ICMP
/* RT_LWIP_SNMP is not set */
...
...
@@ -213,6 +224,7 @@
/* PKG_USING_PARTITION is not set */
/* PKG_USING_SQLITE is not set */
/* PKG_USING_RTI is not set */
/* IoT - internet of things */
...
...
@@ -222,18 +234,17 @@
/* PKG_USING_WEBTERMINAL is not set */
/* PKG_USING_CJSON is not set */
/* PKG_USING_EZXML is not set */
/* Marvell WiFi */
/* PKG_USING_MARVELLWIFI is not set */
/* PKG_USING_NANOPB is not set */
/* security packages */
/* PKG_USING_MBEDTLS is not set */
/* PKG_USING_libsodium is not set */
/* language packages */
/* PKG_USING_JERRYSCRIPT is not set */
/* PKG_USING_MICROPYTHON is not set */
/* multimedia packages */
...
...
@@ -241,10 +252,26 @@
/* PKG_USING_CMBACKTRACE is not set */
/* PKG_USING_EASYLOGGER is not set */
/* PKG_USING_SYSTEMVIEW is not set */
/* miscellaneous packages */
#define PKG_USING_HELLO
/* PKG_USING_FASTLZ is not set */
/* PKG_USING_MINILZO is not set */
/* example package: hello */
/* PKG_USING_HELLO is not set */
/* Privated Packages of RealThread */
/* PKG_USING_CODEC is not set */
/* PKG_USING_PLAYER is not set */
/* Network Utilities */
/* PKG_USING_MDNS is not set */
/* PKG_USING_UPNP is not set */
#define RT_USING_UART0
#define RT_USING_UART1
#define BSP_DRV_CLCD
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录