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

📄 rtl8019.c

📁 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 + -