📄 eth.c
字号:
reg07=0xFF;
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)
{ //此时表示有新的数据包在缓冲区里
//读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议
//在任何操作都最好返回page0
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++)
pRxdnet->bytes.bytebuf[i] = reg10;
/* 以下3句为中止dma的操作,可以不要 */
reg0b=0x00; //read count high 中止DMA操作
reg0a=0x00; //read count low;
reg00=0x22; //complete dma page 0
i=pRxdnet->bytes.bytebuf[3]; //将长度字段的高低字节掉转
pRxdnet->bytes.bytebuf[3]=pRxdnet->bytes.bytebuf[2];
pRxdnet->bytes.bytebuf[2]=i;
pRxdnet->etherframe.uLength=pRxdnet->etherframe.uLength-4;//去掉4个字节的CRC
//表示读入的数据包有效
if(((pRxdnet->bytes.bytebuf[0]&0x01)==0)||(pRxdnet->bytes.bytebuf[1]>0x7F)||(pRxdnet->bytes.bytebuf[1]<0x4C)||(pRxdnet->bytes.bytebuf[2]>0x06)){
//接收状态错误,或者next_page_start错误或者长度错误,将丢弃所有数据包
page(1);
curr=reg07; //page1
page(0); //切换回page0
bnry=curr-1;
if(bnry<0x4C) bnry=0x7F;
reg03=bnry; //write to bnry
return 0;
}
else
{//表示数据包是完好的.读取剩下的数据
if((pRxdnet->etherframe.protocal==0x0800)||(pRxdnet->etherframe.protocal==0x0806))
{
page(0);
//协议为IP或ARP才接收
reg09=bnry; //read page address high
reg08=0x04; //read page address low
reg0b=pRxdnet->etherframe.uLength>>8; //read count high
reg0a=pRxdnet->etherframe.uLength&0xFF; //read count low;
reg00=0x0A; //read dma
for(ii=4;ii<pRxdnet->etherframe.uLength+4;ii++)
pRxdnet->bytes.bytebuf[ii]=reg10;
/* 以下3句为中止dma的操作,可以不要 */
reg0b=0x00; //read count high 中止DMA操作
reg0a=0x00; //read count low;
reg00=0x22; //complete dma page 0
bnry=pRxdnet->bytes.bytebuf[1]-1;//next page start-1
if(bnry<0x4C) bnry=0x7F;
reg03=bnry; //write to bnry
return 1;
}
bnry=pRxdnet->bytes.bytebuf[1]-1;//next page start-1
if(bnry<0x4C) bnry=0x7F;
reg03=bnry; //write to bnry
return 0; //have new packet
}
}
return 0;
}
/*
*****************************************************************************************************
*FUNC: 生成IP包头CRC校验
*NOTE: 返回值: CRC校验值
*****************************************************************************************************
*/
unsigned int createipheadcrc(union netcard xdata *pTxdnet)
{
unsigned int crc;
crc = checksum(pTxdnet->words.wordbuf + 9, 20);
return crc;
}
/*
*****************************************************************************************************
*FUNC:
*NOTE:
*****************************************************************************************************
*/
bit Query8019(void)
{
char bnry,curr;
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) //此时表示有新的数据包在缓冲区里
return 1;
reg0b=0x00; reg0a=0x00; reg00=0x22;//complete dma page 0
}
/*
*****************************************************************************************************
*FUNC:
*NOTE:
*****************************************************************************************************
*/
unsigned int checksum(unsigned int xdata *check,unsigned int length)//计算校验和
{
unsigned long sum=0;
unsigned int i;
for (i=0;i<(length)/2;i++)
sum+=*check++;
if(length&0x01)//表示长度为单数
sum=sum+((*check)&0xff00);
sum=(sum&0xffff)+((sum>>16)&0xffff);//高16位和低16位相加
if(sum&0xffff0000)//表示有进位
sum++;
return ( (unsigned int)(~((sum)&0xffff)) );
}
/*
*****************************************************************************************************
*FUNC:
*NOTE:
*****************************************************************************************************
*/
bit verifyipheadcrc(union netcard xdata *pRxdnet)//对ip头进行校验,错误返回0,正确返回1
{
unsigned int crc;
crc=checksum(&(pRxdnet->ippacket.ippacket[0]),(pRxdnet->ipframe.verandihl&0x0f)*4);
if(crc==0) return (1);
return(0);
}
/*
*****************************************************************************************************
*FUNC: 主循环
*NOTE:
*****************************************************************************************************
*/
void MainCycle(void)//主循环
{
if (recv_packet(&rxdnet) == 1) {
temp_ip_address.words[0]=rxdnet.ipframe.destip[0];
temp_ip_address.words[1]=rxdnet.ipframe.destip[1];
switch (rxdnet.etherframe.protocal) {
case ARP_PROTOCOL: //表示收到一个arp包
if (rxdnet.arpframe.operation == 0x0001) { //表示收到一个arp请求包
ArpAnswer(); //ARP request,处理arp数据包
}
if (rxdnet.arpframe.operation == 0x0002) { //表示收到一个arp应答包
ArpEcho(); //ArpEcho
TCP_ATYARP(); //tcp保活测试
}
break;
case IP_PROTOCOL:
if ((rxdnet.ipframe.verandihl & 0xf0) != 0x40) {
return; //不是IP协议版本4不处理
}
if ((temp_ip_address.dwords != my_ip_address.dwords)
&& (temp_ip_address.dwords != 0xffffffff)){
return; //不是发给我的IP,不处理UDP的DHCP用到广播
}
if (verifyipheadcrc(&rxdnet)) { //校验CKSUM
switch (rxdnet.ipframe.protocal) {
case ICMP_TYPE: //表示为icmp协议
if (temp_ip_address.dwords == 0xffffffff) {
break; //不处理广播IP
}
if(rxdnet.icmpframe.type==8) { //是一个ping的请求包PC ping mcu
PingAnswer();
} else if(rxdnet.icmpframe.type == 0) {
PingEcho(); //是一个ping的应答包MCU PING PC
}
break;
case TCP_TYPE: //表示是tcp协议
if (temp_ip_address.dwords == 0xffffffff) {
break; //不处理广播IP
}
tcp_rcve(&rxdnet);
HttpFlag = FALSE; //退出前要清标志,不然的话客户端源PORT会以80
break;
case UDP_TYPE: //表示是udp协议
udp_rcve(&rxdnet);
break;
//case IGMP_TYPE:
// break;
//case EGP_TYPE:
// break;
//case IGRP_TYPE:
// break;
//case OSPFIGP_TYPE:
// break;
//case ENCAP_TYPE:
// break;
default:
break;
}
}
break;
//case REVARP_PROTOCOL:
// break;
//case SNMP_PROTOCOL:
// break;
//case PPP_PROTOCOL:
// break;
default:
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -