Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
71454cf0
R
rt-thread
项目概览
BaiXuePrincess
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
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看板
未验证
提交
71454cf0
编写于
11月 24, 2017
作者:
B
Bernard Xiong
提交者:
GitHub
11月 24, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1037 from TanekLiang/lpc54608_fixbugs
[BSP] Lpc54608 fixbugs
上级
aa0747f6
02693a20
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
550 addition
and
403 deletion
+550
-403
bsp/lpc54608-LPCXpresso/SConstruct
bsp/lpc54608-LPCXpresso/SConstruct
+17
-6
bsp/lpc54608-LPCXpresso/drivers/drv_emac.c
bsp/lpc54608-LPCXpresso/drivers/drv_emac.c
+524
-390
bsp/lpc54608-LPCXpresso/rtconfig.py
bsp/lpc54608-LPCXpresso/rtconfig.py
+9
-7
未找到文件。
bsp/lpc54608-LPCXpresso/SConstruct
浏览文件 @
71454cf0
...
...
@@ -12,12 +12,23 @@ from building import *
TARGET
=
'rtthread-%s.%s'
%
(
rtconfig
.
BOARD_NAME
,
rtconfig
.
TARGET_EXT
)
env
=
Environment
(
tools
=
[
'mingw'
],
AS
=
rtconfig
.
AS
,
ASFLAGS
=
rtconfig
.
AFLAGS
,
CC
=
rtconfig
.
CC
,
CCFLAGS
=
rtconfig
.
CFLAGS
,
CXX
=
rtconfig
.
CXX
,
CXXFLAGS
=
rtconfig
.
CXXFLAGS
,
AR
=
rtconfig
.
AR
,
ARFLAGS
=
'-rc'
,
LINK
=
rtconfig
.
LINK
,
LINKFLAGS
=
rtconfig
.
LFLAGS
)
if
rtconfig
.
PLATFORM
==
'armcc'
:
env
=
Environment
(
tools
=
[
'mingw'
],
AS
=
rtconfig
.
AS
,
ASFLAGS
=
rtconfig
.
AFLAGS
,
CC
=
rtconfig
.
CC
,
CCFLAGS
=
rtconfig
.
CFLAGS
,
CXX
=
rtconfig
.
CXX
,
CXXFLAGS
=
rtconfig
.
CXXFLAGS
,
AR
=
rtconfig
.
AR
,
ARFLAGS
=
'-rc'
,
LINK
=
rtconfig
.
LINK
,
LINKFLAGS
=
rtconfig
.
LFLAGS
,
# overwrite cflags, because cflags has '--C99'
CXXCOM
=
'$CXX -o $TARGET --cpp -c $CXXFLAGS $_CCCOMCOM $SOURCES'
)
else
:
env
=
Environment
(
tools
=
[
'mingw'
],
AS
=
rtconfig
.
AS
,
ASFLAGS
=
rtconfig
.
AFLAGS
,
CC
=
rtconfig
.
CC
,
CCFLAGS
=
rtconfig
.
CFLAGS
,
CXX
=
rtconfig
.
CXX
,
CXXFLAGS
=
rtconfig
.
CXXFLAGS
,
AR
=
rtconfig
.
AR
,
ARFLAGS
=
'-rc'
,
LINK
=
rtconfig
.
LINK
,
LINKFLAGS
=
rtconfig
.
LFLAGS
)
env
.
PrependENVPath
(
'PATH'
,
rtconfig
.
EXEC_PATH
)
Export
(
'RTT_ROOT'
)
...
...
bsp/lpc54608-LPCXpresso/drivers/drv_emac.c
浏览文件 @
71454cf0
...
...
@@ -22,6 +22,7 @@
*/
#include <rtthread.h>
#include "lwipopts.h"
#include <netif/ethernetif.h>
#include <board.h>
...
...
@@ -32,6 +33,16 @@
#include "fsl_sctimer.h"
#include "fsl_phy.h"
#define DEBUG
//#define ETH_RX_DUMP
//#define ETH_TX_DUMP
#define ETH_STATISTICS
#ifdef DEBUG
#define ETH_PRINTF rt_kprintf
#else
#define ETH_PRINTF(...)
#endif
#define IOCON_PIO_DIGITAL_EN 0x0100u
/*!< Enables digital function */
#define IOCON_PIO_FUNC0 0x00u
/*!< Selects pin function 0 */
...
...
@@ -60,388 +71,313 @@
#define PORT2_IDX 2u
/*!< Port index */
#define PORT4_IDX 4u
/*!< Port index */
#define MAX_ADDR_LEN 6u
#define ENET_RXBD_NUM 4u
#define ENET_TXBD_NUM 4u
#define EMAC_PHY_AUTO 0
#define EMAC_PHY_10MBIT 1
#define EMAC_PHY_100MBIT 2
#define MAX_ADDR_LEN 6
#define ENET_ALIGN(x) \
((unsigned int)((x) + ((ENET_BUFF_ALIGNMENT)-1)) & (unsigned int)(~(unsigned int)((ENET_BUFF_ALIGNMENT)-1)))
/* EMAC_RAM_BASE is defined in board.h and the size is 16KB */
#define RX_DESC_BASE ETH_RAM_BASE
#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*8)
#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*8)
#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*8)
#define RX_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*4)
#define TX_BUF_BASE (RX_BUF_BASE + NUM_RX_FRAG*ETH_FRAG_SIZE)
/* RX and TX descriptor and status definitions. */
#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i))
#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i))
#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i))
#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i))
#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i))
#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i))
#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i))
#define RX_BUF(i) (RX_BUF_BASE + ETH_FRAG_SIZE*i)
#define TX_BUF(i) (TX_BUF_BASE + ETH_FRAG_SIZE*i)
#define ENET_RXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN)
#define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN)
struct
lpc_emac
{
/* inherit from ethernet device */
struct
eth_device
parent
;
rt_uint8_t
phy_mode
;
struct
rt_semaphore
tx_wait
;
ENET_Type
*
base
;
enet_handle_t
handle
;
/* interface address info. */
rt_uint8_t
dev_addr
[
MAX_ADDR_LEN
];
/* hw address */
uint32_t
phyAddr
;
uint8_t
RxBuffDescrip
[
ENET_RXBD_NUM
*
sizeof
(
enet_rx_bd_struct_t
)
+
ENET_BUFF_ALIGNMENT
];
uint8_t
TxBuffDescrip
[
ENET_TXBD_NUM
*
sizeof
(
enet_tx_bd_struct_t
)
+
ENET_BUFF_ALIGNMENT
];
uint8_t
RxDataBuff
[
ENET_RXBD_NUM
*
ENET_ALIGN
(
ENET_RXBUFF_SIZE
)
+
ENET_BUFF_ALIGNMENT
];
uint8_t
TxDataBuff
[
ENET_TXBD_NUM
*
ENET_ALIGN
(
ENET_TXBUFF_SIZE
)
+
ENET_BUFF_ALIGNMENT
];
uint8_t
txIdx
;
};
static
struct
lpc_emac
lpc_emac_device
;
static
struct
rt_semaphore
sem_lock
;
static
struct
rt_event
tx_event
;
#if defined(__GNUC__)
#ifndef __ALIGN_END
#define __ALIGN_END __attribute__((aligned(ENET_BUFF_ALIGNMENT)))
#endif
#ifndef __ALIGN_BEGIN
#define __ALIGN_BEGIN
#endif
#else
#ifndef __ALIGN_END
#define __ALIGN_END
#endif
#ifndef __ALIGN_BEGIN
#if defined(__CC_ARM)
#define __ALIGN_BEGIN __align(ENET_BUFF_ALIGNMENT)
#elif defined(__ICCARM__)
#define __ALIGN_BEGIN
#endif
#endif
#ifdef ETH_STATISTICS
static
uint32_t
isr_rx_counter
=
0
;
static
uint32_t
isr_tx_counter
=
0
;
#endif
#define ENET_RXBD_NUM (4)
#define ENET_TXBD_NUM (4)
#define PHY_ADDR (0x00U)
#define ENET_LOOP_COUNT (20U)
#define ENET_ALIGN(x, align) ((unsigned int)((x) + ((align)-1)) & (unsigned int)(~(unsigned int)((align)-1)))
#define ENET_BuffSizeAlign(n) ENET_ALIGN(n, ENET_BUFF_ALIGNMENT)
__ALIGN_BEGIN
enet_rx_bd_struct_t
g_rxBuffDescrip
[
ENET_RXBD_NUM
]
__ALIGN_END
;
__ALIGN_BEGIN
enet_tx_bd_struct_t
g_txBuffDescrip
[
ENET_TXBD_NUM
]
__ALIGN_END
;
uint8_t
multicastAddr
[
6
]
=
{
0x01
,
0x00
,
0x5e
,
0x00
,
0x01
,
0x81
};
uint8_t
*
g_txbuff
[
ENET_TXBD_NUM
];
uint32_t
g_txIdx
=
0
;
uint8_t
g_txbuffIdx
=
0
;
uint8_t
g_txGenIdx
=
0
;
uint8_t
g_txCosumIdx
=
0
;
uint8_t
g_txUsed
=
0
;
uint8_t
g_rxGenIdx
=
0
;
uint32_t
g_rxCosumIdx
=
0
;
uint32_t
g_rxbuffer
[
ENET_RXBD_NUM
];
static
inline
enet_rx_bd_struct_t
*
get_rx_desc
(
uint32_t
index
)
{
return
(
enet_rx_bd_struct_t
*
)
ENET_ALIGN
(
&
lpc_emac_device
.
RxBuffDescrip
[
index
*
sizeof
(
enet_rx_bd_struct_t
)]);
}
static
inline
enet_tx_bd_struct_t
*
get_tx_desc
(
uint32_t
index
)
{
return
(
enet_tx_bd_struct_t
*
)
ENET_ALIGN
(
&
lpc_emac_device
.
TxBuffDescrip
[
index
*
sizeof
(
enet_tx_bd_struct_t
)]);
}
static
uint8_t
*
ENET_RXRead
(
int32_t
*
length
)
#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
static
void
packet_dump
(
const
char
*
msg
,
const
struct
pbuf
*
p
)
{
uint32_t
control
;
uint8_t
*
data
;
*
length
=
0
;
const
struct
pbuf
*
q
;
rt_uint32_t
i
,
j
;
rt_uint8_t
*
ptr
;
rt_kprintf
(
"%s %d byte
\n
"
,
msg
,
p
->
tot_len
);
/* Get the Frame size */
control
=
ENET_GetRxDescriptor
(
&
g_rxBuffDescrip
[
g_rxGenIdx
]);
if
(
!
(
control
&
ENET_RXDESCRIP_RD_OWN_MASK
))
i
=
0
;
for
(
q
=
p
;
q
!=
RT_NULL
;
q
=
q
->
next
)
{
if
(
control
&
ENET_RXDESCRIP_WR_LD_MASK
)
ptr
=
q
->
payload
;
for
(
j
=
0
;
j
<
q
->
len
;
j
++
)
{
/* if no error */
if
(
control
&
ENET_RXDESCRIP_WR_ERRSUM_MASK
)
if
(
(
i
%
8
)
==
0
)
{
*
length
=
-
1
;
rt_kprintf
(
" "
)
;
}
else
if
(
(
i
%
16
)
==
0
)
{
*
length
=
control
&
ENET_RXDESCRIP_WR_PACKETLEN_MASK
;
data
=
(
uint8_t
*
)
g_rxbuffer
[
g_rxGenIdx
];
rt_kprintf
(
"
\r\n
"
);
}
g_rxGenIdx
=
(
g_rxGenIdx
+
1
)
%
ENET_RXBD_NUM
;
}
}
return
data
;
}
rt_kprintf
(
"%02x "
,
*
ptr
);
static
void
ENET_RXClaim
(
uint8_t
*
buffer
)
{
if
(
ENET_GetDmaInterruptStatus
(
ENET
,
0
)
&
kENET_DmaRxBuffUnavail
)
{
ENET_UpdateRxDescriptor
(
&
g_rxBuffDescrip
[
g_rxCosumIdx
],
buffer
,
NULL
,
true
,
false
);
/* Command for rx poll when the dma suspend. */
ENET_UpdateRxDescriptorTail
(
ENET
,
0
,
(
uint32_t
)
&
g_rxBuffDescrip
[
ENET_RXBD_NUM
]);
}
else
{
ENET_UpdateRxDescriptor
(
&
g_rxBuffDescrip
[
g_rxCosumIdx
],
buffer
,
NULL
,
true
,
false
);
}
if
(
buffer
)
{
g_rxbuffer
[
g_rxCosumIdx
]
=
(
uint32_t
)
buffer
;
i
++
;
ptr
++
;
}
}
g_rxCosumIdx
=
(
g_rxCosumIdx
+
1
)
%
ENET_RXBD_NUM
;
rt_kprintf
(
"
\n\n
"
)
;
}
#else
#define packet_dump(...)
#endif
/* dump */
static
status_t
ENET_TXQueue
(
uint8_t
*
data
,
uint16_t
length
)
static
void
ethernet_callback
(
ENET_Type
*
base
,
enet_handle_t
*
handle
,
enet_event_t
event
,
uint8_t
channel
,
void
*
param
)
{
uint32_t
txdescTailAddr
;
/* Fill the descriptor. */
if
(
ENET_IsTxDescriptorDmaOwn
(
&
g_txBuffDescrip
[
g_txGenIdx
]))
{
return
kStatus_Fail
;
}
ENET_SetupTxDescriptor
(
&
g_txBuffDescrip
[
g_txGenIdx
],
data
,
length
,
NULL
,
0
,
length
,
true
,
false
,
kENET_FirstLastFlag
,
0
);
/* Increase the index. */
g_txGenIdx
=
(
g_txGenIdx
+
1
)
%
ENET_TXBD_NUM
;
g_txUsed
++
;
/* Update the transmit tail address. */
txdescTailAddr
=
(
uint32_t
)
&
g_txBuffDescrip
[
g_txGenIdx
];
if
(
!
g_txGenIdx
)
switch
(
event
)
{
txdescTailAddr
=
(
uint32_t
)
&
g_txBuffDescrip
[
ENET_TXBD_NUM
];
case
kENET_RxIntEvent
:
#ifdef ETH_STATISTICS
isr_rx_counter
++
;
#endif
/* a frame has been received */
eth_device_ready
(
&
(
lpc_emac_device
.
parent
));
break
;
case
kENET_TxIntEvent
:
#ifdef ETH_STATISTICS
isr_tx_counter
++
;
#endif
/* set event */
rt_sem_release
(
&
lpc_emac_device
.
tx_wait
);
break
;
default:
break
;
}
ENET_UpdateTxDescriptorTail
(
ENET
,
0
,
txdescTailAddr
);
return
kStatus_Success
;
}
static
void
ENET_TXReclaim
(
)
static
void
lcp_emac_io_init
(
void
)
{
if
(
!
ENET_IsTxDescriptorDmaOwn
(
&
g_txBuffDescrip
[
g_txCosumIdx
])
&&
(
g_txUsed
>
0
))
{
/* Free tx buffers. */
free
(
g_txbuff
[
g_txCosumIdx
]);
g_txUsed
--
;
g_txCosumIdx
=
(
g_txCosumIdx
+
1
)
%
ENET_TXBD_NUM
;
}
const
uint32_t
port0_pin17_config
=
(
IOCON_PIO_FUNC7
|
/* Pin is configured as ENET_TXD1 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT0_IDX
,
PIN17_IDX
,
port0_pin17_config
);
/* PORT0 PIN17 (coords: E14) is configured as ENET_TXD1 */
const
uint32_t
port2_pin26_config
=
(
IOCON_PIO_FUNC0
|
/* Pin is configured as PIO2_26 */
IOCON_PIO_MODE_PULLUP
|
/* Selects pull-up function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT2_IDX
,
PIN26_IDX
,
port2_pin26_config
);
/* PORT2 PIN26 (coords: H11) is configured as PIO2_26 */
const
uint32_t
port4_pin10_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RX_DV */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN10_IDX
,
port4_pin10_config
);
/* PORT4 PIN10 (coords: B9) is configured as ENET_RX_DV */
const
uint32_t
port4_pin11_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RXD0 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN11_IDX
,
port4_pin11_config
);
/* PORT4 PIN11 (coords: A9) is configured as ENET_RXD0 */
const
uint32_t
port4_pin12_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RXD1 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN12_IDX
,
port4_pin12_config
);
/* PORT4 PIN12 (coords: A6) is configured as ENET_RXD1 */
const
uint32_t
port4_pin13_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_TX_EN */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN13_IDX
,
port4_pin13_config
);
/* PORT4 PIN13 (coords: B6) is configured as ENET_TX_EN */
const
uint32_t
port4_pin14_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RX_CLK */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN14_IDX
,
port4_pin14_config
);
/* PORT4 PIN14 (coords: B5) is configured as ENET_RX_CLK */
const
uint32_t
port4_pin15_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_MDC */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN15_IDX
,
port4_pin15_config
);
/* PORT4 PIN15 (coords: A4) is configured as ENET_MDC */
const
uint32_t
port4_pin16_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_MDIO */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN16_IDX
,
port4_pin16_config
);
/* PORT4 PIN16 (coords: C4) is configured as ENET_MDIO */
const
uint32_t
port4_pin8_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_TXD0 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN8_IDX
,
port4_pin8_config
);
/* PORT4 PIN8 (coords: B14) is configured as ENET_TXD0 */
}
void
ETHERNET_IRQHandler
(
void
)
static
rt_err_t
lpc_emac_phy_init
(
phy_speed_t
*
speed
,
phy_duplex_t
*
duplex
)
{
/* Check for the interrupt source type. */
/* DMA CHANNEL 0. */
uint32_t
status
;
bool
link
=
false
;
int32_t
status
;
/* enter interrupt */
rt_interrupt_enter
();
status
=
PHY_Init
(
lpc_emac_device
.
base
,
lpc_emac_device
.
phyAddr
,
0
);
if
(
status
!=
kStatus_Success
)
{
ETH_PRINTF
(
"PHY_Init failed!
\n
"
);
return
RT_ERROR
;
}
status
=
ENET_GetDmaInterruptStatus
(
ENET
,
0
);
if
(
status
)
/* Wait for link up and get the actual PHY link speed. */
PHY_GetLinkStatus
(
lpc_emac_device
.
base
,
lpc_emac_device
.
phyAddr
,
&
link
);
while
(
!
link
)
{
if
(
status
&
kENET_DmaRx
)
{
/* a frame has been received */
eth_device_ready
(
&
(
lpc_emac_device
.
parent
));
}
if
(
status
&
kENET_DmaTx
)
uint32_t
timedelay
;
ETH_PRINTF
(
"PHY Wait for link up!
\n
"
);
for
(
timedelay
=
0
;
timedelay
<
0xFFFFFU
;
timedelay
++
)
{
/* set event */
rt_event_send
(
&
tx_event
,
0x01
);
__ASM
(
"nop"
);
}
/* Clear the interrupt. */
ENET_ClearDmaInterruptStatus
(
ENET
,
0
,
status
);
PHY_GetLinkStatus
(
lpc_emac_device
.
base
,
lpc_emac_device
.
phyAddr
,
&
link
);
}
/* leave interrupt */
rt_interrupt_leave
();
RT_ASSERT
(
speed
!=
NULL
);
RT_ASSERT
(
duplex
!=
NULL
);
PHY_GetLinkSpeedDuplex
(
lpc_emac_device
.
base
,
lpc_emac_device
.
phyAddr
,
speed
,
duplex
);
return
RT_EOK
;
}
static
rt_err_t
lpc_emac_init
(
rt_device_t
dev
)
{
int32_t
status
,
index
;
void
*
buff
;
int
i
;
phy_speed_t
speed
;
phy_duplex_t
duplex
;
enet_config_t
config
;
bool
link
=
false
;
uint32_t
timedelay
;
uint32_t
refClock
=
50000000
;
/* 50MHZ for rmii reference clock. */
for
(
index
=
0
;
index
<
ENET_RXBD_NUM
;
index
++
)
{
/* This is for rx buffers, static alloc and dynamic alloc both ok. use as your wish. */
buff
=
rt_malloc
(
ENET_FRAME_MAX_FRAMELEN
);
if
(
buff
)
{
g_rxbuffer
[
index
]
=
(
uint32_t
)
buff
;
}
else
{
rt_kprintf
(
"Mem Alloc fail
\r\n
"
);
}
}
/* prepare the buffer configuration. */
enet_buffer_config_t
buffConfig
=
enet_buffer_config_t
buffCfg
;
uint32_t
rxBufferStartAddr
[
ENET_RXBD_NUM
];
lcp_emac_io_init
();
if
(
lpc_emac_phy_init
(
&
speed
,
&
duplex
)
!=
RT_EOK
)
{
ENET_RXBD_NUM
,
ENET_TXBD_NUM
,
&
g_txBuffDescrip
[
0
],
&
g_txBuffDescrip
[
0
],
&
g_rxBuffDescrip
[
0
],
&
g_rxBuffDescrip
[
4
],
&
g_rxbuffer
[
0
],
ENET_BuffSizeAlign
(
ENET_FRAME_MAX_FRAMELEN
),
};
{
const
uint32_t
port0_pin17_config
=
(
IOCON_PIO_FUNC7
|
/* Pin is configured as ENET_TXD1 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT0_IDX
,
PIN17_IDX
,
port0_pin17_config
);
/* PORT0 PIN17 (coords: E14) is configured as ENET_TXD1 */
const
uint32_t
port2_pin26_config
=
(
IOCON_PIO_FUNC0
|
/* Pin is configured as PIO2_26 */
IOCON_PIO_MODE_PULLUP
|
/* Selects pull-up function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT2_IDX
,
PIN26_IDX
,
port2_pin26_config
);
/* PORT2 PIN26 (coords: H11) is configured as PIO2_26 */
const
uint32_t
port4_pin10_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RX_DV */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN10_IDX
,
port4_pin10_config
);
/* PORT4 PIN10 (coords: B9) is configured as ENET_RX_DV */
const
uint32_t
port4_pin11_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RXD0 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN11_IDX
,
port4_pin11_config
);
/* PORT4 PIN11 (coords: A9) is configured as ENET_RXD0 */
const
uint32_t
port4_pin12_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RXD1 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN12_IDX
,
port4_pin12_config
);
/* PORT4 PIN12 (coords: A6) is configured as ENET_RXD1 */
const
uint32_t
port4_pin13_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_TX_EN */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN13_IDX
,
port4_pin13_config
);
/* PORT4 PIN13 (coords: B6) is configured as ENET_TX_EN */
const
uint32_t
port4_pin14_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_RX_CLK */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN14_IDX
,
port4_pin14_config
);
/* PORT4 PIN14 (coords: B5) is configured as ENET_RX_CLK */
const
uint32_t
port4_pin15_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_MDC */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN15_IDX
,
port4_pin15_config
);
/* PORT4 PIN15 (coords: A4) is configured as ENET_MDC */
const
uint32_t
port4_pin16_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_MDIO */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN16_IDX
,
port4_pin16_config
);
/* PORT4 PIN16 (coords: C4) is configured as ENET_MDIO */
const
uint32_t
port4_pin8_config
=
(
IOCON_PIO_FUNC1
|
/* Pin is configured as ENET_TXD0 */
IOCON_PIO_MODE_INACT
|
/* No addition pin function */
IOCON_PIO_INV_DI
|
/* Input function is not inverted */
IOCON_PIO_DIGITAL_EN
|
/* Enables digital function */
IOCON_PIO_INPFILT_OFF
|
/* Input filter disabled */
IOCON_PIO_SLEW_STANDARD
|
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_OPENDRAIN_DI
/* Open drain is disabled */
);
IOCON_PinMuxSet
(
IOCON
,
PORT4_IDX
,
PIN8_IDX
,
port4_pin8_config
);
/* PORT4 PIN8 (coords: B14) is configured as ENET_TXD0 */
}
status
=
PHY_Init
(
ENET
,
PHY_ADDR
,
0
);
if
(
status
==
kStatus_Success
)
{
PHY_GetLinkSpeedDuplex
(
ENET
,
PHY_ADDR
,
&
speed
,
&
duplex
);
/* Use the actual speed and duplex when phy success to finish the autonegotiation. */
config
.
miiSpeed
=
(
enet_mii_speed_t
)
speed
;
config
.
miiDuplex
=
(
enet_mii_duplex_t
)
duplex
;
}
else
{
rt_kprintf
(
"PHY_Init failed!
\n
"
);
return
RT_ERROR
;
}
/* Wait for link up and get the actual PHY link speed. */
PHY_GetLinkStatus
(
ENET
,
PHY_ADDR
,
&
link
);
while
(
!
link
)
/* calculate start addresses of all rx buffers */
for
(
i
=
0
;
i
<
ENET_RXBD_NUM
;
i
++
)
{
rt_kprintf
(
"PHY Wait for link up!
\n
"
);
for
(
timedelay
=
0
;
timedelay
<
0xFFFFFU
;
timedelay
++
)
{
__ASM
(
"nop"
);
}
PHY_GetLinkStatus
(
ENET
,
PHY_ADDR
,
&
link
);
rxBufferStartAddr
[
i
]
=
ENET_ALIGN
(
&
lpc_emac_device
.
RxDataBuff
[
i
*
ENET_ALIGN
(
ENET_RXBUFF_SIZE
)]);
}
buffCfg
.
rxRingLen
=
ENET_RXBD_NUM
;
buffCfg
.
txRingLen
=
ENET_TXBD_NUM
;
buffCfg
.
txDescStartAddrAlign
=
get_tx_desc
(
0U
);
buffCfg
.
txDescTailAddrAlign
=
get_tx_desc
(
0U
);
buffCfg
.
rxDescStartAddrAlign
=
get_rx_desc
(
0U
);
buffCfg
.
rxDescTailAddrAlign
=
get_rx_desc
(
ENET_RXBD_NUM
);
buffCfg
.
rxBufferStartAddr
=
rxBufferStartAddr
;
buffCfg
.
rxBuffSizeAlign
=
ENET_ALIGN
(
ENET_RXBUFF_SIZE
);
/* Get default configuration 100M RMII. */
ENET_GetDefaultConfig
(
&
config
);
/* Use the actual speed and duplex when phy success to finish the autonegotiation. */
config
.
miiSpeed
=
(
enet_mii_speed_t
)
speed
;
config
.
miiDuplex
=
(
enet_mii_duplex_t
)
duplex
;
ETH_PRINTF
(
"Auto negotiation, Speed: "
);
if
(
config
.
miiSpeed
==
kENET_MiiSpeed100M
)
ETH_PRINTF
(
"100M"
);
else
ETH_PRINTF
(
"10M"
);
ETH_PRINTF
(
", Duplex: "
);
if
(
config
.
miiSpeed
==
kENET_MiiSpeed100M
)
ETH_PRINTF
(
"Full
\n
"
);
else
ETH_PRINTF
(
"Half
\n
"
);
/* Initialize
ENET
. */
ENET_Init
(
ENET
,
&
config
,
&
lpc_emac_device
.
dev_addr
[
0
],
refClock
);
/* Initialize
lpc_emac_device.base
. */
ENET_Init
(
lpc_emac_device
.
base
,
&
config
,
&
lpc_emac_device
.
dev_addr
[
0
],
CLOCK_GetFreq
(
kCLOCK_CoreSysClk
)
);
/* Enable the tx/rx interrupt. */
ENET_EnableInterrupts
(
ENET
,
(
kENET_DmaTx
|
kENET_DmaRx
));
E
nableIRQ
(
ETHERNET_IRQn
);
ENET_EnableInterrupts
(
lpc_emac_device
.
base
,
(
kENET_DmaTx
|
kENET_DmaRx
));
E
NET_CreateHandler
(
lpc_emac_device
.
base
,
&
lpc_emac_device
.
handle
,
&
config
,
&
buffCfg
,
ethernet_callback
,
NULL
);
/* Initialize Descriptor. */
ENET_DescriptorInit
(
ENET
,
&
config
,
&
buffConfi
g
);
ENET_DescriptorInit
(
lpc_emac_device
.
base
,
&
config
,
&
buffCf
g
);
/* Active TX/RX. */
ENET_StartRxTx
(
ENET
,
1
,
1
);
ENET_StartRxTx
(
lpc_emac_device
.
base
,
1
,
1
);
eth_device_linkchange
(
&
lpc_emac_device
.
parent
,
RT_TRUE
);
return
RT_EOK
;
}
...
...
@@ -489,39 +425,47 @@ static rt_err_t lpc_emac_control(rt_device_t dev, int cmd, void *args)
/* transmit packet. */
rt_err_t
lpc_emac_tx
(
rt_device_t
dev
,
struct
pbuf
*
p
)
{
rt_uint8_t
*
buffer
;
rt_err_t
result
;
rt_uint32_t
recved
;
/* lock EMAC device */
rt_sem_take
(
&
sem_lock
,
RT_WAITING_FOREVER
);
rt_err_t
result
=
RT_EOK
;
enet_handle_t
*
enet_handle
=
&
lpc_emac_device
.
handle
;
ENET_Type
*
enet_base
=
lpc_emac_device
.
base
;
uint8_t
*
data
;
/* there is no block yet, wait a flag */
result
=
rt_event_recv
(
&
tx_event
,
0x01
,
RT_EVENT_FLAG_AND
|
RT_EVENT_FLAG_CLEAR
,
RT_WAITING_NO
,
&
recved
);
if
(
result
==
RT_EOK
)
ENET_TXReclaim
();
RT_ASSERT
(
p
!=
NULL
);
RT_ASSERT
(
enet_handle
!=
RT_NULL
);
/* Create the buffer for zero-copy transmit. */
buffer
=
(
uint8_t
*
)
malloc
(
p
->
tot_len
);
if
(
buffer
)
if
(
p
->
tot_len
>
ENET_TXBUFF_SIZE
)
{
/* copy data to tx buffer */
pbuf_copy_partial
(
p
,
buffer
,
p
->
tot_len
,
0
);
while
((
g_txbuffIdx
+
1
)
%
ENET_TXBD_NUM
==
g_txCosumIdx
)
return
RT_ERROR
;
}
packet_dump
(
"TX dump"
,
p
);
/* get free tx buffer */
{
rt_err_t
result
;
result
=
rt_sem_take
(
&
lpc_emac_device
.
tx_wait
,
RT_TICK_PER_SECOND
/
10
);
if
(
result
!=
RT_EOK
)
{
r
t_thread_delay
(
RT_TICK_PER_SECOND
/
20
);
// 50 ms
r
eturn
RT_ERROR
;
}
/* Store the buffer for mem free. */
g_txbuff
[
g_txbuffIdx
]
=
buffer
;
g_txbuffIdx
=
(
g_txbuffIdx
+
1
)
%
ENET_TXBD_NUM
;
/* Send the frame out (wait unitl the descriptor ready). */
while
(
ENET_TXQueue
(
buffer
,
p
->
tot_len
)
!=
kStatus_Success
);
}
/* unlock EMAC device */
rt_sem_release
(
&
sem_lock
);
data
=
(
uint8_t
*
)
ENET_ALIGN
(
&
lpc_emac_device
.
RxDataBuff
[
lpc_emac_device
.
txIdx
*
ENET_ALIGN
(
ENET_RXBUFF_SIZE
)]);
pbuf_copy_partial
(
p
,
data
,
p
->
tot_len
,
0
);
lpc_emac_device
.
txIdx
=
(
lpc_emac_device
.
txIdx
+
1
)
/
ENET_TXBD_NUM
;
result
=
ENET_SendFrame
(
enet_base
,
enet_handle
,
data
,
p
->
len
);
RT_ASSERT
(
result
!=
kStatus_ENET_TxFrameBusy
);
if
((
result
==
kStatus_ENET_TxFrameFail
)
||
(
result
==
kStatus_ENET_TxFrameOverLen
))
{
return
RT_ERROR
;
}
else
if
(
result
==
kStatus_ENET_TxFrameBusy
)
{
RT_ASSERT
(
NULL
);
}
return
RT_EOK
;
}
...
...
@@ -529,61 +473,59 @@ rt_err_t lpc_emac_tx(rt_device_t dev, struct pbuf *p)
/* reception packet. */
struct
pbuf
*
lpc_emac_rx
(
rt_device_t
dev
)
{
struct
pbuf
*
p
;
uint8_t
*
data
;
int
length
;
/* init p pointer */
p
=
RT_NULL
;
/* lock EMAC device */
rt_sem_take
(
&
sem_lock
,
RT_WAITING_FOREVER
);
length
=
0
;
data
=
ENET_RXRead
(
&
length
);
if
(
length
>
0
)
{
void
*
buffer
;
/* Update the buffers and then we can delivery the previous buffer diectly to
the application without memcpy. */
buffer
=
rt_malloc
(
ENET_FRAME_MAX_FRAMELEN
);
if
(
buffer
)
uint32_t
length
=
0
;
status_t
status
;
struct
pbuf
*
p
=
RT_NULL
;
enet_handle_t
*
enet_handle
=
&
lpc_emac_device
.
handle
;
ENET_Type
*
enet_base
=
lpc_emac_device
.
base
;
/* Get the Frame size */
status
=
ENET_GetRxFrameSize
(
enet_base
,
enet_handle
,
&
length
,
0
);
/* Call ENET_ReadFrame when there is a received frame. */
if
(
length
!=
0
)
{
/* Received valid frame. Deliver the rx buffer with the size equal to length. */
p
=
pbuf_alloc
(
PBUF_RAW
,
length
,
PBUF_POOL
);
if
(
p
!=
NULL
)
{
ENET_RXClaim
(
buffer
);
status
=
ENET_ReadFrame
(
enet_base
,
enet_handle
,
p
->
payload
,
length
,
0
);
if
(
status
==
kStatus_Success
)
{
packet_dump
(
"RX dump"
,
p
);
return
p
;
}
else
{
ETH_PRINTF
(
" A frame read failed
\n
"
);
pbuf_free
(
p
);
}
}
else
{
E
NET_RXClaim
(
NULL
);
E
TH_PRINTF
(
" pbuf_alloc faild
\n
"
);
}
/* Do what you want to do with the data and then free the used one. */
p
=
pbuf_alloc
(
PBUF_LINK
,
length
,
PBUF_RAM
);
if
(
p
!=
RT_NULL
)
{
rt_memcpy
(
p
->
payload
,
data
,
length
);
p
->
tot_len
=
length
;
}
rt_free
(
data
);
}
else
if
(
length
<
0
)
{
ENET_RXClaim
(
NULL
);
}
/* unlock EMAC device */
rt_sem_release
(
&
sem_lock
);
return
p
;
}
else
if
(
status
==
kStatus_ENET_RxFrameError
)
{
ETH_PRINTF
(
"ENET_GetRxFrameSize: kStatus_ENET_RxFrameError
\n
"
);
ENET_ReadFrame
(
enet_base
,
enet_handle
,
NULL
,
0
,
0
);
}
return
NULL
;
}
int
lpc_emac_hw_init
(
void
)
{
rt_event_init
(
&
tx_event
,
"tx_event"
,
RT_IPC_FLAG_FIFO
);
rt_sem_init
(
&
sem_lock
,
"eth_lock"
,
1
,
RT_IPC_FLAG_FIFO
);
/* set autonegotiation mode */
lpc_emac_device
.
phy_mode
=
EMAC_PHY_AUTO
;
/* init tx semaphore */
rt_sem_init
(
&
lpc_emac_device
.
tx_wait
,
"tx_wait"
,
ENET_TXBD_NUM
,
RT_IPC_FLAG_FIFO
);
lpc_emac_device
.
phyAddr
=
0
;
lpc_emac_device
.
txIdx
=
0
;
lpc_emac_device
.
base
=
ENET
;
// OUI 00-60-37 NXP Semiconductors
lpc_emac_device
.
dev_addr
[
0
]
=
0x00
;
lpc_emac_device
.
dev_addr
[
1
]
=
0x60
;
...
...
@@ -605,6 +547,198 @@ int lpc_emac_hw_init(void)
lpc_emac_device
.
parent
.
eth_tx
=
lpc_emac_tx
;
eth_device_init
(
&
(
lpc_emac_device
.
parent
),
"e0"
);
return
0
;
}
INIT_DEVICE_EXPORT
(
lpc_emac_hw_init
);
#ifdef ETH_STATISTICS
int
emac_stat
(
void
)
{
rt_kprintf
(
"enter rx isr coutner : %d
\n
"
,
isr_rx_counter
);
rt_kprintf
(
"enter tx isr coutner : %d
\n
"
,
isr_tx_counter
);
return
0
;
}
#endif
void
phy_dump
(
void
)
{
status_t
PHY_Read
(
ENET_Type
*
base
,
uint32_t
phyAddr
,
uint32_t
phyReg
,
uint32_t
*
dataPtr
);
int
i
;
for
(
i
=
0
;
i
<
31
;
i
++
)
{
status_t
result
=
kStatus_Success
;
uint32_t
reg
;
result
=
PHY_Read
(
lpc_emac_device
.
base
,
lpc_emac_device
.
phyAddr
,
i
,
&
reg
);
if
(
result
==
kStatus_Success
)
{
rt_kprintf
(
"%02d: %08d
\n
"
,
i
,
reg
);
}
else
{
rt_kprintf
(
"read register %d faild
\n
"
,
i
);
}
}
}
void
emac_dump
(
void
)
{
#define DUMP_REG(__NAME) \
rt_kprintf("%-40s, %08x: %08x\n", #__NAME, (uint32_t)&(lpc_emac_device.base->__NAME), lpc_emac_device.base->__NAME)
DUMP_REG
(
MAC_CONFIG
);
DUMP_REG
(
MAC_EXT_CONFIG
);
DUMP_REG
(
MAC_FRAME_FILTER
);
DUMP_REG
(
MAC_WD_TIMEROUT
);
DUMP_REG
(
MAC_VLAN_TAG
);
DUMP_REG
(
MAC_TX_FLOW_CTRL_Q
[
0
]);
DUMP_REG
(
MAC_TX_FLOW_CTRL_Q
[
1
]);
DUMP_REG
(
MAC_RX_FLOW_CTRL
);
DUMP_REG
(
MAC_TXQ_PRIO_MAP
);
DUMP_REG
(
MAC_RXQ_CTRL
[
0
]);
DUMP_REG
(
MAC_RXQ_CTRL
[
1
]);
DUMP_REG
(
MAC_RXQ_CTRL
[
2
]);
DUMP_REG
(
MAC_INTR_STAT
);
DUMP_REG
(
MAC_INTR_EN
);
DUMP_REG
(
MAC_RXTX_STAT
);
DUMP_REG
(
MAC_PMT_CRTL_STAT
);
DUMP_REG
(
MAC_RWAKE_FRFLT
);
DUMP_REG
(
MAC_LPI_CTRL_STAT
);
DUMP_REG
(
MAC_LPI_TIMER_CTRL
);
DUMP_REG
(
MAC_LPI_ENTR_TIMR
);
DUMP_REG
(
MAC_1US_TIC_COUNTR
);
DUMP_REG
(
MAC_VERSION
);
DUMP_REG
(
MAC_DBG
);
DUMP_REG
(
MAC_HW_FEAT
[
0
]);
DUMP_REG
(
MAC_HW_FEAT
[
1
]);
DUMP_REG
(
MAC_HW_FEAT
[
2
]);
DUMP_REG
(
MAC_MDIO_ADDR
);
DUMP_REG
(
MAC_MDIO_DATA
);
DUMP_REG
(
MAC_ADDR_HIGH
);
DUMP_REG
(
MAC_ADDR_LOW
);
DUMP_REG
(
MAC_TIMESTAMP_CTRL
);
DUMP_REG
(
MAC_SUB_SCND_INCR
);
DUMP_REG
(
MAC_SYS_TIME_SCND
);
DUMP_REG
(
MAC_SYS_TIME_NSCND
);
DUMP_REG
(
MAC_SYS_TIME_SCND_UPD
);
DUMP_REG
(
MAC_SYS_TIME_NSCND_UPD
);
DUMP_REG
(
MAC_SYS_TIMESTMP_ADDEND
);
DUMP_REG
(
MAC_SYS_TIME_HWORD_SCND
);
DUMP_REG
(
MAC_SYS_TIMESTMP_STAT
);
DUMP_REG
(
MAC_TX_TIMESTAMP_STATUS_NANOSECONDS
);
DUMP_REG
(
MAC_TX_TIMESTAMP_STATUS_SECONDS
);
DUMP_REG
(
MAC_TIMESTAMP_INGRESS_CORR_NANOSECOND
);
DUMP_REG
(
MAC_TIMESTAMP_EGRESS_CORR_NANOSECOND
);
DUMP_REG
(
MTL_OP_MODE
);
DUMP_REG
(
MTL_INTR_STAT
);
DUMP_REG
(
MTL_RXQ_DMA_MAP
);
DUMP_REG
(
DMA_MODE
);
DUMP_REG
(
DMA_SYSBUS_MODE
);
DUMP_REG
(
DMA_INTR_STAT
);
DUMP_REG
(
DMA_DBG_STAT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_OP_MODE
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_UNDRFLW
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_DBG
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_ETS_CTRL
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_ETS_STAT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_QNTM_WGHT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_SNDSLP_CRDT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_HI_CRDT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_LO_CRDT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_TXQX_INTCTRL_STAT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_RXQX_OP_MODE
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_RXQX_MISSPKT_OVRFLW_CNT
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_RXQX_DBG
);
DUMP_REG
(
MTL_QUEUE
[
0
].
MTL_RXQX_CTRL
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_OP_MODE
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_UNDRFLW
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_DBG
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_ETS_CTRL
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_ETS_STAT
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_QNTM_WGHT
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_SNDSLP_CRDT
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_HI_CRDT
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_LO_CRDT
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_TXQX_INTCTRL_STAT
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_RXQX_OP_MODE
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_RXQX_MISSPKT_OVRFLW_CNT
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_RXQX_DBG
);
DUMP_REG
(
MTL_QUEUE
[
1
].
MTL_RXQX_CTRL
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_CTRL
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_TX_CTRL
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_RX_CTRL
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_TXDESC_LIST_ADDR
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_RXDESC_LIST_ADDR
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_TXDESC_TAIL_PTR
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_RXDESC_TAIL_PTR
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_TXDESC_RING_LENGTH
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_RXDESC_RING_LENGTH
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_INT_EN
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_RX_INT_WDTIMER
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_SLOT_FUNC_CTRL_STAT
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_CUR_HST_TXDESC
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_CUR_HST_RXDESC
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_CUR_HST_TXBUF
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_CUR_HST_RXBUF
);
DUMP_REG
(
DMA_CH
[
0
].
DMA_CHX_STAT
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_CTRL
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_TX_CTRL
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_RX_CTRL
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_TXDESC_LIST_ADDR
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_RXDESC_LIST_ADDR
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_TXDESC_TAIL_PTR
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_RXDESC_TAIL_PTR
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_TXDESC_RING_LENGTH
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_RXDESC_RING_LENGTH
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_INT_EN
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_RX_INT_WDTIMER
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_SLOT_FUNC_CTRL_STAT
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_CUR_HST_TXDESC
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_CUR_HST_RXDESC
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_CUR_HST_TXBUF
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_CUR_HST_RXBUF
);
DUMP_REG
(
DMA_CH
[
1
].
DMA_CHX_STAT
);
}
void
emac_bd_dump
(
void
)
{
int
i
;
rt_kprintf
(
"rx bd dump:
\n
"
);
for
(
i
=
0
;
i
<
ENET_RXBD_NUM
;
i
++
)
{
enet_rx_bd_struct_t
*
rx_bd
=
get_rx_desc
(
i
);
rt_kprintf
(
"buf1: %p, buf2: %p, ctrl: %08x
\n
"
,
rx_bd
->
buff1Addr
,
rx_bd
->
buff2Addr
,
rx_bd
->
control
);
}
rt_kprintf
(
"tx bd dump:
\n
"
);
for
(
i
=
0
;
i
<
ENET_TXBD_NUM
;
i
++
)
{
enet_tx_bd_struct_t
*
tx_bd
=
get_tx_desc
(
i
);
rt_kprintf
(
"buf1: %p, buf2: %p, len: %08x, ctrl: %08x
\n
"
,
tx_bd
->
buff1Addr
,
tx_bd
->
buff2Addr
,
tx_bd
->
buffLen
,
tx_bd
->
controlStat
);
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT
(
emac_stat
,
dump
emac
stat
data
);
FINSH_FUNCTION_EXPORT
(
phy_dump
,
dump
phy
registers
);
FINSH_FUNCTION_EXPORT
(
emac_dump
,
dump
emac
registers
);
FINSH_FUNCTION_EXPORT
(
emac_bd_dump
,
dump
emac
tx
and
rx
descriptor
);
#endif
bsp/lpc54608-LPCXpresso/rtconfig.py
浏览文件 @
71454cf0
...
...
@@ -16,9 +16,9 @@ elif CROSS_TOOL == 'keil':
PLATFORM
=
'armcc'
EXEC_PATH
=
'D:/Keil_v5'
elif
CROSS_TOOL
==
'iar'
:
print
'================ERROR============================'
print
'Not support iar yet!'
print
'================================================='
print
(
'================ERROR============================'
)
print
(
'Not support iar yet!'
)
print
(
'================================================='
)
exit
(
0
)
if
os
.
getenv
(
'RTT_EXEC_PATH'
):
...
...
@@ -70,12 +70,11 @@ elif PLATFORM == 'armcc':
CFLAGS
=
DEVICE
+
' --apcs=interwork'
AFLAGS
=
DEVICE
LFLAGS
=
DEVICE
+
' --info sizes --info totals --info unused --info veneers --list rtthread_'
+
\
BOARD_NAME
+
'.map --scatter
rtthread-'
+
BOARD_NAME
+
'.sct
'
BOARD_NAME
+
'.map --scatter
LPC54608J512_flash.scf
'
CFLAGS
+=
' -I'
+
EXEC_PATH
+
'/ARM/RV31/INC'
LFLAGS
+=
' --libpath '
+
EXEC_PATH
+
'/ARM/RV31/LIB'
CXXFLAGS
=
CFLAGS
EXEC_PATH
+=
'/arm/bin40/'
if
BUILD
==
'debug'
:
...
...
@@ -83,5 +82,8 @@ elif PLATFORM == 'armcc':
AFLAGS
+=
' -g'
else
:
CFLAGS
+=
' -O2'
CXXFLAGS
=
CFLAGS
CFLAGS
+=
' --c99'
POST_ACTION
=
'fromelf --bin $TARGET --output rtthread.bin
\n
fromelf -z $TARGET'
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录