|
楼主 |
发表于 2010-11-9 18:18:56
|
显示全部楼层
我是一个初学者,感谢楼上的回复
听你的口气,我瞎猜的emac.h\emac.c这两个文件应该猜对了。
周公的例程里,有一个描述网卡硬件的文件,内容是
#define EMAC_RAM_ADDR 0x2007c000
#define EMAC_RAM_SIZE 0x00004000
/* The Ethernet RAM is configured as below, the starting of EMAC_DESCRIPTOR_ADDR depends
on the EMAC_DESCRIPTOR_COUNT or the TOTAL_DESCRIPTOR_SIZE, at this point, the
EMAC_DESCRIPTOR_COUNT for both TX and RX is set to 16:
EMAC_RAM_ADDR 0x2007c000
.
.
.
EMAC_DMA_END EMAC_RAM_ADDR + EMAC_RAM_SIZE - TOTAL_DESCRIPTOR_SIZE
TX_DESCRIPTOR_ADDR = EMAC_DESCRIPTOR_ADDR = EMAC_RAM_END(EMAC_RAM_ADDR+EMAC_RAM_SIZE) - TOTAL_DESCRIPTOR
TX_STATUS_ADDR = TX_DESCRIPTOR_ADDR + TX_DESCRIPTOR_SIZE
RX_DESCRIPTOR_ADDR = TX_DESCRIPTOR_ADDR + TX_DESCRIPTOR_SIZE + TX_STATUS_SIZE
RX_STATUS_ADDR = RX_DESCRIPTOR_ADDR + RX_STATUS_SIZE
( RX_STATUS_ADDR + RX_STATUS_SIZE = EMAC_RAM_END )!!!!!
EMAX_RAM_END 0x7FE04000
Please note that, the descriptors have to be aligned to the 32 bit boundary!!!
Below descriptor addresses have been carefully aligned to the 32-bit boundary.
If not, the descriptors have to be re-aligned!!!
*/
#define EMAC_TX_DESCRIPTOR_COUNT 0x0004
#define EMAC_RX_DESCRIPTOR_COUNT 0x0004
#define TX_DESCRIPTOR_SIZE (EMAC_TX_DESCRIPTOR_COUNT * 8)
#define RX_DESCRIPTOR_SIZE (EMAC_RX_DESCRIPTOR_COUNT * 8)
#define TX_STATUS_SIZE (EMAC_TX_DESCRIPTOR_COUNT * 4)
#define RX_STATUS_SIZE (EMAC_RX_DESCRIPTOR_COUNT * 8)
#define TOTAL_DESCRIPTOR_SIZE (TX_DESCRIPTOR_SIZE + RX_DESCRIPTOR_SIZE + TX_STATUS_SIZE + RX_STATUS_SIZE)
#define EMAC_DESCRIPTOR_ADDR (EMAC_RAM_ADDR + EMAC_RAM_SIZE - TOTAL_DESCRIPTOR_SIZE)
#define TX_DESCRIPTOR_ADDR EMAC_DESCRIPTOR_ADDR
#define TX_STATUS_ADDR (EMAC_DESCRIPTOR_ADDR + TX_DESCRIPTOR_SIZE)
#define RX_DESCRIPTOR_ADDR (TX_STATUS_ADDR + TX_STATUS_SIZE)
#define RX_STATUS_ADDR (RX_DESCRIPTOR_ADDR + RX_DESCRIPTOR_SIZE)
#define EMAC_DMA_ADDR EMAC_RAM_ADDR
#define EMAC_BLOCK_SIZE 0x600
#define EMAC_TX_BLOCK_NUM 4
#define EMAC_RX_BLOCK_NUM 4
#define TOTAL_EMAC_BLOCK_NUM 8
#define EMAC_BUFFER_SIZE (EMAC_BLOCK_SIZE * (EMAC_TX_BLOCK_NUM + EMAC_RX_BLOCK_NUM ))
#define EMAC_TX_BUFFER_ADDR EMAC_RAM_ADDR
#define EMAC_RX_BUFFER_ADDR (EMAC_RAM_ADDR + EMAC_BLOCK_SIZE * EMAC_TX_BLOCK_NUM)
/* EMAC Descriptor TX and RX Control fields */
#define EMAC_TX_DESC_INT 0x80000000
#define EMAC_TX_DESC_LAST 0x40000000
#define EMAC_TX_DESC_CRC 0x20000000
#define EMAC_TX_DESC_PAD 0x10000000
#define EMAC_TX_DESC_HUGE 0x08000000
#define EMAC_TX_DESC_OVERRIDE 0x04000000
#define EMAC_RX_DESC_INT 0x80000000
/* EMAC Descriptor status related definition */
#define TX_DESC_STATUS_ERR 0x80000000
#define TX_DESC_STATUS_NODESC 0x40000000
#define TX_DESC_STATUS_UNDERRUN 0x20000000
#define TX_DESC_STATUS_LCOL 0x10000000
#define TX_DESC_STATUS_ECOL 0x08000000
#define TX_DESC_STATUS_EDEFER 0x04000000
#define TX_DESC_STATUS_DEFER 0x02000000
#define TX_DESC_STATUS_COLCNT 0x01E00000/* four bits, it's a mask, not exact count */
#define RX_DESC_STATUS_ERR 0x80000000
#define RX_DESC_STATUS_LAST 0x40000000
#define RX_DESC_STATUS_NODESC 0x20000000
#define RX_DESC_STATUS_OVERRUN 0x10000000
#define RX_DESC_STATUS_ALGNERR 0x08000000
#define RX_DESC_STATUS_RNGERR 0x04000000
#define RX_DESC_STATUS_LENERR 0x02000000
#define RX_DESC_STATUS_SYMERR 0x01000000
#define RX_DESC_STATUS_CRCERR 0x00800000
#define RX_DESC_STATUS_BCAST 0x00400000
#define RX_DESC_STATUS_MCAST 0x00200000
#define RX_DESC_STATUS_FAILFLT 0x00100000
#define RX_DESC_STATUS_VLAN 0x00080000
#define RX_DESC_STATUS_CTLFRAM 0x00040000
#define DESC_SIZE_MASK 0x000007FF/* 11 bits for both TX and RX */
/* EMAC interrupt controller related definition */
#define EMAC_INT_RXOVERRUN 0x01 << 0
#define EMAC_INT_RXERROR 0x01 << 1
#define EMAC_INT_RXFINISHED 0x01 << 2
#define EMAC_INT_RXDONE 0x01 << 3
#define EMAC_INT_TXUNDERRUN 0x01 << 4
#define EMAC_INT_TXERROR 0x01 << 5
#define EMAC_INT_TXFINISHED 0x01 << 6
#define EMAC_INT_TXDONE 0x01 << 7
#define EMAC_INT_SOFTINT 0x01 << 12
#define EMAC_INT_WOL 0x01 << 13
还有一个应该是跟PHY有关的文件
#define HARDWARE_GLOBALS
#include "../../../config.h"
#include "../include/cfg_net.h"
#include "LPC1700_ADD_R.h"
union REC_BUFF_UNION REC_BUFF[MAX_REC_BUFF];
/* EMAC MODULE ID */
#define PHILIPS_EMAC_MODULE_ID ((0x3902 << 16) | 0x2000)
INT32U tempreg1,tempreg;
INT16U PHYREG[80];
INT16U PHYID;
INT16U EINTSTA;
INT8U LINKSTATUS;
volatile INT32U RXOverrunCount = 0;
volatile INT32U RXErrorCount = 0;
volatile INT32U TXUnderrunCount = 0;
volatile INT32U TXErrorCount = 0;
volatile INT32U RxFinishedCount = 0;
volatile INT32U TxFinishedCount = 0;
volatile INT32U TxDoneCount = 0;
volatile INT32U RxDoneCount = 0;
volatile INT32U CurrentRxPtr = EMAC_RX_BUFFER_ADDR;
volatile INT32U ReceiveLength = 0;
volatile INT32U PacketReceived = FALSE;
INT16U EthernetPHYRead(INT8U paddr,INT8U raddr)
{
INT16U temp16;
MAC_MCMD = 1; //enable read
MAC_MADR = ((paddr&0X1F) <<8 ) + (raddr&0X1F);
while(MAC_MIND & 0X01);
MAC_MCMD = 0;
temp16 = MAC_MRDD;
return temp16;
}
/******************************************************************************
** Function name: EMAC_TxEnable/EMAC_TxDisable
**
** Descriptions: EMAC TX API modules
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void EMAC_TxEnable( void )
{
MAC_COMMAND |= 0x02;
return;
}
void EMAC_TxDisable( void )
{
MAC_COMMAND &= ~0x02;
return;
}
/******************************************************************************
** Function name: EMAC_RxEnable/EMAC_RxDisable
**
** Descriptions: EMAC RX API modules
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void EMAC_RxEnable( void )
{
MAC_COMMAND |= 0x01;
MAC_MAC1 |= 0x01;
return;
}
void EMAC_RxDisable( void )
{
MAC_COMMAND &= ~0x01;
MAC_MAC1 &= ~0x01;
return;
}
void WritePHY( INT32U PHYReg, INT32U PHYData )
{
MAC_MCMD = 0x0000; /* write command */
MAC_MADR = 0X0300 | PHYReg; /* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */
MAC_MWTD = PHYData;
while ( MAC_MIND != 0 );
return;
}
void Write_PHY (INT16U phyadd,int PhyReg, int Value)
{
unsigned int tout;
MAC_MADR = (phyadd<<8) | PhyReg;
MAC_MWTD = Value;
/* Wait utill operation completed */
tout = 0;
for (tout = 0; tout < 50000; tout++) {
if ((MAC_MIND & 1) == 0) {
break;
}
}
}
/*****************************************************************************
** Function name: ReadPHY
**
** Descriptions: Read data from the PHY port
**
** parameters: PHY register
** Returned value: PHY data
**
*****************************************************************************/
INT32U ReadPHY( INT16U phyadd,INT32U PHYReg )
{
INT32U i32;
MAC_MCMD = 0x0001; /* read command */
i32 = (phyadd<<8) | PHYReg; /* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */
MAC_MADR = i32;
while ( MAC_MIND != 0 );
MAC_MCMD = 0x0000;
return( MAC_MRDD );
}
unsigned short Read_PHY ( INT16U phyadd ,unsigned char PhyReg)
{
unsigned int tout;
MAC_MADR = (phyadd<<8) | PhyReg;
MAC_MCMD = 1;
/* Wait until operation completed */
for (tout = 0; tout < 50000; tout++) {
if ((MAC_MIND & 1) == 0) {
break;
}
}
MAC_MCMD = 0;
return (MAC_MRDD);
}
/*****************************************************************************
** Function name: EMACTxDesciptorInit
**
** Descriptions: initialize EMAC TX descriptor table
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void EMACTxDescriptorInit( void )
{
INT32U i;
INT32U *tx_desc_addr, *tx_status_addr;
/*-----------------------------------------------------------------------------
* setup the Tx status,descriptor registers --
* Note, the actual tx packet data is loaded into the ahb2_sram16k memory as part
* of the simulation
*----------------------------------------------------------------------------*/
MAC_TXDESCRIPTOR = TX_DESCRIPTOR_ADDR; /* Base addr of tx descriptor array */
MAC_TXSTATUS = TX_STATUS_ADDR; /* Base addr of tx status */
MAC_TXDESCRIPTORNUM = EMAC_TX_DESCRIPTOR_COUNT - 1; /* number of tx descriptors, 16
*/
for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
{
tx_desc_addr = (INT32U *)(TX_DESCRIPTOR_ADDR + i * 8); /* two words at
a time, packet and control */
*tx_desc_addr = (INT32U)(EMAC_TX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
*(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE - 1));
/* set size only */
}
for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
{
tx_status_addr = (INT32U *)(TX_STATUS_ADDR + i * 4); /* TX status,
one word only, status info. */
*tx_status_addr = (INT32U)0; /* initially, set status info to
0 */
}
MAC_TXPRODUCEINDEX = 0x0; /* TX descriptors point to zero */
return;
}
/*****************************************************************************
** Function name: EMACRxDesciptorInit
**
** Descriptions: initialize EMAC RX descriptor table
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void EMACRxDescriptorInit( void )
{
INT32U i;
INT32U *rx_desc_addr, *rx_status_addr;
/*-----------------------------------------------------------------------------
* setup the Rx status,descriptor registers --
* Note, the actual rx packet data is loaded into the ahb2_sram16k memory as part
* of the simulation
*----------------------------------------------------------------------------*/
MAC_RXDESCRIPTOR = RX_DESCRIPTOR_ADDR; /* Base addr of rx descriptor array */
MAC_RXSTATUS = RX_STATUS_ADDR; /* Base addr of rx status */
MAC_RXDESCRIPTORNUM = EMAC_RX_DESCRIPTOR_COUNT - 1; /* number of rx descriptors, 16
*/
for ( i = 0; i < EMAC_RX_DESCRIPTOR_COUNT; i++ )
{
/* two words at a time, packet and control */
rx_desc_addr = (INT32U *)(RX_DESCRIPTOR_ADDR + i * 8);
*rx_desc_addr = (INT32U)(EMAC_RX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
*(rx_desc_addr+1) = (INT32U)(EMAC_RX_DESC_INT | (EMAC_BLOCK_SIZE - 1));
/* set size only */
}
for ( i = 0; i < EMAC_RX_DESCRIPTOR_COUNT; i++ )
{
/* RX status, two words, status info. and status hash CRC. */
rx_status_addr = (INT32U *)(RX_STATUS_ADDR + i * 8);
*rx_status_addr = (INT32U)0; /* initially, set both status info and
hash CRC to 0 */
*(rx_status_addr+1) = (INT32U)0;
}
MAC_RXCONSUMEINDEX = 0x0; /* RX descriptor points to zero */
return;
}
/**********************************************************************
**函数原型: void SetMacID()
**入口参数: *mac_ptr
**出口参数: 无
**返 回 值: 无
**说 明: 设置芯片物理地址,物理地址已经存储在程序空间内
************************************************************************/
void SetMacID(INT8U * mac_ptr)
{
MAC_SA0 = mac_ptr[0]*256+mac_ptr[1];
MAC_SA1 = mac_ptr[2]*256+mac_ptr[3];
MAC_SA2 = mac_ptr[4]*256+mac_ptr[5];
//把MAC地址写入MY——MAC——ID中
}
INT32U EMACSend( INT32U *EMACBuf, INT32U length )
{
INT32U *tx_desc_addr;
INT32U TxProduceIndex;
INT32U TxConsumeIndex;
INT32U i, templen;
TxProduceIndex = MAC_TXPRODUCEINDEX;
TxConsumeIndex = MAC_TXCONSUMEINDEX;
if ( TxConsumeIndex != TxProduceIndex )
{
return ( FALSE );
}
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
/* reach the limit, that probably should never happen */
/* To be tested */
MAC_TXPRODUCEINDEX = 0;
}
if ( length > EMAC_BLOCK_SIZE )
{
templen = length;
for ( i = 0; (INT32U)(length/EMAC_BLOCK_SIZE) + 1; i++ )
{
templen = length - EMAC_BLOCK_SIZE;
/* two words at a time, packet and control */
tx_desc_addr = (INT32U *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
/* descriptor status needs to be checked first */
if ( templen % EMAC_BLOCK_SIZE )
{
/* full block */
*tx_desc_addr = (INT32U)(EMACBuf + i * EMAC_BLOCK_SIZE);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT |
(EMAC_BLOCK_SIZE - 1));
TxProduceIndex++;
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex; /* transmit now
*/
}
else
{
/* last fragment */
*tx_desc_addr = (INT32U)(EMACBuf + i * EMAC_BLOCK_SIZE);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT |
EMAC_TX_DESC_LAST | (templen -1) );
TxProduceIndex++; /* transmit now */
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex; /* transmit now
*/
break;
}
}
}
else
{
tx_desc_addr = (INT32U *)(TX_DESCRIPTOR_ADDR + TxProduceIndex * 8);
/* descriptor status needs to be checked first */
*tx_desc_addr = (INT32U)(EMACBuf);
/* set TX descriptor control field */
*(tx_desc_addr+1) = (INT32U)(EMAC_TX_DESC_INT | EMAC_TX_DESC_LAST |
EMAC_TX_DESC_PAD| (length -1));
TxProduceIndex++; /* transmit now */
if ( TxProduceIndex == EMAC_TX_DESCRIPTOR_COUNT )
{
TxProduceIndex = 0;
}
MAC_TXPRODUCEINDEX = TxProduceIndex;
}
return ( TRUE );
}
/**********************************************************************
**函数原型: void Send_Packet(struct _pkst *TxdData)
**入口参数: struct _pkst *TxdData :指向要发送数据的结构指针
**
**出口参数: 无
**返 回 值: 无
**说 明: 发送数据包,以太网底层驱动程序,所有的数据发送都要通过该程序
************************************************************************/
void Send_Packet(struct _pkst *TxdData)//
{
struct _pkst *ExPtr;//
INT8U *TEPTR;
INT8U *rxptr;
INT16U ii,length=0,jj;
INT32U intstat;
length=length+TxdData->length;
ExPtr=TxdData->STPTR;
while(ExPtr!=NULL)//计算出要发送的数据的总长度
{
length=length+ExPtr->length;
ExPtr=ExPtr->STPTR;
}
ii=length;
rxptr = (INT8U *)EMAC_TX_BUFFER_ADDR;
TEPTR=TxdData->DAPTR;
for(ii=0;ii<TxdData->length;ii++)
{
*rxptr = *TEPTR;
rxptr++;
TEPTR++;
}
ExPtr=TxdData->STPTR;
while(ExPtr!=NULL)
{
TEPTR=ExPtr->DAPTR;
for(ii=0;ii<ExPtr->length;ii++)
{
*rxptr = *TEPTR;
rxptr++;
TEPTR++;
}
ExPtr=ExPtr->STPTR;
}
//如果少于60
ii=length;
if(length<60)
{
//如果数据长度<60字节,设置长度为60字节
ii=60;
}
rxptr = (INT8U *)EMAC_TX_BUFFER_ADDR;
EMACSend((INT32U *)rxptr,ii);
/***************************************/
//重发数据的处理
for(length=0;length<6;length++) //最多重发6次
{
for(jj=0;jj<1000;jj++)
{//检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃
intstat = MAC_INTSTATUS;
intstat |= EINTSTA;
if ( intstat & EMAC_INT_TXDONE )
{
TxDoneCount++;
break;
}
}
if(intstat & EMAC_INT_TXDONE)//表示发送成功,判断发送状态寄存器TSR,决定
是否出错
{
MAC_INTCLEAR = 0x0f;//EMAC_INT_TXDONE;
EINTSTA &= 0xf0;
break;
}
EMACSend((INT32U *)rxptr,ii); //to sendpacket;
}
/**************************************/
//OS_EXIT_CRITICAL();
}
INT32U EMACReceiveFractions( INT32U StartIndex, INT32U EndIndex, INT32U * dataptr32 )
{
INT32U i, RxLength = 0;
INT32U RxSize;
INT32U *rx_status_addr,*rx_desc_addr,*rx_data_addr;
for ( i = StartIndex; i < EndIndex; i++ )
{
/* Get RX status, two words, status info. and status hash CRC. */
rx_status_addr = (INT32U *)(RX_STATUS_ADDR + StartIndex * 8);
rx_desc_addr = (INT32U *)(RX_DESCRIPTOR_ADDR + StartIndex * 8);
rx_data_addr = (INT32U *)(*rx_desc_addr);
RxSize = (*rx_status_addr & DESC_SIZE_MASK) - 1;
for(i=0;i<(RxSize+3)/4;i++)
dataptr32=*rx_data_addr++;
/* two words at a time, packet and control */
CurrentRxPtr += EMAC_BLOCK_SIZE;
StartIndex++;
/* last fragment of a frame */
if ( *rx_status_addr & RX_DESC_STATUS_LAST )
{
/* set INT bit and RX packet size */
MAC_RXCONSUMEINDEX = StartIndex;
RxLength += RxSize;
break;
}
else /* In the middle of the frame, the RxSize should be
EMAC_BLOCK_SIZE */
/* In the emac.h, the EMAC_BLOCK_SIZE has been set to
the largest
ethernet packet length to simplify the process, so, it
should not
come here in any case to deal with fragmentation.
Otherwise,
fragmentation and repacking will be needed. */
{
/* set INT bit and maximum block size */
MAC_RXCONSUMEINDEX = StartIndex;
/* wait until the whole block is received, size is EMAC_BLOCK_SIZE. */
while ( (*rx_status_addr & DESC_SIZE_MASK) != (EMAC_BLOCK_SIZE - 1));
RxLength += RxSize;
}
}
return( RxLength );
}
/******************************************************************************
** Function name: EMACHandler
**
** Descriptions: EMAC interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void InitNic(INT8U num);
void EMACHandler (INT32U IntStatus)
{
//IENABLE; /* handles nested interrupt */
IntStatus = MAC_INTSTATUS;
IntStatus |= EINTSTA;
if ( IntStatus != 0 ) /* At least one interrupt */
{
if ( IntStatus & EMAC_INT_RXOVERRUN )
{
MAC_INTCLEAR = EMAC_INT_RXOVERRUN;
RXOverrunCount++;
//InitNic(0);
EMACRxDescriptorInit();
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_RXERROR )
{
MAC_INTCLEAR = EMAC_INT_RXERROR;
RXErrorCount++;
//InitNic(0);
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_RXFINISHED )
{
MAC_INTCLEAR = EMAC_INT_RXFINISHED;
RxFinishedCount++;
/* Below should never happen or RX is seriously wrong */
//while ( MAC_RXPRODUCEINDEX != (MAC_RXCONSUMEINDEX - 1) );
}
if ( IntStatus & EMAC_INT_TXUNDERRUN )
{
MAC_INTCLEAR = EMAC_INT_TXUNDERRUN;
TXUnderrunCount++;
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_TXERROR )
{
MAC_INTCLEAR = EMAC_INT_TXERROR;
TXErrorCount++;
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( IntStatus & EMAC_INT_TXFINISHED )
{
MAC_INTCLEAR = EMAC_INT_TXFINISHED;
TxFinishedCount++;
}
EINTSTA &= 0x88;
}
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
/**********************************************************************
**函数原型: unsigned char * Rec_Packet()
**入口参数:?无
**出口参数: 返回数据指针 unsigned char *
**返 回 值: NULL 没有新数据包
** unsigned char * 接收到新数据包
**说 明: 查询是否有新数据包并接收进缓冲区
************************************************************************/
INT8U Rec_Packet()
{
static INT8U REC_BUFF_NUM=0;
INT32U * REC_BUFF_PTR_DWORDS;
INT8U * REC_BUFF_PTR_BYTES;
INT32U RxProduceIndex, RxConsumeIndex;
INT32U RxLength = 0;
INT32U Counter = 0;
INT32U IntStatus;
INT16U templink;
templink = Read_PHY(PHYID ,1 );
if( (templink & 0x0004) ==0 )
{
LINKSTATUS = 0;
OSTimeDly(4);
templink = Read_PHY(PHYID ,1 );
if( templink & 0x0004 )
{
InitNic(0);
}
return 0;
}
if(LINKSTATUS == 0)
InitNic(0);
OS_ENTER_CRITICAL();
rea1:
IntStatus = MAC_INTSTATUS;
IntStatus |= EINTSTA;
if ( IntStatus & EMAC_INT_RXDONE )
{
MAC_INTCLEAR = EMAC_INT_RXDONE;
EINTSTA &= (~EMAC_INT_RXDONE);
RxDoneCount++;
}
else
{
EMACHandler(IntStatus);
OS_EXIT_CRITICAL();
return 0;
}
RxProduceIndex = MAC_RXPRODUCEINDEX;
RxConsumeIndex = MAC_RXCONSUMEINDEX;
if ( RxProduceIndex == EMAC_RX_DESCRIPTOR_COUNT )
{
/* reach the limit, that probably should never happen */
//MAC_RXPRODUCEINDEX = 0;
CurrentRxPtr = EMAC_RX_BUFFER_ADDR;
}
//此时表示有新的数据包在缓冲区里
/* a packet has arrived. */
if ( RxProduceIndex != RxConsumeIndex )
{ //在任何操作都最好返回page0
if(REC_BUFF_NUM==MAX_REC_BUFF)//接收缓冲区号清零
{
REC_BUFF_NUM=0;
}
REC_BUFF_PTR_DWORDS=REC_BUFF[REC_BUFF_NUM].Dwords;//设定接收缓冲区的起始
地址
//=======================================
if ( RxProduceIndex < RxConsumeIndex ) /* Wrapped around already *///翻
转了
{
/* take care of unwrapped, RxConsumeIndex to EMAC_RX_DESCERIPTOR_COUNT
*/
RxLength += EMACReceiveFractions( RxConsumeIndex,
EMAC_RX_DESCRIPTOR_COUNT, REC_BUFF_PTR_DWORDS );
Counter++;
PacketReceived = TRUE;
/* then take care of wrapped, 0 to RxProduceIndex */
if ( RxProduceIndex > 0 )
{
RxLength += EMACReceiveFractions( 0, RxProduceIndex,
REC_BUFF_PTR_DWORDS );
Counter++;
}
}
else /* Normal process *///正常顺序
{
RxLength += EMACReceiveFractions( RxConsumeIndex, RxProduceIndex,
REC_BUFF_PTR_DWORDS );
Counter++;
}
REC_BUFF_PTR_BYTES = REC_BUFF[REC_BUFF_NUM].bytes;
#ifdef Little_End
if((((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0008)//可以减少对
数据缓冲取的利用
||(((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0608))//不
过如果缓冲区足够大就最好不要
#endif
#ifdef Big_End
if((((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0800)//可以减少对
数据缓冲取的利用
||(((ipethernet*)REC_BUFF_PTR_BYTES)->NextProtocal==0x0806))//不
过如果缓冲区足够大就最好不要
#endif
{
REC_BUFF_NUM++;
OS_EXIT_CRITICAL();
Rec_Ethernet_Packed(REC_BUFF_PTR_BYTES,0);
OS_ENTER_CRITICAL();
goto rea1;
//可以直接退出。
}
else
goto rea1;
}//end of if(bnry!=curr)
OS_EXIT_CRITICAL();
return(0);
}
INT32U intcnt;
void Ethernet_Exception(void)
{
extern OS_EVENT *RecPackedFlag;
OS_ENTER_CRITICAL();
OSIntEnter();
OSSemPost(RecPackedFlag);
EINTSTA |= MAC_INTSTATUS;
MAC_INTCLEAR = 0XFF;
intcnt++;
OSIntExit();
OS_EXIT_CRITICAL();
}
/**********************************************************************
**函数原型: void InitNic()
**入口参数:?无
**出口参数: 无
**返 回 值:?无
**说 明:?对芯片的工作寄存器进行设置,各个寄存器的用法可参考文档和
** 络芯片的数据手册
************************************************************************/
INT16U dulxp,speed;
void InitNic(INT8U num)
{
INT32U i;
PCONP |= 0X40000000;
/* Set the PIN to RMII */
// PINSEL2 &= 0x0fc0ccf0;
//PINSEL2 |= 0X50151105; //PINSEL2 = 0x50151105; /* selects P1
[0,1,4,8,9,10,14,15] */
//PINSEL3 &= 0xfffffff0;
//PINSEL3 |= 0X00000005; //PINSEL3 = 0x00000005; /* selects P1[17:16] */
// i = rMAC_MODULEID;
// if(i == OLD_EMAC_MODULE_ID)
PINSEL2 |= (1)|(1<<2)|(1<<8)|(1<<16)|(1<<18)|(1<<20)|(1<<28)|(1<<30); /*
selects P1[0,1,4,8,9,10,14,15] */
// else
//PINSEL2 |= (1)|(1<<2)|(1<<8)|(1<<16)|(1<<18)|(1<<20)|(1<<28)|(1<<30);
PINSEL3 |= 0x00000005; /* selects P1[17:16] */
/* reset : soft,simulation,mcs/rx,rx,mcs/tx,tx */
MAC_MAC1 = 0xCF00; /* [15],[14],[11:8] -> soft resets all MAC internal modules */
/* RegReset,TxReset,RxReset */
MAC_COMMAND = 0x0038; /* reset all datapaths and host registers */
for ( i = 0; i < 0x40; i++ ); /* short delay after reset */
MAC_MAC1 = 0x0; /* deassert all of the above soft resets in MAC1 */
EMAC_TxDisable();
EMAC_RxDisable();
MAC_MAC2 = 0x00; /* initialize MAC2 register to default value */
/* Non back to back inter-packet gap */
MAC_IPGR = 0x0012; /* use the default value recommended in the users manual */
MAC_CLRT = 0x370F; /* Use the default value in the users manual */
MAC_MAXF = 0x0600; /* Use the default value in the users manual */
/* PHY Select RMII */
///rECOMMAND |= (1<<9);
/* Initial MII Mgmt */
// rMCFG |= (7<<2) + 1; //clk div 28,address increment
//MAC_MCFG = 0x801d;
//MAC_MCFG |= 0x0019; /* host clock divided by 20, no suppress preamble, no
scan increment */
MAC_MCFG |= 0x0018;
/* RMII configuration */
//MAC_COMMAND |= 0x0200;
MAC_COMMAND = 0x0240;
//MAC_SUPP = 0x0900; /* RMII setting, PHY support: [8]=0 ->10 Mbps mode, =1
-> 100 Mbps mode */
/* (note bit 4 was set in original test, although spec says its unused) */
//for ( i = 0; i < 0x20; i++ ); /* short delay */
//MAC_SUPP = 0x0100;
MAC_SUPP = 0x0000;
// probe phy address
for(i=0;i<32;i++)
{
PHYID = Read_PHY(i , 2 );
if(PHYID == 0X0022)
break;
}
if(i >= 32)
while(1);
PHYID = i;
/// PHY RESET
Write_PHY(PHYID, 0, 0x9200 );
do
{
OSTimeDly(OS_TICKS_PER_SEC);
tempreg = Read_PHY(PHYID, 0x1f );
if(tempreg&0x001c)
break;
}while(1);
OSTimeDly(OS_TICKS_PER_SEC);
tempreg = Read_PHY(PHYID, 0x1f );
//for(i=0;i<32;i++)
// PHYREG = Read_PHY(PHYID ,i );
tempreg &= 0x001c;
/* INPUT MAC ADDRESS */
SetMacID(NetPort[num].My_Mac);
if(tempreg == 0x0018)//100fdx
{
dulxp = 1;
speed = 100;
MAC_MAC2 = 0x31; /* half duplex, CRC and PAD enabled. */
MAC_SUPP |= 0x0100; /* RMII Support Reg. speed is set to
100M */
MAC_COMMAND |= 0x0640;
/* back to back int-packet gap */
MAC_IPGT = 0x0015; /* IPG setting in half duplex mode */
}
else if(tempreg == 0x0008)//100hdx
{
dulxp = 0;
speed = 100;
MAC_MAC2 = 0x30; /* full duplex, CRC and PAD enabled. */
MAC_SUPP |= 0x0100; /* RMII Support Reg. speed is set to
100M */
MAC_COMMAND |= 0x0240;
/* back to back int-packet gap */
MAC_IPGT = 0x0012; /* IPG setting in full duplex mode */
}
else if(tempreg == 0x0014)//10fdx
{
dulxp = 1;
speed = 10;
MAC_MAC2 = 0x31; /* full duplex, CRC and PAD enabled. */
MAC_SUPP = 0; /* RMII Support Reg. speed is set to 10M */
MAC_COMMAND |= 0x0640;
/* back to back int-packet gap */
MAC_IPGT = 0x0015; /* IPG setting in full duplex mode */
}
else if(tempreg == 0x0004)//10hdx
{
dulxp = 0;
speed = 10;
MAC_MAC2 = 0x30; /* half duplex, CRC and PAD enabled. */
MAC_SUPP = 0; /* RMII Support Reg. speed is set to 10M */
MAC_COMMAND |= 0x0240;
/* back to back int-packet gap */
MAC_IPGT = 0x0012; /* IPG setting in half duplex mode */
}
EMACTxDescriptorInit();
EMACRxDescriptorInit();
MAC_MAC1 |= 0x0002; /* [1]-Pass All Rx Frame */
/* Set up RX filter, accept broadcast and perfect station */
MAC_RXFILTERCTRL = 0x0022; /* [1]-accept broadcast, [5]accept perfect */
MAC_RXFILTERCTRL |= 0x0005;//MULTICAST_UNICAST
MAC_RXFILTERCTRL |= 0x0018;//ENABLE_HASH
MAC_INTCLEAR = 0xFFFF; /* clear all MAC interrupts */
/* MAC interrupt related register setting */
//if ( install_irq( EMAC_INT, (void *)EMACHandler, HIGHEST_PRIORITY ) == FALSE )
//{
// return (FALSE);
//}
EMAC_RxEnable();
EMAC_TxEnable();
LINKSTATUS = 1;
EINTSTA = 0;
//vicIrqFuncSet(44, 5, (unsigned int)Ethernet_Exception);
zyIsrSet (NVIC_ETHR, (unsigned long)Ethernet_Exception, PRIO_FOUR);
MAC_INTENABLE = 0x000c; /* Enable all interrupts except SOFTINT and WOL */
}
INT16U swap_int16(INT16U temp)
{INT16U temp1;
temp1=(temp&0xff00)>>8;
temp=(temp&0x00ff)<<8;
return(temp+temp1);
}
INT32U swap_int32(INT32U temp)
{
union w temp232,temp132;
temp232.dwords=temp;
temp132.bytes.byte0=temp232.bytes.byte3;
temp132.bytes.byte1=temp232.bytes.byte2;
temp132.bytes.byte2=temp232.bytes.byte1;
temp132.bytes.byte3=temp232.bytes.byte0;
return(temp132.dwords);
}
INT16U Char2ToInt16(INT8U * temp)
{
INT16U temp16;
temp16=((INT16U)(*temp))<<8;
temp++;
temp16=temp16+(INT16U)(*temp);
return(temp16);
}
INT32U Char4ToInt32(INT8U * temp)
{
INT32U temp32;
temp32=((INT32U)(*temp))<<24;
temp++;
temp32=temp32+(((INT32U)(*temp))<<16);
temp++;
temp32=temp32+(((INT32U)(*temp))<<8);
temp++;
temp32=temp32+(INT32U)(*temp);
return(temp32);
}
/**********************************************************************
**函数原型: void int_ex1() interrupt 2
**入口参数:?无
**出口参数: 无
**返 回 值:?无
**说 明:?RTL8019AS中断服务程序
************************************************************************/
/*
void int_ex1() interrupt 2
{
// OS_INT_ENTER();
EX_RAM INT8U i,TEMP;
EX1=0;
iic++;
TEMP=Reg00;
page(0);
i=Reg07;
if((i&&0x10)==0x10)
{
OSSemIntPost(RecBufOverFlowFlag);
}
else if((i&&0x01)==0x01)
OSSemIntPost(RecPackedFlag);
Reg07=0XFF;
Reg00=TEMP;
OSIntExit();
}
INT8U rec_data()
{
INT8U i,TEMP;
TEMP=Reg00;
page(0);
i=Reg07;
Reg07=0XFF;
Reg00=TEMP;
if((i&&0x01)==0x01)
return (0);
return(1);
}
*/ |
|