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

📄 ip.c

📁 TI公司的DSP TMS320VC5402开发板的全套资料
💻 C
📖 第 1 页 / 共 2 页
字号:
#include    "cpu_reg.h"
#include	"string.h"
#include	"ip.h"

extern	Uint16	AicRegs;
extern	Uint16  RxSuccessFlag;
extern	Uint16	TxEthnetFrameBuffer[1518/2];
extern	Uint16	RxEthnetFrameBuffer[1518/2];
extern	int		ms;

//小端格式存储
const Uint16 MyMAC[] = { 0xE002, 0xA04C, 0x7A7E };	//本机MAC地址:0x02,0xE0,0x4C,0xA0,0x7E,0x7A

const Uint16 MyIP[] = { 0xA8C0, 0x0B01 };	//192.168.1.11

const Uint16 RemoteIP[] = { 0xA8C0, 0x2801 };	//192.168.1.40

const Uint16 SubnetMask[] = { 0xFFFF, 0x00FF };	//255.255.255.0

const Uint16 GatewayIP[] = { 0xA8C0, 0x0101 };	//192.168.1.1

Uint16 TxBufFlag;
Uint16 bnry,curr;
Uint16 UDPUserDataLenth; 
Uint16 IpEdition;	//IP版本
Uint16 IpServiceType;
Uint16 IpIdent;
Uint16 MyUdpPort;

Uint16 RemoteMAC[3];	//48 bit MAC
Uint16 RecdFrameMAC[3];	
Uint16 RecdFrameIP[2];
Uint16 RecdIpFrameLenth;
Uint16 TxFrameSize;
Uint16 ARPAnswerSuccessFlag;

void delay(int k)
{
	while(k--);
}

Uint16 SwapByte(Uint16	value)
{
	Uint16	temp;
	temp = (value << 8) | (value >> 8 );
	return(temp);
}								

//==============================================================================
/**********************************************************************
**函数原型:    void  page(uchar pagenumber)
**入口参数:   	Uint16	pagenumber: 要切换的页
**出口参数:		无
**返 回 值:	无      
**说    明:	选择页,可选择0,1,2三页,第四页ne000兼容芯片保留 
************************************************************************/
void page(Uint16 pagenumber)
{
	Uint16	temp;
	temp = Reg00;	//command register
	temp = temp & 0x3B ;	//注意txp位不能要
	pagenumber = pagenumber << 6;
	temp = temp | pagenumber;
	Reg00 = temp;
}


/**********************************************************************
**函数原型:     void 	Init8019()
**入口参数:		无
**出口参数:		无
**返 回 值:		无              
**说    明:		对芯片的工作寄存器进行设置,各个寄存器的用法可参考文档和
**				络芯片的数据手册
************************************************************************/
void Init8019()
{
	ms = 0;
	while(ms < 100);
/**********************************************************************

1.Reg00命令寄存器: CR,命令寄存器,地址偏移量00H,为一个字节
  位:  7   6   5   4   3   2   1   0 
名字: PS1 PS0 RD2 RD1 RD0 TXP STA STP 
//============================================
2.
RD2,RD1,RD0: 这3个位代表要执行的功能。
 0   0   1 : 读网卡内存
 0   1   0 : 写网卡内存
 0   1   1 : 发送网卡数据包
 1   *   * : 完成或结束DMA的读写操作
//============================================
3.TXP位置1时发送数据包,发完自动清零
//============================================
4.
STA,STP:	这两个位用来启动命令或停止命令
 1   0 		启动命令
 0   1 		停止命令
//============================================
***********************************************************************/
	Reg00=0x21;		//使芯片处于停止模式,这时进行寄存器设置
	ms = 0;
	while(ms < 100);//延时100毫秒,确保芯片进入停止模式
	page(0);
	delay(10);
	Reg0a = 0x00;   //清RBCR0,RBCR0及RBCR1用来设置DMA传输的字节数
	delay(5);
	Reg0b = 0x00;	//清RBCR1
	delay(5);
	Reg0c = 0xe0;	//RCR,监视模式(地址匹配、CRC校验、帧对齐),不接收广播、多播及小于64字节的数据包
	delay(5);
	Reg0d = 0xe2;  	//TCR,loop back模式
	delay(5);
	Reg01 = 0x4c;   //PSTART = 0x4c,接收环形缓冲区的起始页地址
	delay(5);
	Reg02 = 0x80;   //PSTOP = 0x80,接收环形缓冲区的结束页地址
	delay(5);
	Reg03 = 0x4c;   //BNRY = 4c
	delay(5);
	Reg04 = 0x40;  	//TPSR,发送起始页寄存器,设置发送包的起始页地址
	delay(5);
	Reg07 = 0xff;  	//ISR,清除所有中断标志位,中断状态寄存器
	delay(5);
	Reg0f = 0x01;  	//IMR,中断屏蔽寄存器清0,禁止中断
	delay(5);
	Reg0e = 0xc9;  	//DCR,数据配置寄存器,16位DMA方式

	page(1);
	delay(10);
	Reg07 = 0x4d;	//CURR,指向接收缓冲区用于接收数据的第一个页地址
	delay(5);
	Reg08 = 0x00;	//MAR,多播地址寄存器
	delay(5);
	Reg09 = 0x00;
	delay(5);
	Reg0a = 0x00;
	delay(5);
	Reg0b = 0x00;
	delay(5);
	Reg0c = 0x00;
	delay(5);
	Reg0d = 0x00;
	delay(5);
	Reg0e = 0x00;
	delay(5);
	Reg0f = 0x00;
			
	delay(5);
    Reg01 = 0x02;	//PAR0,本机MAC地址:0x02,0xE0,0x4C,0xA0,0x7E,0x7A,用于自动匹配操作
    delay(5);
    Reg02 = 0xE0;
    delay(5);
    Reg03 = 0x4C;
    delay(5);
    Reg04 = 0xA0;
    delay(5);
    Reg05 = 0x7E;
    delay(5);
    Reg06 = 0x7A;
    delay(5);
			
	page(3);
	delay(10);
	Reg01 = 0x30;
	delay(5);
	Reg04 = 0x80;	//CONFIG1,选择IO基本地址:300H;选择IRQ:INT0
	delay(5);
			
	page(0);
	delay(10);
	Reg0c = 0xce;  	//接收广播、多播及小于64字节的包,不接收有错误的包
	delay(5);	   		
	Reg0d = 0xe0;	//将芯片设置成正常模式,跟外部网络连接
	delay(5);
	Reg00 = 0x22;  	//启动芯片开始工作
    delay(5);

//-----------------------------------
	Reg07 = 0xff;  	//清除所有中断标志位
	ms = 0;
	while(ms < 100);
}


Uint16 CalcCheckSum(Uint16 *Start, Uint16 Count, Uint16 IsTCP, Uint16 IsUDP)
{
    Uint32 Sum;
  
    Sum = 0;
    if ((IsTCP) || (IsUDP)) 
    {
        Sum += MyIP[0];
        Sum += MyIP[1];
        Sum += RemoteIP[0];
        Sum += RemoteIP[1];
        Sum += SwapWord(Count*2);
        if(IsTCP)
             Sum += SwapWord(PROTOCOL_TCP);
        else
             Sum += SwapWord(PROTOCOL_UDP);
    }
    while(Count > 0) 
    {
        Sum += *Start;
        Start ++;
        Count --;
    }
    Sum = (Sum & 0xFFFF) + ((Sum >> 16) & 0xFFFF);
    if(Sum & 0xFFFF0000)
        Sum++;
    return((Uint16)((~Sum) & 0xFFFF));
}


//=============================================================================
/**********************************************************************
**函数原型:    void 		SendFrame(Uint16 *TxdNetBuff,Uint16  length)
**入口参数:		Uint16    	*TxdNetBuff	:指向发送缓冲区
**              uint length					:发送数据包的长度
**出口参数:		无
**返 回 值:	无              
**说    明:	发送数据包,以太网底层驱动程序,所有的数据发送都要通过该程序
************************************************************************/
void SendFrame(Uint16 *TxdNetBuff, Uint16 length)
{
	Uint16	i,ii;
	if(length < 46/2)
    {
    	for(i = length; i < 60/2; i++)	
    		TxEthnetFrameBuffer[i] = 0;
        length = 60/2;
    }
			
	page(0);
	delay(10);						//切换至第0页
	length = length << 1;
	TxBufFlag =! TxBufFlag;			//设置两个发缓区,提高发送效率
	if(TxBufFlag)
	{
		Reg09 = 0x40;				//CRDA1,当前DMA地址,设置发送页地址
	}				
	else
	{
		Reg09 = 0x46;				//设置发送页地址
	}				
    
	Reg08 = 0x00; 					//CRDA0,read page address low
	delay(1);
	Reg0b = length >> 8;			//RBCR1,写发送长度高位
	delay(1);
	Reg0a = length & 0x00ff;        //RBCR0,写发送长度低位  
	delay(1);
	Reg00 = 0x12;					//Remote Write,write dma,page0

	for(i = 0; i < length/2; i++)
	{
		Reg10 = TxEthnetFrameBuffer[i];
   	}
/***************************************/
//以下为终止DMA操作
	Reg0b=0x00; 
	delay(1);
	Reg0a=0x00;
	delay(1);
	Reg00=0x22;						//结束或放弃DMA操作
	delay(1);
/***************************************/

	for(i = 0; i < 6; i++)			//最多重发6次
	{
		for(ii = 0; ii < 1000; ii++)//检查CR寄存器的txp位是否为低,为1说明正在发送,为0说明发完或出错放弃
    	{
        	if((Reg00 & 0x04) == 0)  
        	{ 
        		break; 
        	}
    	}
		if((Reg04 & 0x01) != 0)		//表示发送成功,判断发送状态寄存器TSR,决定是否出错
		{
			break;
		};
		Reg00 = 0x3e;				//TXP = 1
	}
	delay(1);
	Reg07 = 0xff;					//清除所有中断标志位
	if(TxBufFlag)
	{
  		Reg04 = 0x40;   			//txd packet start;
  	}
	else
	{
     	Reg04 = 0x46;  				//txd packet start;
    }
   	delay(1);	
	Reg06 = length >> 8;  			//TBCR1,high byte counter
	delay(1);
	Reg05 = length & 0xff;			//TBCR0,low byte counter
	delay(1);
	Reg07 = 0xff;
	delay(1);
	Reg00 = 0x3e;       			//to sendpacket;
}

/**********************************************************************
**函数原型:    Uint16        Rec_NewPacket()
**入口参数:		无
**出口参数:		无
**返 回 值:	0          没有新数据包
**              1          接收到新数据包
**说    明:	查询是否有新数据包并接收进缓冲区
************************************************************************/
Uint16	RecFrame()
{
	Uint16	i,ii;
	Uint16	Temp,length;
	union
	{
		Uint16	total;	
		struct
		{
			Uint16	high:8;
			Uint16	low:8;
		}e;
	}d;
	for(i = 0; i < 1518/2; i++)	
		RxEthnetFrameBuffer[i] = 0;				 		  		
	page(0);
	delay(10);
	bnry = Reg03;				//读页指针 the last receive buffer page the host has read
	bnry = bnry & 0x00FF;
	page(1);
	delay(10);
	curr = Reg07;				//curr writepoint 8019写页指针 指向接收缓冲区用于接收数据的第一个页地址
	curr = curr & 0x00FF;
	page(0);
	delay(10);
	if((curr == 0))
		return(0);	  			//读的过程出错
	bnry++;
	if(bnry > 0x7f)	
		bnry = 0x4c;
	if(bnry != curr)			//此时表示有新的数据包在缓冲区里
    {					 		//在任何操作都最好返回page0
     	page(0);
     	delay(10);
     //=======================================
     	Reg09 = bnry;			//读页地址的高字节,DMA的当前地址
     	delay(5);
     	Reg08 = 0x00; 			//读页地址的低字节
     	delay(5);
     	Reg0b = 0x00;			//读取字节计数高字节
     	delay(5);

⌨️ 快捷键说明

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