⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtl8019.c

📁 包括DSP实验测试程序、实验示例、应用程序以及经典的DSP的C程序和汇编程序库
💻 C
📖 第 1 页 / 共 2 页
字号:
		delay(1);
		Reg00=0x22;			//结束或放弃DMA操作

		for(i=0;i<6;i++)	//最多重发6次
		{
			for(x=0;x<1000;x++)
    		{//检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃
        		if((Reg00&0x04)==0)  
        			{ break; }
        	}
			if((Reg04&0x01)!=0)//表示发送成功,判断发送状态寄存器TSR,决定是否出错
				{break;};
			Reg00=0x3e;
		}

		Reg07=0xff;
		delay(1);
		Reg04=0x40;   	//txd packet start;
		delay(1);
		Reg06= h;  		//high byte counter
		delay(1);
		Reg05= l;		//low byte counter
		delay(1);
		Reg07=0xff;
		delay(1);
		Reg00=0x3e;     //to sendpacket;
		delay(1);
       
}

unsigned short checksum(unsigned short *buffer, short size)  
{  

   unsigned long cksum;  
   unsigned short   sum;

   cksum=0;
   while(size >0)
   {  
     sum=(*buffer<<8)+(*buffer>>8); 
     buffer++;
     cksum+=sum;  
     size --;  
   }  

   cksum = (cksum >> 16) + (cksum & 0xffff);  

   cksum += (cksum >>16);   //cksum maybe  +1
   sum=(unsigned short)(~cksum);
   sum=(sum<<8)+(sum>>8);

   return (sum);  

}  


void send_udp(unsigned short *buf,unsigned short  length)
{
         unsigned short temp;
         unsigned short tempbuf[1240/2];

         for(temp=0;temp<length;temp++)
           buf[temp]=change_byte(buf[temp]);
         load_udp(buf,&length);
         
         t_iphdr.protocal_ttl   =128;       //usally 32 or 64
         t_iphdr.protocal_ttl  +=(unsigned short)17<<8;  //17=UDP
         t_iphdr.saddr =nod_ipaddr;
         
         t_iphdr.tol_len =change_byte((length+10)<<1);
         t_iphdr.chksum=0;         //it is important
         memcpy(tempbuf,&t_iphdr,sizeof(t_iphdr));
         t_iphdr.chksum=checksum(tempbuf,10);
         load_ip(sendbuf,&length);
         if((t_iphdr.daddr.addr4_3&0xff01)==0xff01)  //是广播地址
           temp=BROADCAST;
         else
           temp=0;
         send_frame(sendbuf,temp,UDP, length);
}


void send_arp(struct ipaddr *ip,unsigned short arp_type)
{
         unsigned short temp;
         arp1.hard_type    =(unsigned short)1<<8;
         arp1.proto_type   =(unsigned short)((2048<<8)+(2048>>8));
         arp1.proto_hard_length   =6;
         arp1.proto_hard_length  +=(unsigned short)4<<8;
         arp1.op_code      =arp_type<<8;
         
         arp1.send_macaddr =MAC_self;
         arp1.send_ipaddr  =nod_ipaddr;
         
         if(arp_type==1)       //请示对方  fill MAC
         {
           arp1.rec_macaddr.addr2_1  =0;
           arp1.rec_macaddr.addr4_3  =0;
           arp1.rec_macaddr.addr6_5  =0;
           temp=BROADCAST;
         }
         else                  //应答对方 fill MAC
         {
           arp1.rec_macaddr=MAC_rec;
           temp=REC_ARP;
         }
         
         arp1.rec_ipaddr   =*ip;
         
         memcpy(sendbuf,&arp1,sizeof(arp1));
         send_frame(sendbuf,temp,ARP,sizeof(arp1));
}


/**********************************************************************
**函数原型:    Uint16        Rec_NewPacket()
**入口参数:		无
**出口参数:		无
**返 回 值:	0          没有新数据包
**              1          接收到新数据包
**说    明:	查询是否有新数据包并接收进缓冲区
************************************************************************/
Uint16	RecFrame()
		{
			Uint16	i,ii;
			Uint16	Temp,length;
			union{
					Uint16	total;	
					struct{
							Uint16	high:8;
							Uint16	low:8;
						  }e;
				 }d;
			for (i = 0;i<25;i++)	RxEthnetFrameBuffer[i] = 0;	 
			page(0);
			delay(10);
			bnry = Reg03;				//bnry page have read 读页指针
			bnry = bnry & 0x00FF;
			page(1);
			delay(10);
			curr = Reg07;				//curr writepoint 8019写页指针
			curr = curr & 0x00FF;
			page(0);
			delay(10);
			if((curr==0))return(0);	//读的过程出错
			bnry++;
			if(bnry>0x7f)	bnry=0x4c;
			if(bnry!=curr)			//此时表示有新的数据包在缓冲区里
    			{					//在任何操作都最好返回page0
     				page(0);
     				delay(10);
     //=======================================
     				Reg09=bnry;		//读页地址的高字节
     				delay(5);
     				Reg08=0x00; 	//读页地址的低字节
     				delay(5);
     				Reg0b=0x00;		//读取字节计数高字节
     				delay(5);
     				Reg0a=18;       //读取字节计数高字节
     				delay(5);
     				Reg00=0x0a;     //启动Remote DMA读操作
	 				delay(5);	
     				for(i=0;i<9;i++)	//读取一包的前18个字节:4字节的8019头部,6字节目的地址,6字节原地址,2字节协议
                    	{
                       		RxEthnetFrameBuffer[i]=Reg10;
                       		delay(1);
                      	}
 //=======================================中止DMA操作
     				Reg0b=0x00;	//
     				delay(1);
     				Reg0a=0x00;	//
     				delay(1);
     				Reg00=0x22;	//结束或放弃DMA操作
     				delay(1);
 //=======================================
					
					d.total = RxEthnetFrameBuffer[0];
					length = RxEthnetFrameBuffer[1];
     				if(((d.e.low & 0x01)==0)||(d.e.high > 0x7f) || (d.e.high < 0x4c)||( length > 1517))
    					{//接收状态错误或下一数据包的起始页地址错误或接收的数据包长度>1500字节
       						page(1);
       						delay(10);
							curr=Reg07; 	//page1
							page(0);		//切换回page0
							delay(10);
        					bnry = curr -1;
        					if(bnry < 0x4c) 	bnry =0x7f;
        					Reg03=bnry; 	//write to bnry     
        					delay(1);
        					Reg07=0xff;
							return(0);
              			}
//=============================================
            
     				else//表示数据包是完好的.读取剩下的数据
     					{
     						Temp = RxEthnetFrameBuffer[8];		
        					if((Temp == Frame_IP)||(Temp == Frame_ARP))
								{ //协议为IP或ARP才接收
                					Reg09 = bnry;   				//read page address high
                					delay(1);
                					Reg08 = 4;      				//read page address low
                					delay(1);
                					Reg0b = length>>8;  //read count high
                					delay(1);
                					Reg0a = length & 0xff;//read count low;
                					delay(1);
                					Reg00=0x0a;                             //read dma
                					delay(1);
						        	length=(length+1)/2;
                					for(ii=2;ii<length+2;ii++)
                						{
                							RxEthnetFrameBuffer[ii]=Reg10;
                						}
                        			//================终止DMA操作
                        			Reg0b=0x00;			//read count high  
                        			delay(1); 
                        			Reg0a=0x00;			//read count low;
                        			delay(1);
                        			Reg00=0x22;			//结束或放弃DMA
                        			delay(1);
                        			//============================
                        		}
                        		//=========================================
                        	d.total = RxEthnetFrameBuffer[0];
                        	bnry = d.e.high - 1;	
                			if(bnry<0x4c)	bnry=0x7f;
                			page(0);
                			delay(10);
	        				Reg03=bnry;      //write to bnry
	        				delay(1);
                			Reg07=0xff;
                			return(1);   //have new packet
               			}
   				}
			else	
				return(0);
		}


void nic_recieve()
{
    unsigned int x,length ;
    unsigned int temp ;
	unsigned int flag;
		
	do{	
		flag = RecFrame();

   		temp=RxEthnetFrameBuffer[8];
   		if(temp==Frame_IP)
        {
       		if(RxEthnetFrameBuffer[20]==DATAPORT)   //有四个字节的头,1000字节的数据
       		{
               header1=RxEthnetFrameBuffer[23]&0x00ff;  //low byte
               header2=RxEthnetFrameBuffer[23]>>8;     
               header3=RxEthnetFrameBuffer[24]&0x00ff;
               header4=RxEthnetFrameBuffer[24]>>8;
               
               getorder();

               if(header2==MPEG1)
               {
               		for(x=25;x<(25+FRAMESIZE);x++)
                	{
                    	if(header1==PROGRAM)
                    	{
			               	DA_wptr++;
                    	   	if(DA_wptr>=(unsigned int)PCMSIZE)
                    	   		DA_wptr=0;
                       		videobuf[DA_wptr]=change_byte(RxEthnetFrameBuffer[x]);
                     	}		
           	   		}
                   	if(header1==PROGRAM)    //video
                    	request_pack++;
              	}
               	else if(header2==MPEG1)
               	{
               		*(IMR)|=0x0800;      //开接收1中断
               	}
           	}
   		}
          
         else if(temp==Frame_ARP)      //ARP
         {
            for(x=9;x<length;x++)
            	RxEthnetFrameBuffer[x-9]=RxEthnetFrameBuffer[x];
            memcpy(&r_ipaddr,RxEthnetFrameBuffer+12,2);
            if(nod_ipaddr.addr2_1==r_ipaddr.addr2_1)
            if(nod_ipaddr.addr4_3==r_ipaddr.addr4_3)
            {
            	if(RxEthnetFrameBuffer[3]==0x01<<8)       //自已请求,对方ARP应答  
            	{
               		memcpy(&MAC_rec,RxEthnetFrameBuffer+4,3); //复制对方的MAC
               		memcpy(&r_ipaddr,RxEthnetFrameBuffer+7,2); //复制对方的IP
               		send_arp(&r_ipaddr,2);
            	}
            	if(RxEthnetFrameBuffer[3]==0x02<<8)       //自已请求,对方ARP应答  
            	{
            		memcpy(&MAC_server,RxEthnetFrameBuffer+4,3);
            		arp_ack=1;
            	}
            }
       	}
   	}while(flag);

}




unsigned short  change_byte(unsigned short value)
{
    unsigned short temp;
    temp=(value<<8)|(value>>8);
    return(temp);
}


void getorder( )
{

       if(header1==PROGRAM)
       {
          dat_type=MP3_DAT;
       }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -