📄 global.c
字号:
/*********************************************************************
* Copright(c) 2004,张会福 湖南科技大学计算机学院
* All rights reserved.
*
*文件名称: global.c
*文件标识:
*摘 要: 定义全局变量,网络底层驱动程序,校验和计算,处理器相关设定
*
*当前版本: V1.0
*作 者: 张会福
*完成日期: 2004.4.10
*
*********************************************************************/
/*********************************************************************
* 公共变量定义
*
********************************************************************/
//#include "uart.c"
#define GLOBAL_GLOBALS
#include "net_cfg.h"
/****************************************************************/
uchar Ping_Count; //ping的次数,决定本地回显次数
uchar Ping_IP_TTL=0; //ping的主机的物理地址生存时间,单位分钟,为0表示IP地址没有解析
uchar Gateway_IP_TTL=0 ; //网关IP地址的物理地址生存时间,单位分钟
//=0表示还没有解析,<5分钟时需要更新
uchar Udp_Count;
uchar Msec=0; //10毫秒
uchar Sec=0; //秒钟
uchar Min=0; //分钟
uchar i=0;
uchar bnry; //读芯片RAM指针
uchar curr; //写芯片RAM指针
uchar RtTime=20; //重发时间
uchar Tcp_Drop_Count=0; //用于关闭tcp连接的计数
uint FrameIndex=0; //IP包的序列号
uint ComRxdRead=0; //串口接收读指针
uint ComTxdRead=0; //串口发送读指针
uint ComRxdWrite=0; //串口接收写指针
uint ComTxdWrite=0; //串口发送写指针
bit ComTxdBufempty=0; //串口发送缓冲区数据空的标志
bit Tx_Buff_Sel=0; //芯片的发送缓冲区选择
bit BiSecond; //两秒时,该标志置1
bit Tcp_Timeout=0; //TCP超时标志,定时器0中断中将该标志置位
bit TcpConnected=0; //TCP连接建立标志
uchar code MacID[6]=MY_MAC_ID;//将RTL8019的物理地址存储在程序空间中
uchar code HexTable[]={"0123456789ABCDEF"}; //为ascii->hex的转换表
xdata uchar Command_Buf[COMMAND_BUFF_SIZE]; //命令缓冲区
xdata uchar IpStr[16];
xdata uchar PortStr[5];
xdata struct Socket_Type TCP1024;
xdata uchar ComRxdBuf[COM_RXD_BUFF_SIZE]; //串口的接收缓冲区
xdata uchar ComTxdBuf[COM_TXD_BUFF_SIZE]; //串口的发送缓冲区
xdata union Netcard RxdNetBuff; //数据接收缓冲区
xdata union Netcard TxdNetBuff; //数据发送缓冲区
xdata union Netcard Resend_Buff;
xdata union Ethernet_Address_Type My_MAC ; //本机的物理地址
xdata union Ethernet_Address_Type Gateway_MAC; //网关的物理地址
xdata union Ethernet_Address_Type Ping_MAC; //PING的物理地址
xdata union Ip_Address_Type My_Ip_Address ; //本机IP地址
xdata union Ip_Address_Type Gateway_Ip_Address; //网关IP地址
xdata union Ip_Address_Type Mask_Ip_Address; //子网掩码
xdata union Ip_Address_Type Ping_Ip_Address; //保存PING命令的目的主机的物理地址
union u RemotePort;
union w CrcTemp;
/**********************************************************************
**函数原型: void delay_ms(uint ms_number)
**入口参数: ms_number: 延时的毫秒数
**出口参数: 无
**返 回 值: 无
**说 明: 延时预定的时间,延时时间与特定的处理器有关
************************************************************************/
void Delay_MS(uint ms_number)
{
uint i;
uint j;
for(j = 0;j < ms_number;j++)
for(i = 0;i < 229;i++);
}
/**********************************************************************
**函数原型: void page(uchar pagenumber)
**入口参数: uchar pagenumber: 要切换的页
**出口参数: 无
**返 回 值: 无
**说 明: 选择页,可选择0,1,2三页,第四页ne000兼容芯片保留
************************************************************************/
void page(uchar pagenumber)
{
uchar data temp;
temp=Reg00; //command register
//temp=temp&0x3f;
temp=temp&0x3B ; //注意txp位不能要
pagenumber=pagenumber <<6;
temp=temp | pagenumber;
Reg00=temp;
}
/**********************************************************************
**函数原型: void SetMacID()
**入口参数: 无
**出口参数: 无
**返 回 值: 无
**说 明: 设置芯片物理地址,物理地址已经存储在程序空间内
************************************************************************/
void SetMacID()
{
My_MAC.bytes[0] = MacID[0]; //取出物理地址,填充到
My_MAC.bytes[1] = MacID[1];
My_MAC.bytes[2] = MacID[2];
My_MAC.bytes[3] = MacID[3];
My_MAC.bytes[4] = MacID[4];
My_MAC.bytes[5] = MacID[5];
page(1);
Reg01 = My_MAC.bytes[0];
Reg02 = My_MAC.bytes[1];
Reg03 = My_MAC.bytes[2];
Reg04 = My_MAC.bytes[3];
Reg05 = My_MAC.bytes[4];
Reg06 = My_MAC.bytes[5];
page(0);
}
/**********************************************************************
**函数原型: void Send_Packet(union Netcard *TxdNetBuff,uint length)
**入口参数: union Netcard *TxdNetBuff :指向发送缓冲区
** uint length :发送数据包的长度
**出口参数: 无
**返 回 值: 无
**说 明: 发送数据包,以太网底层驱动程序,所有的数据发送都要通过该程序
************************************************************************/
void Send_Packet(union Netcard *TxdNetBuff,uint length)
{
uchar i;
uint ii;
page(0); //切换至第0页
if(length<60)
length=60; //如果数据长度<60字节,设置长度为60字节
for(i=0;i<3;i++) //设置源物理地址
{
TxdNetBuff->EtherFrame.SourceMacId[i]=My_MAC.words[i];
}
Tx_Buff_Sel=!Tx_Buff_Sel; //设置两个发缓区,提高发送效率
if(Tx_Buff_Sel)
Reg09=0x40 ; //设置发送页地址
else
Reg09=0x46 ; //设置发送页地址
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=TxdNetBuff->bytes.bytebuf[ii];
}
/***************************************/
//以下为终止DMA操作
Reg0b=0x00;
Reg0a=0x00;
Reg00=0x22; //结束或放弃DMA操作
/***************************************/
for(i=0;i<6;i++) //最多重发6次
{
for(ii=0;ii<1000;ii++)
{//检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃
if((Reg00&0x04)==0)
{ break; }
}
if((Reg04&0x01)!=0)//表示发送成功,判断发送状态寄存器TSR,决定是否出错
{break;};
Reg00=0x3e;
}
Reg07=0xff;
if(Tx_Buff_Sel)
{
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;
}
/**********************************************************************
**函数原型: bit Rec_NewPacket()
**入口参数: 无
**出口参数: 无
**返 回 值: 0 没有新数据包
** 1 接收到新数据包
**说 明: 查询是否有新数据包并接收进缓冲区
************************************************************************/
bit Rec_NewPacket()
{
uchar i;
uint ii;
page(0);
bnry=Reg03; //bnry page have read 读页指针
page(1);
curr=Reg07; //curr writepoint 8019写页指针
page(0);
if((curr==0)) return(0); //读的过程出错
bnry=bnry++;
if(bnry>0x7f) bnry=0x4c;
if(bnry!=curr) //此时表示有新的数据包在缓冲区里
{ //在任何操作都最好返回page0
page(0);
//=======================================
Reg09=bnry; //读页地址的高字节
Reg08=0x00; //读页地址的低字节
Reg0b=0x00; //读取字节计数高字节
Reg0a=18; //读取字节计数高字节
Reg00=0x0a; //启动Remote DMA读操作
for(i=0;i<18;i++)//读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议
{
RxdNetBuff.bytes.bytebuf[i]=Reg10;
}
//=======================================中止DMA操作
Reg0b=0x00; //
Reg0a=0x00; //
Reg00=0x22; //结束或放弃DMA操作
//=======================================
i=RxdNetBuff.bytes.bytebuf[3];
RxdNetBuff.bytes.bytebuf[3]=RxdNetBuff.bytes.bytebuf[2];
RxdNetBuff.bytes.bytebuf[2]=i; //将长度字段的高低字节掉转
RxdNetBuff.EtherFrame.length=RxdNetBuff.EtherFrame.length-4;//去掉4个字节的CRC
//=====================以上各步操作表示读入的数据包有效
if(((RxdNetBuff.bytes.bytebuf[0]&0x01)==0)||(RxdNetBuff.bytes.bytebuf[1]>0x7f)
||(RxdNetBuff.bytes.bytebuf[1]<0x4c)||(RxdNetBuff.bytes.bytebuf[2]>0x06))
{//接收状态错误或下一数据包的起始页地址错误或接收的数据包长度>1500字节
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);
}//接收状态错误或下一数据包的起始页地址错误或接收的数据包长度>1500字节
//=============================================
else//表示数据包是完好的.读取剩下的数据
{
if((RxdNetBuff.EtherFrame.NextProtocal==0x0800)||(RxdNetBuff.EtherFrame.NextProtocal==0x0806))
{ //协议为IP或ARP才接收
Reg09=bnry; //read page address high
Reg08=4; //read page address low
Reg0b=RxdNetBuff.EtherFrame.length>>8; //read count high
Reg0a=RxdNetBuff.EtherFrame.length&0xff;//read count low;
Reg00=0x0a; //read dma
for(ii=4;ii<RxdNetBuff.EtherFrame.length+4;ii++)
{RxdNetBuff.bytes.bytebuf[ii]=Reg10;}
//================终止DMA操作
Reg0b=0x00; //read count high
Reg0a=0x00; //read count low;
Reg00=0x22; //结束或放弃DMA
//============================
}
//=========================================
bnry=RxdNetBuff.bytes.bytebuf[1]-1;
if(bnry<0x4c)
{bnry=0x7f;}
Reg03=bnry; //write to bnry
Reg07=0xff;
if((TCP1024.State==TCP_STATE_ESTABLISHED)&&(RxdNetBuff.IpFrame.NextProtocal==6))
if(RxdNetBuff.IpFrame.SourceIp[0]!=TxdNetBuff.IpFrame.DestId[0])
if(RxdNetBuff.IpFrame.SourceIp[1]!=TxdNetBuff.IpFrame.DestId[1])//目标IP地址是否本机
return(0);
return(1); //have new packet
}//表示数据包是完好的.读取剩下的数据
}//if(bnry!=curr)//此时表示有新的数据包在缓冲区里
return(0);
}
/**********************************************************************
**函数原型: void InitNic()
**入口参数: 无
**出口参数: 无
**返 回 值: 无
**说 明: 对芯片的工作寄存器进行设置,各个寄存器的用法可参考文档和
** 络芯片的数据手册
************************************************************************/
void InitNic()
{
Delay_MS(10);
/**********************************************************************
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 停止命令
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -