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

📄 rtl8019.c

📁 利用51单片机对RTL8109进行控制
💻 C
字号:
#ifndef _rtl8019_c
#define _rtl8019_c
#endif

#include "net.h"
#include "struct.h"
#include "fundef.h"
#include "variable.h"

#define reg00   XBYTE[0xc000]
#define reg01   XBYTE[0xc100]
#define reg02   XBYTE[0xc200]
#define reg03   XBYTE[0xc300]
#define reg04   XBYTE[0xc400]
#define reg05   XBYTE[0xc500]
#define reg06   XBYTE[0xc600]
#define reg07   XBYTE[0xc700]
#define reg08   XBYTE[0xc800]
#define reg09   XBYTE[0xc900]
#define reg0a   XBYTE[0xca00]
#define reg0b   XBYTE[0xcb00]
#define reg0c   XBYTE[0xcc00]
#define reg0d   XBYTE[0xcd00]
#define reg0e   XBYTE[0xce00]
#define reg0f   XBYTE[0xcf00]
#define reg10   XBYTE[0xd000]


unsigned char  bnry;
unsigned char  curr;
unsigned char data next_page;
bit txd_buffer_select=0;

void page(unsigned char pagenumber)
{
	unsigned char data temp;
	temp=reg00;//command register
	temp=temp&0x3B ;//注意txp位不能要
	pagenumber=pagenumber <<6;
	temp=temp | pagenumber;
	reg00=temp;
}
/*
void readmynodeid()
{
	unsigned char data i,temp;
	//读出网卡的物理地址存到my_ethernet_address.bytes[6]里
 	page(0);
 	reg09=0;//读取网卡的ram的地址为0x0000
	reg08=0;
	reg0b=0;
	reg0a=12;//读取12个字节
	reg00=0x0a;//读ram
	send_string("\r\nMAC address=");
	for (i=0;i<6;i=i++)
  	{
  		temp=reg10;
    		my_ethernet_address.bytes[i]=temp;
    		send_char(temp);
    		temp=reg10;
   	}
}
*/

void writemynodeid()
{
	page(1);
	reg01=my_ethernet_address.bytes[0];
	reg02=my_ethernet_address.bytes[1];
	reg03=my_ethernet_address.bytes[2];
	reg04=my_ethernet_address.bytes[3];
	reg05=my_ethernet_address.bytes[4];
	reg06=my_ethernet_address.bytes[5];
	page(0);
}

void send_packet(unsigned int length)
{
/*发送一个数据包的命令,长度最小为60字节,最大1514字节
需要发送的数据包要先存放在txdnet缓冲区*/
	uchar i;
	unsigned int ii;

   	page(0);
   	if(length<60)length=60;

    	for(i=0;i<3;i++)
        {
        	txdnet.etherframe.sourcenodeid[i]=my_ethernet_address.words[i];
        }
/*
for(i=0;i<length+4;i++)
{
	send_hex(txdnet.bytes.bytebuf[i]);
}
*/
   	txd_buffer_select=!txd_buffer_select;

  	if(txd_buffer_select)
   	{
   		reg09=0x40 ;//txdwrite highaddress

   	}
   	else{
        	reg09=0x46 ;//txdwrite highaddress
       	}
 	reg08=0x00; //read page address low
  	reg0b=length>>8;//read count high
  	reg0a=length&0xff;//read count low;
  	reg00=0x12;//write dma, page0

   	for(ii=4;ii<length+4;ii++)
   	{
   		reg10=txdnet.bytes.bytebuf[ii];
   	}

   /* 以下3句为中止dma的操作*/
   	reg0b=0x00;//read count high   中止DMA操作
   	reg0a=0x00;//read count low;
   	reg00=0x22;//complete dma page 0

           //==============

 	for(i=0;i<16;i++)//最多重发16次
 	{

        	for(ii=0;ii<1000;ii++)
         	{//检查txp为是否为低
              		if((reg00&0x04)==0)break;
         	}
		if((reg04&0x01)!=0)//表示发送成功
        	{break;}
		reg00=0x3e;
	}

 	reg07=0xff;

 	if(txd_buffer_select)
 	{
  		reg04=0x40;//txd packet start;
  	}
  	else{
      		reg04=0x46;//txd packet start;
        }

	reg06=length>>8;//high byte counter
	reg05=length&0xff;//low byte counter
	reg07=0xff;
	reg00=0x3e;//to sendpacket;
}

void rtl8019as_reset() //复位网卡
{
 	reset=1;
	delay_ms(200);
	reset=0;
	delay_ms(200);
}

void netcard_init()
{
//	unsigned char temp;

	delay_ms(10);
	rtl8019as_reset(); /*复位网卡*/

	reg00=0x21; //使芯片处于停止模式,这时进行寄存器设置
	//停止模式下,将不会发送和接收数据包
	/*write_register为写网卡寄存器函数*/
	delay_ms(10); //延时10毫秒,确保芯片进入停止模式

	page(0);
	reg0a=0x00;
	reg0b=0x00;
	reg0c= 0xe0; //monitor mode (no packet receive)
	reg0d= 0xe2; //loop back mode
	/*使芯片处于mon和loopback模式,跟外部网络断开  */

	reg01=0x4c;
	reg02=0x80;
	reg03=0x4c;
	reg04=0x40;
	reg07=0xff;/*清除所有中断标志位*/
	reg0f=0x00;//disable all interrupt

	reg0e=0xc8; //byte dma 8位dma方式

	//reg0e=0xc9;// word dma  16位dma方式
	page(1);
	reg07=0x4d;
	reg08=0x00;
	reg09=0x00;
	reg0a=0x00;
	reg0b=0x00;
	reg0c=0x00;
	reg0d=0x00;
	reg0e=0x00;
	reg0f=0x00;
	reg00=0x22; //这时让芯片开始工作
	pwdi=!pwdi;
	//readmynodeid();/*读出网卡的物理地址48位  */
	writemynodeid();/*将网卡地址写入到mar寄存器  */
	page(0);
	reg0c=0xcc; //将网卡设置成正常的模式,跟外部网络连接
	reg0d=0xe0;
	reg00=0x22; //这时让芯片开始工作
	reg07=0xff;/*清除所有中断标志位*/
/*	page(3);
	temp=reg06;
	temp=temp | 0x10;
	reg06=temp;
	send_hex(reg06);
	page(2);
	send_string("\r\npage_stop_register=");

send_string("\r\npage_start_register=");
send_hex(reg01);
pwdi=!pwdi;
send_string("\r\ntransmit_page_start_register=");
send_hex(reg04);
send_string("\r\nreceive_config_register=");
send_hex(reg0c);
pwdi=!pwdi;
send_string("\r\ntransmit_config_register=");
send_hex(reg0d);
send_string("\r\ndata_config_register=");
send_hex(reg0e);
pwdi=!pwdi;
	page(1);
	send_string("\r\npar0_register=");
send_hex(reg01);
send_string("\r\npar1_register=");
send_hex(reg02);
pwdi=!pwdi;
send_string("\r\npar2_register=");
send_hex(reg03);
send_string("\r\npar3_register=");
send_hex(reg04);
pwdi=!pwdi;
send_string("\r\npar4_register=");
send_hex(reg05);
send_string("\r\npar5_register=");
send_hex(reg06);
pwdi=!pwdi;

	page(0);

	send_string("\r\ncr_register=");
send_hex(reg00);
send_string("\r\nbnry_register=");
send_hex(reg03);
pwdi=!pwdi;
send_string("\r\nisr_register=");
send_hex(reg07);
temp1=reg0a;
temp2=reg0b;
send_string("\r\nid0_register=");
send_hex(temp1);
pwdi=!pwdi;
send_string("\r\nid1_register=");
send_hex(temp2);
delay_100ms(10);
pwdi=!pwdi;
delay_100ms(10);
pwdi=!pwdi;
delay_100ms(10);
pwdi=!pwdi;
*/
}

uchar check_new_packet()
{
 //如果收到一个有效的数据包,返回1,否则返回0
  	unsigned char i;
  	unsigned int ii;

   	page(0);
   	bnry=reg03;//bnry page have read 读页指针
   	page(1);
   	curr=reg07;//curr writepoint 8019写页指针
   	page(0);
  	if((curr==0))return(0);//读的过程出错
   	next_page=bnry;
   	bnry=bnry++;
   	if(bnry>0x7f)bnry=0x4c;
   	if(bnry!=curr)//此时表示有新的数据包在缓冲区里
	{
	//读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议
	//在任何操作都最好返回page0
		//send_string("have a new packet");
    		page(0);

  		reg09=bnry;//read page address high
 		reg08=0x00; //read page address low
  		reg0b=0x00;//read count high
  		reg0a=18;//read count low;
  		reg00=0x0a;//read dma
  		for(i=0;i<18;i++)
   		{
   			rxdnet.bytes.bytebuf[i]=reg10;
   		}
   		/* 以下3句为中止dma的操作,可以不要            */
   		reg0b=0x00;//read count high   中止DMA操作
   		reg0a=0x00;//read count low;
   		reg00=0x22;//complete dma page 0

            	i=rxdnet.bytes.bytebuf[3];
		rxdnet.bytes.bytebuf[3]=rxdnet.bytes.bytebuf[2];
		rxdnet.bytes.bytebuf[2]=i;
			/*将长度字段的高低字节掉转        */
		rxdnet.etherframe.length=rxdnet.etherframe.length-4;//去掉4个字节的CRC

       		//表示读入的数据包有效
  		if(((rxdnet.bytes.bytebuf[0]&0x01)==0)||(rxdnet.bytes.bytebuf[1]>0x7f)||(rxdnet.bytes.bytebuf[1]<0x4c)||(rxdnet.bytes.bytebuf[2]>0x06))
		{//next_page_start错误或者长度错误,或者接收状态错误,将丢弃所有数据包
		//	send_string("error packet");
			page(1);
			curr=reg07; //page1
			page(0);//切换回page0
        		bnry = curr -1;
        		if(bnry < 0x4c) bnry =0x7f;
        		reg03=bnry; //write to bnry
		//===================下面这句清除中断状态可以不用
        		reg07=0xff;
			return(0);
		}
		else
		{//表示数据包是完好的.读取剩下的数据
			//============
		//	send_string("ok packet");
			if((rxdnet.etherframe.protocal==0x0800)||(rxdnet.etherframe.protocal==0x0806) ||(rxdnet.etherframe.protocal==0x0805))
			{ //协议为IP或ARP才接收

            			reg09=bnry;//read page address high
          	 		reg08=4; //read page address low
            			reg0b=rxdnet.etherframe.length>>8;//read count high
            			reg0a=rxdnet.etherframe.length&0xff;//read count low;
            			reg00=0x0a;//read dma
                		for(ii=4;ii<rxdnet.etherframe.length+4;ii++)
                	 	{
                			rxdnet.bytes.bytebuf[ii]=reg10;
                 		}

               			reg0b=0x00;//read count high
	               		reg0a=0x00;//read count low;
			   	reg00=0x22;//dma complete  page0

	 		}
		      	bnry=rxdnet.bytes.bytebuf[1]-1;//next page start-1
			if(bnry<0x4c)  {bnry=0x7f;}
			reg03=bnry; //write to bnry
              		reg07=0xff;
              		return(1);//have new packet
              	}
         }
	 return(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -