前几天实现了在局域网里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;
}
待续