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

📄 net_nic.c

📁 最新版uC/CosII平台下CS8900驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
* Note(s)     : (2) See 'CS8900 RECEIVE BUFFER DESCRIPTOR' for packet frame format.
*********************************************************************************************************
*/

NET_LOCAL  void  CS8900_RxPkt (void        *ppkt,
                               CPU_INT16U   size,
                               NET_ERR     *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR      cpu_sr;
#endif
    char       *ptr;


    *perr = NET_NIC_ERR_NONE;

    CPU_CRITICAL_ENTER();
    if (frame_bff_num  == 0) {
        CS8900_DBG_PRINT("Frame buffer underflow\r\n");
        CPU_CRITICAL_EXIT();
        return;
    }

    ptr = (char *)&frame_bff[frame_bff_tail].Frame;
	frame_bff_tail++;

    if (frame_bff_tail >= (CS8900_NUM_ETH_FRAME_BUF - 1)) {
        frame_bff_tail  = 0;
    }
	frame_bff_num--;
    CPU_CRITICAL_EXIT();

    Mem_Copy((char *)ppkt, (char *)ptr,size);
}


/*
*********************************************************************************************************
*                                      CS8900_RxPktDiscard()
*
* Description : Discard network packet from NIC to free NIC packet frames for new receive packets.
*
* Argument(s) : size        Number of packet frame octets.
*
* Return(s)   : none.
*
* Caller(s)   : NetNIC_RxPktDiscard().
*
* Note(s)     : (1) 'size' NOT required for CS8900 packet discard.
*********************************************************************************************************
*/

NET_LOCAL  void  CS8900_RxPktDiscard (CPU_INT16U  size)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
    CPU_SR      cpu_sr;
#endif


    (void)size;

    CPU_CRITICAL_ENTER();
    CPU_CRITICAL_EXIT();
}

/*
*********************************************************************************************************
*                                          CS8900_TxPkt()
*
* Description : (1) Instruct CS8900 NIC to send network packet :
*
*                   (a) Check is transmitter ready.
*                   (b) Copy packet info transmitter buffer
*                   (c) Clear all transmitter errors.
*                   (d) 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.
*                               CS8900_ERR_TX_BUSY              Transmitter not ready.
*
* Return(s)   : none.
*
* Caller(s)   : NetNIC_TxPkt().
*
* Note(s)     : (2) See 'CS8900 RECEIVE BUFFER DESCRIPTOR' for packet frame format.
*********************************************************************************************************
*/

NET_LOCAL  void  CS8900_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_INT16U   stat;
    CPU_INT16U  *sdata;


    *perr = NET_NIC_ERR_NONE;

    CPU_CRITICAL_ENTER();

    CS8900_RegWr(CS8900_TxCMD_OFFSET, PP_TxCmd_TxStart_Full);     /* Step 1: Write the TX command                                */
    CS8900_RegWr(CS8900_TxLEN_OFFSET, size);                      /* Step 2: Bid for Tx                                          */
                                                                  /*         Write the frame length  (number of bytes to TX)     */

                                                                  /* Note: After the frame length has been written, CS8900       */
                                                                  /* reserves Tx bufferfor this bid no matter PP_BusStat_TxRDY   */
                                                                  /* is set or not.                                              */

    stat = CS8900_PPRegRd(PP_BusStat);                            /* Read BusST to verify it is set as Rdy4TxNow.                */

    if ((stat & PP_BusStat_TxBid) != 0) {                         /* Step 3: check if TxBidErr happens                           */
        CS8900_DBG_PRINT("Tx Bid Error!\r\n");
        CPU_CRITICAL_EXIT();                                      /* Step 3.1: enable interrupts at processor level.             */
        *perr = NET_NIC_ERR_NONE;
        return;
   }

   if ((stat & PP_BusStat_TxRDY) == 0) {                          /* Step 4: check if chip is ready for Tx                       */
                                                                  /*         If Bid4Tx not ready, return immediately and wait    */
                                                                  /*         for ReadyForTx Interrupt.                           */
       CPU_CRITICAL_EXIT();                                       /* Step 4.1: enable interrupts at processor level.             */
       *perr = NET_NIC_ERR_NONE;
       return;
   }

   sdata = (CPU_INT16U *)ppkt;                                    /* Step 5: copy Tx data into CS8900's buffer                   */

    if (size > 0) {                                               /* This actually starts the Txmit                              */
        while (size > 1) {                                        /* Output contiguous words, two bytes at a time.               */
            CS8900_RegWr(CS8900_RTDATA_OFFSET, *sdata);
            sdata++;
            size -= 2;
        }
        if (size == 1) {                                          /* If Odd bytes, copy the last one byte to chip.               */
            CS8900_RegWr(CS8900_RTDATA_OFFSET, (*sdata) & 0x00FF);
        }
    }

    CPU_CRITICAL_EXIT();                                          /* Enable interrupts at processor level                        */
}


/*
*********************************************************************************************************
*                                          CS8900_Reset()
*
* Description : (1) Reset the CS8900 by writing to the Self Control Register
*
* Argument(s) : none.
* Return(s)   : 0, -1 (Pass / Fail
* Caller(s)   : CS8900_Init()
*
* Note(s)     : none.
*********************************************************************************************************
*/

NET_LOCAL  CPU_INT32S  CS8900_Reset (void)
{
    CPU_INT16U  i;
    CPU_INT16U  status;


    CS8900_PPRegWr(PP_SelfCtl, PP_SelfCtl_Reset);                 /* Reset chip                                                 */

    NET_BSP_CS8900A_Reset_Delay();                                /* Wait for the chip to come out of reset 10ms minimum        */

    for (i = 0; i < 3000; i++) {                                  /* check PP_SelfStat_InitD bit if the chip successflly reset  */
       status = (CS8900_PPRegRd(PP_SelfStat)&PP_SelfStat_InitD);
       if (status != 0) {
           return (0);
       }
    }

    return (-1);
}

/*
*********************************************************************************************************
*                                          CS8900_Int_Receive()
*
* Description : (1) Process Receive Interrupts
*
* Argument(s) : none.
* Return(s)   : none.
* Caller(s)   : NetNIC_ISR_Handler()
*
* Note(s)     : none.
*********************************************************************************************************
*/

NET_LOCAL CPU_INT32S CS8900_Int_Receive (CS8900_ETH_FRAME *pframe, CPU_INT16U RxEventStatus)
{
    CPU_INT16U   val;
    CPU_INT16U   leftLen;
    CPU_INT16U  *pdata;
    CPU_INT08U  *cp;


                                                                  /* Step 1: Determine if there is Rx Error.                     */
    if ((RxEventStatus & PP_RER_RxOK) == 0) {                     /* If RxOk bit is not set, Rx Error occurred                   */
        if ( RxEventStatus & PP_RER_CRC) {
            CS8900_DBG_PRINT("CRC error.\r\n");
        } else if (RxEventStatus & PP_RER_RUNT) {
            CS8900_DBG_PRINT("RUNT error.\r\n");
        } else if (RxEventStatus & PP_RER_EXTRA) {
            CS8900_DBG_PRINT("EXTRA error.\r\n");
        } else {
            CS8900_DBG_PRINT("Unknown Error.\r\n");
        }

        CS8900_PPRegRd(PP_Rx_LENGTH);                             /* Step 2: skip this received error frame.                     */
                                                                  /* Note: Must skip this received error frame.                  */
                                                                  /* Otherwise, CS8900 hangs here.                               */
                                                                  /* Read the length of Rx frame                                 */

        val  = CS8900_PPRegRd(PP_RxCFG);                          /* Write Skip to RxCfg Register and also keep the              */
                                                                  /* current configuration.                                      */
        val |= PP_RxCFG_Skip1;
        CS8900_PPRegWr(PP_RxCFG, val);

        return (-1);                                              /* return failed                                               */
    }

    if (frame_bff_num >= CS8900_NUM_ETH_FRAME_BUF) {
        CS8900_DBG_PRINT("Frame buffer overflow\r\n");
        return (-1);
    }

    frame_bff_num++;

    pframe->size = CS8900_PPRegRd(PP_Rx_LENGTH);                  /* Step 3: Read the length of Rx frame                         */

    pdata        = (CPU_INT16U *)pframe->Frame;                   /* Step 4: Read the Rx data from Chip and store it to          */
                                                                  /*         the stacks buffer                                   */
    leftLen      = pframe->size;

    while (leftLen >= 2) {                                        /* read 2 bytes at a time                                      */
        *pdata++ = CS8900_RegRd(CS8900_RTDATA_OFFSET);
        leftLen -= 2;
    }

    if (leftLen == 1) {                                           /* if odd bytes, read the last byte from chip                  */
        val      = CS8900_RegRd(CS8900_RTDATA_OFFSET);            /* Read the last byte from chip                                */
        cp       = (CPU_INT08U *)pdata;                           /* point to the last one byte of the user buffer               */

        *cp      = (CPU_INT08U)(val & 0xFF);                      /* truncate the word (2-bytes) read from chip to one byte      */
    }

    return (pframe->size);
}

/*
*********************************************************************************************************
*                                         NetNIC_MAC_AddrSet()
*
* Description : Set NIC's hardware (MAC) address.
*
* Argument(s) : paddr       Pointer to memory buffer to receive NIC's hardware address.
*
*               perr        Pointer to variable that will hold the return error code from this function :
*
*                               NET_IF_ERR_NONE                 NIC's hardware address successfully returned.
*                               NET_IF_ERR_INVALID_MAC          Invalid or uninitialized hardware address.
*
* Return(s)   : none.
*
* Caller(s)   : User Application.
*
* Note(s)     : (1) NIC's hardware address also known as MAC (Media Access Control) or physical address.
*
*               (2) NIC's hardware address accessed in octets from CPU_INT08U arrays.
*
*               (3) Should only be called after net_init() from the user application.
*********************************************************************************************************
*/

void  NetNIC_MAC_AddrSet (CPU_INT08U  *paddr,
                          NET_ERR     *perr)
{
    CPU_INT08U  i;
    CPU_INT16U  reg_val;


    *perr = NET_IF_ERR_NONE;
                                                                  /* Write the user defined MAC address to the CS8900            */
                                                                  /* Note the MAC is byte swappd since its a  cs8900 reg write   */
    reg_val = (NetIF_MAC_Addr[1] << DEF_OCTET_NBR_BITS) | NetIF_MAC_Addr[0];
    CS8900_PPRegWr(PP_IA + 0, reg_val);
    reg_val = (NetIF_MAC_Addr[3] << DEF_OCTET_NBR_BITS) | NetIF_MAC_Addr[2];
    CS8900_PPRegWr(PP_IA + 2, reg_val);
    reg_val = (NetIF_MAC_Addr[5] << DEF_OCTET_NBR_BITS) | NetIF_MAC_Addr[4];
    CS8900_PPRegWr(PP_IA + 4, reg_val);
                                                                  /* Read the CS8900 MAC registers and confirm the MAC address   */
    for (i = 0; i < sizeof(NetIF_MAC_Addr); i += sizeof(CPU_INT16U)) {
        reg_val = CS8900_PPRegRd(PP_IA + i);
        if (reg_val != (CPU_INT16U)((NetIF_MAC_Addr[i + 1] << DEF_OCTET_NBR_BITS) | NetIF_MAC_Addr[i])) {
            *perr = NET_ERR_INIT_INCOMPLETE;
            return;
        }
    }
}
	 	 			 		    	 				 	    	 	 	 		    	     	 	 	 		 	  	  	  	     	 	      	   		 	 	 	   		   			 	     			  			 		   	 			       	  	 		  	 	  	 		 		   		  	  			 	  	 		 	 	 			 	 		 		 	 		 	   		 	 	 	   		     			  			 		  	 		 	  			 	 	 	 	  		  	   		   	   	 				 		 			 			  			 		   		 		 				 		 	    		   	  		 

⌨️ 快捷键说明

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