Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
AdRainty
rt-thread
提交
58769e67
R
rt-thread
项目概览
AdRainty
/
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看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
58769e67
编写于
8月 30, 2022
作者:
o777788
提交者:
GitHub
8月 29, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
修复imxrt1170网络驱动问题 (#6342)
1、修复ksz8081.c编译错误; 2、修复rt1170网络驱动问题
上级
b11cb41a
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
283 addition
and
4 deletion
+283
-4
bsp/imxrt/libraries/drivers/drv_eth.c
bsp/imxrt/libraries/drivers/drv_eth.c
+277
-4
bsp/imxrt/libraries/drivers/drv_ksz8081.c
bsp/imxrt/libraries/drivers/drv_ksz8081.c
+6
-0
未找到文件。
bsp/imxrt/libraries/drivers/drv_eth.c
浏览文件 @
58769e67
...
...
@@ -8,6 +8,7 @@
* 2017-10-10 Tanek the first version
* 2019-5-10 misonyo add DMA TX and RX function
* 2020-10-14 wangqiang use phy device in phy monitor thread
* 2022-08-29 xjy198903 add 1170 rgmii support
*/
#include <rtthread.h>
...
...
@@ -29,8 +30,8 @@
#include <netif/ethernetif.h>
#include "lwipopts.h"
#define ENET_RXBD_NUM (
4
)
#define ENET_TXBD_NUM (
4
)
#define ENET_RXBD_NUM (
5
)
#define ENET_TXBD_NUM (
3
)
#define ENET_RXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN)
#define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN)
...
...
@@ -122,6 +123,7 @@ void _enet_rx_callback(struct rt_imxrt_eth *eth)
void
_enet_tx_callback
(
struct
rt_imxrt_eth
*
eth
)
{
dbg_log
(
DBG_LOG
,
"_enet_tx_callback
\n
"
);
if
(
eth
->
tx_is_waiting
==
RT_TRUE
)
{
eth
->
tx_is_waiting
=
RT_FALSE
;
...
...
@@ -451,6 +453,277 @@ static rt_err_t rt_imxrt_eth_control(rt_device_t dev, int cmd, void *args)
return
RT_EOK
;
}
static
bool
_ENET_TxDirtyRingAvailable
(
enet_tx_dirty_ring_t
*
txDirtyRing
)
{
return
!
txDirtyRing
->
isFull
;
}
static
uint16_t
_ENET_IncreaseIndex
(
uint16_t
index
,
uint16_t
max
)
{
assert
(
index
<
max
);
/* Increase the index. */
index
++
;
if
(
index
>=
max
)
{
index
=
0
;
}
return
index
;
}
static
void
_ENET_ActiveSendRing
(
ENET_Type
*
base
,
uint8_t
ringId
)
{
assert
(
ringId
<
(
uint8_t
)
FSL_FEATURE_ENET_INSTANCE_QUEUEn
(
base
));
volatile
uint32_t
*
txDesActive
=
NULL
;
/* Ensure previous data update is completed with Data Synchronization Barrier before activing Tx BD. */
__DSB
();
switch
(
ringId
)
{
case
0
:
txDesActive
=
&
(
base
->
TDAR
);
break
;
#if FSL_FEATURE_ENET_QUEUE > 1
case
1
:
txDesActive
=
&
(
base
->
TDAR1
);
break
;
case
2
:
txDesActive
=
&
(
base
->
TDAR2
);
break
;
#endif
/* FSL_FEATURE_ENET_QUEUE > 1 */
default:
txDesActive
=
&
(
base
->
TDAR
);
break
;
}
#if defined(FSL_FEATURE_ENET_HAS_ERRATA_007885) && FSL_FEATURE_ENET_HAS_ERRATA_007885
/* There is a TDAR race condition for mutliQ when the software sets TDAR
* and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
* This will cause the udma_tx and udma_tx_arbiter state machines to hang.
* Software workaround: introduces a delay by reading the relevant ENET_TDARn_TDAR 4 times
*/
for
(
uint8_t
i
=
0
;
i
<
4U
;
i
++
)
{
if
(
*
txDesActive
==
0U
)
{
break
;
}
}
#endif
/* Write to active tx descriptor */
*
txDesActive
=
0
;
}
static
status_t
_ENET_SendFrame
(
ENET_Type
*
base
,
enet_handle_t
*
handle
,
const
uint8_t
*
data
,
uint32_t
length
,
uint8_t
ringId
,
bool
tsFlag
,
void
*
context
)
{
assert
(
handle
!=
NULL
);
assert
(
data
!=
NULL
);
assert
(
FSL_FEATURE_ENET_INSTANCE_QUEUEn
(
base
)
!=
-
1
);
assert
(
ringId
<
(
uint8_t
)
FSL_FEATURE_ENET_INSTANCE_QUEUEn
(
base
));
volatile
enet_tx_bd_struct_t
*
curBuffDescrip
;
enet_tx_bd_ring_t
*
txBdRing
=
&
handle
->
txBdRing
[
ringId
];
enet_tx_dirty_ring_t
*
txDirtyRing
=
&
handle
->
txDirtyRing
[
ringId
];
enet_frame_info_t
*
txDirty
=
NULL
;
uint32_t
len
=
0
;
uint32_t
sizeleft
=
0
;
uint32_t
address
;
status_t
result
=
kStatus_Success
;
uint32_t
src
;
uint32_t
configVal
;
bool
isReturn
=
false
;
uint32_t
primask
;
/* Check the frame length. */
if
(
length
>
ENET_FRAME_TX_LEN_LIMITATION
(
base
))
{
result
=
kStatus_ENET_TxFrameOverLen
;
}
else
{
/* Check if the transmit buffer is ready. */
curBuffDescrip
=
txBdRing
->
txBdBase
+
txBdRing
->
txGenIdx
;
if
(
0U
!=
(
curBuffDescrip
->
control
&
ENET_BUFFDESCRIPTOR_TX_READY_MASK
))
{
result
=
kStatus_ENET_TxFrameBusy
;
}
/* Check txDirtyRing if need frameinfo in tx interrupt callback. */
else
if
((
handle
->
txReclaimEnable
[
ringId
])
&&
!
_ENET_TxDirtyRingAvailable
(
txDirtyRing
))
{
result
=
kStatus_ENET_TxFrameBusy
;
}
else
{
/* One transmit buffer is enough for one frame. */
if
(
handle
->
txBuffSizeAlign
[
ringId
]
>=
length
)
{
/* Copy data to the buffer for uDMA transfer. */
#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
address
=
MEMORY_ConvertMemoryMapAddress
((
uint32_t
)
curBuffDescrip
->
buffer
,
kMEMORY_DMA2Local
);
#else
address
=
(
uint32_t
)
curBuffDescrip
->
buffer
;
#endif
/* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
pbuf_copy_partial
((
const
struct
pbuf
*
)
data
,
(
void
*
)
address
,
length
,
0
);
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
if
(
handle
->
txMaintainEnable
[
ringId
])
{
DCACHE_CleanByRange
(
address
,
length
);
}
#endif
/* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
/* Set data length. */
curBuffDescrip
->
length
=
(
uint16_t
)
length
;
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
/* For enable the timestamp. */
if
(
tsFlag
)
{
curBuffDescrip
->
controlExtend1
|=
ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK
;
}
else
{
curBuffDescrip
->
controlExtend1
&=
(
uint16_t
)(
~
ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK
);
}
#endif
/* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
curBuffDescrip
->
control
|=
(
ENET_BUFFDESCRIPTOR_TX_READY_MASK
|
ENET_BUFFDESCRIPTOR_TX_LAST_MASK
);
/* Increase the buffer descriptor address. */
txBdRing
->
txGenIdx
=
_ENET_IncreaseIndex
(
txBdRing
->
txGenIdx
,
txBdRing
->
txRingLen
);
/* Add context to frame info ring */
if
(
handle
->
txReclaimEnable
[
ringId
])
{
txDirty
=
txDirtyRing
->
txDirtyBase
+
txDirtyRing
->
txGenIdx
;
txDirty
->
context
=
context
;
txDirtyRing
->
txGenIdx
=
_ENET_IncreaseIndex
(
txDirtyRing
->
txGenIdx
,
txDirtyRing
->
txRingLen
);
if
(
txDirtyRing
->
txGenIdx
==
txDirtyRing
->
txConsumIdx
)
{
txDirtyRing
->
isFull
=
true
;
}
primask
=
DisableGlobalIRQ
();
txBdRing
->
txDescUsed
++
;
EnableGlobalIRQ
(
primask
);
}
/* Active the transmit buffer descriptor. */
_ENET_ActiveSendRing
(
base
,
ringId
);
}
else
{
/* One frame requires more than one transmit buffers. */
do
{
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
/* For enable the timestamp. */
if
(
tsFlag
)
{
curBuffDescrip
->
controlExtend1
|=
ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK
;
}
else
{
curBuffDescrip
->
controlExtend1
&=
(
uint16_t
)(
~
ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK
);
}
#endif
/* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/* Update the size left to be transmit. */
sizeleft
=
length
-
len
;
#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
address
=
MEMORY_ConvertMemoryMapAddress
((
uint32_t
)
curBuffDescrip
->
buffer
,
kMEMORY_DMA2Local
);
#else
address
=
(
uint32_t
)
curBuffDescrip
->
buffer
;
#endif
/* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
src
=
(
uint32_t
)
data
+
len
;
/* Increase the current software index of BD */
txBdRing
->
txGenIdx
=
_ENET_IncreaseIndex
(
txBdRing
->
txGenIdx
,
txBdRing
->
txRingLen
);
if
(
sizeleft
>
handle
->
txBuffSizeAlign
[
ringId
])
{
/* Data copy. */
(
void
)
memcpy
((
void
*
)(
uint32_t
*
)
address
,
(
void
*
)(
uint32_t
*
)
src
,
handle
->
txBuffSizeAlign
[
ringId
]);
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
if
(
handle
->
txMaintainEnable
[
ringId
])
{
/* Add the cache clean maintain. */
DCACHE_CleanByRange
(
address
,
handle
->
txBuffSizeAlign
[
ringId
]);
}
#endif
/* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
/* Data length update. */
curBuffDescrip
->
length
=
handle
->
txBuffSizeAlign
[
ringId
];
len
+=
handle
->
txBuffSizeAlign
[
ringId
];
/* Sets the control flag. */
configVal
=
(
uint32_t
)
curBuffDescrip
->
control
;
configVal
&=
~
ENET_BUFFDESCRIPTOR_TX_LAST_MASK
;
configVal
|=
ENET_BUFFDESCRIPTOR_TX_READY_MASK
;
curBuffDescrip
->
control
=
(
uint16_t
)
configVal
;
if
(
handle
->
txReclaimEnable
[
ringId
])
{
primask
=
DisableGlobalIRQ
();
txBdRing
->
txDescUsed
++
;
EnableGlobalIRQ
(
primask
);
}
/* Active the transmit buffer descriptor*/
_ENET_ActiveSendRing
(
base
,
ringId
);
}
else
{
(
void
)
memcpy
((
void
*
)(
uint32_t
*
)
address
,
(
void
*
)(
uint32_t
*
)
src
,
sizeleft
);
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
if
(
handle
->
txMaintainEnable
[
ringId
])
{
/* Add the cache clean maintain. */
DCACHE_CleanByRange
(
address
,
sizeleft
);
}
#endif
/* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
curBuffDescrip
->
length
=
(
uint16_t
)
sizeleft
;
/* Set Last buffer wrap flag. */
curBuffDescrip
->
control
|=
ENET_BUFFDESCRIPTOR_TX_READY_MASK
|
ENET_BUFFDESCRIPTOR_TX_LAST_MASK
;
if
(
handle
->
txReclaimEnable
[
ringId
])
{
/* Add context to frame info ring */
txDirty
=
txDirtyRing
->
txDirtyBase
+
txDirtyRing
->
txGenIdx
;
txDirty
->
context
=
context
;
txDirtyRing
->
txGenIdx
=
_ENET_IncreaseIndex
(
txDirtyRing
->
txGenIdx
,
txDirtyRing
->
txRingLen
);
if
(
txDirtyRing
->
txGenIdx
==
txDirtyRing
->
txConsumIdx
)
{
txDirtyRing
->
isFull
=
true
;
}
primask
=
DisableGlobalIRQ
();
txBdRing
->
txDescUsed
++
;
EnableGlobalIRQ
(
primask
);
}
/* Active the transmit buffer descriptor. */
_ENET_ActiveSendRing
(
base
,
ringId
);
isReturn
=
true
;
break
;
}
/* Update the buffer descriptor address. */
curBuffDescrip
=
txBdRing
->
txBdBase
+
txBdRing
->
txGenIdx
;
}
while
(
0U
==
(
curBuffDescrip
->
control
&
ENET_BUFFDESCRIPTOR_TX_READY_MASK
));
if
(
isReturn
==
false
)
{
result
=
kStatus_ENET_TxFrameBusy
;
}
}
}
}
return
result
;
}
/* ethernet device interface */
/* transmit packet. */
rt_err_t
rt_imxrt_eth_tx
(
rt_device_t
dev
,
struct
pbuf
*
p
)
...
...
@@ -469,7 +742,7 @@ rt_err_t rt_imxrt_eth_tx(rt_device_t dev, struct pbuf *p)
do
{
result
=
ENET_SendFrame
(
imxrt_eth_device
.
enet_base
,
enet_handle
,
(
const
uint8_t
*
)
p
,
p
->
tot_len
,
RING_ID
,
false
,
NULL
);
result
=
_
ENET_SendFrame
(
imxrt_eth_device
.
enet_base
,
enet_handle
,
(
const
uint8_t
*
)
p
,
p
->
tot_len
,
RING_ID
,
false
,
NULL
);
if
(
result
==
kStatus_ENET_TxFrameBusy
)
{
...
...
@@ -730,7 +1003,7 @@ static int rt_hw_imxrt_eth_init(void)
tid
=
rt_thread_create
(
"phy"
,
phy_monitor_thread_entry
,
RT_NULL
,
1024
,
4096
,
RT_THREAD_PRIORITY_MAX
-
2
,
2
);
if
(
tid
!=
RT_NULL
)
...
...
bsp/imxrt/libraries/drivers/drv_ksz8081.c
浏览文件 @
58769e67
...
...
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2020-10-14 wangqiang the first version
* 2022-08-29 xjy198903 add rt1170 support
*/
#include <rtthread.h>
...
...
@@ -71,7 +72,12 @@
#define PHY_TIMEOUT_COUNT 0x3FFFFFFU
/* defined the Reset pin, PORT and PIN config by menuconfig */
#ifdef SOC_IMXRT1170_SERIES
#define RESET_PIN GET_PIN(PHY_RESET_KSZ8081_PORT, PHY_RESET_KSZ8081_PIN)
#else
#define RESET_PIN GET_PIN(PHY_RESET_PORT, PHY_RESET_PIN)
#endif
/*******************************************************************************
* Prototypes
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录