summaryrefslogtreecommitdiff
path: root/bsp/stm32/libraries/HAL_Drivers
diff options
context:
space:
mode:
authorBernard Xiong <[email protected]>2019-10-28 16:18:49 +0800
committerGitHub <[email protected]>2019-10-28 16:18:49 +0800
commita29fd11ffbe5f068076e45147be3f2a20d92e2ec (patch)
treed6399f4a3a16f7175cd3c84ca2fb77ef1245586f /bsp/stm32/libraries/HAL_Drivers
parent381f176859d3439b28f90725edd4ca3a989b75b7 (diff)
parent65afdf050afb31625801705682b0ca809ee2fe95 (diff)
Merge pull request #3034 from xfan1024/stm32-ethernet
优化STM32以太网驱动
Diffstat (limited to 'bsp/stm32/libraries/HAL_Drivers')
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drv_eth.c197
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drv_eth.h28
2 files changed, 112 insertions, 113 deletions
diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_eth.c b/bsp/stm32/libraries/HAL_Drivers/drv_eth.c
index 12308a7391..db1c501937 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drv_eth.c
+++ b/bsp/stm32/libraries/HAL_Drivers/drv_eth.c
@@ -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;
-
- 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
- {
- LOG_D("PHY_BASIC_STATUS_REG read error.");
- rt_thread_mdelay(100);
- continue;
- }
+ phy_linkchange();
- /* linkchange */
- if (phy_speed_new != phy_speed)
+ if (stm32_eth_device.parent.netif->flags & NETIF_FLAG_LINK_UP)
{
- 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);
+ /* 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_MSAK_REG, PHY_INT_MASK);
-
- break;
+ /* enable phy interrupt */
+ HAL_ETH_WritePHYRegister(&EthHandle, PHY_INTERRUPT_MASK_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);
diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_eth.h b/bsp/stm32/libraries/HAL_Drivers/drv_eth.h
index 378aca5838..07f25b107e 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drv_eth.h
+++ b/bsp/stm32/libraries/HAL_Drivers/drv_eth.h
@@ -39,7 +39,7 @@
/* The PHY interrupt source flag register. */
#define PHY_INTERRUPT_FLAG_REG 0x1DU
/* The PHY interrupt mask register. */
-#define PHY_INTERRUPT_MSAK_REG 0x1EU
+#define PHY_INTERRUPT_MASK_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_MSAK_REG 0x15U
+#define PHY_INTERRUPT_MASK_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__ */