"); //-->
/*************************dm9000.c writer zxw 2010.3.26******************************/
#include"dm9000.h"
#include "def.h"
#include "ARP.h"
/************************************************************************************/
/******************************函数宏定义********************************************/
#define XIO_In16(InputPtr) (*(volatile unsigned int*)(InputPtr))
#define XIO_In8(InputPtr) (*(volatile unsigned char*)(InputPtr))
#define XIO_In32(InputPtr) (*(volatile unsigned long*)(InputPtr))
#define XIO_Out16(OutputPtr,Value) ((*(volatile unsigned int *)(OutputPtr))=(Value))
#define DM_ADD (*(volatile U16*)0x20000300)
#define DM_CMD (*(volatile U16*)0x20000304)
/************************************************************************************/
/******************************函数申明**********************************************/
unsigned int ior(unsigned long BaseAddress,unsigned int reg);
unsigned int Dm9000_Read(unsigned long BaseAddress,int type);
void Dm9000_Write(unsigned long BaseAddress,int type,unsigned int Value);
void iow(unsigned long BaseAddress,unsigned int reg,unsigned int data);
void delay(unsigned int t);
void Dm9000_reset(void);
void clear_interrupts(void);
void phy_write(unsigned long BaseAddress,unsigned int reg,unsigned int value);
void Dm9000_init(unsigned long BaseAddress);
void TransmitPacket(unsigned char *data_ptr,unsigned short tx_len);
unsigned char ReceivePacket(unsigned char *data_ptr);
/**********************************定义接受数组和发送数组****************************/
//unsigned char data_ptrR[MAX_PACKET_SIZE];
//unsigned char data_ptrT[MAX_PACKET_SIZE];
unsigned char ether_addr0[6]={8,90,90,90,90,90};
//unsigned char ether_addr1[6]={8,90,90,90,90,90};
/***************************函数实体********************************************************/
void dm9000_reg_write(U8 reg, U8 data)
{
delay(1000);//之前定义的微妙级延时函数,这里延时20us
DM_ADD = reg;//将寄存器地址写到INDEX端口
delay(1000);
DM_CMD = data;//将数据写到DATA端口,即写进寄存器
}
/**********************************************/
U8 dm9000_reg_read(U8 reg)
{
delay(1000);
DM_ADD = reg;
delay(1000);
return DM_CMD;//将数据从寄存器中读出
}
unsigned int ior(unsigned long BaseAddress,unsigned int reg)
{
delay(100);
Dm9000_Write(BaseAddress,IO_addr,reg);
delay(100);
return Dm9000_Read(BaseAddress,IO_data);
}
unsigned int Dm9000_Read(unsigned long BaseAddress,int type)
{
return XIO_In16(BaseAddress+type);
}
void iow(unsigned long BaseAddress,unsigned int reg,unsigned int data)
{
delay(100);
Dm9000_Write(BaseAddress,IO_addr,reg);
delay(100);
Dm9000_Write(BaseAddress,IO_data,data);
}
void Dm9000_Write(unsigned long BaseAddress,int type,unsigned int value)
{
XIO_Out16(BaseAddress+type,value);
}
void Dm9000_reset(void)
{
iow(BaseAddress1,DM9000_NCR,0x03);
delay(100);
iow(BaseAddress1,DM9000_NCR,0x00);
iow(BaseAddress1,DM9000_NCR,0x03);
delay(100);
iow(BaseAddress1,DM9000_NCR,0x00);
}
void delay(unsigned int t)
{
while(t--);
}
void clear_interrupts(void)
{
iow(BaseAddress1,DM9000_IMR,0x80);
}
void phy_write(unsigned long BaseAddress,unsigned int reg,unsigned int value)
{
/*set phy register address into EPAR REG.0CH*/
iow(BaseAddress,0x0c,reg|0x40);
/*phy register address setting,and Dm9000_phy 0ffset=0x40*/
/*fill phy write data into EPDR REG.0xEH®.0DH*/
/*phy data hign_byte*/
iow(BaseAddress,0x0E,((value>>8)&0xff));
/*phy data low_byte*/
iow(BaseAddress,0x0D,value&0xff);
/*issue phy+write commmand=0x0a into EPCR REG.0BH*/
/*clear phy commmand first*/
iow(BaseAddress,0x0B,0x08);
/*issue phy+write command*/
Dm9000_Write(BaseAddress,IO_data,0x0A);
delay(25);
/*clear phy command again*/
Dm9000_Write(BaseAddress,IO_data,0x08);
/*wait 1~30us(>20us)for phy+write completion*/
delay(25);
}
/***********************DM9000初始化*********************************/
void Dm9000_init(unsigned long BaseAddress)
/*initialize Dm9000 LAN chip*/
{
unsigned int i;
/*set the internal phy power_on(GPIOs normal setting)*/
//iow(BaseAddress,0x1E,0x01);
iow(BaseAddress,DM9000_GPCR,0x01);
delay(100);
/*GPCR REG.1E=1 selected GPIO0"output" port for internal phy*/
// iow(BaseAddress,0x1F,0x00);
iow(BaseAddress,DM9000_GPR,0x00);
delay(100);
/*GPR REG.1F GPIO0 Bit[0]=0 to active interal phy*/
/*wait >2ms for phy powner_up ready*/
/*software-reset */
Dm9000_reset();
delay(100);
/*set GPIO0=1 then GPIO=0 to turn off and on the internal phy*/
/*GPR Bit[0]=1 turn-off phy*/
// iow(BaseAddress,0x1f,0x01);
/*GPR Bit[0]=0 to active phy*/
// iow(BaseAddress,0x1f,0x00);
/*wait >4ms for phy powner-up*/
// delay(10000);
/*set phy operation mode*/
/*reset phy:registers back to the default states */
// phy_write(BaseAddress,0,phy_reset);
/*wait>30us for phy software-reset ok*/
// delay(350);
/*turn off phy reduce -powner-down mode only*/
// phy_write(BaseAddress,16,0x404);
// phy_write(BaseAddress,4,phy_txab);
/*set phy TX ability:ALL+Flow_control*/
// phy_write(BaseAddress,0,0x1200);
/*phy auto-NEGO re-start enable(RESTART_AUTO_NEGOTIATION+AUTO_NEGOTIATION_ENABLE)to auto sense and recovery phy registers*/
/*wait>2ms for phy auto-sense linking to partner*/
iow(BaseAddress,DM9000_NSR,0x2C);
delay(100);
iow(BaseAddress,DM9000_ISR,0x3f);
delay(100);
iow(BaseAddress,DM9000_RCR,0x38);
delay(100);
iow(BaseAddress,DM9000_TCR,0x00);
delay(100);
iow(BaseAddress,DM9000_BPTR,0x3f);
delay(100);
iow(BaseAddress,DM9000_FCTR,0x3a);
delay(100);
iow(BaseAddress,DM9000_FCR,0xff);
delay(100);
iow(BaseAddress,DM9000_SMCR,0x00);
delay(100);
for(i=0;i<6;i++)
{
iow(ETH_Port_0,0x16+i,ether_addr0[i]);
delay(100);
}
iow(BaseAddress,DM9000_NSR,0x2C);
delay(100);
iow(BaseAddress,DM9000_ISR,0x3f);
delay(100);
iow(BaseAddress,DM9000_IMR,0x81);
delay(100);
/*store MAC address into NIC*/
/* if(Num==0)
{
for(i=0;i<6;i++)
iow(ETH_Port_0,16+i,ether_addr0[i]);
}
else if(Num==1)
{
for(i=0;i<6;i++)
iow(ETH_Port_1,16+i,ether_addr1[i]);
}
/*clear any pending interrupt*/
/* clear_interrupts();
iow(BaseAddress,DM9000_NSR,0x2C);
/*clear the TX status:TX1END,TX2END,WAKEUP 3bits,by RW/C1*/
/*program operating registers*/
/* iow(BaseAddress,DM9000_NCR,NCR_set);
/*NCR REG.00 enable the chip functions(and disable this MAC loopback mode back to normal)*/
/* iow(BaseAddress,0x08,BPTR_set);
/*BPTR REG.08(if necessary)RX Back Pressure Threshold in Half duplex moe only:High Water 3KB,600us*/
/* iow(BaseAddress,0x09,FCTR_set);
/*FCTR REG.09(if necessary)Flow Control Threshold setting High/Low Water Overflow 5KB/10KB*/
/* iow(BaseAddress,0x0A,RTFCR_set);
/*RTFCR REG.0AH (if necessary)RX/TX Flow Control Register enable TXPEN,BKPM(TX_Half),FLCE(RX)*/
/* iow(BaseAddress,0x0f,0x00);/*clear the all Event*/
//iow(BaseAddress,0x2D,0x80);/*Switch LED to mode 1*/
/*set other registers depending on applications*/
//iow(BaseAddress,ETXCSR,ETXCSR_set);
/*enable interrupts to active DM9000 on*/
/* iow(BaseAddress,DM9000_IMR,INTR_set);
/*enable RX(Broadcast/ALL_MULTICAST)*/
/* iow(BaseAddress,DM9000_RCR,0x39);*/
}
/********************************************/
void DM9000_init1(void)
{
U8 i;
dm9000_reg_write(DM9000_NCR, dm9000_reg_read(DM9000_NCR)&(~(1<<7)));
dm9000_reg_write(DM9000_GPCR, 0x01);//设置 GPCR(1EH) bit[0]=1,使DM9000的GPIO3为输出。
dm9000_reg_write(DM9000_GPR, 0x00);//GPR bit[0]=0 使DM9000的GPIO3输出为低以激活内部PHY。
// delay(50000);//延时2ms以上等待PHY上电。
// delay(50000);
// delay(50000);
while(!(dm9000_reg_read(DM9000_NSR)&0x40));//延时2ms以上
dm9000_reg_write(DM9000_NCR, 0x03);//软件复位
do {
delay(1000);//延时20us以上等待软件复位完成
} while (dm9000_reg_read(DM9000_NCR) & 1);
dm9000_reg_write(DM9000_NCR, 0x00);//复位完成,设置正常工作模式。
dm9000_reg_write(DM9000_NCR, 0x03);//第二次软件复位,为了确保软件复位完全成功。此步骤是必要的。
do {
delay(1000);//延时20us以上等待软件复位完成
} while (dm9000_reg_read(DM9000_NCR) & 1);
dm9000_reg_write(DM9000_NCR, 0x00);
/*以上完成了DM9000的复位操作*/
dm9000_reg_write(DM9000_NSR, 0x2c);//清除各种状态标志位
dm9000_reg_write(DM9000_ISR, 0x3f);//清除所有中断标志位
/*以上清除标志位*/
dm9000_reg_write(DM9000_RCR, 0x6f);//接收控制
dm9000_reg_write(DM9000_TCR, 0x00);//发送控制
dm9000_reg_write(DM9000_BPTR, 0x3f);
dm9000_reg_write(DM9000_FCTR, 0x3a);
dm9000_reg_write(DM9000_FCR, 0xff);
dm9000_reg_write(DM9000_SMCR, 0x00);
/*以上是功能控制,具体功能参考参考数据手册的介绍*/
for(i=0; i<6; i++)
dm9000_reg_write(0x16 + i, ether_addr0[i]);//mac_addr[]自己定义一下吧,6个字节的MAC地址
/*以上存储MAC地址(网卡物理地址)到芯片中去,这里没有用EEPROM,所以需要自己写进去*/
/*关于MAC地址的说明,要参考网络相关书籍或资料*/
dm9000_reg_write(DM9000_NSR, 0x2c);
dm9000_reg_write(DM9000_ISR, 0x3f);
/*为了保险,上面有清除了一次标志位*/
dm9000_reg_write(DM9000_IMR, 0x83);
/*中断使能(或者说中断屏蔽),即开启我们想要的中断,关闭不想要的,这里只开启的一个接收中断*/
}
/********************发送数据包*********************/
void TransmitPacket(unsigned char *data_ptr,unsigned short tx_len)
{
unsigned int i,len;
/*mask NIC interrupts IMR:PAR only*/
delay(1000);
dm9000_reg_write(DM9000_IMR,PAR_set);
// while(dm9000_reg_read(DM9000_IMR)&0x03);
len=tx_len;
/*issue TX packet'length into TXPLH REG.FDH&TXPLL REG.FCH*/
/*TXPLH High_byte length*/
delay(1000);
dm9000_reg_write(DM9000_TXPLH,(len>>8)&0x0ff);
/*TXPLL low_byte length*/
delay(1000);
dm9000_reg_write(DM9000_TXPLL,len&0x0FF);
/*write transmit data to chip SRAM*/
/*set MWCMD REG.F8H TX I/O port ready*/
delay(1000);
DM_ADD=DM9000_MWCMD;
delay(1000);
for(i=0;i<tx_len;i+=2)
{
//
Uart_SendByte(data_ptr[i]);
//delay(20000);
//delay(20000);
Uart_SendByte(data_ptr[i+1]);
DM_CMD=(data_ptr[i+1]<<8)|data_ptr[i];
// DM_CMD=data_ptr[i];
delay(50000);
delay(50000);
delay(50000);
}
/*issue TX polling commmand activated*/
/*TXCR Bit[0] TXREQ auto clear after TX completed*/
dm9000_reg_write(DM9000_TCR,0x01);
/*wait TX transmit done*/
while(!(dm9000_reg_read(DM9000_NSR)&0x0C));
/*clear the NSR Register*/
dm9000_reg_write(DM9000_NSR,0x2c);
/*ren-enable NIC interrupts*/
dm9000_reg_write(DM9000_RCR,0x39);
// dm9000_reg_write(DM9000_IMR,INTR_set);
dm9000_reg_write(DM9000_IMR,0x81);
}
/******************数据包接收函数****************************/
unsigned char ReceivePacket(unsigned char *data_ptr)
{
unsigned int rx_len;
unsigned char rx_READY;
unsigned int Tmp,RxStatus,i;
RxStatus=rx_len=0;
// dm9000_reg_write(DM9000_RCR, 0x38);//接收控制
// dm9000_reg_write(DM9000_IMR, 0x80);
/* mask NIC interrupts IMR:PAR only*/
// iow(BaseAddress,DM9000_IMR,PAR_set);
/* if(dm9000_reg_read(DM9000_ISR)&0x01)
{
dm9000_reg_write(DM9000_ISR,0x01) ;
}*/
/* dummy read a byte from MRCMDX REG.F0H*/
rx_READY=dm9000_reg_read(DM9000_MRCMDX);
// Uart_SendByte(rx_READY);
/* got most updated byte:rx_READY*/
// rx_READY=Dm9000_Read(BaseAddress,IO_data)&0x03;
/*check if(rx_READY==0x01):received packet ready?*/
if((rx_READY&0x0ff)!=DM9000_PKT_READY)
{
rx_READY=dm9000_reg_read(DM9000_MRCMDX);
if((rx_READY&0x01)!=DM9000_PKT_READY)
{
if((rx_READY&0x01)!=0x00)
{
dm9000_reg_write(DM9000_IMR, 0x80);//屏幕网卡中断
DM9000_init1();//重新初始化
dm9000_reg_write(DM9000_IMR, 0x81);//打开网卡中断
}
return 0;
}
}
/*got RX_Status&RX_Length from RX SRAM*/
RxStatus=dm9000_reg_read(DM9000_MRCMD);
delay(1000);
rx_len=DM_CMD;
/*Check this packet_status GOOD or BAD? */
if(!(RxStatus&0xBF00)&&(rx_len<MAX_PACKET_SIZE))
{
/*read 1 received packet from RX SRAM into RX buffer*/
for(i=0;i<rx_len;i+=2)
{
delay(1000);
Tmp=DM_CMD;
data_ptr[i]=Tmp&0xFF;
data_ptr[i+1]=(Tmp>>8)&0xFF;
}
}/*end if(GOODPACKET)*/
else {return 0;}
if(rx_len>1000) return 0;
// dm9000_reg_write(DM9000_IMR,0x83);
/* if((ARPBUFR->ethhdr.type != HON(0x0806))\
&&(ARPBUFR->ethhdr.type != HON(0x0800))) { return 0;}
return (ARPBUFR->ethhdr.type); */
return 1;
}
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。