⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fec.c

📁 Freescale MCF5445evb 参考测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Parameters: *  ch      FEC channel *  nif     Pointer to Network Interface (NIF) structure *  dst     Destination MAC Address *  src     Source MAC Address *  type    Ethernet Frame Type *  length  Number of bytes to be transmitted (doesn't include type,  *          src, or dest byte count) *  pkt     Pointer packet network buffer * * Return Value: *  0       success *  1       otherwise */intfec_send (int ch, uint8 *dst, uint8 *src, uint16 type, NBUF *nbuf){    FECBD *pTxBD;    /* Check the length */    if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU)        return 1;    /*      * Copy the destination address, source address, and Ethernet      * type into the packet      */    memcpy(&nbuf->data[0],  dst,   6);    memcpy(&nbuf->data[6],  src,   6);    memcpy(&nbuf->data[12], &type, 2);    /* Grab the next available Tx Buffer Descriptor */    pTxBD = fecbd_tx_alloc(ch);        if (pTxBD != NULL)    {   /* There was an empty slot in the TxBD ring */        /* Put the buffer into the TxBD ring queue */        queue_add(&txbd_queue[ch],(QNODE *)nbuf);        /* Setup the buffer descriptor for transmission */        pTxBD->data = nbuf->data;         pTxBD->length = nbuf->length + ETH_HDR_LEN;//        pTxBD->status = 0;        pTxBD->status |= (TX_BD_R | TX_BD_L);		        /* Continue the Tx DMA task (in case it was waiting for a new TxBD) */        fec_tx_continue(ch);    }    else    {   /* The TxBD ring was full */        /* Add this packet to the send holding queue */        queue_add(&send_queue[ch],(QNODE *)nbuf);    }    return 0;}/********************************************************************//* * Enable interrupts on the selected FEC * * Parameters: *  ch      FEC channel *  pri     Interrupt Priority *  lvl     Interrupt Level */voidfec_irq_enable(int ch){    int fec_vbase, vector;    void fec0_irq_handler(void);    void fec1_irq_handler(void);    if (ch == 0)        fec_vbase = 64 + 23;    else if (ch == 1)        fec_vbase = 64 + 49;        for (vector = fec_vbase; vector <= fec_vbase + 13; vector++)    {        if (ch == 0)        {            /* Put the handler in the vector table */            mcf5xxx_set_handler(vector, (ADDRESS)fec0_irq_handler);        }        else if (ch == 1)        {            /* Put the handler in the vector table */            mcf5xxx_set_handler(vector, (ADDRESS)fec1_irq_handler);        }    }    /* Enable FEC interrupts to the ColdFire core      * Setup each ICR with a unique interrupt level combination */    fec_vbase -= 64;    /* FEC Rx Frame */    MCF_INTC0_ICR(fec_vbase+4)  = MCF_INTC_ICR_IL(INTC_LVL_FEC);    /* FEC Rx Buffer */                                  MCF_INTC0_ICR(fec_vbase+5)  = MCF_INTC_ICR_IL(INTC_LVL_FEC);    /* FEC Tx Frame */                                   MCF_INTC0_ICR(fec_vbase+0)  = MCF_INTC_ICR_IL(INTC_LVL_FEC);    /* FEC Tx Buffer */                                  MCF_INTC0_ICR(fec_vbase+1)  = MCF_INTC_ICR_IL(INTC_LVL_FEC);    /* FEC FIFO Underrun */                                  MCF_INTC0_ICR(fec_vbase+2)  = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);    /* FEC Collision Retry Limit */                                  MCF_INTC0_ICR(fec_vbase+3)  = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);    /* FEC MII */                                    //MCF_INTC0_ICR(fec_vbase+6)  = MCF_INTC_ICR_IL(INTC_LVL_FEC(ch));    /* FEC Late Collision */                                     MCF_INTC0_ICR(fec_vbase+7)  = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);    /* FEC Heartbeat Error */                                    MCF_INTC0_ICR(fec_vbase+8)  = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);    /* FEC Graceful Stop Comlete */                                  MCF_INTC0_ICR(fec_vbase+9)  = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);    /* FEC Bus Error */                                  MCF_INTC0_ICR(fec_vbase+10) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);    /* FEC Babbling Transmit */                                  MCF_INTC0_ICR(fec_vbase+11) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);    /* FEC Babbling Receive */                                   MCF_INTC0_ICR(fec_vbase+12) = MCF_INTC_ICR_IL(INTC_LVL_FEC+1);                                     /* Enable the FEC interrupts in the mask register */        if (ch == 0)    {    	        MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK32 |                        MCF_INTC_IMRH_INT_MASK33 |                        MCF_INTC_IMRH_INT_MASK34 |                        MCF_INTC_IMRH_INT_MASK35 );    MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK23 |                        MCF_INTC_IMRL_INT_MASK24 |                        MCF_INTC_IMRL_INT_MASK25 |                        MCF_INTC_IMRL_INT_MASK26 |                        MCF_INTC_IMRL_INT_MASK27 |                        MCF_INTC_IMRL_INT_MASK28 |                        MCF_INTC_IMRL_INT_MASK29 |                        MCF_INTC_IMRL_INT_MASK30 |                        MCF_INTC_IMRL_INT_MASK31 |                        MCF_INTC_IMRL_MASKALL);    }    else if (ch == 1)    MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK49 |                        MCF_INTC_IMRH_INT_MASK50 |                        MCF_INTC_IMRH_INT_MASK51 |                        MCF_INTC_IMRH_INT_MASK52 |                        MCF_INTC_IMRH_INT_MASK53 |                        MCF_INTC_IMRH_INT_MASK54 |                        MCF_INTC_IMRH_INT_MASK55 |                        MCF_INTC_IMRH_INT_MASK56 |                        MCF_INTC_IMRH_INT_MASK57 |                        MCF_INTC_IMRH_INT_MASK58 |                        MCF_INTC_IMRH_INT_MASK59 |                        MCF_INTC_IMRH_INT_MASK60 |                        MCF_INTC_IMRH_INT_MASK61);    /* Clear any pending FEC interrupt events */    MCF_FEC_EIR = MCF_FEC_EIR_CLEAR_ALL;    /* Unmask all FEC interrupts */    MCF_FEC_EIMR = MCF_FEC_EIMR_UNMASK_ALL;}/********************************************************************//* * Disable interrupts on the selected FEC * * Parameters: *  ch      FEC channel */voidfec_irq_disable(int ch){    int vector, fec_vbase;    fec_vbase = 64 + 23;         for (vector = fec_vbase; vector <= fec_vbase + 13; vector++)     {        /* Disable interrupts to the ColdFire core */        MCF_INTC0_ICR(vector - 64) = 0;    }    /* Mask all FEC interrupts */    MCF_FEC_EIMR = MCF_FEC_EIMR_MASK_ALL;    /* Mask the FEC interrupt in the interrupt controller */    if (ch == 0)    {    	            MCF_INTC0_IMRH |= 0                        | MCF_INTC_IMRH_INT_MASK32            | MCF_INTC_IMRH_INT_MASK33            | MCF_INTC_IMRH_INT_MASK34            | MCF_INTC_IMRH_INT_MASK35;        MCF_INTC0_IMRL |= 0             	| MCF_INTC_IMRL_INT_MASK23            | MCF_INTC_IMRL_INT_MASK24            | MCF_INTC_IMRL_INT_MASK25            | MCF_INTC_IMRL_INT_MASK26            | MCF_INTC_IMRL_INT_MASK27            | MCF_INTC_IMRL_INT_MASK28            | MCF_INTC_IMRL_INT_MASK29            | MCF_INTC_IMRL_INT_MASK30            | MCF_INTC_IMRL_INT_MASK31;    }   }/********************************************************************//* * FEC interrupt handler * * Parameters: *  nif     NIF structure */static voidfec_irq_handler(NIF* nif){    uint32 event, eir;        /* Determine which interrupt(s) asserted by AND'ing the     * pending interrupts with those that aren't masked. */    eir = MCF_FEC_EIR;    event = eir & MCF_FEC_EIMR;    #ifdef DEBUG_PRINT    if (event != eir)        printf("Pending but not enabled: 0x%08X\n",(event ^ eir));    #endif    /* Clear the event(s) in the EIR immediately */    MCF_FEC_EIR = event;    if (event & MCF_FEC_EIR_UN)    {        fec_log[nif->ch].errors++;        fec_log[nif->ch].un++;        #ifdef DEBUG        printf("FEC Tx FIFO Underflow\n");        #endif    }    if (event & MCF_FEC_EIR_RL)    {        fec_log[nif->ch].errors++;        fec_log[nif->ch].rl++;        #ifdef DEBUG        printf("FEC Collision Retry Limit\n");        #endif        //fec_resend(nif->ch);    }    if (event & MCF_FEC_EIR_LC)    {        fec_log[nif->ch].errors++;        fec_log[nif->ch].lc++;        #ifdef DEBUG        printf("FEC Late Collision\n");        #endif        //fec_resend(nif->ch);    }    if (event & MCF_FEC_EIR_EBERR)    {        fec_log[nif->ch].errors++;        fec_log[nif->ch].eberr++;        #ifdef DEBUG        printf("FEC/DMA fatal bus error!\n");        #endif        fec_eth_stop(nif->ch);    }    if (event & MCF_FEC_EIR_MII)    {        fec_log[nif->ch].mii++;    }    if (event & MCF_FEC_EIR_RXB || event & MCF_FEC_EIR_RXF)    {        fec_rx_handler(nif);    }    if (event & MCF_FEC_EIR_TXB || event & MCF_FEC_EIR_TXF)    {        fec_tx_handler(nif, event);    }    if (event & MCF_FEC_EIR_GRA)    {        fec_log[nif->ch].gra++;    }    if (event & MCF_FEC_EIR_BABT)    {        fec_log[nif->ch].errors++;        fec_log[nif->ch].babt++;        #ifdef DEBUG        printf("FEC Babbling transmit error\n");        #endif    }    if (event & MCF_FEC_EIR_BABR)    {        fec_log[nif->ch].errors++;        fec_log[nif->ch].babr++;        #ifdef DEBUG        printf("FEC Babbling receive error\n");        #endif    }    if (event & MCF_FEC_EIR_HBERR)    {        fec_log[nif->ch].errors++;        fec_log[nif->ch].hberr++;        #ifdef DEBUG        printf("HBERR\n");        #endif    }}__interrupt__void fec0_irq_handler(void){    fec_irq_handler(&nif[0]);}__interrupt__static void fec1_irq_handler(void){    fec_irq_handler(&nif[1]);}/********************************************************************//* * Configure the selected Ethernet port and enable all operations * * Parameters: *  cfg     FEC configuration structure *  sys_clk System clock frequency - used for MII speed calculation * * Return Value: *  0 if the Ethernet was successfully started *  non-zero otherwise  */intfec_eth_start(FEC_CONFIG *cfg, int sys_clk){    int status;	    /* Disable FEC interrupts */    fec_irq_disable(cfg->ch);    /* Initialize the event log */    fec_log_init(cfg->ch);    /* Initialize the buffer descriptor ring */    status = fecbd_init(cfg->ch, cfg->nrxbd, cfg->ntxbd);    if (status)    {        #ifdef DEBUG_PRINT            printf("\nfecbd_init() failed with status code %d: ",status);            if (status == ERR_MALLOC)                printf("ERR_MALLOC\n");            else if (status == ERR_NBUFALLOC)                printf("ERR_NBUFALLOC\n");        #endif        return -1;    }    /* Initialize the PHY interface */    if ((cfg->mode == FEC_MODE_MII || cfg->mode == FEC_MODE_RMII) &&         cfg->initphy == YES)    {        fec_mii_init(cfg->ch, sys_clk);        if (eth_phy_autoneg(cfg->phyaddr, cfg->speed, cfg->duplex))        {            #ifdef DEBUG_PRINT                printf("eth_phy_autoneg() failed\n");            #endif            fecbd_flush(cfg->ch);            return -1;        }    }    /* Initialize the FEC */    fec_reset(cfg->ch);    fec_init(cfg->ch, cfg->mode, cfg->duplex, cfg->prom, cfg->mac);	fec_mib_init(cfg->ch);    /* Initialize and enable FEC interrupts */    fec_irq_enable(cfg->ch);/*    MCF_SCM_MPR |= 0        | MCF_SCM_MPR_MPROT2(7)        | MCF_SCM_MPR_MPROT3(7);*///	MCF_SCM_MPR = MCF_SCM_MPR_MPR(1);      /* Enable the FEC channel */    MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;    /* Start the Rx FEC DMA */    //fec_rx_continue(cfg->ch);    return 0;}/********************************************************************//* * Stop the selected Ethernet port * * Parameters: *  ch      FEC channel */voidfec_eth_stop(int ch){    int level;    /* Disable interrupts */    level = asm_set_ipl(7);    /* Gracefully disable the transmitter */    fec_tx_stop(ch);    /* Disable FEC interrupts */    fec_irq_disable(ch);    /* Disable the FEC channel */    MCF_FEC_ECR &= ~MCF_FEC_ECR_ETHER_EN;    /* Clean up the BDs and buffer queues */    fecbd_flush(ch);        /* Restore interrupt level */    asm_set_ipl(level);}/********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -