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

📄 net_nic.c

📁 DM9000A的网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:

    CPU_CRITICAL_ENTER();                                           /* See 'DM9000 REGISTERS  Note #5b'.                        */
    NetNIC_WrReg_8(DM9000A_IMR, IMR_PAR);
    NetNIC_WrReg_8(DM9000A_RCR, 0x00);	                            /* RX disable                                               */
    CPU_CRITICAL_EXIT();
}


/*
*********************************************************************************************************
*                                         NetNIC_ISR_Handler()
*
* Description : (1) Decode ISR & call appropriate ISR handler :
*
*                   (a) DM9000A Receive Buffer Not Available ISR     NetNIC_RxPktDiscard().
*                   (b) DM9000A Receive  ISR                         NetNIC_RxISR_Handler().
*                   (c) DM9000A Transmit ISR                         NetNIC_TxISR_Handler().
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Caller(s)   : This is an ISR
*
* Note(s)     : (2) DM9000A ISR  MUST call NetNIC_ISR_Handler() & MUST be developer-implemented in
*
*                       \<Your Product Application>\net_isr*.*
*
*                           where
*                                   <Your Product Application>    directory path for Your Product's Application.
*
*               (3) This function clears the interrupt source(s) on an external interrupt controller &, if
*                   ENABLED, MUST be developer-implemented in
*
*                       \<Your Product Application>\net_isr.c
*
*                           where
*                                   <Your Product Application>    directory path for Your Product's Application.
*
*********************************************************************************************************
*/

void  NetNIC_ISR_Handler (void)
{
    CPU_INT08U      int_status;
    CPU_INT08U      int_mask;


    int_status  =  NetNIC_RdReg_8(DM9000A_ISR) & 0x3F;              /* Read the interrupt status register                       */
    int_mask    =  NetNIC_RdReg_8(DM9000A_IMR);                     /* Read the interrupt mask register                         */

    if (int_status & ~int_mask) {                                   /* Clear any interrupt not handled                          */
        NetNIC_WrReg_8(DM9000A_ISR, int_status & ~int_mask);
    }

    int_status &=  int_mask;                                        /* AND status with mask to determine ints. to handle        */

    if ((int_status & ISR_PR) == ISR_PR) {                          /* Check for 'packet received' interrupt.                   */
        NetNIC_RxISR_Handler();
        NetNIC_WrReg_8(DM9000A_ISR, ISR_PR);                        /* Clear packet received interrupt.                         */
    }

    if ((int_status & ISR_PT) == ISR_PT) {                          /* Check for 'packet transmitted' interrupt.                */
#if DM9000A_TX_QUEUE_MODE == DM9000A_TX_QUEUE_TWO_PACKETS
        if (NetNIC_TxNQueued == 2) {                                /* If two packets are queued . . .                          */
            NetNIC_WrReg_8(DM9000A_TXPLL,  NetNIC_TxLenQueued       & 0xFF); /* Write low  byte of length into register         */
            NetNIC_WrReg_8(DM9000A_TXPLH, (NetNIC_TxLenQueued >> 8) & 0xFF); /* Write high byte of length into register         */
            NetNIC_WrReg_8(DM9000A_TCR,   TCR_TXREQ);               /* Set a TX request command                                 */

            NetNIC_TxLenQueued = 0;                                 /* Length value is no longer valid.                         */
        }
        NetNIC_TxNQueued--;                                         /* Decrement number of queued packets.                      */
#endif

        NetNIC_TxISR_Handler();
        NetNIC_WrReg_8(DM9000A_ISR, ISR_PT);                        /* Clear packet transmitted interrupt.                      */
    }

    if (int_status & (ISR_ROS | ISR_ROO)) {                         /* Clear all receiver errors.                               */
        if (int_status & ISR_ROS) {
            NetNIC_WrReg_8(DM9000A_ISR, ISR_ROS);                   /* Clear receive counter overflow interrupt.                */
        }
        if (int_status & ISR_ROO) {
            NetNIC_WrReg_8(DM9000A_ISR, ISR_ROO);                   /* Clear receive overflow interrupt.                        */
        }
    }

    NetBSP_IntClr();
}


/*
*********************************************************************************************************
*                                        NetNIC_RxISR_Handler()
*
* Description : Signal Network Interface Receive Task that a receive packet is available.
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Caller(s)   : NetNIC_ISR_Handler().
*
* Note(s)     : (1) NetNIC_ISR_Handler() decodes DM9000A Receive ISR & calls NetNIC_RxISR_Handler().
*********************************************************************************************************
*/

static  void  NetNIC_RxISR_Handler (void)
{
    NET_ERR         err;
                                                                    /* Interrupts are acknowledged when ISR read.               */
                                                                    /* ISR are previously read in NetNIC_ISR_Handler().         */
    NetOS_IF_RxTaskSignal(&err);
}


/*
*********************************************************************************************************
*                                         NetNIC_RxPktGetSize()
*
* Description : Get network packet size from NIC.
*
* Argument(s) : none.
*
* Return(s)   : Size, in octets, of NIC's next network packet.
*
* Caller(s)   : NetIF_RxTaskHandler().
*********************************************************************************************************
*/

CPU_INT16U  NetNIC_RxPktGetSize (void)
{
    CPU_INT16U      size;


    size = DM9000A_EMAC_RxPktGetSize();

    return (size);
}


/*
*********************************************************************************************************
*                                    DM9000A_EMAC_RxPktGetSize()
*
* Description : (1) Get network packet size from NIC :
*                   (a) Read packet frame size.
*
* Argument(s) : none.
*
* Return(s)   : Size, in octets, of NIC's next network packet.
*
* Caller(s)   : NetNIC_RxPktGetSize().
*
* Note(s)     : (1) See 'DM9000 EMAC RECEIVE BUFFER DESCRIPTOR' for packet frame format.
*
*               (2) The first byte of the 16-bit status is checked:
*                       (a) if it is 0, the no packet has been received;
*                       (b) if it is 1, then a packet is in the SRAM;
*                       (c) if it is neither 0 nor 1, then an error has occurred and the NIC will be
*                           restarted.
*
*               (3) The length is decreased by 4 to account for the 4-byte FCS.  Though these bytes will
*                   not be written into a TCP/IP buffer, they must still be removed (i.e., read) from
*                   the DM9000A SRAM.
*********************************************************************************************************
*/

static  CPU_INT16U  DM9000A_EMAC_RxPktGetSize (void)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR          cpu_sr;
#endif

    CPU_INT16U      size;
    CPU_INT16U      status;
    NET_ERR         err;


    DM9000A_ENTER();

    err              = NET_NIC_ERR_NONE;
    size             = 0;                                           /* Fall-through value                                       */

    status           = NetNIC_RdReg_8(DM9000A_MRCMDX);              /* Dummy read to determine if packet is ready        (0xF0) */
    status           = NetNIC_RdData_8() & 0xFF;                    /* Read status byte                                  (0xF0) */

    if (status == 0x00) {                                           /* If first byte of status is 0x00, packet is not in SRAM.  */
        size         = 0;

                                                                    /* If first byte of status is 0x01                          */
    } else if (status == 0x01) {                                    /*      then a packet has been received and is in SRAM      */
#if   DM9000A_IO_MODE   == DM9000A_IO_8_BITS                        /* 8 bits of data is read per access                        */
        NetNIC_WrReg_16(DM9000A_MRCMD);                             /*      Prepare to read with auto-increment          (0xF2) */

        status       = NetNIC_RdData_8();                           /*      Read lower byte of status word               (0xF2) */
        status      |= (CPU_INT16U)NetNIC_RdData_8() << 8;          /*      Read upper byte of status word               (0xF2) */
        size         = NetNIC_RdData_8();                           /*      Read lower byte of size word                 (0xF2) */
        size        |= (CPU_INT16U)NetNIC_RdData_8() << 8;          /*      Read upper byte of size word                 (0xF2) */
        size        -= 4;                                           /*      Decrease by 4 to account for FCS                    */
#elif DM9000A_IO_MODE   == DM9000A_IO_16_BITS                       /* 16 bits of data are read per access                      */
        NetNIC_WrIx_8(DM9000A_MRCMD);                               /*      Prepare to read with auto-increment          (0xF2) */

        status       = NetNIC_RdData_16();                          /*      Read status word                             (0xF2) */
        size         = NetNIC_RdData_16() - 4;                      /*      Read size word and decrement by 4            (0xF2) */
#endif

        status     >>= 8;                                           /* Upper byte of status is copy of RSR                      */

        if (size     > 1536) {                                      /* If length is greater than longest expected packet . . .  */
            DM9000A_Restart(&err);                                  /* . . .then reset DM9000A . . . . . .                      */
            size     = 0;                                           /* . . .and return size of 0.                               */
        } else if (status & RSR_ERRORS) {                           /* If there are receive errors . . . . . .                  */
            size     = 0;                                           /* . . .return size of 0.                                   */
        } else {
            ;
        }
                                                                    /* If first byte of status is neither 0x00 or 0x01          */
    } else {                                                        /* . . .then an error has occurred                          */
        DM9000A_Restart(&err);                                      /* . . .so reset DM9000A                                    */
        size         = 0;                                           /* . . .and return size of 0.                               */
    }

    DM9000A_EXIT();


    return (size);
}


/*
*********************************************************************************************************
*                                            NetNIC_RxPkt()
*
* Description : Read network packet from NIC into buffer.
*
* Argument(s) : ppkt        Pointer to memory buffer to receive NIC packet.
*
*               size        Number of packet frame octets to read into buffer.
*
*               perr        Pointer to variable that will hold the return error code from this function :
*
*                               NET_NIC_ERR_NONE            Packet successfully read.
*                               NET_ERR_INIT_INCOMPLETE     Network initialization NOT complete.
*                               NET_NIC_ERR_NULL_PTR        Argument 'ppkt' passed a NULL pointer.
*                               NET_NIC_ERR_INVALID_SIZE    Invalid size.
*
* Return(s)   : none.
*
* Caller(s)   : NetIF_RxTaskHandler().
*
* Note(s)     : (1) NetNIC_RxPkt() blocked until network initialization completes; perform NO action.
*********************************************************************************************************
*/

void  NetNIC_RxPkt (void        *ppkt,
                    CPU_INT16U   size,
                    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


    if (Net_InitDone != DEF_YES) {                                  /* If init NOT complete, exit rx (see Note #2).             */
       *perr = NET_ERR_INIT_INCOMPLETE;
        return;
    }

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

                                                                    /* --------------------- VALIDATE SIZE -------------------- */
    if (size < NET_IF_FRAME_MIN_SIZE) {
       *perr = NET_NIC_ERR_INVALID_SIZE;
        return;
    }
#endif

    DM9000A_EMAC_RxPkt(ppkt, size, perr);                          /* Rd rx pkt from NIC.                                       */

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

    NET_CTR_STAT_INC(NetNIC_StatRxPktCtr);

    *perr = NET_NIC_ERR_NONE;
}


/*
*********************************************************************************************************

⌨️ 快捷键说明

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