您的位置:首页 > 其它

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

2012-07-07 18:08 381 查看

3.5 DM9000的数据包发送函数

3.5.1 思路

抓住主干;step by step。

3.5.2 发送数据包的过程

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

首先,我们看发送过程:

a) 检测内存数据位宽

b) 将数据写入TX SRAM

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

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

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

当数据包被发送完毕后,

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

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

注意:内存数据位宽是可以通过ISR的bit[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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: