S3C2440A 的DM9000网卡应用

前几天实现了在局域网里s3c2440A与PC实现了ARP协议的通信,成功的程序

主要是网卡芯片资料要好好研究一下

利用ARM芯片的总线时序可以很方便地实现

原来网络也可以用很少的几行代码实现最基本的功能

#include <string.h>


#define INDEXport   (*(volatile unsigned short *) 0x18000000)
#define DATAport    (*(volatile unsigned short *) 0x18000004)

#define DM9000_NCR 0x00
#define DM9000_NSR 0x01
#define DM9000_TCR 0x02
#define DM9000_RCR 0x05
#define DM9000_PAR 0x10

#define DM9000_GPR 0x1F
#define DM9000_RCSCSR 0x32
#define DM9000_MRCMDX 0xF0
#define DM9000_MRCMD  0xF2
#define DM9000_MWCMD 0xF8

#define DM9000_TXPLL 0xFC
#define DM9000_TXPLH 0xFD
#define DM9000_ISR 0xFE
#define DM9000_IMR 0xFF

void DM9000_Write(U16 Register,U16 Value)
{
 INDEXport=Register;
 DATAport =Value;
}
U16 DM9000_Read(U16 Register)
{
 INDEXport=Register;
 return  DATAport;
}

void DM9000_Delay(U32 t)
{
   U32 i;
   for(;t>0;t--)
   {
     for(i=0;i<100;i++){}
   }
}
void DM9000_Init(void)

 //1.To power on the internal PHY
 DM9000_Write(DM9000_GPR,0x00); 
 DM9000_Delay(5000);
 //2.To do a sofeware Reset for the DM9000A initial 
 DM9000_Write(DM9000_NCR,0x01);
 DM9000_Delay(3000);

 DM9000_Write(DM9000_IMR,0x80);
 //
 DM9000_Write(DM9000_PAR,  0x45);
 DM9000_Write(DM9000_PAR+1,0x45);
 DM9000_Write(DM9000_PAR+2,0x45);
 DM9000_Write(DM9000_PAR+3,0x45);
 DM9000_Write(DM9000_PAR+4,0x45);
 DM9000_Write(DM9000_PAR+5,0x45);

 //
 DM9000_Write(DM9000_NSR,0x2C);
 DM9000_Write(DM9000_ISR,0x3F);

 DM9000_Write(DM9000_RCR,0x7F);
 DM9000_Write(DM9000_RCSCSR,0x03);
 //Enable Packet Received Interrupt
 DM9000_Write(DM9000_IMR,0x81);
 //UART0puts("DM9000 Init finished/n/r");
}

void DM9000_Transmit(U8 *TBuf,int length)
{
 U32 i,status;
 DM9000_Write(DM9000_IMR,0x80);

 INDEXport=DM9000_MWCMD;

 for(i=0;i<length;i+=2)
 { 
  DATAport=(U16)(TBuf[i]|(TBuf[i+1]<<8));
 }

 DM9000_Write(DM9000_TXPLH,(U16)(length>>8&0xFF));
 DM9000_Write(DM9000_TXPLL,(U16)(length&0xFF));

 DM9000_Write(DM9000_TCR,0x01);   //Tx Request Command
 while(1)
 {
  status=DM9000_Read(DM9000_TCR);
  if(!(status&0x01))  break;
 }
 DM9000_Write(DM9000_NSR,0x0C);
 DM9000_Write(DM9000_IMR,0x81); 
}

typedef struct eth_hdr    
{
 U8 D_MAC[6];    
 U8 S_MAC[6];    
 U16 type;       
}ETH_HDR;

typedef struct arp   
{
 ETH_HDR ethhdr;  

 U16 hwtype;       //硬件类型(1表示传输的是以太网MAC地址)
 U16 protocol;   //协议类型(0x0800表示传输的是IP地址)
 U8 hwlen;    
 U8 protolen;   
 U16 opcode;    //操作(1表示ARP请求,2表示ARP应答)
 U8 S_MAC[6];   
 U8 S_IP[4];   
 U8 D_MAC[6];   
 U8 D_IP[4];      
}ARP;
ARP * ArpBuf;

U8 Buf[100];
U8 Rx_Buf[200];
U8 MyMAC[6]=    {0x45,0x45,0x45,0x45,0x45,0x45};
U8 BroadCast[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
U8 PCMAC[6]=    {0x00,0x1A,0x92,0x3D,0x75,0x36};

U8 MyIP[4]=     {192,168,131,25};
U8 PCIP[4]=     {192,168,131,200};
#define ChangeText(n)  (U16)(((n>>8)&0xFF)|(n&0xFF)<<8)
void ARPRequest(void)
{
 ArpBuf=(ARP *)Buf; 
 memcpy(ArpBuf->ethhdr.D_MAC,BroadCast,6);
 memcpy(ArpBuf->ethhdr.S_MAC,MyMAC,6);
 ArpBuf->ethhdr.type=ChangeText(0x0806);
 ArpBuf->hwtype=ChangeText(1);
 ArpBuf->protocol=ChangeText(0x0800);
 ArpBuf->hwlen=6;
 ArpBuf->protolen=4;
 ArpBuf->opcode=ChangeText(1);
 memcpy(ArpBuf->S_MAC,MyMAC,6);
 memcpy(ArpBuf->S_IP,MyIP,4);
 memcpy(ArpBuf->D_IP,PCIP,4);
 DM9000_Transmit(Buf,42);
}
U16 Re_Packet(U8 *RxBuf)
{
  U32 i;
 U16 Rx_Length;
 U16 status;
 U16 Rx_Ready;
 U16 tmp;
  Rx_Ready= DM9000_Read(DM9000_MRCMDX);
 putc(Rx_Ready);
 Rx_Ready= DM9000_Read(DM9000_MRCMDX);
 putc(Rx_Ready);
 if((Rx_Ready&0x01)==1)
 {
  status=DM9000_Read(DM9000_MRCMD);
  Rx_Length=DATAport;
  if(!(status & 0xbf00) && (Rx_Length < 1522))
  for(i=0;i<Rx_Length;i+=2)
  {
   tmp=DATAport;
   RxBuf[i]  =tmp&0x0FF;
   RxBuf[i+1]=(tmp>>8)&0x0FF;
  }
  return Rx_Length;
 }
 else if((Rx_Ready&0x02)!=0)
 {
  DM9000_Init();
  return 0; 
 }
 return 0;
}
void delay()
{
    int i,j;
 for(i=0;i<0x00FF;i++)
  for(j=0;j<0x04FF;j++);
}
void LED(int n)
{
 GPFDAT=~(n<<4);
}
static void __irq LANIRQ_ISR(void)
{
    U32 INT_status;
 U16 length;
 U8  flag,i;
 //GPFDAT=0x00;
 //delay();
 length=Re_Packet(Rx_Buf);
 flag=1;
 for(i=0;i<6;i++)
  {
   if(Rx_Buf[i]!=0x45)
    flag=0;  
  }
 if(flag==1)
   UART0puta(Rx_Buf,length);

 INT_status=DM9000_Read(DM9000_ISR);
 if(INT_status&0x01)
   {
    DM9000_Write(DM9000_ISR,0x01);
   }

 EINTPND=1<<9;
 SRCPND=1<<5;  
    INTPND=INTPND;
}

void Interrupt_Init(void)
{
 pISR_EINT8_23=(U32)LANIRQ_ISR;
 GPGCON=0x8;
 EXTINT1=0x40;
 INTMSK=0xFFFFFFDF;
 EINTMASK=0xFFFFFDFF;
 SRCPND=1<<5;
 INTPND=1<<5;
 EINTPND=0xFFFFFFFF; 
}

int Main()

 int i;

 GPFCON=0x5500;
 GPFDAT=0xC0;
 UART0_Init();
 DM9000_Init();
 Interrupt_Init();
 while(1)
 {
  for(i=1;i<=9;i++)
   {
       LED(i);
   delay();
  }  
  ARPRequest();
 } 
    return 0;
}

待续

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值