📄 rtl8019as.c
字号:
//**********************************
//*版本: Test 1.0
//*作者: XUGUOHONG
//*E-MAIL: KK20Y@YAHOO.COM.CN
//*WEBSITE:microdesign.000webhost.com
//**********************************
#include <rtl8019as.h>
#include <iom162v.h>
//**********************************
//* 系统 MAC地址设定(根据需要修正)
//**********************************
unsigned char SYSMAC[6]={0X00,0X11,0X22,0X33,0X44,0X55};
//**********************************
//* 系统 IP地址设定(根据需要修正)
//**********************************
unsigned char SYSIP[4]={192,168,0,8};
void rtl8019as_init(void);
void int0_init(void);
void int0_neton(void);
void getpacket(void);
void sendpacket(unsigned int);
//*************************
// RTL8019AS初始化
//*************************
void rtl8019as_init(void)
{
unsigned char temp;
rtl8019_rst( ); // 硬件复位
write_8019(RSTPORT,read_8019(RSTPORT)); // 软件复位
delay_ms(20); // 复位等待建立
if( read_8019(ISR)&0b10000000==0)
{
// 硬件故障处理
}
write_8019(CR,0X21); // 停止NIC,退出DMA,PAGE0
delay_ms(20); // 等待
write_8019(DCR,0X58); // 数据配置寄存器,
write_8019(RBCR0,0X00); // 远端DMA字节计数寄存器0
write_8019(RBCR1,0X00); // 远端DMA字节计数寄存器1
write_8019(RCR,0X04); // 接收配置寄存器,
//RING BUFFER中的地址分配
//每页 256 BYTE
//最大帧 1518 BYTE 0X05EE
//TPSR发送起始地址:0x4000
// + 0x05EE = 0X45EE
//PSTART页起始地址:0X4600
//PSTOP页结束地址: 0X6000
write_8019(TPSR,0X40); // 数据包发送开始页地址
write_8019(TCR,0X02); // 发送配置寄存器,
write_8019(PSTART,0X46); //
write_8019(BNRY,0X46); //
write_8019(PSTOP,0X60); //
write_8019(CR,0X61); // 选择第2页
delay_ms(2);
write_8019(CURR,0X46);
for(temp=0;temp<6;temp++)
write_8019(PAR0+temp,SYSMAC[temp]); // 写入MAC地址
write_8019(CR,0X21);
delay_ms(20);
write_8019(CR,0X22);
write_8019(ISR,0xFF); // 清除中断标志位
write_8019(IMR,0x11); // 中断屏蔽寄存器,置"1"允许相应的位
write_8019(TCR,0x00);
}
//****************************
// 中断初始化
//****************************
void int0_init()
{
MCUCR|=(0<<ISC01)|(1<<ISC00);
GICR|=(1<<INT0);
asm("sei");
}
//****************************
// 中断处理子程序
//1.中断开始说明有数据包接收
//2.首先,写入读命令
//3.读取前四个字节来计算包长度
//4.根据长度来循环读出数据
//5.在读取的过程中可能在有数据送入,而此时检测不到
//6.读取当前数据后,比较BNRY和CURR判断是否已将所有数据读出
//7.未读完,继续读取
//8.已读完,将BNRY和CURR恢复初值
//****************************
#pragma interrupt_handler int0_neton:iv_INT0
void int0_neton(void)
{
unsigned char temp;
unsigned char datah;
unsigned char datal;
asm("cli"); // 关闭中断
temp= read_8019(ISR);
if( (temp&0b00010000)==0b00010000 ) // 是否OVERRUN
{
//overrun(); // OVERRUN处理
rtl8019as_init( );
asm("sei");
}
else if( (temp&0b00000001)==0b00000001 ) // 数据包是否有错
{
getpacket(); // 接收数据包
}
// 检测是否在8019缓存中还有其他数据包存在
// 必须考虑在中断处理中有其他网络数据包接
// 入而未检测到
datah=read_8019(BNRY); // 检测BNRY是否等于CURR
write_8019(CR,0x62); // BNRY=CURR数据已读完成
datal=read_8019(CURR);
write_8019(CR,0x22);
while(datah<datal)
{
getpacket(); // BNRY!=CURR数据未读完,继续读
datah=read_8019(BNRY); // 检测BNRY是否等于CURR
write_8019(CR,0x62); // BNRY=CURR数据已读完成
datal=read_8019(CURR);
write_8019(CR,0x22);
}
write_8019(BNRY,0X46); // 所有数据读完后,归位
write_8019(CR,0X61); // 选择第2页
write_8019(CURR,0X46); // 所有数据读完后,归位
write_8019(CR,0X22);
write_8019(ISR,0xFF);
asm("sei");
}
//************************************
// 数据包接收子程序
//1. 接收到一个数据包
//2. 处理一个数据包
//3. ***数据包在这里不适合用嵌套来完成检测和读取
// ***因为这样会占用大量的RAM空间,从而使堆栈益出.
//************************************
void getpacket(void)
{
unsigned char temp;
unsigned int counter;
unsigned char datah;
unsigned char datal;
unsigned int RXLEN; // 接收数据长度
unsigned char PAGEHEADER[4]; // 接收数据,头四位数据
write_8019(CR,0X1A); // 发送SEND PACKET命令来接受数据
for(temp=0;temp<4;temp++) // 先读出头四位数据来计算数据包长度
{
PAGEHEADER[temp]=read_8019(RDMAPORT); // 头四个数据先读出
}
RXLEN=PAGEHEADER[PACKETLENH]; // 计算数据包大小
RXLEN=RXLEN<<8;
RXLEN=RXLEN+PAGEHEADER[PACKETLENL];
for(counter=0;counter<RXLEN;counter++) // 将数据读入SRAM 62256
{ // 从SRAM地址0X0000开始
write_62256(counter,read_8019(RDMAPORT)); // 大小64-1518Byte
//uart_send(read_62256(counter));
}
temp= read_8019(ISR);
while((temp&0b01000000)==0b00000000) // 检测是否DMA完成
{
temp= read_8019(ISR);
}
//==================================================================
//===对收到的数据包进行判断选择处理=== // 与协议上层接口
datah=read_62256(12); // 数据包类型判断
datal=read_62256(13);
if( (datah==0x08)&&(datal==0x00) )
{
ip();
}
else if( (datah==0x08)&(datal==0x06) )
{
arp(); // 已完成
}
else if( (datah==0x80)&(datal==0x35) )
{
//rarp();
}
else if( (datah==0x86)&(datal==0xdd) )
{
//ipv6();
}
else
{
;
}
//==================================================================
}
//****************************
// 数据包发送子程序
//****************************
void sendpacket(unsigned int TXLEN)
{
unsigned char temp;
unsigned int counter;
write_8019(CR,0X22);
write_8019(ISR,0xFF); // 清除中断标志位
write_8019(RSAR0,0X00); // MCU写入buffer ring 的起始地址
write_8019(RSAR1,0X40);
write_8019(ISR,0xFF); // 清除中断标志位
write_8019(RBCR0,TXLEN); // 写入数计数,MCU TO 8019 COUNTER
write_8019(RBCR1,TXLEN>>8);
write_8019(CR,0X12); // 执行REMOTEWRTIE指令
for(counter=0;counter<TXLEN;counter++)
{
write_8019(RDMAPORT,read_62256(counter));
//uart_send(read_62256(counter));
}
temp= read_8019(ISR);
while(temp&0b01000000==0b00000000) // 等待DMA完成
;
write_8019(ISR,0xFF); // 清除中断标志位
write_8019(TBCR0,TXLEN); // 写入数计数,8019 TO NET COUNTER
write_8019(TBCR1,TXLEN>>8);
write_8019(CR,0X24); // 开始MCU TO NET 发送
temp= read_8019(ISR); // 等待数据发送完成
while(temp&0b00000010==0b00000000) // 等待数据发送无误结束
temp= read_8019(ISR); //
write_8019(ISR,0xFF); // 清除中断标志位
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -