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

📄 rtl8019as.c

📁 S3C44B0X接8019的源代码
💻 C
字号:
 #include <string.h>
#include <stdio.h>
#include "rtl8019as.h"
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\MyType.h"
#include "..\inc\NetProtocol.h"

extern BYTE	g_SrcIP_Addr[];
extern BYTE	g_SrcMAC_Addr[];

void DelayMs(unsigned short MSecond);
void RTL8019AS_Rreset();
void Page(unsigned char PageNo);

void __irq rtl8019INT(void)
{
	unsigned char HSYNC;
	HSYNC = rEXTINTPND;			//read the interrup condition
	rEXTINTPND=0xf;					//clear ExINTPEND reg
	rI_ISPC |= BIT_EINT4567;		//clear pending bit
	OUT_B(P0_ISR, 0xFF);
}

void InitRTL8019AS()
{
	unsigned char val;
	short			i;
	RTL8019AS_Rreset();		// 网卡复位	

	OUT_B(P_CR, 0x21);			// 置CR:选择页0的寄存器,网卡停止运行,因为还没有初始化;	
	DelayMs(10);				// 延时10毫秒,确保芯片进入停止模式;

	OUT_B(P0_PSTART, 0x4C);		// 设接收缓冲区起始地址为0x4c;
	OUT_B(P0_PSTOP, 0x80);		// 设接收缓冲区结束地址为0x80(第0x7f页有效);
	OUT_B(P0_BNRY, 0x4C);		// 设接收缓冲区读页指针为0x4c;
	OUT_B(P0_TPSR, 0x40);		// 设发送缓冲区起始地址为0x40。
	OUT_B(P0_TCR, 0xE0);
	OUT_B(P0_ISR, 0xFF);		// 清除中断状态寄存器所有中断标志位;
	OUT_B(P0_IMR, 0x00);		// 设中断屏蔽寄存器,屏蔽所有中断。
	OUT_B(P0_DCR, 0xC8);		// 置数据配置寄存器:FIFO开始;高字节MD15-8,低字节MD7-0;8位DMA方式。
//	OUT_B(P0_RCR, 0xDF); 
	OUT_B(P0_RCR, 0xDC); 
	OUT_B(P0_RBCR0, 0x00);		// 给远程DMA字节计数器低字节清0;
	OUT_B(P0_RBCR1, 0x00);		// 给远程DMA字节计数器高字节清0;

	OUT_B(P_CR, 0x61);

	DelayMs(10);
	OUT_B(P1_CURR, 0x4D);		// 置当前页寄存器:指向当前正在写的页的下一页,
				// 初始化时指向0x4c+1=0x4d。

	for(i = 0; i < MAC_ADDR_LEN; i++)
	{
		OUT_B(P1_PAR0+i, g_SrcMAC_Addr[i]);		// 设物理地址寄存器i值
	}
	for(i = 0; i < 8; i++)
	{
		OUT_B(P1_MAR0+i, 0x00);					// 设组播地址寄存器i值
	}
	OUT_B(P_CR, 0x22);		// 设命令寄存器:选择页0的寄存器,让8019芯片开始工作;

}

void S3c44b0x_init_for_RTL8019(void)
{
     U32 i = 0;

     //PCONB PB7 = 1 select nGCS3
     rPCONB |=  (0x01<<8);

     //PCONG PG3->7:6 = 11 select EINT4
     rPCONG |=  (0x03<<8);

     //rPUPG  PG3->3 = 1 pull up enable
     rPUPG |= (0x01<<4);

     //rEXTINT  EINT3->14:12 = 000  low
    // rEXTINT |=   (0x01<<14);
     //rEXTINT &= ~(0x01<<13);
     //rEXTINT &= ~(0x01<<12);
	 rEXTINT &= ~(0x01<<18);
     rEXTINT &= ~(0x01<<17);
     rEXTINT &= ~(0x01<<16);

     //nGCS2  16BIT no nWBE no wait
     //11:ST2 =0 , 10: WS2 =0 , 9.8: DW2 = 01
   //  rBWSCON |=  (0x01<<11);
  //   rBWSCON &= ~(0x01<<10);
 //    rBWSCON &= ~(0x01<<9);
//     rBWSCON |=  (0x01<<8);
	 rBWSCON |=  (0x01<<15);
     rBWSCON &= ~(0x01<<14);
     rBWSCON &= ~(0x01<<13);
     rBWSCON &= ~(0x01<<12);

     //B2_Tacs		EQU	0x3	;4clk
     //B2_Tcos		EQU	0x3	;4clk
     //B2_Tacc		EQU	0x7	;14clk
     //B2_Tcoh		EQU	0x3	;4clk
     //B2_Tah		EQU	0x3	;4clk
     //B2_Tacp		EQU	0x3	;6clk
     //B2_PMC		EQU	0x0	;normal(1data)
     rBANKCON3 = 0x0700;


     //rPCONE PE3->7:6 = 01 output
     rPCONE &= ~(0x01<<7);
     rPCONE |=	(0x01<<6);

     //rPUPE PE3->3 = 1 pull up enable
     rPUPE |= (0x01<<3);

     //rPDATE PE3 = 1 -> 0  => rst 8019
     rPDATE |= (0x01<<3);
     for(i=0;i<200000;i++);
     rPDATE &= ~(0x01<<3);
     for(i=0;i<200000;i++);
	rNCACHBE0 = (((((0x8000000)>>12)+1)<<16)|((0x6000000)>>12));
	rSYSCFG= SYSCFG_8KBn;
}


void DelayMs(unsigned short MSecond)
{	
	int i,j;

	for(i=0; i<MSecond;i++)
	{
		for(j=0; j< 5000;j++)
			;
	}
}


void Page(unsigned char PageNo)		// 设置寄存器页数
{
	unsigned char ByteVal;

//Uart_Printf("PageNo=[%d].\n",PageNo);
	ByteVal=IN_B(P_CR);
//Uart_Printf("ByteVal.in=[%x].\n",ByteVal);
	ByteVal=(ByteVal&0x3f)|(PageNo<<6)|0x20;
//Uart_Printf("ByteVal.out=[%x].\n",ByteVal);
	OUT_B(P_CR, ByteVal);
}

void RTL8019AS_Rreset()	// 网卡复位
{
	unsigned char val;

	val = IN_B(P_RESET);
	OUT_B(P_RESET, val);
	DelayMs(100);
}


/*
RTL8019AS接收帧格式:
接收状态(1),下一页指针(1),以太网帧长度(2),目的IP地址DA(6),源IP地址SA(6),类型TYPE/长度LEN(2),数据域DATA(<=1500),
填充PAD(可选),校验FCS(4)
*/
BYTE RTL8019AS_RcvPacket(Frame8019 *Packet)
{
	static  int   currCount = 0;
	BYTE 	i;
	BYTE 	reProtocol = PROTOCOL_NULL;
	short 	j;
	WORD	frameLen = 0;
	WORD    packetLen = 0;
#define    PACK_HEAD_LEN    18
	unsigned char Bnry, Curr;
	Page(0);							// 选择页0的寄存器
	Bnry=IN_B(P0_BNRY);			// 读接收缓冲区读页指针

	Page(1);					// 选择第1页的寄存器
	Curr=IN_B(P1_CURR);			// 读接收缓冲区写页指针

	Page(0);
	if (Curr==0 || Curr > 0x7f || Curr < 0x4c)
		return PROTOCOL_NULL; 						// 读的过程出错返回0

	Bnry++;

//Uart_Printf("Bnry = %x,  Curr = %x\n", Bnry, Curr);

	if (Bnry>0x7F || Bnry < 0x4c)
		Bnry=0x4C;

	if (Bnry!=Curr)
	{	// 此时表示有新的数据包在缓冲区里;
		// 读取一包的前18个字节:4字节的8019头部,
		// 6字节目的地址,6字节源地址,2字节协议
		Page(0);					// 返回到页0
		OUT_B(P0_RSAR1, Bnry);		// 设远程(DMA)起始地址寄存器1(高字节)为Bnry
		OUT_B(P0_RSAR0, 0x00);		// 设远程(DMA)起始地址寄存器0(低字节)为0
		OUT_B(P0_RBCR1, 0x00);		// 设远程字节计数寄存器1(高字节)为0
		OUT_B(P0_RBCR0, PACK_HEAD_LEN);		// 设远程字节计数寄存器0(低字节)[准备读包头18字节]
		OUT_B(P_CR, 0x0A);			// 设命令寄存器:选择页0, 远程DMA读, 开始执行。

		Uart_Printf("\nRTL8019AS_RcvPacket      %d\n", ++currCount);
//Uart_Printf("EtherPacket Header :\n");
		for (i=0; i<PACK_HEAD_LEN; i++)		// 读18个字节
		{
			*((BYTE *)Packet + i) = IN_B(P_DMA_PORT);
//Uart_Printf(" %x,", *((BYTE *)Packet + i));
		}
//Uart_Printf("\n");	


		frameLen = (Packet->Length[1]<<8) + Packet->Length[0];


		frameLen -= 4;	// 去掉4个字节的CRC,表示读入的数据包有效
//		if(((Packet->Status & 0x01) == 0)||(Packet->NextPage > 0x7F)||
		if((Packet->NextPage > 0x7F)||
			(Packet->NextPage < 0x4C)||(frameLen > 1514))
		{	// 接收状态错误, 或者NextPageStart错误,或者长度错误, 将丢弃所有数据包
			Uart_Printf(" RTL8019AS_RcvPacket   WRONG   \n");
//Uart_Printf("Status 0x%.2x   NextPage 0x%.2x  0x%.2x%.2x    %d\n", 
//               Packet->Status,  Packet->NextPage, Packet->Length[1],Packet->Length[0], frameLen);	

			Page(1);					// 选页1的寄存器
			Curr=IN_B(P1_CURR);	// 读接收缓冲区写页指针

			Page(0);					// 选页0的寄存器
			Bnry=Curr-1;

			if (Bnry<0x4C)
				Bnry=0x7F;
			OUT_B(P0_BNRY, Bnry);	// 写接收缓冲区读页指针
//Uart_Printf("WRONG Bnry = %x, Curr = %x\n", Bnry, Curr);
			return PROTOCOL_NULL;
		}
		else
		{	// 表示数据包是完好的.读取剩下的数据
			if (((Packet->Status & 0x01) == 1) && (Packet->Protocol[0] == 0x08) && (Packet->Protocol[1] ==0x00 || Packet->Protocol[1] ==0x06))		// ARP包0x0806
			{

				// 协议为IP或ARP才接收
				OUT_B(P0_RSAR1, Bnry);			// 设远程起始地址寄存器1(高字节)
				OUT_B(P0_RSAR0, PACK_HEAD_LEN);				// 设远程起始地址寄存器0(低字节)
				packetLen  = frameLen - 14; 
				OUT_B(P0_RBCR1, packetLen >>8);	// 设远程字节计数寄存器1(高字节)
				OUT_B(P0_RBCR0, packetLen & 0xff);	// 设远程字节计数寄存器0(高字节)
				OUT_B(P_CR, 0x0A);			// 设命令寄存器:选择页0, 远程读, 开始执行。

				for (j = 0; j < packetLen; j++)
					Packet->Packet[j]=IN_B(P_DMA_PORT);	// 读远程DMA口
				
				reProtocol = (Packet->Protocol[1] ==0x06) ? PROTOCOL_ARP : PROTOCOL_IP;
			
			}
			else
			{
				reProtocol = PROTOCOL_NULL;
			}

			
			Bnry=Packet->NextPage-1;		// 下一页指针减1
			if (Bnry<0x4C)
				Bnry=0x7F;
			OUT_B(P0_BNRY, Bnry);					// 设接收缓冲区读页指针
			
			return reProtocol;									// 读包成功,返回1
		}
	}
	return PROTOCOL_NULL;			// 不成功,返回0
}

// ne2000 发包子程序
// 发送一个数据包的命令, 长度最小为60 字节,
// 最大1514 字节需要发送的数据包要先存放在 txdnet 缓冲区

void RTL8019AS_SndPacket(Frame8019 *Packet, short Length)
{
	static unsigned char TransBufSwitch=0;
	unsigned char i;
	short j;

	Page(0);		// 选择页0的寄存器

	if (Length<60)
		Length=60;

	TransBufSwitch=!TransBufSwitch;

	if (TransBufSwitch)
		OUT_B(P0_RSAR1, 0x40);		// 设远程(DMA)起始地址寄存器1=前缓冲区首页
	else
		OUT_B(P0_RSAR1, 0x46);		// 设远程(DMA)起始地址寄存器1=后缓冲区首页 

	OUT_B(P0_RSAR0, 0x00);			// 设远程(DMA)起始地址寄存器0(低字节)值

	OUT_B(P0_RBCR1, (BYTE)(Length>>8));		// 设远程字节计数器寄存器1(高字节)
	OUT_B(P0_RBCR0, (BYTE)(Length&0xFF));	// 设远程字节计数器寄存器0(低字节)

	OUT_B(P_CR, 0x12);		// 设命令寄存器:选择0页寄存器, 远程写DMA, 起始命令。

	for (j=4; j<Length+4; j++)
		OUT_B(P_DMA_PORT, *((BYTE *)Packet + j));	// 写远程DMA口

for (i=0; i<6; i++)					// 最多重发6 次
{
for (j=0; j<1000; j++)
if ((IN_B(P_CR)&0x04)==0)	// 读命令寄存器,检查TXP:为是否为低(传送结束或中止)
break;
if ((IN_B(P0_TSR)&0x01)!=0)		// 读发送状态寄存器,检查PTX:发送成功为1时,退出;
break;
OUT_B(P_CR, 0x3E);				// 设命令寄存器:选择页0,中止DMA,执行发送。
}


	// 发送新的数据帧
	if (TransBufSwitch)
		OUT_B(P0_TPSR, 0x40);			// 设发送页起始寄存器=前缓冲区首页;
	else
		OUT_B(P0_TPSR, 0x46);			// 设发送页起始寄存器=后缓冲区首页;

	OUT_B(P0_TBCR1, (BYTE)(Length>>8));			// 设发送字节计数器1(高字节)
	OUT_B(P0_TBCR0, (BYTE)(Length&0xFF));		// 设发送字节计数器0(低字节)
	OUT_B(P_CR, 0x3E);					// 设命令寄存器:选择页0,中止DMA,执行发送。
}

⌨️ 快捷键说明

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