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

📄 lan8xx.c

📁 这是单板上DPRAM的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
ETHER(E_SCC1_BASE).iaddr2 = 0;
ETHER(E_SCC1_BASE).iaddr3 = 0;
ETHER(E_SCC1_BASE).iaddr4 = 0;
ETHER(E_SCC1_BASE).taddr_h = 0;
ETHER(E_SCC1_BASE).taddr_m = 0;
ETHER(E_SCC1_BASE).taddr_l = 0;
ETHER(E_SCC1_BASE).tfbd_ptr = E_BuffDescOffset(TxFirstBdPtr);
ETHER(E_SCC1_BASE).tlbd_ptr = E_BuffDescOffset(RxFirstBdPtr);

TxLastBdPtr->status = WRAP;

/*---------------------------------------------------------------------*/
/* Send command to re-initialize transmit and receive parameters.      */
/*---------------------------------------------------------------------*/
CPM_CMD(INIT_RX_TX_PARAMS|SCC1_CH_NUM); /* Changed by szg */

/*---------------------------------------------------------------------*/
/* Clear previous events and set up the interrupt mask registers.      */
/*---------------------------------------------------------------------*/
E_SCC1EventReg = 0xFFFF;
E_SCC1MaskReg  = 0x001E;
SPLX(E_CP_IntMaskReg |= EN_SCC1;)

/*---------------------------------------------------------------------*/
/* Put the Ethernet sync pattern in the synchronization register.      */
/*---------------------------------------------------------------------*/
E_SCC1DataSyncReg = 0xD555;

/*---------------------------------------------------------------------*/
/* Set SCC1 General and Protocol-Specific Mode Registers.              */
/*---------------------------------------------------------------------*/
E_SCC1GenModeReg_l = TX_CLK_INVERT + ETHER_PREAM_LGTH + ETHER_PREAM_PAT
                     + ETHER_MODE;
E_SCC1GenModeReg_h = 0x00000000;

#if (GDPP_FULL_DUPLEX==YES)
E_SCC1ProtoModeReg = SINGLE_PADDR + CCITT_CRC + FULL_DUPLEX+  //change by cm
                     RCV_BROADCASTS + IGNORE_22_BITS;
#else                     
E_SCC1ProtoModeReg = SINGLE_PADDR + CCITT_CRC +
                     RCV_BROADCASTS + IGNORE_22_BITS;
#endif

#ifdef MBX8xx
/*---------------------------------------------------------------------*/
/* Configure port C to enable !RTS (TENA)                              */
/*---------------------------------------------------------------------*/
E_PortCPinAssgmntReg  |= PC15;
/*E_PortCDataDirReg     |= PC15; */
E_PortCDataDirReg     &= ~(PC15);
#endif

#if (ADS8xx || SBC8xx)
/*---------------------------------------------------------------------*/
/* Configure port B to enable !RTS(TENA).                              */
/*---------------------------------------------------------------------*/
E_PortBPinAssgmntReg |=  BIT12;
E_PortBDataDirReg    |=  BIT12;
#endif

/*---------------------------------------------------------------------*/
/* Enable the transmitter and receiver.                                */
/*---------------------------------------------------------------------*/
E_SCC1GenModeReg_l = TX_CLK_INVERT + ETHER_PREAM_LGTH + ETHER_PREAM_PAT
                     + ENABLE_RVR + ENABLE_TMT + ETHER_MODE;
}

/***********************************************************************/
/*  InitBuffers: Initialize driver's pools of receive buffers and      */
/*               transmit headers                                      */
/*                                                                     */
/***********************************************************************/
static void InitBuffers(void)
{
UINT i;
RX_BUFF *rxb_ptr, *next_rxb_ptr;

/*---------------------------------------------------------------------*/
/* Zero out the transmit headers and the receive buffers.              */
/*---------------------------------------------------------------------*/
clear(TxHeaders, sizeof(TX_HDR)*NrTxHdrs);
clear(RxBuffs, sizeof(RxBuffs));

/*---------------------------------------------------------------------*/
/* Link the transmit headers together in the free list.                */
/*---------------------------------------------------------------------*/
TxhFreeHead = &TxHeaders[0];
for (i = 0; i < NrTxHdrs - 1; i++)
    TxHeaders[i].next = &TxHeaders[i + 1];
TxHeaders[NrTxHdrs - 1].next = NULL;

/*---------------------------------------------------------------------*/
/* Initialize the list of queued transmit headers to empty.            */
/*---------------------------------------------------------------------*/
TxhOutHead = NULL;
TxhOutTail = NULL;

/*---------------------------------------------------------------------*/
/* Link the receive buffers together in the free list.  Note that      */
/* each receive buffer must be longword aligned.                       */
/*---------------------------------------------------------------------*/
RxbFreeHead = (RX_BUFF *)ALIGN(((ULONG)RxBuffs), 4);
rxb_ptr = RxbFreeHead;
for (i = 0; i < NR_RXBUFFS - 1; i++)
    {
    next_rxb_ptr =
     (RX_BUFF *)ALIGN((((ULONG)rxb_ptr) + sizeof(RX_BUFF)), 4);
    rxb_ptr->next = next_rxb_ptr;
    rxb_ptr = next_rxb_ptr;
    }
rxb_ptr->next = NULL;
}

/***********************************************************************/
/* AssignRxBuffers: Beginning with the first receive buffer descriptor */
/*              used to receive a packet since this function last      */
/*              assigned a buffer, reassign buffers to "used" receive  */
/*              buffer descriptors, and mark them as EMPTY; available  */
/*              to be used again by the SCC1.                          */
/*                                                                     */
/***********************************************************************/
static void AssignRxBuffers(void)
{
ULONG old_level;
RX_BUFF *BufPtr;

for (;;)
    {
    old_level = splx(MAX_ILEV);

    /*-----------------------------------------------------------------*/
    /* Exit if no receive buffer descriptors are in "unused" state.    */
    /*-----------------------------------------------------------------*/
    if (RxUsedPtr->address != NULL)
        {
        splx(old_level);
        break;
        }

    /*-----------------------------------------------------------------*/
    /* Exit if no buffer envelopes are free to give out right now.     */
    /*-----------------------------------------------------------------*/
    if ((BufPtr = RxbFreeHead) == NULL)
        {
        splx(old_level);
        break;
        }
    else
        RxbFreeHead = BufPtr->next;

    /*-----------------------------------------------------------------*/
    /* Assign packet, prepare descriptor, and advance pointer.         */
    /*-----------------------------------------------------------------*/
    RxUsedPtr->address = BufPtr;
    RxUsedPtr->length  = 0;
    if (RxUsedPtr >= RxLastBdPtr)
        {
        RxUsedPtr->status = EMPTY + LOG_EVENT + WRAP;
        RxUsedPtr = RxFirstBdPtr;
        }
    else
        {
        RxUsedPtr->status = EMPTY + LOG_EVENT;
        RxUsedPtr++;
        }

    splx(old_level);
    }
}

/***********************************************************************/
/* ReclaimTxFrames: Reclaim transmit Frames which have been sent out   */
/*                  by SCC1.                                           */
/*                                                                     */
/*     OUTPUTS: TxUsedPtr is updated                                   */
/*       NOTES: TxUsedPtr points to the first buffer descriptor of the */
/*                 next frame to be reclaimed.                         */
/*                                                                     */
/***********************************************************************/
static void ReclaimTxFrames(void)
{
ULONG   i, old_level;
TX_HDR *TxhPtr;
BuffDescType *TxUsedLIFPtr;  /* points to last BD in the frame started */
                             /* by TxUsedPtr */
for (;;)
    {
    old_level = splx(MAX_ILEV);

    /*-----------------------------------------------------------------*/
    /* If an ISR came and reclaimed everything already get out!        */
    /*-----------------------------------------------------------------*/
    if ((TxUsedPtr == TxNewPtr) && (TxFreeBDs == NrTxBds))
        {
        splx(old_level);
        return;
        }

    /*-----------------------------------------------------------------*/
    /* Set TxUsedLIFPtr to point to the last BD for the frame which    */
    /* begins with *TxUsedPtr                                          */
    /*-----------------------------------------------------------------*/
    TxUsedLIFPtr = TxUsedPtr;
    i = 0;
    while (!(TxUsedLIFPtr->status & LAST_IN_FRAME))
        {
        IncTxBDptr(TxUsedLIFPtr);
        if (i++ > NrTxBds)
            {
            /*---------------------------------------------------------*/
            /* The current frame in the BD pool does not have the last */
            /* in frame bit set. This can only mean the BD pool is in  */
            /* an unknown state. Perform a clean-up and restart the    */
            /* transmitter.                                            */
            /*---------------------------------------------------------*/
            CleanUpTx();
            splx(old_level);
            return;
            }
        }

    /*-----------------------------------------------------------------*/
    /* If the last buffer in the current frame has not been sent we    */
    /* cannot reclaim the buffers and should exit the loop.            */
    /*-----------------------------------------------------------------*/
    if (TxUsedLIFPtr->status & READY)
       {
       splx(old_level);
       return;
       }

    /*-----------------------------------------------------------------*/
    /* Frame has been sent.  Set TxhPtr to point to the transmit       */
    /* header associated with the frame, and return the message block  */
    /* triplet.                                                        */
    /*-----------------------------------------------------------------*/
    TxhPtr = (TX_HDR *) TxUsedPtr->address;
    if ((TxUsedPtr->length != 14) || (TxhPtr == NULL))
            {
            /*---------------------------------------------------------*/
            /* We only add headers with a 14 byte size, so anything    */
            /* else means the BD pool is out of sync with our idea of  */
            /* the current state. Clean up all the BDs and restart the */
            /* transmitter.                                            */
            /*---------------------------------------------------------*/
            CleanUpTx();
            splx(old_level);
            return;
            }

    if (!TxhPtr->NoRetFlag)
        Ni_funcs.freemsg( ((TX_HDR *)(TxUsedPtr->address))->msg_ptr);

    /*-----------------------------------------------------------------*/
    /* Advance TxUsedLIFPtr to point to the next BD following this     */
    /* frame. Then loop through all the BDs in this frame, zeroing the */
    /* address, collecting error statistics, and increasing the number */
    /* of Free Tx BDs.                                                 */
    /*-----------------------------------------------------------------*/
    IncTxBDptr(TxUsedLIFPtr);
    do
        {
        TxUsedPtr->address = NULL;

        /*-------------------------------------------------------------*/
        /* If an outbound buffer in the frame had an error, update MIB */
        /* statics.                                                    */
        /*-------------------------------------------------------------*/
        if (TxUsedPtr->status
                & (LATE_COL | AT_RETRY_LIMIT | UNDERRUN | CARRIER_LOST))
        outerrors++;

        /*-------------------------------------------------------------*/
        /* Advance TxUsedPtr address and the free BD counter           */
        /*-------------------------------------------------------------*/
        IncTxBDptr(TxUsedPtr);
        TxFreeBDs++;
        if (TxFreeBDs > NrTxBds)
            {
            /*---------------------------------------------------------*/
            /* The number of Free BDs should never be more than the    */
            /* total number of BDs. If this happens, clean up the Tx   */
            /* BDs and restart the transmitter.                        */
            /*---------------------------------------------------------*/
            CleanUpTx();
            splx(old_level);
            return;
            }
        } while (TxUsedPtr != TxUsedLIFPtr);

    /*-----------------------------------------------------------------*/
    /* Finally, return the transmit header to the free list.           */
    /*-----------------------------------------------------------------*/
    TxhPtr->next = TxhFreeHead;
    TxhFreeHead  = TxhPtr;

⌨️ 快捷键说明

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