📄 rtl8019.c
字号:
#include "..\GloblDef\GloblDef.h"
//#include "..\uip\uip.h"
//8019MAC地址
//u8_t DT_XDATA ether_addr[6] = {0x52,0x54,0x4c,0x30,0x2e,0x2f};
static u8_t DT_XDATA insending;
static u8_t DT_XDATA startpageofpacket;//包的起始业地址
u8_t DT_XDATA head[10];
/* last trasmit start page */
static u8_t DT_XDATA lastsendstartpage;
/* 读8019寄存器,port是寄存器地址,返回u8_t型
/*u8_t readreg(u16_t port)
{
return *((u8_t xdata *)port);
}*/
#define readreg(port) (*((u8_t DT_XDATA*)port))
/* 写一字节数据到8019的寄存器
/*void writereg(u16_t port,u8_t value)
{
*((u8_t xdata *)port) = value;
}*/
#define writereg(port,value) (*((u8_t DT_XDATA *)port) = value)
// 选8019那一业
// TO DO:set bit 7-6 in CR, CR_TXP must be 0(if 1 the packet is retrasmit)
#define RTLpage(Index) writereg(CR,(readreg(CR) & 0x3B)|(u8_t)(Index << 6))
void set_phisical_address(void);
/* reset rtl8019 and init registers, LocalMacAddr is MAC address */
void RTLdev_init() REENTRANT_MUL
{
//u8_t localMACaddr[6];//存以太网地址
u8_t temp;//,content,content1,content2;
u16_t i;
rtl_reset=0;//8019是高复位
_nop();
_nop();
rtl_reset=1;
/* after hardware reset a longdelay is necessary for rtl to self-initial */
for(i=0; i < RTL_DELAY_AFTER_HARDWARE_RESET; i++);
{
_nop();
_nop();
}
/* reset: write to reset port */
temp = readreg(RESET_PORT);//复位
writereg(RESET_PORT,temp);
/* init RTL registers*/
writereg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND)); /* set page0, stop command. command is stop after power up. */
temp=readreg(CR);
writereg(PSTART_WPAGE0, RECEIVE_START_PAGE); /* 设接收缓冲区Pstart */
writereg(PSTOP_WPAGE0, RECEIVE_STOP_PAGE); /* Pstop */
//调试
RTLpage(2);
//content=readreg(PSTART_WPAGE0);
//content1=readreg(PSTOP_WPAGE0);
RTLpage(0);
//
writereg(BNRY_WPAGE0, RECEIVE_START_PAGE); /* 当前接收缓冲指针BNRY */
//content=readreg(BNRY_WPAGE0);//调试
writereg(TPSR_WPAGE0, SEND_START_PAGE0); /* 发送缓存区TPSR */
writereg(DCR_WPAGE0, 0xC8); /* DCR: refer to define of DCR in Rtl8019as.h */
//writereg(RCR_WPAGE0, 0xCE); /* RCR: refer to define of RCR in Rtl8019as.h */
writereg(RCR_WPAGE0, 0xCE); /* 调试用RCR: DE,地址不同也收,CE地址不同不收 */
writereg(TCR_WPAGE0, 0xE0); /* TCR: refer to define of TCR in Rtl8019as.h */
writereg(IMR_WPAGE0,0); /* RTL recieve interrupt enabled */
writereg(ISR_WPAGE0, 0xFF); /* write FF to clear up all interrupt status */
RTLpage(1);
writereg(CURR_WPAGE1,RECEIVE_START_PAGE + 1);//空接收缓冲指针
/* MAR0 */
writereg(0x08,0x00);
writereg(0x09,0x41);
writereg(0x0a,0x00);
writereg(0x0b,0x80);
writereg(0x0c,0x00);
writereg(0x0d,0x00);
writereg(0x0e,0x00);
writereg(0x0f,0x00);
/* set phisical address */
set_phisical_address();
/* transimit start page */
lastsendstartpage = SEND_START_PAGE0;
startpageofpacket = RECEIVE_START_PAGE + 1;
RTLpage(3);
//content=readreg(CONFIG0_RPAGE3);
//content1=readreg(CONFIG1_RPAGE3);
//content2=readreg(CONFIG2_RPAGE3);
//content=readreg(CONFIG3_RPAGE3);
/* in the beginning, no packet is in sending */
insending = FALSE;
/* initial over, start command and receive */
writereg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
//RTLpage(0);
//content=readreg(CR);
//content1=0;
}
//功能:设置8019的物理地址
//入口:
//
//
//出口无;
void set_phisical_address(void)
{
//u8_t content5;
RTLpage(1);
/* set phisical address */
writereg(PRA0_WPAGE1,uip_ethaddr.addr[0]);//设本设备地址
writereg(PRA1_WPAGE1,uip_ethaddr.addr[1]);
writereg(PRA2_WPAGE1,uip_ethaddr.addr[2]);
writereg(PRA3_WPAGE1,uip_ethaddr.addr[3]);
writereg(PRA4_WPAGE1,uip_ethaddr.addr[4]);
writereg(PRA5_WPAGE1,uip_ethaddr.addr[5]);
/* content5=readreg(PRA0_WPAGE1);
tiao=content5;
content5=readreg(PRA1_WPAGE1);
tiao=content5;
content5=readreg(PRA2_WPAGE1);
tiao=content5;
content5=readreg(PRA3_WPAGE1);
tiao=content5;
content5=readreg(PRA4_WPAGE1);
tiao=content5;
content5=readreg(PRA5_WPAGE1);
tiao=content5;*/
RTLpage(0);
}
//功能:写数据到8019缓存
//入口:address,要写入的地址
// size:长度
// * buff:起始地址
//出口无;
void RTLWriteRam(u16_t address, u16_t size, u8_t * buff) REENTRANT_MUL
{
u8_t *endp;
u8_t prepage; /* store page */
prepage = readreg(CR);
RTLpage(0);
writereg(RSARH_WPAGE0,(u8_t)((address>>8)&0x00ff));//写远DMA地址
writereg(RSARL_WPAGE0,(u8_t)address);
writereg(RBCRH_WPAGE0,(u8_t)((size>>8)&0x00ff));//远DMA计数
writereg(RBCRL_WPAGE0,(u8_t)size);
writereg(CR,(0x00 | CR_REMOTE_WRITE | CR_START_COMMAND));
for(endp = buff + size; buff < endp;)
{
writereg(REMOTE_DMA_PORT,*(buff++));//通过DMA写数据入8019
}
/* complete dma */
writereg(RBCRH_WPAGE0,0);
writereg(RBCRL_WPAGE0,0);
writereg(CR,((prepage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));//停止写
}
//功能:从8019读数据缓冲
//入口:address,要读出的地址
// size:长度
// * buff:写入缓冲起始地址
//出口无;
void RTLReadRam(u16_t address,u16_t size,u8_t * buff) REENTRANT_MUL
{
u8_t * endp;
u8_t prepage; /* store page */
prepage = readreg(CR);
RTLpage(0);
writereg(RSARH_WPAGE0,(u8_t)((address>>8)&0x00ff));
writereg(RSARL_WPAGE0,(u8_t)address);
writereg(RBCRH_WPAGE0,(u8_t)((size>>8)&0x00ff));
writereg(RBCRL_WPAGE0,(u8_t)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);
writereg(CR,((prepage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_START_COMMAND));
writereg(ISR_RPAGE0,0XFF);
}
//功能:通过8019发送一个包数据
//入口:buffer,要发送的包的储存地方
// size:长度
//
//出口 返回是否正确标志;
//注:实际buffer=uip_buf; size=uip_len
u8_bit RTLdev_send() REENTRANT_MUL
{
u8_t startpage;
u8_t prepage;
u16_t i;
/* if send is already running */
if(insending == TRUE)
return FALSE;
else
insending = TRUE;
/* store page */
prepage = readreg(CR);
/* check pakcet size */
if(uip_len < MIN_PACKET_SIZE)
{
uip_len = MIN_PACKET_SIZE;
}
else
{
if(uip_len > MAX_PACKET_SIZE)
uip_len = MAX_PACKET_SIZE;
}
/* write packet to ram */
if(lastsendstartpage == SEND_START_PAGE0)
{
startpage = SEND_START_PAGE1;
lastsendstartpage = SEND_START_PAGE1;
}
else
{
startpage = SEND_START_PAGE0;
lastsendstartpage = SEND_START_PAGE0;
}
if(uip_slen>0)
{
if(send_which_pack==TCP_PACK)
{
for(i=0; i < uip_slen; i++)
{
uip_buf[40 + UIP_LLH_LEN+i] = uip_appdata[i];
}
}
else if(send_which_pack==UDP_PACK)
{
for(i=0; i < uip_slen; i++)
{
//uip_buf[28 + UIP_LLH_LEN+i] = uip_appdata[i];
}
}
}
RTLWriteRam((u16_t)(((u16_t)startpage)<<8),uip_len,uip_buf);
/* wait for last time trasmition to complete */
while((readreg(CR) & CR_TXP) == CR_TXP);
/* write trasmit start page and size */
RTLpage(0);
writereg(TPSR_WPAGE0,startpage); /* TPSR */
writereg(TBCRL_WPAGE0,(u8_t)uip_len);/*low */
writereg(TBCRH_WPAGE0,(u8_t)((uip_len>>8)&0x00ff)); /*high*/
writereg(CR,((prepage&0xC0) | CR_ABORT_COMPLETE_DMA | CR_TXP | CR_START_COMMAND));
insending = FALSE;
return TRUE;
}
//功能:读8019收一个包数据
//入口:无
//
//出口 返回是读到的数据长度;
//注:影响uip_buf uip_len
u16_t RTLdev_read() REENTRANT_MUL
{
u8_t data curr,bnry,content,content1;
u8_t DT_XDATA *s;
u16_t address;
u16_t packetsize=0;
//struct SMemHead DT_XDATA *MemHead;
s=uip_buf;
/* if send is running don't crrupt RTL register*/
if(insending == TRUE)
return 0;
//MemHead = NULL;
RTLpage(1);
curr = readreg(CURR_RPAGE1);
RTLpage(0);
writereg(ISR_RPAGE0,0XFF);//清ISR寄存器
//调试
content=readreg(ISR_RPAGE0);
//content=readreg(BNRY_WPAGE0);
content1=readreg(BNRY_WPAGE0);
/* 检查起始业地址是否因为某种错误而超出地址
check if startpage exceed range becasue of unknow error */
if(startpageofpacket >= RECEIVE_STOP_PAGE || startpageofpacket < RECEIVE_START_PAGE)
{
/* use curr as the startpageofpacket in this case */
startpageofpacket = curr;
return 0;
}
/* 查是否有新的包
check if there is packets to read */
if(startpageofpacket == curr)
return 0;
/*
* read a packet
*/
/* 读包的头信息
read packet head imformation */
address = ((u16_t)startpageofpacket)<<8;
RTLReadRam(address,10,head);
/* packet size, sub 4 bytes, this 4 byte is MAC checksum */
packetsize = ((u16_t)head[3])*256 + head[2] - 4;
/* check rsr, if isn't a good packet no read */
//if(head[0] & RSR_RECEIVE_NO_ERROR)
if((head[0] | RSR_RECEIVE_NO_ERROR)==0||head[1]>(RECEIVE_STOP_PAGE-1)
||head[1]<RECEIVE_START_PAGE||packetsize>1514)//调试用
{//
RTLpage(0);
startpageofpacket=curr;
bnry = startpageofpacket - 1;
if(bnry < RECEIVE_START_PAGE)
bnry = RECEIVE_STOP_PAGE - 1;
writereg(BNRY_WPAGE0,bnry);
return 0;
}
else
{ /* this is a good packet */
address += 4;
//if(startpageofpacket > head[1] && head[1] != RECEIVE_START_PAGE)
//{
//RTLReadRam(address,(u16_t)((((u16_t)RECEIVE_STOP_PAGE)<<8) - address),s); /* read from rtl */
//RTLReadRam((u16_t)(((u16_t)RECEIVE_START_PAGE)<<8),(u16_t)(packetsize - ((((u16_t)RECEIVE_STOP_PAGE)<<8) - address)),
// s + ((((u16_t)RECEIVE_STOP_PAGE)<<8) - address)); /* read from rtl */
//}
//else
//{
RTLReadRam(address,packetsize,s); /* read from rtl */
//}
}
/* get next packet start page */
startpageofpacket = head[1];
/* reset bnry */
bnry = startpageofpacket - 1;
if(bnry < RECEIVE_START_PAGE)
bnry = RECEIVE_STOP_PAGE - 1;
writereg(BNRY_WPAGE0,bnry);
return packetsize;
}
void test_RTL8019(void)
{
u8_t DT_XDATA content[2]={1,2},
content1[2]={0,0},i,j;
//u8_t content3;
RTLpage(3);
i=readreg(CONFIG3_RPAGE3);
RTLWriteRam(0x4100, 2, content);
RTLReadRam(0x4100, 2, content1);
for(i=0;i<2;i++)
{
if(content[i]!=content1[i])
{
j=0;
}
}
}
/*void Start8019()
{
writereg(CR,CR_ABORT_COMPLETE_DMA | CR_START_COMMAND);
}
void Stop8019()
{
writereg(CR,CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND);
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -