打印

GD32F2x 以太网外设配置

[复制链接]
1455|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aizaixiyuanqian|  楼主 | 2021-1-31 11:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void enet_initpara_config(enet_option_enum option, uint32_t para)
{
    switch(option){
    case FORWARD_OPTION:
        /* choose to configure forward_frame, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)FORWARD_OPTION;
        enet_initpara.forward_frame = para;
        break;
    case DMABUS_OPTION:
        /* choose to configure dmabus_mode, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)DMABUS_OPTION;
        enet_initpara.dmabus_mode = para;
        break;
    case DMA_MAXBURST_OPTION:
        /* choose to configure dma_maxburst, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)DMA_MAXBURST_OPTION;
        enet_initpara.dma_maxburst = para;
        break;
    case DMA_ARBITRATION_OPTION:
        /* choose to configure dma_arbitration, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)DMA_ARBITRATION_OPTION;
        enet_initpara.dma_arbitration = para;
        break;
    case STORE_OPTION:
        /* choose to configure store_forward_mode, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)STORE_OPTION;
        enet_initpara.store_forward_mode = para;
        break;
    case DMA_OPTION:
        /* choose to configure dma_function, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)DMA_OPTION;
        enet_initpara.dma_function = para;
        break;
    case VLAN_OPTION:
        /* choose to configure vlan_config, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)VLAN_OPTION;
        enet_initpara.vlan_config = para;
        break;
    case FLOWCTL_OPTION:
        /* choose to configure flow_control, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)FLOWCTL_OPTION;
        enet_initpara.flow_control = para;
        break;
    case HASHH_OPTION:
        /* choose to configure hashtable_high, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)HASHH_OPTION;
        enet_initpara.hashtable_high = para;
        break;
    case HASHL_OPTION:
        /* choose to configure hashtable_low, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)HASHL_OPTION;
        enet_initpara.hashtable_low = para;
        break;
    case FILTER_OPTION:
        /* choose to configure framesfilter_mode, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)FILTER_OPTION;
        enet_initpara.framesfilter_mode = para;
        break;
    case HALFDUPLEX_OPTION:
        /* choose to configure halfduplex_param, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)HALFDUPLEX_OPTION;
        enet_initpara.halfduplex_param = para;
        break;
    case TIMER_OPTION:
        /* choose to configure timer_config, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)TIMER_OPTION;
        enet_initpara.timer_config = para;
        break;
    case INTERFRAMEGAP_OPTION:
        /* choose to configure interframegap, and save the configuration parameters */
        enet_initpara.option_enable |= (uint32_t)INTERFRAMEGAP_OPTION;
        enet_initpara.interframegap = para;
        break;
    default:
        break;   
    }      
}

使用特权

评论回复
沙发
aizaixiyuanqian|  楼主 | 2021-1-31 12:11 | 只看该作者
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));
        /* 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);  
        /* 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((uint16_t)RESET !=(phy_value & PHY_SPEED_STATUS)){
            media_temp |= ENET_SPEEDMODE_10M;
        }else{
            media_temp |= ENET_SPEEDMODE_100M;
        }   
    }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);      
    }
    /* after configuring the PHY, use mediamode to configure registers */
    reg_value = ENET_MAC_CFG;
    /* configure ENET_MAC_CFG register */
    reg_value &= (~(ENET_MAC_CFG_SPD |ENET_MAC_CFG_DPM |ENET_MAC_CFG_LBM));
    reg_value |= media_temp;
    ENET_MAC_CFG = reg_value;
   
   
    /* 2st, configure checksum */
    if(RESET != ((uint32_t)checksum & ENET_CHECKSUMOFFLOAD_ENABLE)){
        ENET_MAC_CFG |= ENET_CHECKSUMOFFLOAD_ENABLE;
      
        reg_value = ENET_DMA_CTL;
        /* configure ENET_DMA_CTL register */
        reg_value &= ~ENET_DMA_CTL_DTCERFD;
        reg_value |= ((uint32_t)checksum & ENET_DMA_CTL_DTCERFD);
        ENET_DMA_CTL = reg_value;
    }
   
    /* 3rd, configure recept */
    ENET_MAC_FRMF |= (uint32_t)recept;
   
    /* 4th, configure different function options */
    /* configure forward_frame related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)FORWARD_OPTION)){
        reg_temp = enet_initpara.forward_frame;
              
        reg_value = ENET_MAC_CFG;
        temp = reg_temp;
        /* configure ENET_MAC_CFG register */
        reg_value &= (~ENET_MAC_CFG_APCD);
        temp &= ENET_MAC_CFG_APCD;
        reg_value |= temp;
        ENET_MAC_CFG = reg_value;
      
        reg_value = ENET_DMA_CTL;
        temp = reg_temp;
        /* configure ENET_DMA_CTL register */
        reg_value &= (~(ENET_DMA_CTL_FERF |ENET_DMA_CTL_FUF));
        temp &= ((ENET_DMA_CTL_FERF | ENET_DMA_CTL_FUF)<<2);
        reg_value |= (temp >> 2);
        ENET_DMA_CTL = reg_value;
    }

    /* configure dmabus_mode related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)DMABUS_OPTION)){
        temp = enet_initpara.dmabus_mode;
      
        reg_value = ENET_DMA_BCTL;
        /* configure ENET_DMA_BCTL register */
        reg_value &= ~(ENET_DMA_BCTL_AA | ENET_DMA_BCTL_FB \
                      |ENET_DMA_BCTL_FPBL);
        reg_value |= temp;
        ENET_DMA_BCTL = reg_value;
    }

    /* configure dma_maxburst related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_MAXBURST_OPTION)){   
        temp = enet_initpara.dma_maxburst;
      
        reg_value = ENET_DMA_BCTL;
        /* configure ENET_DMA_BCTL register */
        reg_value &= ~(ENET_DMA_BCTL_RXDP| ENET_DMA_BCTL_PGBL | ENET_DMA_BCTL_UIP);   
        reg_value |= temp;
        ENET_DMA_BCTL = reg_value;
    }

    /* configure dma_arbitration related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_ARBITRATION_OPTION)){   
        temp = enet_initpara.dma_arbitration;
      
        reg_value = ENET_DMA_BCTL;
        /* configure ENET_DMA_BCTL register */
        reg_value &= ~(ENET_DMA_BCTL_RTPR | ENET_DMA_BCTL_DAB);
        reg_value |= temp;
        ENET_DMA_BCTL = reg_value;
    }
   
    /* configure store_forward_mode related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)STORE_OPTION)){   
        temp = enet_initpara.store_forward_mode;
      
        reg_value = ENET_DMA_CTL;
        /* configure ENET_DMA_CTL register */
        reg_value &= ~(ENET_DMA_CTL_RSFD | ENET_DMA_CTL_TSFD| ENET_DMA_CTL_RTHC| ENET_DMA_CTL_TTHC);
        reg_value |= temp;
        ENET_DMA_CTL = reg_value;
    }

    /* configure dma_function related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)DMA_OPTION)){   
        reg_temp = enet_initpara.dma_function;
              
        reg_value = ENET_DMA_CTL;
        /* configure ENET_DMA_CTL register */
        reg_value &= (~(ENET_DMA_CTL_DAFRF |ENET_DMA_CTL_OSF));
        reg_value |= reg_temp;
        ENET_DMA_CTL = reg_value;
    }

    /* configure vlan_config related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)VLAN_OPTION)){   
        reg_temp = enet_initpara.vlan_config;
              
        reg_value = ENET_MAC_VLT;
        /* configure ENET_MAC_VLT register */
        reg_value &= ~(ENET_MAC_VLT_VLTI | ENET_MAC_VLT_VLTC);
        reg_value |= reg_temp;
        ENET_MAC_VLT = reg_value;
    }

    /* configure flow_control related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)FLOWCTL_OPTION)){   
        reg_temp = enet_initpara.flow_control;
              
        reg_value = ENET_MAC_FCTL;
        temp = reg_temp;
        /* configure ENET_MAC_FCTL register */
        reg_value &= ~(ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \
                      | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN);
        temp &= (ENET_MAC_FCTL_PTM |ENET_MAC_FCTL_DZQP |ENET_MAC_FCTL_PLTS \
                 | ENET_MAC_FCTL_UPFDT |ENET_MAC_FCTL_RFCEN |ENET_MAC_FCTL_TFCEN);
        reg_value |= temp;
        ENET_MAC_FCTL = reg_value;
      
        reg_value = ENET_MAC_FCTH;
        temp = reg_temp;
        /* configure ENET_MAC_FCTH register */
        reg_value &= ~(ENET_MAC_FCTH_RFA |ENET_MAC_FCTH_RFD);
        temp &= ((ENET_MAC_FCTH_RFA | ENET_MAC_FCTH_RFD )<<8);
        reg_value |= (temp >> 8);
        ENET_MAC_FCTH = reg_value;
    }   
   
    /* configure hashtable_high related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)HASHH_OPTION)){   
        ENET_MAC_HLH = enet_initpara.hashtable_high;
    }

    /* configure hashtable_low related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)HASHL_OPTION)){   
        ENET_MAC_HLL = enet_initpara.hashtable_low;
    }   

    /* configure framesfilter_mode related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)FILTER_OPTION)){   
        reg_temp = enet_initpara.framesfilter_mode;
              
        reg_value = ENET_MAC_FRMF;
        /* configure ENET_MAC_FRMF register */
        reg_value &= ~(ENET_MAC_FRMF_SAFLT | ENET_MAC_FRMF_SAIFLT | ENET_MAC_FRMF_DAIFLT \
                      | ENET_MAC_FRMF_HMF | ENET_MAC_FRMF_HPFLT | ENET_MAC_FRMF_MFD \
                      | ENET_MAC_FRMF_HUF | ENET_MAC_FRMF_PCFRM);
        reg_value |= reg_temp;
        ENET_MAC_FRMF = reg_value;
    }  

    /* configure halfduplex_param related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)HALFDUPLEX_OPTION)){   
        reg_temp = enet_initpara.halfduplex_param;
              
        reg_value = ENET_MAC_CFG;
        /* configure ENET_MAC_CFG register */
        reg_value &= ~(ENET_MAC_CFG_CSD | ENET_MAC_CFG_ROD | ENET_MAC_CFG_RTD \
                      | ENET_MAC_CFG_BOL | ENET_MAC_CFG_DFC);
        reg_value |= reg_temp;
        ENET_MAC_CFG = reg_value;
    }

    /* configure timer_config related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)TIMER_OPTION)){   
        reg_temp = enet_initpara.timer_config;
              
        reg_value = ENET_MAC_CFG;
        /* configure ENET_MAC_CFG register */
        reg_value &= ~(ENET_MAC_CFG_WDD | ENET_MAC_CFG_JBD);
        reg_value |= reg_temp;
        ENET_MAC_CFG = reg_value;
    }
   
    /* configure interframegap related registers */
    if(RESET != (enet_initpara.option_enable & (uint32_t)INTERFRAMEGAP_OPTION)){   
        reg_temp = enet_initpara.interframegap;
              
        reg_value = ENET_MAC_CFG;
        /* configure ENET_MAC_CFG register */
        reg_value &= ~ENET_MAC_CFG_IGBS;
        reg_value |= reg_temp;
        ENET_MAC_CFG = reg_value;
    }   

    enet_state = SUCCESS;
    return enet_state;
}

使用特权

评论回复
板凳
aizaixiyuanqian|  楼主 | 2021-1-31 12:12 | 只看该作者
ErrStatus enet_software_reset(void)
{
    uint32_t timeout = 0U;
    ErrStatus enet_state = ERROR;
    uint32_t dma_flag;
   
    /* reset all core internal registers located in CLK_TX and CLK_RX */
    ENET_DMA_BCTL |= ENET_DMA_BCTL_SWR;
   
    /* wait for reset operation complete */
    do{
        dma_flag = (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR);
        timeout++;
    }while((RESET != dma_flag) && (ENET_DELAY_TO != timeout));

    /* reset operation complete */   
    if(RESET == (ENET_DMA_BCTL & ENET_DMA_BCTL_SWR)){
        enet_state = SUCCESS;
    }
   
    return enet_state;
}

使用特权

评论回复
地板
aizaixiyuanqian|  楼主 | 2021-1-31 12:43 | 只看该作者
uint32_t enet_rxframe_size_get(void)
{
    uint32_t size = 0U;
    uint32_t status;
   
    /* get rdes0 information of current RxDMA descriptor */
    status = dma_current_rxdesc->status;
   
    /* if the desciptor is owned by DMA */
    if((uint32_t)RESET != (status & ENET_RDES0_DAV)){
        return 0U;
    }
   
    /* if has any error, or the frame uses two or more descriptors */
    if((((uint32_t)RESET) != (status & ENET_RDES0_ERRS)) ||
       (((uint32_t)RESET) == (status & ENET_RDES0_LDES)) ||
       (((uint32_t)RESET) == (status & ENET_RDES0_FDES))){
        /* drop current receive frame */
        enet_rxframe_drop();

        return 1U;
    }

    /* if is an ethernet-type frame, and IP frame payload error occurred */
    if((((uint32_t)RESET) != (status & ENET_RDES0_FRMT)) &&
       (((uint32_t)RESET) != (status & ENET_RDES0_PCERR))){
         /* drop current receive frame */
         enet_rxframe_drop();

        return 1U;
    }  

    /* if CPU owns current descriptor, no error occured, the frame uses only one descriptor */
    if((((uint32_t)RESET) == (status & ENET_RDES0_DAV)) &&
       (((uint32_t)RESET) == (status & ENET_RDES0_ERRS)) &&
       (((uint32_t)RESET) != (status & ENET_RDES0_LDES)) &&
       (((uint32_t)RESET) != (status & ENET_RDES0_FDES))){
        /* get the size of the received data including CRC */
        size = GET_RDES0_FRML(status);
        /* substract the CRC size */
        size = size - 4U;
    }else{
        enet_unknow_err++;
        enet_rxframe_drop();

        return 1U;        
    }

    /* return packet size */
    return size;
}

使用特权

评论回复
5
aizaixiyuanqian|  楼主 | 2021-1-31 12:45 | 只看该作者
void enet_descriptors_chain_init(enet_dmadirection_enum direction)
{
    uint32_t num = 0U, count = 0U, maxsize = 0U;
    uint32_t desc_status = 0U, desc_bufsize = 0U;
    enet_descriptors_struct *desc, *desc_tab;
    uint8_t *buf;  

    /* if want to initialize DMA Tx descriptors */
    if (ENET_DMA_TX == direction){
        /* save a copy of the DMA Tx descriptors */
        desc_tab = txdesc_tab;
        buf = &tx_buff[0][0];
        count = ENET_TXBUF_NUM;
        maxsize = ENET_TXBUF_SIZE;
      
        /* select chain mode */
        desc_status = ENET_TDES0_TCHM;
      
        /* configure DMA Tx descriptor table address register */
        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
        dma_current_txdesc = desc_tab;
    }else{
        /* if want to initialize DMA Rx descriptors */
        /* save a copy of the DMA Rx descriptors */
        desc_tab = rxdesc_tab;
        buf = &rx_buff[0][0];
        count = ENET_RXBUF_NUM;
        maxsize = ENET_RXBUF_SIZE;
      
        /* enable receiving */
        desc_status = ENET_RDES0_DAV;
        /* select receive chained mode and set buffer1 size */
        desc_bufsize = ENET_RDES1_RCHM | (uint32_t)ENET_RXBUF_SIZE;
      
        /* configure DMA Rx descriptor table address register */
        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
        dma_current_rxdesc = desc_tab;
    }
    dma_current_ptp_rxdesc = NULL;
    dma_current_ptp_txdesc = NULL;
   
    /* configure each descriptor */   
    for(num=0U; num < count; num++){
        /* get the pointer to the next descriptor of the descriptor table */
        desc = desc_tab + num;

        /* configure descriptors */
        desc->status = desc_status;         
        desc->control_buffer_size = desc_bufsize;
        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);
   
        /* if is not the last descriptor */
        if(num < (count - 1U)){
            /* configure the next descriptor address */
            desc->buffer2_next_desc_addr = (uint32_t)(desc_tab + num + 1U);
        }else{
            /* when it is the last descriptor, the next descriptor address
            equals to first descriptor address in descriptor table */
            desc->buffer2_next_desc_addr = (uint32_t) desc_tab;  
        }
    }  
}

使用特权

评论回复
6
aizaixiyuanqian|  楼主 | 2021-1-31 13:17 | 只看该作者
void enet_descriptors_ring_init(enet_dmadirection_enum direction)
{
    uint32_t num = 0U, count = 0U, maxsize = 0U;
    uint32_t desc_status = 0U, desc_bufsize = 0U;
    enet_descriptors_struct *desc;
    enet_descriptors_struct *desc_tab;
    uint8_t *buf;
  
    /* configure descriptor skip length */
    ENET_DMA_BCTL &= ~ENET_DMA_BCTL_DPSL;
    ENET_DMA_BCTL |= DMA_BCTL_DPSL(0);
  
    /* if want to initialize DMA Tx descriptors */
    if (ENET_DMA_TX == direction){
        /* save a copy of the DMA Tx descriptors */
        desc_tab = txdesc_tab;
        buf = &tx_buff[0][0];
        count = ENET_TXBUF_NUM;
        maxsize = ENET_TXBUF_SIZE;      
      
        /* configure DMA Tx descriptor table address register */
        ENET_DMA_TDTADDR = (uint32_t)desc_tab;
        dma_current_txdesc = desc_tab;
    }else{
        /* if want to initialize DMA Rx descriptors */
        /* save a copy of the DMA Rx descriptors */
        desc_tab = rxdesc_tab;
        buf = &rx_buff[0][0];
        count = ENET_RXBUF_NUM;
        maxsize = ENET_RXBUF_SIZE;      
      
        /* enable receiving */
        desc_status = ENET_RDES0_DAV;
        /* set buffer1 size */
        desc_bufsize = ENET_RXBUF_SIZE;
      
         /* configure DMA Rx descriptor table address register */
        ENET_DMA_RDTADDR = (uint32_t)desc_tab;
        dma_current_rxdesc = desc_tab;
    }
    dma_current_ptp_rxdesc = NULL;
    dma_current_ptp_txdesc = NULL;
   
    /* configure each descriptor */   
    for(num=0U; num < count; num++){
        /* get the pointer to the next descriptor of the descriptor table */
        desc = desc_tab + num;

        /* configure descriptors */
        desc->status = desc_status;
        desc->control_buffer_size = desc_bufsize;      
        desc->buffer1_addr = (uint32_t)(&buf[num * maxsize]);   
   
        /* when it is the last descriptor */
        if(num == (count - 1U)){
            if (ENET_DMA_TX == direction){
                /* configure transmit end of ring mode */  
                desc->status |= ENET_TDES0_TERM;
            }else{
                /* configure receive end of ring mode */
                desc->control_buffer_size |= ENET_RDES1_RERM;
            }
        }
    }   
}

使用特权

评论回复
7
aizaixiyuanqian|  楼主 | 2021-1-31 13:46 | 只看该作者
ErrStatus enet_frame_receive(uint8_t *buffer, uint32_t bufsize)
{
    uint32_t offset = 0U, size = 0U;
   
    /* the descriptor is busy due to own by the DMA */
    if((uint32_t)RESET != (dma_current_rxdesc->status & ENET_RDES0_DAV)){
        return ERROR;
    }
   

    /* if buffer pointer is null, indicates that users has copied data in application */
    if(NULL != buffer){
        /* if no error occurs, and the frame uses only one descriptor */
        if((((uint32_t)RESET) == (dma_current_rxdesc->status & ENET_RDES0_ERRS)) &&
           (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_LDES)) &&  
           (((uint32_t)RESET) != (dma_current_rxdesc->status & ENET_RDES0_FDES))){      
            /* get the frame length except CRC */
            size = GET_RDES0_FRML(dma_current_rxdesc->status);
            size = size - 4U;
            
            /* to avoid situation that the frame size exceeds the buffer length */
            if(size > bufsize){
                return ERROR;
            }
            
            /* copy data from Rx buffer to application buffer */
            for(offset = 0U; offset<size; offset++){
                (*(buffer + offset)) = (*(__IO uint8_t *) (uint32_t)((dma_current_rxdesc->buffer1_addr) + offset));
            }
            
        }else{
            /* return ERROR */
            return ERROR;
        }
    }
    /* enable reception, descriptor is owned by DMA */
    dma_current_rxdesc->status = ENET_RDES0_DAV;

    /* check Rx buffer unavailable flag status */
    if ((uint32_t)RESET != (ENET_DMA_STAT & ENET_DMA_STAT_RBU)){
        /* clear RBU flag */
        ENET_DMA_STAT = ENET_DMA_STAT_RBU;
        /* resume DMA reception by writing to the RPEN register*/
        ENET_DMA_RPEN = 0U;
    }
  
    /* update the current RxDMA descriptor pointer to the next decriptor in RxDMA decriptor table */      
    /* chained mode */
    if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RCHM)){      
        dma_current_rxdesc = (enet_descriptors_struct*) (dma_current_rxdesc->buffer2_next_desc_addr);   
    }else{   
        /* ring mode */
        if((uint32_t)RESET != (dma_current_rxdesc->control_buffer_size & ENET_RDES1_RERM)){
            /* if is the last descriptor in table, the next descriptor is the table header */
            dma_current_rxdesc = (enet_descriptors_struct*) (ENET_DMA_RDTADDR);      
        }else{
            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
            dma_current_rxdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_rxdesc + ETH_DMARXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)));      
        }
    }
  
    return SUCCESS;
}

使用特权

评论回复
8
aizaixiyuanqian|  楼主 | 2021-1-31 14:43 | 只看该作者
ErrStatus enet_frame_transmit(uint8_t *buffer, uint32_t length)
{
    uint32_t offset = 0U;
    uint32_t dma_tbu_flag, dma_tu_flag;
   
    /* the descriptor is busy due to own by the DMA */
    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_DAV)){
        return ERROR;
    }
   
    /* only frame length no more than ENET_MAX_FRAME_SIZE is allowed */
    if(length > ENET_MAX_FRAME_SIZE){
        return ERROR;
    }
   
    /* if buffer pointer is null, indicates that users has handled data in application */
    if(NULL != buffer){   
        /* copy frame data from application buffer to Tx buffer */
        for(offset = 0U; offset < length; offset++){
            (*(__IO uint8_t *) (uint32_t)((dma_current_txdesc->buffer1_addr) + offset)) = (*(buffer + offset));
        }
    }
   
    /* set the frame length */
    dma_current_txdesc->control_buffer_size = length;
    /* set the segment of frame, frame is transmitted in one descriptor */   
    dma_current_txdesc->status |= ENET_TDES0_LSG | ENET_TDES0_FSG;
    /* enable the DMA transmission */
    dma_current_txdesc->status |= ENET_TDES0_DAV;
   
    /* check Tx buffer unavailable flag status */
    dma_tbu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TBU);
    dma_tu_flag = (ENET_DMA_STAT & ENET_DMA_STAT_TU);
   
    if ((RESET != dma_tbu_flag) || (RESET != dma_tu_flag)){
        /* clear TBU and TU flag */
        ENET_DMA_STAT = (dma_tbu_flag | dma_tu_flag);
        /* resume DMA transmission by writing to the TPEN register*/
        ENET_DMA_TPEN = 0U;
    }
  
    /* update the current TxDMA descriptor pointer to the next decriptor in TxDMA decriptor table*/  
    /* chained mode */
    if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TCHM)){     
        dma_current_txdesc = (enet_descriptors_struct*) (dma_current_txdesc->buffer2_next_desc_addr);   
    }else{   
        /* ring mode */
        if((uint32_t)RESET != (dma_current_txdesc->status & ENET_TDES0_TERM)){
            /* if is the last descriptor in table, the next descriptor is the table header */
            dma_current_txdesc = (enet_descriptors_struct*) (ENET_DMA_TDTADDR);      
        }else{
            /* the next descriptor is the current address, add the descriptor size, and descriptor skip length */
            dma_current_txdesc = (enet_descriptors_struct*) (uint32_t)((uint32_t)dma_current_txdesc + ETH_DMATXDESC_SIZE + (GET_DMA_BCTL_DPSL(ENET_DMA_BCTL)));
        }
    }

    return SUCCESS;
}

使用特权

评论回复
9
aizaixiyuanqian|  楼主 | 2021-1-31 14:44 | 只看该作者
void enet_transmit_checksum_config(enet_descriptors_struct *desc, uint32_t checksum)
{
    desc->status &= ~ENET_TDES0_CM;
    desc->status |= checksum;
}

使用特权

评论回复
10
aizaixiyuanqian|  楼主 | 2021-1-31 14:45 | 只看该作者
FlagStatus enet_flag_get(enet_flag_enum enet_flag)
{
    if(RESET != (ENET_REG_VAL(enet_flag) & BIT(ENET_BIT_POS(enet_flag)))){
        return SET;
    }else{
        return RESET;
    }
}

使用特权

评论回复
11
aizaixiyuanqian|  楼主 | 2021-1-31 14:45 | 只看该作者
void enet_registers_get(enet_registers_type_enum type, uint32_t *preg, uint32_t num)
{
    uint32_t offset = 0U, max = 0U, limit = 0U;
   
    offset = (uint32_t)type;
    max = (uint32_t)type + num;
    limit = sizeof(enet_reg_tab)/sizeof(uint16_t);
   
    /* prevent element in this array is out of range */
    if(max > limit){
        max = limit;
    }
   
    for(; offset < max; offset++){
        /* get value of the corresponding register */
        *preg = REG32((ENET) + enet_reg_tab[offset]);
        preg++;
    }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

1353

帖子

6

粉丝