/* init RTL registers*/
WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND)); /* set page0, stop command. command is stop after power up. */
delayms(10); //确保芯片进入停止状态
WriteReg(DCR_WPAGE0, 0xC8); /* DCR: refer to define of DCR in Rtl8019as.h */
WriteReg(RBCRH_WPAGE0,0);
WriteReg(RBCRL_WPAGE0,0);
//使芯片与网络断开
WriteReg(RCR_WPAGE0, 0x20); /* RCR: refer to define of RCR in Rtl8019as.h */
WriteReg(TCR_WPAGE0, 0x02); /* TCR: refer to define of TCR in Rtl8019as.h */
WriteReg(PSTART_WPAGE0, RECEIVE_START_PAGE); /* Pstart */
WriteReg(PSTOP_WPAGE0, RECEIVE_STOP_PAGE); /* Pstop *///0x80也可以使用
WriteReg(BNRY_WPAGE0, RECEIVE_START_PAGE); /* BNRY */
WriteReg(TPSR_WPAGE0, SEND_START_PAGE0); /* TPSR */
WriteReg(ISR_WPAGE0, 0xFF); /* write FF to clear up all interrupt status */
WriteReg(IMR_WPAGE0,0x0);
WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND));
WriteReg(CURR_WPAGE1,RECEIVE_START_PAGE + 1);
/* set phisical address */
WriteReg(PRA0_WPAGE1,LocalMACAddr[0]);
WriteReg(PRA1_WPAGE1,LocalMACAddr[1]);
WriteReg(PRA2_WPAGE1,LocalMACAddr[2]);
WriteReg(PRA3_WPAGE1,LocalMACAddr[3]);
WriteReg(PRA4_WPAGE1,LocalMACAddr[4]);
WriteReg(PRA5_WPAGE1,LocalMACAddr[5]);
/* MAR0 */
WriteReg(0x07, 0xff);
WriteReg(0x08, 0xff);
WriteReg(0x09, 0xff);
WriteReg(0x0a, 0xff);
WriteReg(0x0b, 0xff);
WriteReg(0x0c, 0xff);
WriteReg(0x0d, 0xff);
WriteReg(0x0e, 0xff);
WriteReg(0x0f, 0xff);
WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
WriteReg(RCR_WPAGE0, 0xCC); /* RCR: refer to define of RCR in Rtl8019as.h */
WriteReg(TCR_WPAGE0, 0x00); /* TCR: refer to define of TCR in Rtl8019as.h */
/* transimit start page */
LastSendStartPage = SEND_START_PAGE0;
StartPageOfPacket = RECEIVE_START_PAGE + 1;
/* in the beginning, no packet is in sending */
InSending = FALSE;
/* initial over, start command and receive */
WriteReg(ISR_WPAGE0, 0xFF); /* write FF to clear up all interrupt status */
}
/* read rlt ram data to buffer */
void RTLReadRam(WORD address,WORD size,BYTE DT_XDATA * buff)
{
BYTE DT_XDATA * Endp;
BYTE PrePage; /* store page */
PrePage = ReadReg(CR);
RTLPage(0);
WriteReg(RSARH_WPAGE0,(BYTE)((address> > 8)&0x00ff));
WriteReg(RSARL_WPAGE0,(BYTE)address);
WriteReg(RBCRH_WPAGE0,(BYTE)((size> > 8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(BYTE)size);
WriteReg(CR,(0x00 | CR_REMOTE_READ | CR_START_COMMAND));
for(Endp = buff + size; buff < Endp;)
{
*(buff++) = ReadReg(REMOTE_DMA_PORT);
}
/* complete dma */
WriteReg(RBCRH_WPAGE0,0);
WriteReg(RBCRL_WPAGE0,0);
}
//接收函数
struct SMemHead DT_XDATA * RTLReceivePacket(void) REENTRANT_SIG
{
BYTE curr,bnry,flag;
WORD address;
WORD PacketSize;
struct SMemHead DT_XDATA *MemHead;
/* if send is running don't crrupt RTL register*/
if(InSending == TRUE)
return NULL;
MemHead = NULL;
//让芯片停止工作
WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND));
curr = ReadReg(CURR_RPAGE1);
//检查当前接收地址是否超出范围
if(StartPageOfPacket > = RECEIVE_STOP_PAGE || StartPageOfPacket < RECEIVE_START_PAGE)
{
StartPageOfPacket = curr;
WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
return NULL;
}
if(StartPageOfPacket == curr){
//没数据接收
WriteReg(CR,(CR_PAGE1 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
return NULL;
}
//读取头4个字节
address = ((WORD)StartPageOfPacket) < <8;
RTLReadRam(address,4,Head);
//判断是否是正确的包
if(Head[0] & RSR_RECEIVE_NO_ERROR)
{
//接收数据包的长度
PacketSize = (((WORD)Head[3]) < <8) + Head[2] - 4;
/* allocate buffer and read packet into buffer */
flag=0;
//判断长度是否溢出
if(PacketSize <MAX_PACKET_SIZE+1) flag|=0x01;
//判断下一个包页地址是否正确
if((Head[1] <RECEIVE_STOP_PAGE)&&(Head[1]> RECEIVE_START_PAGE-1))
flag|=0x10;
if(flag==0x11){
//都正确
address += 4;
//接收以太网报文头
RTLReadRam(address, sizeof(struct SEtherHead), (uchar *)&EtherHead);
//只接收IP和ARP协议的报文
if((EtherHead.type==0x0800)||(EtherHead.type==0x0806)){
address+=sizeof(struct SEtherHead);
if((MemHead = MemAllocate(PacketSize)) != NULL)
{
RTLReadRam(address,PacketSize,MemHead-> pStart); /* read from rtl */
}
}
}else{
if(!flag){
Head[1]=curr;
}else{
if(flag==0x01){
//根据包长度计算下一个包所在的页
Head[1]=StartPageOfPacket+Head[3];
if(Head[2]) Head[1]++;
}
}
}
}
else{
Head[1]=curr;
}
//得到下一个包的页地址
StartPageOfPacket = Head[1];
//写入BNRY寄存器
bnry = StartPageOfPacket - 1;
if(bnry < RECEIVE_START_PAGE)
bnry = RECEIVE_STOP_PAGE - 1;
//关闭DMA状态
WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
WriteReg(BNRY_WPAGE0,bnry);
return MemHead;
}