📄 rtl8019.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 + -