📄 rtl8019.c
字号:
#include "cpu_reg.h"
#include "string.h"
#include "RTL8019.h"
struct ipaddr server_ipaddr,nod_ipaddr,r_ipaddr;
struct mac MAC_server,MAC_broad,MAC_rec;
struct mac MAC_self,MAC_nod;
struct iphdr t_iphdr;
struct igmphdr t_igmphdr;
struct udphdr t_udphdr;
struct pre_udphdr pre_udphdr1;
Uint16 TxNetBuf[1518/2];
Uint16 RxNetBuf[1518/2];
Uint16 TxBufFlag;
Uint16 bnry,curr;
extern int ms;
void InitProtocal(void);
void delay(int k)
{
while(k--);
}
//==============================================================================
/**********************************************************************
**函数原型: void page(uchar pagenumber)
**入口参数: Uint16 pagenumber: 要切换的页
**出口参数: 无
**返 回 值: 无
**说 明: 选择页,可选择0,1,2三页,第四页ne000兼容芯片保留
************************************************************************/
void page(Uint16 pagenumber)
{
Uint16 temp;
temp = Reg00; //command register
temp = temp&0x3B ; //注意txp位不能要
pagenumber=pagenumber <<6;
temp=temp | pagenumber;
Reg00=temp;
}
/**********************************************************************
**函数原型: void Init8019()
**入口参数: 无
**出口参数: 无
**返 回 值: 无
**说 明: 对芯片的工作寄存器进行设置,各个寄存器的用法可参考文档和
** 络芯片的数据手册
************************************************************************/
void Init8019()
{
ms =0;
while(ms<100);
/**********************************************************************
1.Reg00命令寄存器: CR,命令寄存器,地址偏移量00H,为一个字节
位: 7 6 5 4 3 2 1 0
名字: PS1 PS0 RD2 RD1 RD0 TXP STA STP
//============================================
2.
RD2,RD1,RD0: 这3个位代表要执行的功能。
0 0 1 : 读网卡内存
0 1 0 : 写网卡内存
0 1 1 : 发送网卡数据包
1 * * : 完成或结束DMA的读写操作
//============================================
3.TXP位置1时发送数据包,发完自动清零
//============================================
4.
STA,STP: 这两个位用来启动命令或停止命令
1 0 启动命令
0 1 停止命令
//============================================
********************************************************/
Reg00=0x21; //使芯片处于停止模式,这时进行寄存器设置
InitProtocal();
ms = 0;
while(ms<100); //延时100毫秒,确保芯片进入停止模式
page(0);
delay(10);
Reg0a= 0x00; //清rbcr0
delay(1);
Reg0b= 0x00; //清rbcr1
delay(1);
Reg0c= 0xe0; //RCR,监视模式,不接收数据包
delay(1);
Reg0d= 0xe2; //TCR,loop back模式
delay(1);
Reg01= 0x4c; //pstart = 0x4c
delay(1);
Reg02= 0x80; //pstop = 0x80
delay(1);
Reg03= 0x4c; //bnry = 4c
delay(1);
Reg04= 0x40; //TPSR,发送起始页寄存器
delay(1);
Reg07= 0xff; //清除所有中断标志位,中断状态寄存器
delay(1);
Reg0f= 0x00; //中断屏蔽寄存器清0,禁止中断
delay(1);
Reg0e= 0xc9; // 数据配置寄存器,16位dma方式
page(1);
delay(10);
Reg07= 0x4d;
delay(1);
Reg08= 0x00;
delay(1);
Reg09= 0x00;
delay(1);
Reg0a= 0x00;
delay(1);
Reg0b= 0x00;
delay(1);
Reg0c= 0x00;
delay(1);
Reg0d= 0x00;
delay(1);
Reg0e= 0x00;
delay(1);
Reg0f= 0x00;
Reg01= MAC_self.addr2_1;
Reg02= MAC_self.addr2_1>>8;
Reg03= MAC_self.addr4_3;
Reg04= MAC_self.addr4_3>>8;
Reg05= MAC_self.addr6_5;
Reg06= MAC_self.addr6_5>>8;
page(0);
delay(10);
Reg0c= 0xce; //将芯片设置成正常模式,跟外部网络连接
delay(1);
Reg0d= 0xe0;
delay(1);
Reg00= 0x22; //启动芯片开始工作
//-----------------------------------
Reg07= 0xff; //清除所有中断标志位
ms = 0;
while(ms<100);
}
void InitProtocal(void)
{
/* server_ip=192.168.1.40 */
server_ipaddr.addr2_1 =192;
server_ipaddr.addr2_1 +=(Uint16)168<<8;
server_ipaddr.addr4_3 =1;
server_ipaddr.addr4_3 +=(Uint16)40<<8;
//192.168.1.1
nod_ipaddr.addr2_1 =192;
nod_ipaddr.addr2_1 +=(Uint16)168<<8;
nod_ipaddr.addr4_3 =1;
nod_ipaddr.addr4_3 +=(1<<8);
t_iphdr.tos_version =69;
t_iphdr.tos_version +=(Uint16)0<<8; //usally not use
t_iphdr.id =20; //++IP_id;
t_iphdr.id +=(Uint16)52<<8;
t_iphdr.frag_off =0;
t_iphdr.protocal_ttl =128; //usally 32 or 64
t_iphdr.protocal_ttl +=(Uint16)17<<8;
t_iphdr.saddr =nod_ipaddr;
t_iphdr.daddr =server_ipaddr;
//UDP PORT
t_udphdr.sport =1024; //1*256+0x08,9901
t_udphdr.dport =1025; //1*256+0x07,9901
pre_udphdr1.saddr=t_iphdr.saddr;
pre_udphdr1.daddr=t_iphdr.daddr;
pre_udphdr1.protocal_value =0;
pre_udphdr1.protocal_value +=17<<8; //UDP
// FF-FF-FF-FF-FF-FF
MAC_broad.addr2_1 =255;
MAC_broad.addr2_1 +=(Uint16)255<<8;
MAC_broad.addr4_3 =255;
MAC_broad.addr4_3 +=(Uint16)255<<8;
MAC_broad.addr6_5 =255;
MAC_broad.addr6_5 +=(Uint16)255<<8;
// 02-E0-4C-A0-7E-7A
MAC_self.addr2_1 =1<<1;
MAC_self.addr2_1 +=(Uint16)224<<8;
MAC_self.addr4_3 =76;
MAC_self.addr4_3 +=(Uint16)160<<8;
MAC_self.addr6_5 =126;
MAC_self.addr6_5 +=(Uint16)122<<8;
// 00-E0-4C-A0-7E-7A
MAC_nod.addr2_1 =0;
MAC_nod.addr2_1 +=(Uint16)224<<8;
MAC_nod.addr4_3 =76;
MAC_nod.addr4_3 +=(Uint16)160<<8;
MAC_nod.addr6_5 =126;
MAC_nod.addr6_5 +=(Uint16)122<<8;
}
//=============================================================================
/**********************************************************************
**函数原型: void SendFrame(Uint16 *TxdNetBuff,Uint16 length)
**入口参数: Uint16 *TxdNetBuff :指向发送缓冲区
** uint length :发送数据包的长度
**出口参数: 无
**返 回 值: 无
**说 明: 发送数据包,以太网底层驱动程序,所有的数据发送都要通过该程序
************************************************************************/
void SendFrame(Uint16 *TxdNetBuff,Uint16 length)
{
Uint16 i,ii;
if(length<46/2)
{
for(i=length;i<60/2;i++) TxNetBuf[i]=0;
length=60/2;
}
page(0);
delay(10); //切换至第0页
length = length <<1;
TxBufFlag=!TxBufFlag; //设置两个发缓区,提高发送效率
if(TxBufFlag)
{Reg09=0x40 ;} //设置发送页地址
else
{Reg09=0x46 ;} //设置发送页地址
Reg08=0x00; //read page address low
delay(1);
Reg0b = length >>8; //写发送长度高位
delay(1);
Reg0a = length & 0x00ff; //写发送长度低位
delay(1);
Reg00=0x12; //write dma, page0
for(i=0;i<length/2;i++)
{
Reg10 = TxNetBuf[i];
}
/***************************************/
//以下为终止DMA操作
Reg0b=0x00;
delay(1);
Reg0a=0x00;
delay(1);
Reg00=0x22; //结束或放弃DMA操作
delay(1);
/***************************************/
for(i=0;i<6;i++) //最多重发6次
{
for(ii=0;ii<1000;ii++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -