【学习笔记】DM9000裸机驱动(二)之接收发送函数

转自:http://blog.csdn.net/chjr1000/article/details/7724958

3.5 DM9000的数据包发送函数

3.5.1 思路

    抓住主干;step by step

3.5.2 发送数据包的过程

     DM9000发送数据总共包括两个过程:(1)发送过程;(2)状态职置位过程。

     首先,我们看发送过程:

a) 检测内存数据位宽

b) 将数据写入TX SRAM

c) 将传输的长度写入MDRAL & MDRAH

d) 将TXCRTXREQ置为1,当数据发送完毕后将TXREQ0(这个标志位可以用来检测数据是否发送完毕)。

       然后,我们看状态置位过程:

       当数据包被发送完毕后,

a) 系统会将ISR(reg_FEH)的bit[1]PTS1(之前必须设置IMRPTM位为1,即使能数据包发送)。这个状态位可以用在中断服务函数中。

b) 系统会使NSR(reg_01)bit[2]TX1END1。这个中断位可以用在轮询中。

注意:内存数据位宽是可以通过ISRbit[7:6]设置的,可以设置为8bit, 16bit, 32bit

3.5.3 数据包发送函数

//================================================================
//DM9000_send_Packet
//DM9000 packet发送函数
//================================================================
void DM9000_sendPacket(U8 *data_str, U32 length)
{
	U32 len; //数据的长度
	U32 i;
	U8  tmp;
	//==========数据发送开始=============//
	Uart_Printf("\r\nDM9000\r\n发送数据...\r\n");
	//1.关闭网卡中断
	DM9000_Write(IMR,0x80);	//先禁止网卡中断,防止在发送数据时被中断干扰。
	//2.将传输长度写到TXPLH和TXPLL中
	len = length;			//将发送长度写入
	DM9000_Write(TXPLH,(len>>8)&0x0ff);
	DM9000_Write(TXPLL,len & 0x0ff);
	//3.将数据写入TX SRAM中,通过MWCMD。
	rDM9000_ADDR = MWCMD; //将Memory Write CMD发送到ADD上
	for(i=0; i<len; i+=2)
	{
		uDelay(2);
		DM9000_WriteC_DATA(data_str[i] | (data_str[i+1]<<8));
	}
	//4.将TXCR的TXREQ置位
	DM9000_Write(TXCR, 0x01);
	
	//5.等待数据发送完成					   
	while(1)
	{
		U8 status;
		status = DM9000_Read(TXCR);
		if((status & 0x01) == 0x00)
			break;
	}
	//Uart_Printf("\r\n数据发送完毕,进入检测阶段\r\n");
	//==========数据发送结束=============//
	//==========状态置位开始=============//
	tmp = DM9000_Read(NSR);
	//Uart_Printf("\r\nNSR = %x\r\n",tmp);
	if(tmp && 0x04)
	{
		if((TSRI&0xfc) == 0x00)
			;//Uart_Printf("TSRI成功\r\n");
		else
			;//Uart_Printf("TSRI失败\r\n");
	}
	DM9000_Write(NSR,0xfc);	//清除状态寄存器,以防止对下一次的干扰。
							//由于发送数据没有设置中断,因此不必处理中断标志位。
	DM9000_Write(IMR,0x81);	//DM9000网卡的接收中断使能。
	Uart_Printf("\r\n数据发送完毕\r\n");
}

3.6 数据包接收函数

3.6.1 DM9000接收数据包结构

   第一个字节表明其后是否还有数据包;

   第二个字节和接收状态寄存器(RXSR)的值相同;

   第个和第四个为接收数据包的长度。

   其它字节为接收数据包。

3.6.2 DM9000接收数据包过程

   DM9000接收数据包共包括两个过程:(1)接收过程;(2)状态置位过程。

   接收过程如下:

(1)通过MRCMDX读数据包的第一个字节,并辨别其后是否有数据包;

(2)驱动IO的宽度;

(3)通过MRCMD读数据包的第二和第三字节,得到RXSR的值和接收数据包的长度;

(4)接收数据包

   状态置位过程:

   数据包接收完成后,会置位ISR的第一位置为1

3.6.3 DM9000的数据包接收函数

//================================================================
//DM9000_received_Packet
//DM9000 packet接收函数
//================================================================
U32 DM9000_receivePacket(U8 *data_str)
{
	U8  RX_First_byte=0;//RX SRAM的第一个字节的值
	U8  RX_status=0;//寄存器RXSR的值
	U32 RX_length=0;//接收数据包的长度
	U16  data_temp=0;
	U32 i;//计数用	
	//读取RX SRAM的第一个字节
	RX_First_byte = DM9000_Read(MRCMDX);//读取RX SRAM的第一个字节的值
	Uart_Printf("RX_First_byte = 0x%x",RX_First_byte);									//第一次读取经常得到00
	RX_First_byte = DM9000_Read(MRCMDX);//第二次读取一般能得到数据
	Uart_Printf("RX_First_byte = 0x%x",RX_First_byte);
	//读取RX SRAM的第二、三、四个字节
	if(RX_First_byte == 0x01)
	{
		U8 io_mode = DM9000_Read(ISR)>>6;
		rDM9000_ADDR = MRCMD; //将Memory Write CMD发送到ADD上
		
		if(io_mode == 0)//IO word mode
		{
			RX_First_byte = DM9000_ReadC_DATA();//读取接收状态寄存器的值
			Uart_Printf("\r\nRX_First_byte = %d\r\nRX_status = %d\r\n",RX_First_byte&0x00ff,(RX_status>>8)&0x00ff);
			RX_length = DM9000_ReadC_DATA();//读取接收状态寄存器的值
			Uart_Printf("\r\nRX_length = %d\r\n",RX_length);;
		}
		else if(io_mode == 1)//IO dword mode
		{
		
		}
		else if(io_mode == 2)//IO byte mode
		{
		
		}
		
		//读取接收的数据包
		for(i=0;i<RX_length;i=i+2)
		{
			//uDelay(20);
			data_temp = DM9000_ReadC_DATA();//读取到的16bit的数据
			data_str[i]   = data_temp&0x00ff;
			//Uart_Printf("data_str[%d] = %x",i,data_str[i]);
			Uart_Printf("  %x",data_str[i]);
			data_str[i+1] = (data_temp >> 8)&0x00ff;
			//Uart_Printf("data_str[%d] = %x",i+1,data_str[i+1]);
			Uart_Printf("  %x",data_str[i+1]);
		}
		//Uart_Printf("\r\nRX Data :%s.\r\n",data_str);//接收的数据
		//Uart_Printf("\r\nRX_length is %ld\r\n",RX_length);//接收的数据的长度
		return RX_length;
			
	}
	else
	{
		Uart_Printf("无数据包");
		return -1;
	}
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值