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

📄 udp.c

📁 RTL8019以太网开发板资料
💻 C
📖 第 1 页 / 共 4 页
字号:
/************************************************************************
FileName:      Udp.c
Description:   Udp protocol process  
Date:          2007 09 21                                                                                 
************************************************************************/
#include "Main.h"
#include "EEPROM.h"
/************************************************************************/
bit EthernetBuf0DataFlag;                                    // 以太网卡缓冲0已有数据             
bit EthernetLinkFlag;                                    // 以太网是否LINK上
bit EthernetNoDataFlag;                                  // 以太网芯片中没有数据 

UWORK16 RTL8019asRcvNum;                        // 在缓存中以太网包的个数,16K存满64页,每页256字节 
xdata ST_RECEIVE_ETHERNET gstaRevEthernet;             // 接收以太网包 
xdata ST_ETHERNET_STATISTICS gstEthernetStatistics;    // 以太网卡收发统计
xdata UWORK8 MAC_Remote_buf[ETHER_HEAD_LEN];         // 以太网头(目的MAC,源MAC,协议) 
xdata UWORK8 NetSend_buf[NET_SEND_BUFF];           // 以太网发送缓冲 
xdata UWORK8 gucaSegTemp[SEGMENT_DATA];                // 分片数据 


/*************************************************************************************/
bit  ARPFinishFlag;                                    // ARP完成标志
bit  IPConflitTestFlag;                                  // IP冲突测试 
bit  IPOrMacConfiltFlag;                             // IP,MAC冲突标志 
bit  StartConfiltLedFlag;                                // 冲突时启动快闪 
/************************************************************************/
xdata ST_ARP_FORMAT ArpRequestFormat;                     // ARP帧请求格式
xdata ST_ARP_FORMAT ArpAnswerFormat;                         // ARP应答格式 
xdata ST_ARP_CACHE  ArpCache_Buf[REMOTE_IP_NUM];       // ARP高速缓存 
UWORK8 IpModeNum;                                  // 在不同模式下IP数据不一样 
UWORK8 ArpCachePoniter;                        // ARP高速缓存指针 
xdata UWORK8 gucARPOddNum;                             // 老化后,ARP完不成的次数 
xdata UWORK8 ArpPhases;                              //ARP阶段    
/************************************************************************/
xdata ST_IP_HEAD_FORMAT gstIphead;
xdata UWORK16 LocalIpID;                                 // 本地IP的ID号 
xdata UWORK16 RevIpID;                              // 接收的ID号 

xdata UWORK8 IPAddress_buf[IP_LEN];                    // IP地址 
xdata UWORK8 SubNetMask_buf[IP_LEN];                   // 子网掩码 
xdata UWORK8 GateWay_buf[IP_LEN];                      // 网关 

bit  gbMoreSegFlag;                                    // 还有更多的分片标志 
bit  gbHaveFragment;                                   // 有分片标志 
/***********************************************************************/
xdata UWORK8 SetupIP_RcvSignal[32];              // 接收前导和标志信号 
xdata UWORK8 SetupIP_SendSignal[32];             // 发送前导和标志信号 
xdata ST_UDP_STATISTICS gstUDPStatistics;              // UDP统计 
/*********************************************************************
函数名:       void InitPara(void)
功能:         初始化网络参数
输入:         系统启动或者参数改变时 
输出:         将IP,端口号等参数从flash中读出进行配置
返回:         none
日期:         2006/05/30
*********************************************************************/
void InitPara(void)
{
    memcpy(&MAC_Remote_buf[6],&NetParameter.MAC_Local_buf[0],MAC_LEN);			//把源本地MAC地址复制到发送MAC缓存中
    memcpy(&IPAddress_buf[0],&NetParameter.IP_Local_buf[0],IP_LEN);       // 本地IP
    memcpy(&SubNetMask_buf[0],&NetParameter.SubMask_buf[0],IP_LEN);		  // 掩码 
    memcpy(&GateWay_buf[0],&NetParameter.Gateway[0],IP_LEN);			 // 默认网关
    memcpy(&ArpCache_Buf[0].ucaIP[0],&NetParameter.IP_Remote_buf[0],IP_LEN);			  // 远程IP1
    ArpCache_Buf[0].usRemotePort = NetParameter.Port_Remote;		 //远程端口号1
    ARPFinishFlag  = FALSE;
    EthernetLinkFlag = FALSE;
}
/*********************************************************************
函数名:       UWORK8 RTL8019asInit(void)
功能:         初始化RTL8019AS
输入:         None 
输出:         None
返回:         OK, ERROR
日期:         2004/02/04
*********************************************************************/
UWORK8 RTL8019asInit(void)
{
    xdata UWORK8 ucBNRY,ucLoop,ucLoop1;
    xdata UWORK8 ucMAR0,ucMAR1,ucMAR2,ucMAR3,ucMAR4,ucMAR5,ucMAR6,ucMAR7;    

    EX0 = FALSE;      // 禁止外部中断0
    RTL8019asReset();
    RTL8019asWrite(RW0_CR,0x21);                                        // 网卡停止运行 
    DelayMs(10);                                                      // 延时100ms,确保芯片进入停止模式 

    RTL8019asRead(R0_ID0,ucLoop);                                       // 读入芯片ID号 
    RTL8019asRead(R0_ID1,ucLoop1);
	
	if((RTL8019AS_ID0 != ucLoop) || (RTL8019AS_ID1 != ucLoop1))
    {
        return ERROR;
    }
    RTL8019asWrite(W0_DCR,0xd8);                                        // 8位DMA方式 
    RTL8019asWrite(W0_RBCR0,0x00);									  // 清零远程DMA读/写的字节数 
    RTL8019asWrite(W0_RBCR1,0x00);
    
     // 芯片处于监视和环回模式,跟外部网络断开 */
    RTL8019asWrite(W0_RCR,0xe0);                                        // 监视模式 
    RTL8019asWrite(W0_TCR,0xe2);                                        // 环回模式 

     // 使用0x40-0x4B为网卡的发送缓冲区,共12页,刚好可以存储2个最大的以太网包 
     // 使用0x4c~0x7f 为网卡的接收缓冲区共52 页 */
    RTL8019asWrite(W0_PSTART,0x4c);
    RTL8019asWrite(W0_PSTOP,0x80);
    RTL8019asWrite(RW0_BNRY,0x4c);                                      // 读页指针
     // 清除所用中断标志 
    RTL8019asWrite(RW0_ISR,0xff);                                       // 写1清零,上电必须清零 
    RTL8019asWrite(W0_IMR,RW0_ISR_TXE |RW0_ISR_RXE |
                        RW0_ISR_PTX | RW0_ISR_PRX);                   // 使能发送完成,发送出现错误,接收完成,接收出现错误中断    
    Page1();
    RTL8019asWrite(RW1_CURR,0x4d);                                      // 当前网卡正在写的页 

    RTL8019asWrite(RW1_MAR0,0x00);							   // 禁止组播 
    RTL8019asWrite(RW1_MAR1,0x00);
    RTL8019asWrite(RW1_MAR2,0x00);
    RTL8019asWrite(RW1_MAR3,0x00);
    RTL8019asWrite(RW1_MAR4,0x00);
    RTL8019asWrite(RW1_MAR5,0x00);
    RTL8019asWrite(RW1_MAR6,0x00);
    RTL8019asWrite(RW1_MAR7,0x00);
    
    RTL8019asWrite(RW1_PAR0,NetParameter.MAC_Local_buf[0]);				 // 初始化MAC 
    RTL8019asWrite(RW1_PAR1,NetParameter.MAC_Local_buf[1]);
    RTL8019asWrite(RW1_PAR2,NetParameter.MAC_Local_buf[2]);
    RTL8019asWrite(RW1_PAR3,NetParameter.MAC_Local_buf[3]);
    RTL8019asWrite(RW1_PAR4,NetParameter.MAC_Local_buf[4]);
    RTL8019asWrite(RW1_PAR5,NetParameter.MAC_Local_buf[5]);
    
    Page3();
    Rtl3ConfigEnable();                                               // page3配置使能 
    Rtl3IntEnable();                                                  // 中断引脚使能 
    Auto3DetectNMT();                                                 // 自动选择网络媒介类型 
    RTL8019asWrite(RW3_CONFIG2,0);
    RTL8019asWrite(RW3_CONFIG3,R3_CONFIG3_LEDS1|R3_CONFIG3_LEDS0);
    Rtl3ConfigDisable();                                              // page3配置禁止
    Page0();
	
	RTL8019asRead(RW0_BNRY,ucBNRY);					   // 读出部分值,比较写入的值来判断是否初始化成功
   
    Page1();
    RTL8019asRead(RW1_MAR0,ucMAR0);
    RTL8019asRead(RW1_MAR1,ucMAR1);
    RTL8019asRead(RW1_MAR2,ucMAR2);
    RTL8019asRead(RW1_MAR3,ucMAR3);
    RTL8019asRead(RW1_MAR4,ucMAR4);
    RTL8019asRead(RW1_MAR5,ucMAR5);
    RTL8019asRead(RW1_MAR6,ucMAR6);
    RTL8019asRead(RW1_MAR7,ucMAR7);

    StartTimer(0,100);                                                // 运行灯定时器,1秒钟闪烁 
    StartTimer(8,105);                                                // 检测以太网link与否 
    StartTimer(9,1000);                                               // 以太网芯片保护校验 

    StartTimer(13,6000);                                              // 自我保护 

    if((0x4c == ucBNRY) && (0x00 == ucMAR0) && (0x00 == ucMAR1)
    && (0x00 == ucMAR2) && (0x00 == ucMAR3) && (0x00 == ucMAR4) 
    && (0x00 == ucMAR5) && (0x00 == ucMAR6) && (0x00 == ucMAR7))
    {      
        ArpRequestFormat.usHTYPE = HTYPE;		  //初始化ARP请求包
        ArpRequestFormat.usPTYPE = PTYPE;
        ArpRequestFormat.ucHLEN  = HLEN;
        ArpRequestFormat.ucPLEN  = PLEN;
        memcpy(&ArpRequestFormat.ucaSHA[0],&NetParameter.MAC_Local_buf[0],MAC_LEN);  // 源MAC地址 
        memset(&ArpRequestFormat.ucaTHA,0,MAC_LEN);                        // 目的MAC 

        ArpAnswerFormat.usHTYPE  = HTYPE;		 //初始化ARP应答包 
        ArpAnswerFormat.usPTYPE = PTYPE;
        ArpAnswerFormat.ucHLEN  = HLEN;
        ArpAnswerFormat.ucPLEN  = PLEN;
        ArpAnswerFormat.usOPER  = OPER_APLY;                                  // ARP应答 
        memcpy(&ArpAnswerFormat.ucaSHA[0],&NetParameter.MAC_Local_buf[0],MAC_LEN);      // 源MAC地址 

        gstIphead.ucVerAndLen = 0x45;			//初始化IP包
        gstIphead.ucDs = 0x00;
        gstIphead.usSegOffset = 0x00;
        gstIphead.ucTTL = 0x80;
        
        LocalIpID = rand();                                               // IP发送的16位标志,上电初始化为一个随机值

        Page0();														  // 将网片配置成正常工作模式
        RTL8019asWrite(W0_RCR,0xcc);                                      // 接收广播和组播数据
        RTL8019asWrite(W0_TCR,0xe0);
        RTL8019asWrite(W0_RBCR0,0x00);
        RTL8019asWrite(W0_RBCR1,0x00);
        RTL8019asWrite(RW0_CR,0x22);                                      // 网片开始工作
        RTL8019asWrite(RW0_ISR,0xff);                                     // 清除所有中断 
        EX0 = TRUE;    // 外部中断0使能                                   // 使能外部中断0
        IPOrMacConfiltFlag = FALSE; 
        EthernetLinkFlag = FALSE;
        IPConflitTestFlag = FALSE;
        return OK;
    }
    else
    {
        return ERROR;
    }
}
/*********************************************************************
函数名:       UWORK8 If8019SendReady(void)
功能:         检测以太网是否发送准备好
输入:         串口有数据需要发送 
输出:         
返回:         OK, ERROR
日期:         2007/03/13
*********************************************************************/
UWORK8 If8019SendReady(void)
{
     // ARP完成且发送完成 
    if(ARPFinishFlag && (FALSE == EthernetBuf0DataFlag))		//缓冲0有数据标志
    {
        return OK;
    }
    else
    {
        return ERROR;
    }       
}
/*********************************************************************
函数名:       void RcvEthernetData(void)
功能:         接收以太网数据
输入:         None 
输出:         None
返回:         OK, ERROR
日期:         2007/03/13
*********************************************************************/
void RcvEthernetData(void)
{
    UWORK16 ucTemp,ucResult;
    
    EX0 = FALSE;      // 禁止外部中断0
	if(0 != RTL8019asRcvNum)                            // 以太网芯片缓存中是否有以太网包 
    {
        EX0 = FALSE;      // 禁止外部中断0
        ucTemp = RevEthernetPacket();				   //解析网络包
 //   SerialSendbuf((UWORK8 *)&gstaRevEthernet.usprotocol,sizeof(ST_RECEIVE_ETHERNET));
		EX0 = TRUE;    // 外部中断0使能
        if(OK == ucTemp)                            // 正确接收了数据,记录的缓存减1 
        {
		   
		    RTL8019asRcvNum--;
            EthernetNoDataFlag = FALSE;
            switch(gstaRevEthernet.usprotocol)			   // 劈以太网帧 
		    {
		        case IP_type:			  //IP协议
		             IpReceive();
		            break;
		        case ARP_type:			 //ARP协议
		             ArpProcess();
		            break;
		        default:
		            break;
		    } 
        } 
    }
    else                                               // 可能中断未被及时执行 
    {
       if(FALSE == EthernetNoDataFlag)                 // 可能有没有及时中断造成数据没有读完 
        {
            EX0 = FALSE;      // 禁止外部中断0
            Page1();
            RTL8019asRead(RW1_CURR,ucTemp);              // 比较读指针和写指针,判断是否有数据            
            Page0();
           if((ucTemp < 0x80) && (ucTemp > 0x4b))      // 读的过程是否出错,CUUR处于0x4c~0x7f 
            {
                RTL8019asRead(RW0_BNRY,ucResult);
                ucResult++;
               if(ucResult > 0x7f)
                {
                    ucResult = 0x4c;
                }
               if(ucTemp != ucResult)                  // 是否有没有读完的数据 
                {
                    ucTemp = RevEthernetPacket();
                    EX0 = TRUE;    // 外部中断0使能
                   if(OK == ucTemp)                 // 正确接收了数据,记录的缓存减1 
                    {
                        switch(gstaRevEthernet.usprotocol)			   // 劈以太网帧 
					    {
					        case IP_type:
					             IpReceive();
					            break;
					        case ARP_type:
					             ArpProcess();
					            break;
					        default:
					            break;
					    }             
                    }
                }
                else
                {
                    EthernetNoDataFlag = TRUE;        // 以太网芯片中确实没有了数据 
                }
            }
            EX0 = TRUE;    // 外部中断0使能
        }
    }
    EX0 = TRUE;    // 外部中断0使能
}
/*********************************************************************
函数名:       UWORK8 SendEthernetPacket(UWORK16 usEthDataSendLen)
功能:         发送以太网包
输入:         协议头长度,串口数据长度,临时数据长度 
输出:         None
返回:         OK, ERROR
日期:         2004/12/06
*********************************************************************/
UWORK8 SendEthernetPacket(UWORK16 usEthDataSendLen)
{
    UWORK16 usLoop;
    UWORK8 ucLenHigh,ucLenLow,ucLoop,ucPadding = 0;

   if(FALSE == EthernetLinkFlag)                            // 以太网link上,才能发送数据
    {
        return ERROR;
    }
    
    if(EthernetBuf0DataFlag)                                      //清除缓冲0有数据标志, 网络正忙,等待 
    {
        for(usLoop = 0; usLoop < 5; usLoop++)
        {
            DelayMs(5);
            if(FALSE == EthernetBuf0DataFlag)					//清除缓冲0有数据标志
            {
                break;
            }
        }
        if(5 == usLoop)
        {
            return ERROR;                                // 等待超时,丢弃数据 
        }
    }
    EX0 = FALSE;      // 禁止外部中断0
    Page0();
    RTL8019asWrite(W0_RSAR1,0x40);                            // 缓冲区0,远程DMA高地址
    RTL8019asWrite(W0_RSAR0,0x00);                            // 远程DMA低地址 
     
    usLoop = ETHER_HEAD_LEN + usEthDataSendLen;				  // 帧长 = 以太网头 + 数据 
    if(usLoop < 60)       

⌨️ 快捷键说明

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