📄 xemac_l.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 + -