📄 8019driver.c
字号:
/*********************************************************************************
* 8019driver.C v1.00 8019驱动程序 *
* 版权(c) 2004- 北京百科融创科技有限公司 *
* 设计者: 赵治心 *
* 邮箱: ourui.wl@263.net *
**********************************************************************************/
//#include "tcp_ip.h"
#include <stdio.h>
#include "DataType.h"
#include "y13.h"
#include "8019head.h"
//#include "global.h"
extern unsigned int RevBuffer[500];
extern unsigned int RevLength;
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/*
对网卡的复位端口的读或写将复位网卡,网卡内部将执行复位过程。读写是随意的,
写入任意的数都将复位网卡。
*/
void Reset8019()
{
int i;
i=ResetPort;//读网卡的复位端口
ResetPort=i; //写网卡的复位端口
for(i=0;i<3000;i++);
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/*
从实验当中也发现,只要再置位TXP位就可以重发该数据包(重发数据包时,不需要
设置TPSTART,TBCR0,TBCR1).
CR,command register:
位 7 6 5 4 3 2 1 0
名字 PS1 PS0 RD2 RD1 RD0 TXP STA STP
---PS1和PS0这两个位用来选择寄存器页,PS1 PS0=00时选择寄存器页0,
=01时选择寄存器页1, =10时选择寄存器页2,=11时选择寄存器页3.
--RD2,RD1,RD0这3个位代表要执行的功能。
=001 读网卡内存
=010 写网卡内存
=011 发送网卡数据包
=1** 完成或结束DMA的读写操作
---TXP这个位写入1时发送数据包,发完自动清零
---STA,STP这两个位用来启动命令或停止命令
=10 启动命令
=01 停止命令
*/
void SetPage(int pagenumber)
{
int temp;
temp=CR;
temp=temp&0x003B; //注意不是0x3F ,TXP位在平时一定要置为0.
pagenumber=pagenumber<<6;
temp=temp|pagenumber;
CR=temp;
}
////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
int Test8019()
{
int ID,ID1;
// SetPage(0);
ID=(RTL8019ID0)&0x00ff;
ID1=(RTL8019ID1)&0x00ff;
ID=(RTL8019ID1<<8) | ID;
return ID;
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/*
PAR0,PAR1, PAR2, PAR3,PAR4,PAR5
这几个寄存器是网卡的工作时候用的地址,只有符合这个地址的数据包才接收,
这个地址是可以设置为其他的值,不一定设置为网卡的物理地址,为了不跟别的
网卡地址冲突,最好设置为网卡的地址,(如果用户需要设置为其他的值,也是可以的).
*/
void SetMACAdd()
{
SetPage(1);
PAR0=MAC_Addr[0];//sed_lclEthAddr[0]; //PAR0
PAR1=MAC_Addr[0];//sed_lclEthAddr[1]; //PAR1
PAR2=MAC_Addr[0];//sed_lclEthAddr[2]; //PAR2
PAR3=MAC_Addr[0];//sed_lclEthAddr[3]; //PAR3
PAR4=MAC_Addr[0];//sed_lclEthAddr[4]; //PAR4
PAR5=MAC_Addr[0];//sed_lclEthAddr[5]; //PAR5
SetPage(0);
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/*
PSTART 接收缓冲区的起始页的地址。
PSTOP 接收缓冲区的结束页地址。(该页不用于接收)
BNRY 指向最后一个已经读取的页(读指针)
CURR 当前的接收结束页地址。(写指针)
--网卡含有16K字节的RAM,地址为0x4000-0x7fff(指的是网卡上的存储地址,
而不是ISA总线的地址,是网卡工作用的存储器),每256个字节称为一页,共有64页。
页的地址就是地址的高8位,页地址为0x40--0x7f 。这16k的ram的一部分用来存放接收
的数据包,一部分用来存储待发送的数据包。当然也可以给用户使用。(例如把网卡
设置成使用8K的ram,另外8K的ram就可以用来给单片机作为存储器,但我没有这样做,
原因是操作网卡上的ram比较复杂)
---在我的程序中使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储2个
最大的以太网包。使用0x4c-0x7f为网卡的接收缓冲区,共52页。因此PSTART=0x4c,
PSTOP=0x80(0x80为停止页,就是直到0x7f,是接收缓冲区,不包括0x80) 刚开始,
网卡没有接收到任何数据包,所以,BNRY设置为指向第一个接收缓冲区的页0x4c)
这四个寄存器用于接收的设置。
--CURR是网卡写内存的指针。它指向当前正在写的页的下一页。那么初始化它就应
该指向0x4c+1=0x4d 。网卡写完接收缓冲区一页,就将这个页地址加一,CURR=CURR+1。
这是网卡自动加的。当加到最后的空页(这里是0x80,PSTOP)时,将CURR置为接收缓冲
区的第一页(这里是0x4c,PSTART),也是网卡自动完成的。当CURR=BNRY时,表示缓冲
区全部被存满,数据没有被用户读走,这时网卡将停止往内存写数据,新收到的数据包
将被丢弃不要,而不覆盖旧的数据。此时实际上出现了内存溢出。
---而BNRR要由用户来操作。用户从网卡读走一页数据,要将BNRY加一,然后再写
到BNRY寄存器。 当BNRY加到最后的空页(0x80,PSTOP)时,同样要将BNRY变成第一
个接收页(PSTART,0x4c)BNRY=0x4c;
---CURR和BNRY主要用来控制缓冲区的存取过程,保证能顺次写入和读出)。
当CURR=BNRY+1(或当BNRY=0x7f ,CURR=0x4c)时,网卡的接收缓冲区里没有数据,
表示没有收到数据包。 用户通过这个判断知道没有包可以读。当上述条件不成立时,
表示接收到新的数据包。然后用户应该读取数据包,直到上述条件成立时,表示所以
数据包已经读完,此时停止读取数据包。
--TPSR 为发送页的起始页地址。初始化为指向第一个发送缓冲区的页,0x40。
--RCR 接收配置寄存器,设置为使用接收缓冲区,仅接收自己的地址的数据包
(以及广播地址数据包)和多点播送地址包,小于64字节的包丢弃(这是协议的规定,
设置成接收是用于网络分析),校验错的数据包不接收。
--TCR 发送配置寄存器,启用crc自动生成和自动校验,工作在正常模式。
--DCR 数据配置寄存器,设置为使用FIFO缓存,普通模式,16位数据传输模式,
字节顺序为高位字节在前,低位字节在后(符合我们的习惯)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -