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

📄 ip.c

📁 RTL8019以太网开发板资料
💻 C
📖 第 1 页 / 共 2 页
字号:
					            break;
					    }             
                    }
                }
                else
                {
                    EthernetNoDataFlag = TRUE;        // 以太网芯片中确实没有了数据 
                }
            }
            EX0 = TRUE;    // 外部中断0使能
        }
    }
    EX0 = TRUE;    // 外部中断0使能
}
/*********************************************************************
函数名:       void SendDiagnoseData(void)
功能:         发送诊断数据
输入:         None 
输出:         None
返回:         OK, ERROR
日期:         2004/10/12
*********************************************************************/
void SendDiagnoseData(void)
{
    UWORK8 ucLenHigh,ucLenLow;
    UWORK16 usLen,usLoop;
    xdata UWORK8 ucaDiagData[500 + ETHER_HEAD_LEN];

    memcpy(&ucaDiagData[0],&NetParameter.MAC_Local_buf[0],12);        // 组帧数据 
    ucaDiagData[12] = 0x08;
    ucaDiagData[13] = 0x00;
    for(usLoop = ETHER_HEAD_LEN; usLoop < 500 + ETHER_HEAD_LEN; usLoop++)
    {
        ucaDiagData[usLoop] = 0xaa;
    } 
               // 远程DMA写操作 
    RTL8019asWrite(W0_RSAR1,0x40);                            // 缓冲区0,远程DMA高地址
    RTL8019asWrite(W0_RSAR0,0x00);                            // 缓冲区0,远程DMA低地址 
    usLen = 500 + ETHER_HEAD_LEN;
    ucLenLow = (UWORK8)usLen;
    ucLenHigh = (UWORK8)(usLen >> 8);
    //RTL8019asWrite(W0_RBCR1,0x0f);                          // 根据资料,需要先将RBCR1写入0x0f 
    RTL8019asWrite(W0_RBCR1,ucLenHigh);                       // 设置远程DMA写的字节数 
    RTL8019asWrite(W0_RBCR0,ucLenLow);
    //RTL8019asWrite(RW0_CR,0x0a);                            // 在写命令之前应该先读一下 
    RTL8019asWrite(RW0_CR,0x12);                              // 启动远程DMA写 
    for(usLoop = 0; usLoop < usLen; usLoop++)
    {
        RTL8019asWrite(RTL_REMOTE,ucaDiagData[usLoop]);
    }
    RTL8019asWrite(RW0_ISR,0xff);                             // 清除所有中断 
                    // 启动发包命令 
    RTL8019asWrite(W0_TPSR,0x40);                             // 本地DMA地址 
    RTL8019asWrite(W0_TBCR1,ucLenHigh);                       // 本地DMA字节数 
    RTL8019asWrite(W0_TBCR0,ucLenLow);
    RTL8019asWrite(RW0_CR,0x3e);                              // 启动网卡发包 
}
/*********************************************************************
函数名:       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)       
    {
        ucLenHigh = 0;
        ucLenLow  = 60;                                     // 至少发送60个字节 
        ucPadding = (UWORK8)(60 - usLoop);
    }
    else
    {
        ucLenLow  = (UWORK8)usLoop;
        ucLenHigh = (UWORK8)(usLoop >> 8);
    }
    
    RTL8019asWrite(W0_RBCR1,ucLenHigh);                       // 设置远程DMA写的字节数
    RTL8019asWrite(W0_RBCR0,ucLenLow);
    RTL8019asWrite(RW0_CR,0x12);                              // 启动远程DMA写 

    for(ucLoop = 0; ucLoop < ETHER_HEAD_LEN; ucLoop++)      // 发送以太网头 
    {
        RTL8019asWrite(RTL_REMOTE,MAC_Remote_buf[ucLoop]);
    }
    for(usLoop = 0; usLoop < usEthDataSendLen; usLoop++) 	   // 发送数据 , W0_RBCR自动减少,W0_RSAR 自动增加,这是以太网片DMA的特征 
    {
        RTL8019asWrite(RTL_REMOTE,NetSend_buf[usLoop]);
    }
    
    if(0 != ucPadding)                                      // 填充的数据 
    {
        for(ucLoop = 0; ucLoop < ucPadding; ucLoop++)
        {
             RTL8019asWrite(RTL_REMOTE,0);                    // 填充0 
        }
    }
    
    while(1)
    {
        RTL8019asRead(RW0_ISR,ucLoop);
        if(RW0_ISR_RDC & ucLoop)                            // 等待远程DMA操作结束 
        {
            RTL8019asWrite(RW0_ISR,RW0_ISR_RDC);              // 清除DMA结束标志 
            break;
        }
    }
    RTL8019asWrite(W0_RBCR1,0x00);                            // 远程DMA字节数设为0 
    RTL8019asWrite(W0_RBCR0,0x00);
    RTL8019asWrite(RW0_CR,0x22);                              // 远程DMA停止 
    
    RTL8019asWrite(W0_TPSR,0x40);                             // 本地DMA地址 
    RTL8019asWrite(W0_TBCR1,ucLenHigh);                       // 本地DMA字节数 
    RTL8019asWrite(W0_TBCR0,ucLenLow);
    RTL8019asWrite(RW0_CR,0x3e);                              // 启动网卡发包         
    EthernetBuf0DataFlag = 1;    						  //缓冲0有数据标志
    EX0 = TRUE;    // 外部中断0使能
    return OK;
}
/*********************************************************************
函数名:       UWORK8 gstaRevEthernetPacket(void)
功能:         接收以太网包
输入:         None 
输出:         None
返回:         OK, ERROR
日期:         2004/07/29
*********************************************************************/
UWORK8 RevEthernetPacket(void)
{
    UWORK8 RcvPackHead[4];
    UWORK8 ucBnry,ucLoop,ucCurr;
    UWORK16 usRcvLen,usLoop;
    UWORK8 *pucEthernet;
    
    Page1();
    RTL8019asRead(RW1_CURR,ucCurr);                           // 读出当前写指针 
    if((ucCurr < 0x4c) || (ucCurr > 0x7f))                  // 读的过程出错 
    {
        Page0();
        return ERROR;
    }
    Page0();
    RTL8019asRead(RW0_BNRY,ucBnry);                           //读取边界指针 
    if((ucBnry < 0x4c) || (ucBnry > 0x7f))
    {
        if(0x4c == ucCurr)
        {
            ucCurr = 0x7f;                                  // 掉头 
        }
        else
        {
            ucCurr--;
        }
        RTL8019asWrite(RW0_BNRY,ucCurr);                      // 写取边界指针
        gstEthernetStatistics.ulEthernetBnryRegError++;
        return ERROR;
    }
    
    if(0x7f == ucBnry)
    {
        ucBnry = 0x4c;
    }
    else
    {
        ucBnry++;
    }
    RTL8019asWrite(W0_RSAR1,ucBnry);                          // 远程DMA起始地址
    RTL8019asWrite(W0_RSAR0,0x00);

         // 只读取接收状态字(8位),下一页指针(8位)和以太网帧长度(16位)共4个字节 
    RTL8019asWrite(W0_RBCR1,0x00);                            // 设置远程DMA读的字节数4个 
    RTL8019asWrite(W0_RBCR0,0x04);
    RTL8019asWrite(RW0_CR,0x0a);                              // 启动读取数据 

    for(ucLoop = 0; ucLoop < 4; ucLoop++)
    {
        RTL8019asRead(RTL_REMOTE,RcvPackHead[ucLoop]);
    }

    while(1)
    {
        RTL8019asRead(RW0_ISR,ucLoop);
        if(RW0_ISR_RDC & ucLoop)                            // 等待远程DMA操作结束
        {
            RTL8019asWrite(RW0_ISR,RW0_ISR_RDC);              // 清除DMA结束标志 
            break;
        }
    }
    RTL8019asWrite(W0_RBCR1,0x00);                            // 远程DMA字节数设为0
    RTL8019asWrite(W0_RBCR0,0x00);
    RTL8019asWrite(RW0_CR,0x22);                              // 远程DMA停止 
    
    usRcvLen  = (UWORK16)RcvPackHead[3];                 // 高8位 
    usRcvLen <<= 8;
    usRcvLen |= (UWORK16)RcvPackHead[2];                 // 低8位 

    if((RcvPackHead[1] > 0x7f) || (RcvPackHead[1] < 0x4c) || (usRcvLen > 1518))   // 1514 + 4
    {
            // 如果下一页指针错误或者长度错误,将丢弃所有的包 */        
        Page1();
        RTL8019asRead(RW1_CURR,ucCurr);                       // 读出当前写指针 
        if((ucCurr < 0x4c) || (ucCurr > 0x7f))              // 读的过程出错 
        {
            RTL8019asWrite(RW1_CURR,0x4d);                    // 重新赋值 
            Page0();
            RTL8019asWrite(RW0_BNRY,0x4c);                    // 写取边界指针 
        }
        else
        {
            Page0();
            if(0x4c == ucCurr)
            {
                ucCurr = 0x7f;                              // 掉头
            }
            else
            {
                ucCurr--;
            }
            RTL8019asWrite(RW0_BNRY,ucCurr);                  // 写取边界指针
        }
        RTL8019asRcvNum = 0;
        gstEthernetStatistics.ulEthernetNextRegError++;
        return ERROR;
    }
    else                                                    // 读取正确的数据
    {
        usRcvLen -= 4;                                      // 去掉CRC 
        pucEthernet = (UWORK8 *)&gstaRevEthernet.ucaDestNodID[0];          
        RTL8019asWrite(W0_RBCR1,(UWORK8)(usRcvLen >> 8));     // 设置远程DMA读的字节数 
        RTL8019asWrite(W0_RBCR0,(UWORK8)usRcvLen);
        RTL8019asWrite(W0_RSAR1,ucBnry);                      // 远程DMA起始地址
        RTL8019asWrite(W0_RSAR0,0x04);
        RTL8019asWrite(RW0_CR,0x0a);                          // 启动读取数据 
        for(usLoop = 0; usLoop < usRcvLen; usLoop++)
        {
            RTL8019asRead(RTL_REMOTE,*pucEthernet);           // 远程DMA读 
            pucEthernet++;
        } 
        while(1)
        {
            RTL8019asRead(RW0_ISR,ucLoop);
            if(RW0_ISR_RDC & ucLoop)                        // 等待远程DMA操作结束 
            {
                RTL8019asWrite(RW0_ISR,RW0_ISR_RDC);          // 清除DMA结束标志 
                break;
            }
        }  
        RTL8019asWrite(W0_RBCR1,0x00);
        RTL8019asWrite(W0_RBCR0,0x00);
        RTL8019asWrite(RW0_CR,0x22);                          // 终止远程DMA操作 
        
        if(0x4c == RcvPackHead[1])
        {
            RcvPackHead[1] = 0x7f;
        }
        else
        {
            RcvPackHead[1]--;
        }
        RTL8019asWrite(RW0_BNRY,RcvPackHead[1]);           // 更新读指针   
    }
    return OK;
}


⌨️ 快捷键说明

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