Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
okll00
rt-thread
提交
a29fd11f
R
rt-thread
项目概览
okll00
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
a29fd11f
编写于
10月 28, 2019
作者:
B
Bernard Xiong
提交者:
GitHub
10月 28, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #3034 from xfan1024/stm32-ethernet
优化STM32以太网驱动
上级
381f1768
65afdf05
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
113 addition
and
114 deletion
+113
-114
bsp/stm32/libraries/HAL_Drivers/drv_eth.c
bsp/stm32/libraries/HAL_Drivers/drv_eth.c
+87
-112
bsp/stm32/libraries/HAL_Drivers/drv_eth.h
bsp/stm32/libraries/HAL_Drivers/drv_eth.h
+26
-2
未找到文件。
bsp/stm32/libraries/HAL_Drivers/drv_eth.c
浏览文件 @
a29fd11f
...
...
@@ -7,7 +7,8 @@
* Date Author Notes
* 2018-11-19 SummerGift first version
* 2018-12-25 zylx fix some bugs
* 2019-06-10 SummerGift optimize PHY state detection process
* 2019-06-10 SummerGift optimize PHY state detection process
* 2019-09-03 xiaofan optimize link change detection process
*/
#include "board.h"
...
...
@@ -390,47 +391,94 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
LOG_E
(
"eth err"
);
}
#ifdef PHY_USING_INTERRUPT_MODE
static
void
eth_phy_isr
(
void
*
args
)
enum
{
PHY_LINK
=
(
1
<<
0
),
PHY_100M
=
(
1
<<
1
),
PHY_FULL_DUPLEX
=
(
1
<<
2
),
};
static
void
phy_linkchange
()
{
rt_uint32_t
status
=
0
;
static
rt_uint8_t
link_status
=
1
;
static
rt_uint8_t
phy_speed
=
0
;
rt_uint8_t
phy_speed_new
=
0
;
rt_uint32_t
status
;
HAL_ETH_ReadPHYRegister
(
&
EthHandle
,
PHY_INTERRUPT_FLAG_REG
,
(
uint32_t
*
)
&
status
);
LOG_D
(
"phy interrupt status reg is 0x%X"
,
status
);
HAL_ETH_ReadPHYRegister
(
&
EthHandle
,
PHY_BASIC_STATUS_REG
,
(
uint32_t
*
)
&
status
);
LOG_D
(
"phy basic status reg is 0x%X"
,
status
);
if
(
status
&
PHY_LINKED_STATUS_MASK
)
if
(
status
&
(
PHY_AUTONEGO_COMPLETE_MASK
|
PHY_LINKED_STATUS_MASK
)
)
{
if
(
link_status
==
0
)
rt_uint32_t
SR
;
phy_speed_new
|=
PHY_LINK
;
SR
=
HAL_ETH_ReadPHYRegister
(
&
EthHandle
,
PHY_Status_REG
,
(
uint32_t
*
)
&
SR
);
LOG_D
(
"phy control status reg is 0x%X"
,
SR
);
if
(
PHY_Status_SPEED_100M
(
SR
))
{
phy_speed_new
|=
PHY_100M
;
}
if
(
PHY_Status_FULL_DUPLEX
(
SR
))
{
phy_speed_new
|=
PHY_FULL_DUPLEX
;
}
}
if
(
phy_speed
!=
phy_speed_new
)
{
phy_speed
=
phy_speed_new
;
if
(
phy_speed
&
PHY_LINK
)
{
link_status
=
1
;
LOG_D
(
"link up"
);
if
(
phy_speed
&
PHY_100M
)
{
LOG_D
(
"100Mbps"
);
stm32_eth_device
.
ETH_Speed
=
ETH_SPEED_100M
;
}
else
{
stm32_eth_device
.
ETH_Speed
=
ETH_SPEED_10M
;
LOG_D
(
"10Mbps"
);
}
if
(
phy_speed
&
PHY_FULL_DUPLEX
)
{
LOG_D
(
"full-duplex"
);
stm32_eth_device
.
ETH_Mode
=
ETH_MODE_FULLDUPLEX
;
}
else
{
LOG_D
(
"half-duplex"
);
stm32_eth_device
.
ETH_Mode
=
ETH_MODE_HALFDUPLEX
;
}
/* send link up. */
eth_device_linkchange
(
&
stm32_eth_device
.
parent
,
RT_TRUE
);
}
}
else
{
if
(
link_status
==
1
)
else
{
link_status
=
0
;
LOG_I
(
"link down"
);
/* send link down. */
eth_device_linkchange
(
&
stm32_eth_device
.
parent
,
RT_FALSE
);
}
}
}
#ifdef PHY_USING_INTERRUPT_MODE
static
void
eth_phy_isr
(
void
*
args
)
{
rt_uint32_t
status
=
0
;
HAL_ETH_ReadPHYRegister
(
&
EthHandle
,
PHY_INTERRUPT_FLAG_REG
,
(
uint32_t
*
)
&
status
);
LOG_D
(
"phy interrupt status reg is 0x%X"
,
status
);
phy_linkchange
();
}
#endif
/* PHY_USING_INTERRUPT_MODE */
static
uint8_t
phy_speed
=
0
;
#define PHY_LINK_MASK (1<<0)
static
void
phy_monitor_thread_entry
(
void
*
parameter
)
{
uint8_t
phy_addr
=
0xFF
;
uint8_t
phy_speed_new
=
0
;
rt_uint32_t
status
=
0
;
uint8_t
detected_count
=
0
;
while
(
phy_addr
==
0xFF
)
...
...
@@ -468,102 +516,29 @@ static void phy_monitor_thread_entry(void *parameter)
while
(
1
)
{
phy_
speed_new
=
0
;
phy_
linkchange
()
;
if
(
HAL_ETH_ReadPHYRegister
(
&
EthHandle
,
PHY_BASIC_STATUS_REG
,
(
uint32_t
*
)
&
status
)
==
HAL_OK
)
{
LOG_D
(
"PHY BASIC STATUS REG:0x%04X"
,
status
);
if
(
status
&
(
PHY_AUTONEGO_COMPLETE_MASK
|
PHY_LINKED_STATUS_MASK
))
{
rt_uint32_t
SR
;
phy_speed_new
=
PHY_LINK_MASK
;
if
(
HAL_ETH_ReadPHYRegister
(
&
EthHandle
,
PHY_Status_REG
,
(
uint32_t
*
)
&
SR
)
==
HAL_OK
)
{
LOG_D
(
"PHY Control/Status REG:0x%04X "
,
SR
);
if
(
SR
&
PHY_100M_MASK
)
{
phy_speed_new
|=
PHY_100M_MASK
;
}
else
if
(
SR
&
PHY_10M_MASK
)
{
phy_speed_new
|=
PHY_10M_MASK
;
}
if
(
SR
&
PHY_FULL_DUPLEX_MASK
)
{
phy_speed_new
|=
PHY_FULL_DUPLEX_MASK
;
}
}
else
{
LOG_D
(
"PHY PHY_Status_REG read error."
);
rt_thread_mdelay
(
100
);
continue
;
}
}
}
else
if
(
stm32_eth_device
.
parent
.
netif
->
flags
&
NETIF_FLAG_LINK_UP
)
{
LOG_D
(
"PHY_BASIC_STATUS_REG read error."
);
rt_thread_mdelay
(
100
);
continue
;
}
/* linkchange */
if
(
phy_speed_new
!=
phy_speed
)
{
if
(
phy_speed_new
&
PHY_LINK_MASK
)
{
LOG_D
(
"link up "
);
if
(
phy_speed_new
&
PHY_100M_MASK
)
{
LOG_D
(
"100Mbps"
);
stm32_eth_device
.
ETH_Speed
=
ETH_SPEED_100M
;
}
else
{
stm32_eth_device
.
ETH_Speed
=
ETH_SPEED_10M
;
LOG_D
(
"10Mbps"
);
}
if
(
phy_speed_new
&
PHY_FULL_DUPLEX_MASK
)
{
LOG_D
(
"full-duplex"
);
stm32_eth_device
.
ETH_Mode
=
ETH_MODE_FULLDUPLEX
;
}
else
{
LOG_D
(
"half-duplex"
);
stm32_eth_device
.
ETH_Mode
=
ETH_MODE_HALFDUPLEX
;
}
/* send link up. */
eth_device_linkchange
(
&
stm32_eth_device
.
parent
,
RT_TRUE
);
#ifdef PHY_USING_INTERRUPT_MODE
/* configuration intterrupt pin */
rt_pin_mode
(
PHY_INT_PIN
,
PIN_MODE_INPUT_PULLUP
);
rt_pin_attach_irq
(
PHY_INT_PIN
,
PIN_IRQ_MODE_FALLING
,
eth_phy_isr
,
(
void
*
)
"callbackargs"
);
rt_pin_irq_enable
(
PHY_INT_PIN
,
PIN_IRQ_ENABLE
);
/* enable phy interrupt */
HAL_ETH_WritePHYRegister
(
&
EthHandle
,
PHY_INTERRUPT_MSA
K_REG
,
PHY_INT_MASK
);
break
;
/* configuration intterrupt pin */
rt_pin_mode
(
PHY_INT_PIN
,
PIN_MODE_INPUT_PULLUP
);
rt_pin_attach_irq
(
PHY_INT_PIN
,
PIN_IRQ_MODE_FALLING
,
eth_phy_isr
,
(
void
*
)
"callbackargs"
);
rt_pin_irq_enable
(
PHY_INT_PIN
,
PIN_IRQ_ENABLE
);
/* enable phy interrupt */
HAL_ETH_WritePHYRegister
(
&
EthHandle
,
PHY_INTERRUPT_MAS
K_REG
,
PHY_INT_MASK
);
#if defined(PHY_INTERRUPT_CTRL_REG)
HAL_ETH_WritePHYRegister
(
&
EthHandle
,
PHY_INTERRUPT_CTRL_REG
,
PHY_INTERRUPT_EN
)
;
#endif
}
/* link up. */
else
{
LOG_I
(
"link down"
);
/* send link down. */
eth_device_linkchange
(
&
stm32_eth_device
.
parent
,
RT_FALSE
);
}
phy_speed
=
phy_speed_new
;
break
;
#endif
}
/* link up. */
else
{
LOG_I
(
"link down"
);
/* send link down. */
eth_device_linkchange
(
&
stm32_eth_device
.
parent
,
RT_FALSE
)
;
}
rt_thread_delay
(
RT_TICK_PER_SECOND
);
...
...
bsp/stm32/libraries/HAL_Drivers/drv_eth.h
浏览文件 @
a29fd11f
...
...
@@ -39,7 +39,7 @@
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x1DU
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_M
SA
K_REG 0x1EU
#define PHY_INTERRUPT_M
AS
K_REG 0x1EU
#define PHY_LINK_DOWN_MASK (1<<4)
#define PHY_AUTO_NEGO_COMPLETE_MASK (1<<6)
...
...
@@ -48,6 +48,9 @@
#define PHY_10M_MASK (1<<2)
#define PHY_100M_MASK (1<<3)
#define PHY_FULL_DUPLEX_MASK (1<<4)
#define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK)
#define PHY_Status_SPEED_100M(sr) ((sr) & PHY_100M_MASK)
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
#endif
/* PHY_USING_LAN8720A */
#ifdef PHY_USING_DM9161CEP
...
...
@@ -55,14 +58,35 @@
#define PHY_10M_MASK ((1<<12) || (1<<13))
#define PHY_100M_MASK ((1<<14) || (1<<15))
#define PHY_FULL_DUPLEX_MASK ((1<<15) || (1<<13))
#define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK)
#define PHY_Status_SPEED_100M(sr) ((sr) & PHY_100M_MASK)
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x15U
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_M
SA
K_REG 0x15U
#define PHY_INTERRUPT_M
AS
K_REG 0x15U
#define PHY_LINK_CHANGE_FLAG (1<<2)
#define PHY_LINK_CHANGE_MASK (1<<9)
#define PHY_INT_MASK 0
#endif
/* PHY_USING_DM9161CEP */
#ifdef PHY_USING_DP83848C
#define PHY_Status_REG 0x10U
#define PHY_10M_MASK (1<<1)
#define PHY_FULL_DUPLEX_MASK (1<<2)
#define PHY_Status_SPEED_10M(sr) ((sr) & PHY_10M_MASK)
#define PHY_Status_SPEED_100M(sr) (!PHY_Status_SPEED_10M(sr))
#define PHY_Status_FULL_DUPLEX(sr) ((sr) & PHY_FULL_DUPLEX_MASK)
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x12U
#define PHY_LINK_CHANGE_FLAG (1<<13)
/* The PHY interrupt control register. */
#define PHY_INTERRUPT_CTRL_REG 0x11U
#define PHY_INTERRUPT_EN ((1<<0)|(1<<1))
/* The PHY interrupt mask register. */
#define PHY_INTERRUPT_MASK_REG 0x12U
#define PHY_INT_MASK (1<<5)
#endif
/* PHY_USING_DP83848C */
#endif
/* __DRV_ETH_H__ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录