📄 udp.c
字号:
{
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;
}
/*********************************************************************
函数名: UWORK8 RTL8019asCheck(void)
功能: 诊断RTL8019AS
输入: None
输出: None
返回: OK, ERROR
日期: 2004/02/04
*********************************************************************/
UWORK8 RTL8019asCheck(void)
{
UWORK8 ucValue,ucLoop;
xdata UWORK8 ucaFIFO[8];
Page0(); // 1. 诊断数据线路
EX0 = FALSE; // 禁止外部中断0
RTL8019asWrite(W0_RCR,0xe1); // 不接收广播和组播数据,接收错误包
RTL8019asWrite(W0_TCR,0xe7); // cable环回模式,CRC产生禁止
RTL8019asWrite(W0_DCR,0xc0); // 8位DMA方式
SendDiagnoseData(); // 发送诊断数据
DelayMs(50);
RTL8019asRead(RW0_ISR,ucValue);
RTL8019asRead(RW0_CR,ucLoop);
if((RW0_ISR_PTX | RW0_ISR_RXE) == ucValue) // 发送完成,CRC错误
{
for(ucLoop = 0; ucLoop < 8; ucLoop++) // 读取FIFO中的8个数据
{
RTL8019asRead(R0_FIFO,ucaFIFO[ucLoop]);
}
}
else
{
return ERROR;
}
if((0xaa == ucaFIFO[0]) && (0xaa == ucaFIFO[1]) && (0x02 == ucaFIFO[2]) &&
(0x02 == ucaFIFO[3]) && (0x02 == ucaFIFO[4]) && (0xaa == ucaFIFO[5]) &&
(0xaa == ucaFIFO[6]) && (0xaa == ucaFIFO[7]))
{
Page0();
RTL8019asWrite(W0_RCR,0xcc); // 接收广播和组播数据
RTL8019asWrite(W0_TCR,0xe0);
RTL8019asWrite(W0_DCR,0xd8); // 8位DMA方式
RTL8019asWrite(W0_RBCR0,0x00);
RTL8019asWrite(W0_RBCR1,0x00);
RTL8019asWrite(RW0_CR,0x22); // 网片开始工作
RTL8019asWrite(RW0_ISR,0xff); //清除所有中断
EX0 = TRUE; // 外部中断0使能
ET0 = FALSE; // 禁止timer0中断
gusMsTick = 0;
ET0 = TRUE; // 使能timer0中断
return OK;
}
else
{
return ERROR;
}
}
/*********************************************************************
函数名: 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 RTL8019asReset(void)
功能: 初始化RTL8019AS
输入: None
输出: None
返回: OK, ERROR
日期: 2004/02/04
*********************************************************************/
UWORK8 RTL8019asReset(void)
{
RTL8019asResetFoot = 1;
DelayMs(5);
RTL8019asResetFoot = 0;
return OK;
}
/*********************************************************************
函数名: UWORK16 CheckSum(UWORK16 *pusPointer,UWORK16 usDataLen)
功能: 计算校验和
输入: 十六位的数据指针,数据长度
输出: 计算校验和
返回: 校验和的反码
日期: 2004/12/20
*********************************************************************/
UWORK16 CheckSum(UWORK16 *pusPointer,UWORK16 usDataLen)
{
UWORK8 ucDataLen,ucNum,ucLoop,ucLoopNum;
UWORK16 usRealDataLen;
UWORK32 ulCheckSum = 0;
usRealDataLen = usDataLen >> 1; // 8位长度变为16位长度
ucNum = usRealDataLen / 255;
ucDataLen = usRealDataLen % 255;
// 将循环变量换成8位,提高运行速度
for(ucLoopNum = 0; ucLoopNum < ucNum; ucLoopNum++)
{
for(ucLoop = 0; ucLoop < 255; ucLoop++)
{
ulCheckSum += *pusPointer;
pusPointer++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -