gd32f30x_enet.c的网卡初始化时上电时网线未插入会卡住很长时间

gd32f30x_enet.c的网卡初始化时上电时网线未插入会卡住很长时间,导致ETH初始化部分未能成功完成并且在执行enet_init() 时由于网线没接上,会在while((RESET == phy_value) && (timeout < PHY_READ_TO))卡住很长时间,之后即使再插入网线,程序中没有再次进行初始化的逻辑补充,从而导致网络异常。

//修改后的代码
void enet_system_setup(void)
{
    nvic_configuration();   
  
    /* configure the GPIO ports for ethernet pins */
    enet_gpio_config();
    
    /* configure the ethernet MAC/DMA */
    enet_mac_dma_config();

#if 0
    if(0 == enet_init_status){
        while(1){
        }
    }
#endif
    
    enet_interrupt_enable(ENET_DMA_INT_NIE);
    enet_interrupt_enable(ENET_DMA_INT_RIE);
}

/*!
    \brief      configures the ethernet interface
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void enet_mac_dma_config(void)
{
    ErrStatus reval_state = ERROR;
    
    /* enable ethernet clock  */
    rcu_periph_clock_enable(RCU_ENET);
    rcu_periph_clock_enable(RCU_ENETTX);
    rcu_periph_clock_enable(RCU_ENETRX);
    
    /* reset ethernet on AHB bus */
    enet_deinit();

    reval_state = enet_software_reset();
    if(ERROR == reval_state){
        while(1){
        }
    }
/* configure the parameters which are usually less cared for enet initialization */  
//  enet_initpara_config(HALFDUPLEX_OPTION, ENET_CARRIERSENSE_ENABLE|ENET_RECEIVEOWN_ENABLE|ENET_RETRYTRANSMISSION_DISABLE|ENET_BACKOFFLIMIT_10|ENET_DEFERRALCHECK_DISABLE);
//  enet_initpara_config(DMA_OPTION, ENET_FLUSH_RXFRAME_ENABLE|ENET_SECONDFRAME_OPT_ENABLE|ENET_NORMAL_DESCRIPTOR);

    enet_head_init_usr();
#if 0
#ifdef CHECKSUM_BY_HARDWARE
    enet_init_status = enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_BROADCAST_FRAMES_PASS);
#else  
    enet_init_status = enet_init(ENET_AUTO_NEGOTIATION, ENET_NO_AUTOCHECKSUM, ENET_BROADCAST_FRAMES_PASS);
#endif /* CHECKSUM_BY_HARDWARE */
#endif  
}

/*!
    \brief      insert a delay time
    \param[in]  ncount: specifies the delay time length
    \param[out] none
    \param[out] none
*/
static void enet_delay(uint32_t ncount)
{
    __IO uint32_t delay_time = 0U;

    for(delay_time = ncount; delay_time != 0U; delay_time--){
    }
}

/*!
    \brief      initialize ENET peripheral with generally concerned parameters, call it by enet_init() 
    \param[in]  none
    \param[out] none
    \retval     none
*/
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;

    /* 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_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; 
}

void enet_head_init_usr(void)
{
  /* PHY interface configuration, configure SMI clock and reset PHY chip */
  if(ERROR == enet_phy_config()){
      _ENET_DELAY_(PHY_RESETDELAY);
      if(ERROR == enet_phy_config()){
//          return enet_state;
      }
  }
  /* initialize ENET peripheral with generally concerned parameters */
  enet_default_init();  
}
//enet_init() 如果网线没接上,会在while((RESET == phy_value) && (timeout < PHY_READ_TO));卡住很长时间
ErrStatus enet_init(enet_mediamode_enum mediamode, enet_chksumconf_enum checksum, enet_frmrecept_enum recept)
{
    uint32_t reg_value=0U, reg_temp = 0U, temp = 0U;
    uint32_t media_temp = 0U;
    uint32_t timeout = 0U;
    uint16_t phy_value = 0U;  
    ErrStatus phy_state= ERROR, enet_state = ERROR;

    /* PHY interface configuration, configure SMI clock and reset PHY chip */
    if(ERROR == enet_phy_config()){
        _ENET_DELAY_(PHY_RESETDELAY);
        if(ERROR == enet_phy_config()){
            return enet_state;
        }
    }
    /* initialize ENET peripheral with generally concerned parameters */
    enet_default_init();

    /* 1st, configure mediamode */
    media_temp = (uint32_t)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));		//#1 卡住很长时间
        /* return ERROR due to timeout */
        if(PHY_READ_TO == timeout){
            return enet_state;
        }
        /* reset timeout counter */
        timeout = 0U;
//在另外的线程中增加监控网线接入后重新会网卡初始化
  enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_BROADCAST_FRAMES_PASS);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值