DM9000单片机驱动代码.docx
《DM9000单片机驱动代码.docx》由会员分享,可在线阅读,更多相关《DM9000单片机驱动代码.docx(10页珍藏版)》请在冰豆网上搜索。
![DM9000单片机驱动代码.docx](https://file1.bdocx.com/fileroot1/2023-1/6/b927942f-2363-4b59-ae56-07e63b20167d/b927942f-2363-4b59-ae56-07e63b20167d1.gif)
DM9000单片机驱动代码
标题:
DM9000单片机驱动代码
2010-09-1210:
16:
07
/*************************dm9000.cwriterzxw2010.3.26******************************/
#include"dm9000.h"
#include"def.h"
#include"ARP.h"
/************************************************************************************/
/******************************函数宏定义********************************************/
#defineXIO_In16(InputPtr)(*(volatileunsignedint*)(InputPtr))
#defineXIO_In8(InputPtr)(*(volatileunsignedchar*)(InputPtr))
#defineXIO_In32(InputPtr)(*(volatileunsignedlong*)(InputPtr))
#defineXIO_Out16(OutputPtr,Value)((*(volatileunsignedint*)(OutputPtr))=(Value))
#defineDM_ADD(*(volatileU16*)0x20000300)
#defineDM_CMD(*(volatileU16*)0x20000304)
/************************************************************************************/
/******************************函数申明**********************************************/
unsignedintior(unsignedlongBaseAddress,unsignedintreg);
unsignedintDm9000_Read(unsignedlongBaseAddress,inttype);
voidDm9000_Write(unsignedlongBaseAddress,inttype,unsignedintValue);
voidiow(unsignedlongBaseAddress,unsignedintreg,unsignedintdata);
voiddelay(unsignedintt);
voidDm9000_reset(void);
voidclear_interrupts(void);
voidphy_write(unsignedlongBaseAddress,unsignedintreg,unsignedintvalue);
voidDm9000_init(unsignedlongBaseAddress);
voidTransmitPacket(unsignedchar*data_ptr,unsignedshorttx_len);
unsignedcharReceivePacket(unsignedchar*data_ptr);
/**********************************定义接受数组和发送数组****************************/
//unsignedchardata_ptrR[MAX_PACKET_SIZE];
//unsignedchardata_ptrT[MAX_PACKET_SIZE];
unsignedcharether_addr0[6]={8,90,90,90,90,90};
//unsignedcharether_addr1[6]={8,90,90,90,90,90};
/***************************函数实体********************************************************/
voiddm9000_reg_write(U8reg,U8data)
{
delay(1000);//之前定义的微妙级延时函数,这里延时20us
DM_ADD=reg;//将寄存器地址写到INDEX端口
delay(1000);
DM_CMD=data;//将数据写到DATA端口,即写进寄存器
}
/**********************************************/
U8dm9000_reg_read(U8reg)
{
delay(1000);
DM_ADD=reg;
delay(1000);
returnDM_CMD;//将数据从寄存器中读出
}
unsignedintior(unsignedlongBaseAddress,unsignedintreg)
{
delay(100);
Dm9000_Write(BaseAddress,IO_addr,reg);
delay(100);
returnDm9000_Read(BaseAddress,IO_data);
}
unsignedintDm9000_Read(unsignedlongBaseAddress,inttype)
{
returnXIO_In16(BaseAddress+type);
}
voidiow(unsignedlongBaseAddress,unsignedintreg,unsignedintdata)
{
delay(100);
Dm9000_Write(BaseAddress,IO_addr,reg);
delay(100);
Dm9000_Write(BaseAddress,IO_data,data);
}
voidDm9000_Write(unsignedlongBaseAddress,inttype,unsignedintvalue)
{
XIO_Out16(BaseAddress+type,value);
}
voidDm9000_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);
}
voiddelay(unsignedintt)
{
while(t--);
}
voidclear_interrupts(void)
{
iow(BaseAddress1,DM9000_IMR,0x80);
}
voidphy_write(unsignedlongBaseAddress,unsignedintreg,unsignedintvalue)
{
/*setphyregisteraddressintoEPARREG.0CH*/
iow(BaseAddress,0x0c,reg|0x40);
/*phyregisteraddresssetting,andDm9000_phy0ffset=0x40*/
/*fillphywritedataintoEPDRREG.0xEH®.0DH*/
/*phydatahign_byte*/
iow(BaseAddress,0x0E,((value>>8)&0xff));
/*phydatalow_byte*/
iow(BaseAddress,0x0D,value&0xff);
/*issuephy+writecommmand=0x0aintoEPCRREG.0BH*/
/*clearphycommmandfirst*/
iow(BaseAddress,0x0B,0x08);
/*issuephy+writecommand*/
Dm9000_Write(BaseAddress,IO_data,0x0A);
delay(25);
/*clearphycommandagain*/
Dm9000_Write(BaseAddress,IO_data,0x08);
/*wait1~30us(>20us)forphy+writecompletion*/
delay(25);
}
/***********************DM9000初始化*********************************/
voidDm9000_init(unsignedlongBaseAddress)
/*initializeDm9000LANchip*/
{
unsignedinti;
/*settheinternalphypower_on(GPIOsnormalsetting)*/
//iow(BaseAddress,0x1E,0x01);
iow(BaseAddress,DM9000_GPCR,0x01);
delay(100);
/*GPCRREG.1E=1selectedGPIO0"output"portforinternalphy*/
//iow(BaseAddress,0x1F,0x00);
iow(BaseAddress,DM9000_GPR,0x00);
delay(100);
/*GPRREG.1FGPIO0Bit[0]=0toactiveinteralphy*/
/*wait>2msforphypowner_upready*/
/*software-reset*/
Dm9000_reset();
delay(100);
/*setGPIO0=1thenGPIO=0toturnoffandontheinternalphy*/
/*GPRBit[0]=1turn-offphy*/
//iow(BaseAddress,0x1f,0x01);
/*GPRBit[0]=0toactivephy*/
//iow(BaseAddress,0x1f,0x00);
/*wait>4msforphypowner-up*/
//delay(10000);
/*setphyoperationmode*/
/*resetphy:
registersbacktothedefaultstates*/
//phy_write(BaseAddress,0,phy_reset);
/*wait>30usforphysoftware-resetok*/
//delay(350);
/*turnoffphyreduce-powner-downmodeonly*/
//phy_write(BaseAddress,16,0x404);
//phy_write(BaseAddress,4,phy_txab);
/*setphyTXability:
ALL+Flow_control*/
//phy_write(BaseAddress,0,0x1200);
/*phyauto-NEGOre-startenable(RESTART_AUTO_NEGOTIATION+AUTO_NEGOTIATION_ENABLE)toautosenseandrecoveryphyregisters*/
/*wait>2msforphyauto-senselinkingtopartner*/
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);
/*storeMACaddressintoNIC*/
/*if(Num==0)
{
for(i=0;i<6;i++)
iow(ETH_Port_0,16+i,ether_addr0[i]);
}
elseif(Num==1)
{
for(i=0;i<6;i++)
iow(ETH_Port_1,16+i,ether_addr1[i]);
}
/*clearanypendinginterrupt*/
/*clear_interrupts();
iow(BaseAddress,DM9000_NSR,0x2C);
/*cleartheTXstatus:
TX1END,TX2END,WAKEUP3bits,byRW/C1*/
/*programoperatingregisters*/
/*iow(BaseAddress,DM9000_NCR,NCR_set);
/*NCRREG.00enablethechipfunctions(anddisablethisMACloopbackmodebacktonormal)*/
/*iow(BaseAddress,0x08,BPTR_set);
/*BPTRREG.08(ifnecessary)RXBackPressureThresholdinHalfduplexmoeonly:
HighWater3KB,600us*/
/*iow(BaseAddress,0x09,FCTR_set);
/*FCTRREG.09(ifnecessary)FlowControlThresholdsettingHigh/LowWaterOverflow5KB/10KB*/
/*iow(BaseAddress,0x0A,RTFCR_set);
/*RTFCRREG.0AH(ifnecessary)RX/TXFlowControlRegisterenableTXPEN,BKPM(TX_Half),FLCE(RX)*/
/*iow(BaseAddress,0x0f,0x00);/*cleartheallEvent*/
//iow(BaseAddress,0x2D,0x80);/*SwitchLEDtomode1*/
/*setotherregistersdependingonapplications*/
//iow(BaseAddress,ETXCSR,ETXCSR_set);
/*enableinterruptstoactiveDM9000on*/
/*iow(BaseAddress,DM9000_IMR,INTR_set);
/*enableRX(Broadcast/ALL_MULTICAST)*/
/*iow(BaseAddress,DM9000_RCR,0x39);*/
}
/********************************************/
voidDM9000_init1(void)
{
U8i;
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);//GPRbit[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);
/*中断使能(或者说中断屏蔽),即开启我们想要的中断,关闭不想要的,这里只开启的一个接收中断*/
}
/********************发送数据包*********************/
voidTransmitPacket(unsignedchar*data_ptr,unsignedshorttx_len)
{
unsignedinti,len;
/*maskNICinterruptsIMR:
PARonly*/
delay(1000);
dm9000_reg_write(DM9000_IMR,PAR_set);
//while(dm9000_reg_read(DM9000_IMR)&0x03);
len=tx_len;
/*issueTXpacket'lengthintoTXPLHREG.FDH&TXPLLREG.FCH*/
/*TXPLHHigh_bytelength*/
delay(1000);
dm9000_reg_write(DM9000_TXPLH,(len>>8)&0x0ff);
/*TXPLLlow_bytelength*/
delay(1000);
dm9000_reg_write(DM9000_TXPLL,len&0x0FF);
/*writetransmitdatatochipSRAM*/
/*setMWCMDREG.F8HTXI/Oportready*/
delay(1000);
DM_ADD=DM9000_MWCMD;
delay(1000);
for(i=0;i{
//
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);
}
/*issueTXpollingcommmandactivated*/
/*TXCRBit[0]TXREQautoclearafterTXcompleted*/
dm9000_reg_write(DM9000_TCR,0x01);
/*waitTXtransmitdone*/
while(!
(dm9000_reg_read(DM9000_NSR)&0x0C));
/*cleartheNSRRegister*/
dm9000_reg_write(DM9000_NSR,0x2c);
/*ren-enableNICinterrupts*/
dm9000_reg_write(DM9000_RCR,0x39);
//dm9000_reg_write(DM9000_IMR,INTR_se