📄 ip.c
字号:
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 + -