DM9000 Ethernet communication
接收封包结构:
uint16_t dm9000x_receivepacket(uint8_t* packet, uint16_t maxlen)
{
uint8_t mac_addr[]={0x00,0xe0,0x3d,0xf4,0xdd,0xf7};
unsigned char ready;
unsigned char rx_io_mode;
unsigned int rx_status = 0x00;
unsigned int rx_length = 0x00;
unsigned int rx_length_bak = 0x00;
unsigned int temp=0x0000;
unsigned int i;
ready = 0;//希望读取到“01H”
/*以下为有效数据包前的4个状态字节*/
if(ior(DM9000_ISR) & 0x01)
{
iow(DM9000_ISR, 0x01);
}
/*清除接收中断标志位*/
ready = ior(DM9000_MRCMDX); // 第一次读取,一般读取到的是 00H
if((ready & 0x0ff) != 0x01)
{
ready = ior(DM9000_MRCMDX); // 第二次读取,总能获取到数据
if((ready & 0x01) != 0x01)
{
if((ready & 0x01) != 0x00) //若第二次读取到的不是 01H 或 00H ,则表示没有初始化成功
{
iow(DM9000_IMR, 0x80);//屏幕网卡中断
dm9000x_inital(mac_addr);//重新初始化
iow(DM9000_IMR, 0x81);//打开网卡中断
}
goto rx_erro;
}
}
rx_io_mode = ior(DM9000_ISR) >> 7;
if(DM9000X_BYTE_MODE == (rx_io_mode & 0x01))
{
rx_status = ior(DM9000_MRCMD) + (ior(DM9000_MRCMD) << 8);
rx_length = ior(DM9000_MRCMD) + (ior(DM9000_MRCMD) << 8);
if(!(rx_status & 0xbf00) && (rx_length < 1522))
{
rx_length_bak = rx_length;
while(rx_length_bak--)
{
*(packet++) = ior(DM9000_MRCMD);
}
}
else
{
//printf("bad data!\r\n");
goto rx_erro;
}
}
else if(DM9000X_WORD_MODE == (rx_io_mode & 0x00))
{
////////////前四位 是接受包的状态字节/////////////////
rx_status = ior(DM9000_MRCMD);
//printf("DM9000X_WORD_MODE:rx_status = %d\r\n",rx_status);
rx_length = ior(DM9000_MRCMD);
//printf("DM9000X_WORD_MODE:rx_length = %d\r\n",rx_length);
if(!(rx_status & 0xbf00) && (rx_length < 1522))
{
rx_length_bak = rx_length;
//printf("Rx_length = %d\r\n",rx_length);
for(i = 0; i < rx_length; i += 2) {
temp= ior(DM9000_MRCMD);
packet[i]=temp & 0xff;
packet[i+1]=(temp>>8) & 0xff;
}
//printf("DM9000X_WORD_MODE Packet\r\n");
}
else
{
rx_length = 0;
printf("bad data!\r\n");
return 0;
}
printf("dm9000 io mode is 16bit.....!\n");
}
return rx_length;
rx_erro:
return 0;
}
void dm9000x_sendpacket( uint8_t* packet, uint16_t len)
{
uint16_t length = len;
uint16_t io_mode;
u16 i,Temp;
iow(DM9000_IMR, 0x80);//先禁止网卡中断,防止在发送数据时被中断干扰
io_mode = ior(DM9000_ISR) >> 7;
if(DM9000X_BYTE_MODE == (io_mode & 0x01))
{
while(length--)
{
iow(DM9000_MWCMD,*(packet++));
}
}
else
{
for(i=0;i<length;i+=2)
{
Temp = packet[i]|( packet[i+1]<< 8); iow(DM9000_MWCMD,Temp); } printf("dm9000x_sendpacket:dm9000 io mode is 16bit.....!\n"); } iow(DM9000_TXPLH, (len>>8) & 0x0ff);
iow(DM9000_TXPLL, len & 0x0ff);
iow(DM9000_TCR, 0x01);//发送数据到以太网上
while(!(ior(DM9000_NSR)&0x0C))
dm9000_delay(5);
iow(DM9000_NSR, 0x00);//清除状态寄存器,由于发送数据没有设置中断,因此不必处理中断标志位
iow(DM9000_IMR, 0x81);//DM9000网卡的接收中断使能
}