国产以太网PHY芯片SR8021由gd32f450移植到gd32f470

@国产以太网PHY芯片SR8021由gd32f450移植到gd32f470

国产以太网PHY芯片SR8021由gd32f450移植到gd32f470

由于有国产化要求,需要将以太网及主控芯片全部换成国产,参考例程是基于GD32F450的,在移植过程中遇到一些容易忽略的地方,导致程序一致卡在gd32fxx_enet.c中enet_phy_config()的位置,有类似情况的小伙伴,可以参考一下。

故障排查

虽然将GD32F450上的代码全部知道GD32F470平台后,一直卡在卡在gd32fxx_enet.c中enet_phy_config(),经过排查发现GD32的官方库文件也需要修改,分别为gd32f4xx_enet.h和gd32f4xx_enet.c。

需要修改的地方

GD32F470的例程基于GD32F4xx_Demo_Suites_V2.6.1版本;
针对gd32f4xx_enet.h的修改:
在头文件69行的位置修改如下内容:
1.添加宏定义“#define SR8201F 2”;
2.修改宏定义PHY_TYPE为SR8201F,“#define PHY_TYPE SR8201F”;
3.修改宏定义PHY_ADDRESS为3,“#define PHY_ADDRESS ((uint16_t)0x3U)”;
在这里插入图片描述

#ifndef _PHY_H_
#define DP83848                          0
#define LAN8700                          1
#define SR8201F                          2
#define PHY_TYPE                         SR8201F

#define PHY_ADDRESS                      ((uint16_t)0x3U)                         /*!< phy address determined by the hardware */

在头文件88行位置添加如下内容:
在这里插入图片描述

#if(PHY_TYPE == LAN8700) 
#define PHY_SR                           31U                                    /*!< tranceiver status register */
#define PHY_SPEED_STATUS                 ((uint16_t)0x0004)                     /*!< configured information of speed: 10Mbit/s */
#define PHY_DUPLEX_STATUS                ((uint16_t)0x0010)                     /*!< configured information of duplex: full-duplex */
#elif(PHY_TYPE == DP83848)
#define PHY_SR                           16U                                    /*!< tranceiver status register */
#define PHY_SPEED_STATUS                 ((uint16_t)0x0002)                     /*!< configured information of speed: 10Mbit/s */
#define PHY_DUPLEX_STATUS                ((uint16_t)0x0004)                     /*!< configured information of duplex: full-duplex */
#elif(PHY_TYPE == SR8201F)
#define PHY_SR                           PHY_REG_BCR                            /*!< tranceiver status register */
#define PHY_SPEED_STATUS                 ((uint16_t)0x2000)                     /*!< configured information of speed: 10Mbit/s */
#define PHY_DUPLEX_STATUS                ((uint16_t)0x0100)                     /*!< configured information of duplex: full-duplex */
#endif /* PHY_TYPE */

针对gd32f4xx_enet.c的修改:
1.修改函数ErrStatus enet_init(enet_mediamode_enum mediamode, …),修改内容如下图所示
在这里插入图片描述
此处为该函数中的一部分,

    /* if is PHY auto negotiation */
    if((uint32_t)ENET_AUTO_NEGOTIATION == media_temp) {
        /* wait for PHY_LINKED_STATUS bit be set */
        do {
            enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value);
            phy_value &= PHY_LINKED_STATUS;
            timeout++;
        } while((RESET == phy_value) && (timeout < PHY_READ_TO));
        /* return ERROR due to timeout */
        if(PHY_READ_TO == timeout) {
            return enet_state;
        }
        /* reset timeout counter */
        timeout = 0U;

        /* enable auto-negotiation */
        phy_value = PHY_AUTONEGOTIATION;
        phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value);
        if(!phy_state) {
            /* return ERROR due to write timeout */
            return enet_state;
        }

        /* wait for the PHY_AUTONEGO_COMPLETE bit be set */
        do {
            enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BSR, &phy_value);
            phy_value &= PHY_AUTONEGO_COMPLETE;
            timeout++;
        } while((RESET == phy_value) && (timeout < (uint32_t)PHY_READ_TO));
        /* return ERROR due to timeout */
        if(PHY_READ_TO == timeout) {
            return enet_state;
        }
        /* reset timeout counter */
        timeout = 0U;

        /* read the result of the auto-negotiation */
        //enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_SR, &phy_value);
				enet_phy_write_read(ENET_PHY_READ, PHY_ADDRESS, PHY_REG_BCR, &phy_value);
        /* configure the duplex mode of MAC following the auto-negotiation result */
        if((uint16_t)RESET != (phy_value & PHY_DUPLEX_STATUS)) {
            media_temp = ENET_MODE_FULLDUPLEX;
        } else {
            media_temp = ENET_MODE_HALFDUPLEX;
        }
        /* configure the communication speed of MAC following the auto-negotiation result */
#if(PHY_TYPE == SR8201F)
        if((uint16_t)RESET !=(phy_value & PHY_SPEED_STATUS)){
            media_temp |= ENET_SPEEDMODE_100M;
        }else{
            media_temp |= ENET_SPEEDMODE_10M;
        }
#elif
        if((uint16_t)RESET !=(phy_value & PHY_SPEED_STATUS)){
            media_temp |= ENET_SPEEDMODE_10M;
        }else{
            media_temp |= ENET_SPEEDMODE_100M;
        }
#endif
    } else {
        phy_value = (uint16_t)((media_temp & ENET_MAC_CFG_DPM) >> 3);
        phy_value |= (uint16_t)((media_temp & ENET_MAC_CFG_SPD) >> 1);
        phy_state = enet_phy_write_read(ENET_PHY_WRITE, PHY_ADDRESS, PHY_REG_BCR, &phy_value);
        if(!phy_state) {
            /* return ERROR due to write timeout */
            return enet_state;
        }
        /* PHY configuration need some time */
        _ENET_DELAY_(PHY_CONFIGDELAY);
    }

2.修改static void enet_default_init(void),修改内容如下图所示:
在这里插入图片描述

static void enet_default_init(void)
{
    uint32_t reg_value = 0U;

    /* MAC */
    /* configure ENET_MAC_CFG register */
    reg_value = ENET_MAC_CFG;
    reg_value &= MAC_CFG_MASK;
    reg_value |= ENET_WATCHDOG_ENABLE | ENET_JABBER_ENABLE | ENET_INTERFRAMEGAP_96BIT \
                 | ENET_SPEEDMODE_10M | ENET_MODE_HALFDUPLEX | ENET_LOOPBACKMODE_DISABLE \
                 | ENET_CARRIERSENSE_ENABLE | ENET_RECEIVEOWN_ENABLE \
                 | ENET_RETRYTRANSMISSION_ENABLE | ENET_BACKOFFLIMIT_10 \
                 | ENET_DEFERRALCHECK_DISABLE \
                 | ENET_TYPEFRAME_CRC_DROP_DISABLE \
                 | ENET_AUTO_PADCRC_DROP_DISABLE \
                 | ENET_CHECKSUMOFFLOAD_DISABLE;
    ENET_MAC_CFG = reg_value;

    /* configure ENET_MAC_FRMF register */
    ENET_MAC_FRMF = ENET_SRC_FILTER_DISABLE | ENET_DEST_FILTER_INVERSE_DISABLE \
                    | ENET_MULTICAST_FILTER_PERFECT | ENET_UNICAST_FILTER_PERFECT \
                    | ENET_PCFRM_PREVENT_ALL | ENET_BROADCASTFRAMES_ENABLE \
                    | ENET_PROMISCUOUS_DISABLE | ENET_RX_FILTER_ENABLE;

    /* configure ENET_MAC_HLH, ENET_MAC_HLL register */
    ENET_MAC_HLH = 0x0U;

    ENET_MAC_HLL = 0x0U;

    /* configure ENET_MAC_FCTL, ENET_MAC_FCTH register */
    reg_value = ENET_MAC_FCTL;
    reg_value &= MAC_FCTL_MASK;
    reg_value |= MAC_FCTL_PTM(0) | ENET_ZERO_QUANTA_PAUSE_DISABLE \
                 | ENET_PAUSETIME_MINUS4 | ENET_UNIQUE_PAUSEDETECT \
                 | ENET_RX_FLOWCONTROL_DISABLE | ENET_TX_FLOWCONTROL_DISABLE;
    ENET_MAC_FCTL = reg_value;

		ENET_MAC_FCTH = ENET_DEACTIVE_THRESHOLD_512BYTES |ENET_ACTIVE_THRESHOLD_1536BYTES;

    /* configure ENET_MAC_VLT register */
    ENET_MAC_VLT = ENET_VLANTAGCOMPARISON_16BIT | MAC_VLT_VLTI(0);

    /* DMA */
    /* configure ENET_DMA_CTL register */
    reg_value = ENET_DMA_CTL;
    reg_value &= DMA_CTL_MASK;
    reg_value |= ENET_TCPIP_CKSUMERROR_DROP | ENET_RX_MODE_STOREFORWARD \
                 | ENET_FLUSH_RXFRAME_ENABLE | ENET_TX_MODE_STOREFORWARD \
                 | ENET_TX_THRESHOLD_64BYTES | ENET_RX_THRESHOLD_64BYTES \
								 |ENET_FORWARD_ERRFRAMES_DISABLE |ENET_FORWARD_UNDERSZ_GOODFRAMES_DISABLE \
                 | ENET_SECONDFRAME_OPT_DISABLE;
    ENET_DMA_CTL = reg_value;

    /* configure ENET_DMA_BCTL register */
    reg_value = ENET_DMA_BCTL;
    reg_value &= DMA_BCTL_MASK;
    reg_value = ENET_ADDRESS_ALIGN_ENABLE | ENET_ARBITRATION_RXTX_2_1 \
                | ENET_RXDP_32BEAT | ENET_PGBL_32BEAT | ENET_RXTX_DIFFERENT_PGBL \
                | ENET_FIXED_BURST_ENABLE | ENET_MIXED_BURST_DISABLE \
                | ENET_NORMAL_DESCRIPTOR;
    ENET_DMA_BCTL = reg_value;
}

修改以上内容后,程序可以正确运行
在这里插入图片描述
希望以上内容对你有所帮助,欢迎相互学习!!!

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值