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

📄 net_nic.c

📁 网络层芯片DM9000A驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    DM9000A_EMAC_TxPkt(ppkt, size, perr);                           /* Tx pkt to DM9000.                                        */

    if (*perr != NET_NIC_ERR_NONE) {
        NetNIC_TxPktDiscard(perr);
        return;
    }

    NET_CTR_STAT_INC(NetNIC_StatTxPktCtr);

    *perr = NET_NIC_ERR_NONE;
}


/*
*********************************************************************************************************
*                                        DM9000A_EMAC_TxPkt()
*
* Description : (1) Instruct DM9000 EMAC to send network packet :
*                   (a) Check is transmitter ready.
*                   (b) Clear all transmitter errors.
*                   (c) Inform transmitter about buffer address and size.
*                       This starts actual transmission of the packet.
*
* Argument(s) : ppkt        Pointer to memory buffer to transmit NIC packet.
*               ----        Argument checked in NetNIC_TxPkt().
*
*               size        Number of packet frame octets to write to frame.
*
*               perr        Pointer to variable that will hold the return error code from this function :
*
*                               NET_NIC_ERR_NONE                Packet successfully transmitted.
*                               DM9000_EMAC_ERR_TX_BUSY     Transmitter not ready.
* Return(s)   : none.
*
* Caller(s)   : NetNIC_TxPkt().
*
* Note(s)     : (1) The DM9000A has two transmit buffers.  This function, as written, will not issue
*                   the transmit command on the second buffer while the data from the first is still
*                   being transmitted (or waiting to be transmitted).  Instead, the data is written
*                   to the buffer and the data length stored.  This second buffer's data will be
*                   transmitted from NetNIC_ISR_Handler() when a transmit completed interrupt is
*                   received.
*********************************************************************************************************
*/

static  void  DM9000A_EMAC_TxPkt (void        *ppkt,
                                  CPU_INT16U   size,
                                  NET_ERR     *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR          cpu_sr;
#endif

    CPU_INT08U  *p8;
    CPU_INT16U  *p16;
    CPU_INT16U  sizetmp;


    DM9000A_ENTER();

    p8                 = (CPU_INT08U *)ppkt;
    p16                = (CPU_INT16U *)ppkt;
    sizetmp            = size;

    NetNIC_WrIx_8(DM9000A_MWCMD);                                   /* Prepare to write memory with auto-increment              */

#if   DM9000A_IO_MODE == DM9000A_IO_8_BITS
    (void)p16;

    while (size > 0) {
        NetNIC_WrData_8(*p8);                                       /* Write byte of data to register                           */
        p8++;                                                       /* Increment packet pointer                                 */
        size--;
    }
#elif DM9000A_IO_MODE == DM9000A_IO_16_BITS
    (void)p8;

    while (size >= 2) {
        NetNIC_WrData_16(*p16);                                     /* Write word of data to register                           */
        p16++;                                                      /* Increment packet pointer                                 */
        size          -= 2;
    }
    if (size == 1) {                                                /* If an odd number of packets need be transmitted          */
        NetNIC_WrData_16((CPU_INT16U)(*(CPU_INT08U *)p16) & 0x00FF);/* Write data to register                                   */
    }
#endif

#if DM9000A_TX_QUEUE_MODE == DM9000A_TX_QUEUE_TWO_PACKETS
    if (NetNIC_TxNQueued == 0) {                                    /* If no packets are queued . . .                           */
        NetNIC_WrReg_8(DM9000A_TXPLL,  sizetmp       & 0xFF);       /* . . .write low  byte of length into register   (0xFCh)   */
        NetNIC_WrReg_8(DM9000A_TXPLH, (sizetmp >> 8) & 0xFF);       /* . . .write high byte of length into register   (0xFDh)   */
        NetNIC_WrReg_8(DM9000A_TCR,   TCR_TXREQ);                   /* . . .set a TX request command                  (0x02[0]) */
        NetOS_NIC_TxRdySignal();                                    /* . . .and indicate that another packet can be tx'ed.      */
    } else if (NetNIC_TxNQueued == 1) {                             /* If one packet is queued . . .                            */
        NetNIC_TxLenQueued = sizetmp;                               /* . . .then store length of packet.                        */
    }

    NetNIC_TxNQueued++;                                             /* Increment number of queued packets                       */
#else
    NetNIC_WrReg_8(DM9000A_TXPLL,  sizetmp       & 0xFF);           /* Write low  byte of length into register        (0xFCh)   */
    NetNIC_WrReg_8(DM9000A_TXPLH, (sizetmp >> 8) & 0xFF);           /* Write high byte of length into register        (0xFDh)   */
    NetNIC_WrReg_8(DM9000A_TCR,   TCR_TXREQ);                       /* Set a TX request command                       (0x02[0]) */
#endif

    DM9000A_EXIT();

    *perr = NET_NIC_ERR_NONE;                                       /* Return no error to the stack                             */
}


/*
*********************************************************************************************************
*                                         NetNIC_TxPktDiscard()
*
* Description : On any Transmit errors, set error.
*
* Argument(s) : pbuf        Pointer to network buffer.
*
*               perr        Pointer to variable that will hold the return error code from this function :
*
*                               NET_ERR_TX                  Transmit error; packet discarded.
*
* Return(s)   : none.
*
* Caller(s)   : NetNIC_TxPkt().
*********************************************************************************************************
*/

static  void  NetNIC_TxPktDiscard (NET_ERR  *perr)
{
#if (NET_CTR_CFG_STAT_EN     == DEF_ENABLED)
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR   cpu_sr;
#endif
#endif


    NET_CTR_ERR_INC(NetNIC_ErrTxPktDiscardedCtr);

   *perr = NET_ERR_TX;
}


/*
*********************************************************************************************************
*                                        NetNIC_TxISR_Handler()
*
* Description : (1) Clear transmit interrupt &/or transmit errors :
*
*                   (a) Acknowledge transmit interrupt.
*                   (b) Post transmit FIFO empty signal.
*
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Caller(s)   : NetNIC_ISR_Handler().
*
* Note(s)     : (2) NetNIC_ISR_Handler() decodes DM9000 Transmit ISR & calls NetNIC_TxISR_Handler().
*********************************************************************************************************
*/

static  void  NetNIC_TxISR_Handler (void)
{
                                                                    /* Interrupts are acknowledged when ISR read.               */
                                                                    /* ISR are previously read in NetNIC_ISR_Handler().         */

                                                                    /* --------------- POST TX COMPLETE SIGNAL ---------------- */
    NetOS_NIC_TxRdySignal();
}


/*
*********************************************************************************************************
*                                         NetNIC_TxPktPrepare()
*
* Description : Prepare to transmit data packets from network driver layer to network interface card.
*
* Argument(s) : ppkt        Pointer to memory buffer to transmit NIC packet.
*
*               size        Number of packet frame octets to write to frame.
*
*               perr        Pointer to variable that will hold the return error code from this function :
*
*                               NET_NIC_ERR_NONE            Packet successfully transmitted.
*                               NET_ERR_INIT_INCOMPLETE     Network initialization NOT complete.
*
*                                                           - RETURNED BY NetNIC_TxPktDiscard() : -
*                               NET_ERR_TX                  Transmit error; packet discarded.
*
* Return(s)   : none.
*
* Caller(s)   : NetIF_Pkt_Tx().
*
* Note(s)     : (1) NetNIC_TxPktPrepare() blocked until network initialization completes; perform NO action.
*********************************************************************************************************
*/

void  NetNIC_TxPktPrepare (void        *ppkt,
                           CPU_INT16U   size,
                           NET_ERR     *perr)
{
    if (Net_InitDone != DEF_YES) {                                  /* If init NOT complete, exit tx (see Note #1).             */
       *perr = NET_ERR_INIT_INCOMPLETE;
        return;
    }

#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)                     /* --------------------- VALIDATE PTR --------------------  */
    if (ppkt == (void *)0) {
        NetNIC_TxPktDiscard(perr);
        return;
    }
#endif

    DM9000A_EMAC_TxPktPrepare(ppkt, size, perr);                    /* Prepare to tx pkt to DM9000A.                            */

    if (*perr != NET_NIC_ERR_NONE) {
        NetNIC_TxPktDiscard(perr);
        return;
    }

    *perr = NET_NIC_ERR_NONE;
}


/*
*********************************************************************************************************
*                                    DM9000A_EMAC_TxPktPrepare()
*
* Description : (1) Copy packet into local NIC TX buffer prior to the end of the transmission of the last
                    packet.
*
* Argument(s) : ppkt        Pointer to memory buffer to transmit NIC packet.
*               ----        Argument checked in NetNIC_TxPkt().
*
*               size        Number of packet frame octets to write to frame.
*
*               perr        Pointer to variable that will hold the return error code from this function :
*
*                               NET_NIC_ERR_NONE                Packet successfully transmitted.
* Return(s)   : none.
*
* Caller(s)   : NetNIC_TxPktPrepare().
*********************************************************************************************************
*/

static void  DM9000A_EMAC_TxPktPrepare (void        *ppkt,
                                        CPU_INT16U   size,
                                        NET_ERR     *perr)
{
   *perr = NET_NIC_ERR_NONE;
}


/*
*********************************************************************************************************
*                                           NetNIC_PhyRegRd()
*
* Description : Read PHY data value.
*
* Argument(s) : phy         PHY address, normally 0.
*               reg         PHY register.
*               perr        Pointer to variable that will hold the return error code from this function
*
* Return(s)   : Data read from PHY register.
*
* Caller(s)   : DM9000A_EMAC_Init()
*
* Note(s)     : Register ALWAYS reads 16-bit data values.
*********************************************************************************************************
*/

CPU_INT16U  NetNIC_PhyRegRd (CPU_INT08U  phy,
                             CPU_INT08U  reg,
                             NET_ERR    *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR      cpu_sr;
#endif
    CPU_INT16U  reg_val;


    CPU_CRITICAL_ENTER();
    NetNIC_WrReg_8(DM9000A_EPAR, phy | reg);                        /* Write PHY register offset into register           (0x0C) */
    NetNIC_WrReg_8(DM9000A_EPCR, EPCR_ERPRR | EPCR_EPOS);           /* Write PHY + READ command into register            (0x0B) */
    CPU_CRITICAL_EXIT();

    NetBSP_DlyU(100);

    CPU_CRITICAL_ENTER();
    NetNIC_WrReg_8(DM9000A_EPCR, EPCR_EPOS);                        /* Write PHY command into register                   (0x0B) */
    reg_val  = NetNIC_RdReg_8(DM9000A_EPDRL);                       /* Read  low byte from register                      

⌨️ 快捷键说明

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