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

📄 xemac_l.c

📁 实用的程序代码
💻 C
字号:
/* $Id: xemac_l.c,v 1.3 2002/06/05 22:52:42 moleres Exp $ */
/******************************************************************************
*
*       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,
*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY
*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*       FOR A PARTICULAR PURPOSE.
*
*       (c) Copyright 2002 Xilinx Inc.
*       All rights reserved.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemac_l.c
*
* This file contains low-level polled functions to send and receive Ethernet
* frames.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a rpm  04/29/02 First release
* </pre>
*
******************************************************************************/

/***************************** Include Files *********************************/

#include "xemac_l.h"

/************************** Constant Definitions *****************************/

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Function Prototypes ******************************/

/************************** Variable Definitions *****************************/

/*****************************************************************************/
/**
*
* Send an Ethernet frame. This size is the total frame size, including header.
* This function blocks waiting for the frame to be transmitted.
*
* @param BaseAddress is the base address of the device
* @param FramePtr is a pointer to word-aligned frame
* @param Size is the size, in bytes, of the frame
*
* @return
*
* None.
*
* @note
*
* None.
*
******************************************************************************/
void XEmac_SendFrame(Xuint32 BaseAddress, Xuint8 *FramePtr, int Size)
{
    int i;
    int WordCount = Size / sizeof(Xuint32);
    int Remainder = Size % sizeof(Xuint32);
    Xuint32 *WordBuffer = (Xuint32 *)FramePtr;

    /*
     * Write each full word to the EMAC
     */
    for (i=0; i < WordCount; i++)
    {
        XIo_Out32(BaseAddress + XEM_PFIFO_TXDATA_OFFSET, WordBuffer[i]);
    }

    /*
     * If frame was not word-aligned, write the last word shifted
     * correctly.
     */
    if (Remainder > 0)
    {
        Xuint32 LastWord = 0;
        Xuint8 *ExtraBytesBuffer = (Xuint8 *)(WordBuffer + WordCount);

        switch (Remainder)
        {
            case 1:
                LastWord = ExtraBytesBuffer[0] << 24;
                break;

            case 2:
                LastWord = ExtraBytesBuffer[0] << 24 |
                           ExtraBytesBuffer[1] << 16;
                break;

            case 3:
                LastWord = ExtraBytesBuffer[0] << 24 |
                           ExtraBytesBuffer[1] << 16 |
                           ExtraBytesBuffer[2] << 8;
                break;
        }

        /* write the last 32 bit word to the FIFO and return with no errors */
        XIo_Out32(BaseAddress + XEM_PFIFO_TXDATA_OFFSET, LastWord);
    }

    /*
     * The frame is in the Fifo, now send it
     */
    XIo_Out32(BaseAddress + XEM_TPLR_OFFSET, Size);

    /*
     * Loop on the status waiting for the transmit to be complete
     */
    while (!XEmac_mIsTxDone(BaseAddress));

    /* Need to read the Transmit Status Register to get rid of the status */
    (void)XIo_In32(BaseAddress + XEM_TSR_OFFSET);

    /*
     * Clear the status now so we're ready again next time
     */
    XIo_Out32(BaseAddress + XEM_ISR_OFFSET, XEM_EIR_XMIT_DONE_MASK);
}


/*****************************************************************************/
/**
*
* Receive a frame. Wait for a frame to arrive.
*
* @param BaseAddress is the base address of the device
* @param FramePtr is a pointer to a word-aligned buffer where the frame will
*        be stored.
*
* @return
*
* The size, in bytes, of the frame received.
*
* @note
*
* None.
*
******************************************************************************/
int XEmac_RecvFrame(Xuint32 BaseAddress, Xuint8 *FramePtr)
{
    int Length;
    int i;
    int WordCount;
    int Remainder;
    Xuint32 *WordBuffer = (Xuint32 *)FramePtr;

    /*
     * Wait for a frame to arrive
     */
    while (XEmac_mIsRxEmpty(BaseAddress));

    /*
     * Get the length of the frame that arrived
     */
    Length = XIo_In32(BaseAddress + XEM_RPLR_OFFSET);

    /*
     * Clear the status now that the length is read so we're ready again
     * next time
     */
    XIo_Out32(BaseAddress + XEM_ISR_OFFSET, XEM_EIR_RECV_DONE_MASK);

    /*
     * Read each word out of the EMAC fifo
     */
    WordCount = Length / sizeof(Xuint32);
    Remainder = Length % sizeof(Xuint32);

    /*
     * Read each full word from the EMAC
     */
    for (i=0; i < WordCount; i++)
    {
        WordBuffer[i] = XIo_In32(BaseAddress + XEM_PFIFO_RXDATA_OFFSET);
    }

    /*
     * If frame was not word-aligned, read the last word and shift correctly
     */
    if (Remainder > 0)
    {
        Xuint32 LastWord;
        Xuint8 *ExtraBytesBuffer = (Xuint8 *)(WordBuffer + WordCount);

        LastWord = XIo_In32(BaseAddress + XEM_PFIFO_RXDATA_OFFSET);

        switch (Remainder)
        {
            case 1:
                ExtraBytesBuffer[0] = (Xuint8)(LastWord >> 24);
                break;

            case 2:
                ExtraBytesBuffer[0] = (Xuint8)(LastWord >> 24);
                ExtraBytesBuffer[1] = (Xuint8)(LastWord >> 16);
                break;

            case 3:
                ExtraBytesBuffer[0] = (Xuint8)(LastWord >> 24);
                ExtraBytesBuffer[1] = (Xuint8)(LastWord >> 16);
                ExtraBytesBuffer[2] = (Xuint8)(LastWord >> 8);
                break;
        }
    }

    return Length;
}

⌨️ 快捷键说明

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