?? 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 + -