⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp.c

📁 bf533平台下的DM9000A的测试代码
💻 C
字号:
#include <ccblkfn.h>
#include <cdefBF533.h>
#include <DM9000.h>
#include <sysreg.h>
#include <Header.h>
#include <UDP.h>

#define	true	1
#define	false	0
#define MAX_PACK_LEN 0x200
//typedef	int			bool;

//typedef	int			bool;
uchar clientEther[6] = {0x00, 0x5e, 0xf6, 0x34, 0xd8, 0x3d};
ulong clientIP = 0x3400a8c0;
uchar PktBuf[608];

enum DM9000_PHY_mode {
	DM9000_10MHD = 0,
	DM9000_100MHD = 1,
	DM9000_10MFD = 4,
	DM9000_100MFD = 5,
	DM9000_AUTO = 8,
	DM9000_1M_HPNA = 0x10
};

int media_mode = DM9000_AUTO;

#define DM9000_outb(d,r) ( *(volatile uchar *)r = d )
#define DM9000_outw(d,r) ( *(volatile ushort *)r = d )
#define DM9000_inb(r) (*(volatile uchar *)r)
#define DM9000_inw(r) (*(volatile ushort *)r)

void MemCpy(void *dest, void *src, int cnt)
{
    char *s1 = dest, *s2 = src, *endptr = (char *)dest+cnt;
    while(s1 < endptr)
         *s1++ = *s2++;
    return;
}

void RxPacketHandle(uchar *rxPktBuf, int len)
{
    ETH_HEADER     *et   = (ETH_HEADER *)rxPktBuf;
    IP_HEADER      *ip   = (IP_HEADER *)(rxPktBuf + 14);
    ARP_HEADER     *arp  = (ARP_HEADER *)(rxPktBuf + 14);
    ICMP_HEADER    *icmp = (ICMP_HEADER *)(rxPktBuf + 34);
    ushort         prot;
    ushort         pklen;
    prot = SWAP16(et->et_protlen);
    switch(prot)
    {
        case 0x806:
             MemCpy(&rxPktBuf[0], (char*)et->et_src, 6);
             MemCpy(&rxPktBuf[6], (char*)clientEther, 6);
             *(short *)(&rxPktBuf[12]) = SWAP16(0x806);
             *(short *)(&rxPktBuf[14]) = SWAP16(0x0001);
             *(short *)(&rxPktBuf[16]) = SWAP16(0x800);
             rxPktBuf[18]              = 0x06;
             rxPktBuf[19]              = 0x04;
             *(short *)(&rxPktBuf[20]) = SWAP16(0x0002);
             MemCpy(&(rxPktBuf[32]), &(rxPktBuf[22]), 6);
             MemCpy(&(rxPktBuf[38]), &(rxPktBuf[28]), 4);
             MemCpy(&(rxPktBuf[22]), clientEther, 6);
             MemCpy(&(rxPktBuf[28]), &(clientIP), 4);
             
             EthTx(rxPktBuf, 42);
             break;
        case 0x800:
             pklen = SWAP16(ip->ip_len);
             if((pklen<=20)||(pklen>MAX_PACK_LEN))
                  return;
             pklen-=20;
             icmp->icmp_op=0;
             icmp->icmp_chksum=0;
             icmp->icmp_chksum=~IPChksum((char *)icmp, pklen/2);
             MemCpy((char *)&(ip->ip_dest), (char *)&(ip->ip_src), 4);
             MemCpy((char *)&(ip->ip_src), (char *)&clientIP, 4);
             ip->ip_chksum = 0;
             ip->ip_ttl = 0x40;
             ip->ip_chksum = ~IPChksum((char *)ip, 10);
             MemCpy(&rxPktBuf[0], (char *)et->et_src, 6);
             MemCpy(&rxPktBuf[6], (char *)clientEther, 6);
             TxPacket(rxPktBuf, 34+pklen);
             break;
         default:
             break;
    }
    return;
}

unsigned IPChksum(char *ptr, int len){
	ulong		xsum;

	xsum = 0;
	while (len-- > 0)
		xsum += *((ushort *)ptr)++;
	xsum = (xsum & 0xffff) + (xsum >> 16);
	xsum = (xsum & 0xffff) + (xsum >> 16);
	return xsum & 0xffff;
}	// IPChksum.

void MemSet(void *dest, char c, int len)
{
    char *s = dest;
    char *limit = (char *)dest + len;
    while(s<limit)*s++ = c;
}

int dm9000_probe(void)
{
	int i;
	ulong id_val;
		
	for(i = 0; i < 3; i ++) 
	{
		id_val = DM9000_ior(DM9000_VIDL);
		id_val |= DM9000_ior(DM9000_VIDH) << 8;
		id_val |= DM9000_ior(DM9000_PIDL) << 16;
		id_val |= DM9000_ior(DM9000_PIDH) << 24;
		if (id_val == DM9000_ID) 
		{
			return 1;
		}	
	}
	return 0;
}

// Set PHY operationg mode
void set_PHY_mode(void)
{
	ushort phy_reg4 = 0x01e1, phy_reg0 = 0x1000;
	if (!(media_mode & DM9000_AUTO)) {
		switch (media_mode) {
		case DM9000_10MHD:
			phy_reg4 = 0x21;
			phy_reg0 = 0x0000;
			break;
		case DM9000_10MFD:
			phy_reg4 = 0x41;
			phy_reg0 = 0x1100;
			break;
		case DM9000_100MHD:
			phy_reg4 = 0x81;
			phy_reg0 = 0x2000;
			break;
		case DM9000_100MFD:
			phy_reg4 = 0x101;
			phy_reg0 = 0x3100;
			break;
		}
		phy_write(4, phy_reg4);	// Set PHY media mode 
		phy_write(0, phy_reg0);	//  Tmp 
	}
	DM9000_iow(DM9000_GPCR, 0x01);	// Let GPIO0 output 
	DM9000_iow(DM9000_GPR, 0x00);	// Enable PHY 
}

// General Purpose dm9000 reset routine
void dm9000_reset(void)
{
	DM9000_iow(DM9000_NCR, NCR_RST);
	delay(100000);		// delay 1ms
}

//  Initilize dm9000 board

bool EthInit()
{
	int i,oft, lnk;
    ulong id_val;
	MemSet((char *)0x20100300, 0x0, 2);		// Test Code
	dm9000_reset();

	if(dm9000_probe() == 1)
	{
    	DM9000_iow(DM9000_GPR, 0x00);	// REG_1F bit0 activate phyxcer
        set_PHY_mode();
		DM9000_iow(DM9000_NCR, 0x0);	// only intern phy supported by now 
		DM9000_iow(DM9000_TCR, 0);	// TX Polling clear 
		DM9000_iow(DM9000_SMCR, 0);	// Special Mode 
		DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);	// clear TX status 
		DM9000_iow(DM9000_ISR, 0x0f);	// Clear interrupt status 
		for (i = 0, oft = 0x10; i < 6; i++, oft++) 
		{
			DM9000_iow(oft, clientEther[i]);
		}
		for (i = 0, oft = 0x16; i < 8; i++, oft++) 
		{
			DM9000_iow(oft, 0xff);
		}
		DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);	// RX enable 
		DM9000_iow(DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);   /* Enable TX/RX interrupt mask */
		//while ((phy_read(1) & 0x20));
		delay(100000);		// delay 1ms
		return 1;
	}
     return 0;
}

uchar DM9000_ior(int reg)
{
	DM9000_outb(reg, DM9000_IO);
	delay(100);	
	return DM9000_inb(DM9000_DATA);	
}


//  Write a byte to I/O port
void DM9000_iow(int reg, uchar value)
{
	DM9000_outb(reg, DM9000_IO);
	delay(100);	
	DM9000_outb(value, DM9000_DATA);
}


// Read a word from phyxcer
ushort phy_read(int reg)
{
	ushort val;

	// Fill the phyxcer register into REG_0C 
	DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
	DM9000_iow(DM9000_EPCR, 0xc);	// Issue phyxcer read command 
	delay(10000);		// Wait read complete 
	DM9000_iow(DM9000_EPCR, 0x0);	// Clear phyxcer read command 
	val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);

	// The read data keeps on REG_0D & REG_0E 
	//DM9000_DBG("phy_read(%d): %d\n", reg, val);
	return val;
}


// Write a word to phyxcer
void phy_write(int reg, ushort value)
{
	// Fill the phyxcer register into REG_0C 
	DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);

	// Fill the written data into REG_0D & REG_0E 
	DM9000_iow(DM9000_EPDRL, (value & 0xff));
	DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
	DM9000_iow(DM9000_EPCR, 0xa);	// Issue phyxcer write command 
	delay(50000);		// Wait write complete 
	DM9000_iow(DM9000_EPCR, 0x0);	// Clear phyxcer write command 
}

int EthTx(uchar *packet, int length)
{
	uchar *data_ptr;
	ulong tmplen, i;
	int tmo;
	
	// Move data to DM9000 TX RAM 
	//while(DM9000_ior(DM9000_TCR) & TCR_TXREQ);         //发送完成
	data_ptr = (uchar *) packet;
	DM9000_outb(DM9000_MWCMD, DM9000_IO);

	tmplen = (length + 1) / 2;
	for (i = 0; i < tmplen; i++) 
	{
		DM9000_outw(((ushort *) data_ptr)[i], DM9000_DATA);
	}
    // Set TX length to DM9000 
	DM9000_iow(DM9000_TXPLL, length & 0xff);
	DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);

	// Issue TX polling command 
	DM9000_iow(DM9000_TCR, TCR_TXREQ);	
	return 1;
}

// Received a packet and pass to upper layer
bool EthRx()
{
	uchar  rxbyte;
	uchar   *rxPktBuf = PktBuf;
	ushort IntStatus, RxStatus, RxLen = 0;
	ulong  tmplen, i;

	IntStatus = DM9000_ior(DM9000_ISR);              /* Got ISR */
	DM9000_iow(DM9000_ISR, (uchar)IntStatus);        /* Clear ISR status */
 
	DM9000_ior(DM9000_MRCMDX);	// Dummy read 
    rxbyte = DM9000_inb(DM9000_DATA);	// Got most updated data 

	if (rxbyte == 0)
		return 0;
	// Status check: this byte must be 0 or 1 
	if (rxbyte > 1) 
	{
	    delay(100);
	    DM9000_iow(DM9000_RCR, 0x00);	// Stop Device 
	}

	// A packet ready now  & Get status/length 
	DM9000_outb(DM9000_MRCMD, DM9000_IO);

	RxStatus = DM9000_inw(DM9000_DATA);
	RxLen = DM9000_inw(DM9000_DATA);

	// Move data from DM9000 
	// Read received packet from RX SRAM 
	tmplen = (RxLen+1)/2;
	for (i = 0; i < tmplen; i++)
	{
	    ((ushort *) rxPktBuf)[i] = DM9000_inw(DM9000_DATA);
	}
    RxPacketHandle((uchar *)rxPktBuf, RxLen);
    return 1;

}

void delay(unsigned int Value)
{
    unsigned int i=0;
    for(i=0; i<Value; i++)
    {
    }
}

bool RxPacket()
{
    return EthRx();
}

void TxPacket(char *txPktBuf, int len)
{
    EthTx(txPktBuf, len);
}

bool NetInit(void)
{
    return EthInit();
}

void Init_EBIU(void)
{
	*pEBIU_AMBCTL0	= 0xfffc7bb0;
	*pEBIU_AMBCTL1	= 0x7bb07bb0;
	*pEBIU_AMGCTL	= 0x000f;
}

void Init_PLL(void)
{
    int test;

	sysreg_write(reg_SYSCFG, 0x32);		//Initialize System Configuration Register
    *pPLL_DIV = 0x0007;
	*pSIC_IWR = 0x1;
	*pPLL_CTL = 0x2C00;
	*pPLL_LOCKCNT = 0x0200;
    test = cli();
	idle();
	sti(test);	
}//end Init_PLL

//void Init_CtrlReg(void)
//{
//    *pCtrlReg1_S = 0x41;
//    delay(10000);
//}

void main()
{
    Init_PLL();
    Init_EBIU();
    //Init_CtrlReg();
    EthInit();
    while(1)
    {
        //*pFIO_FLAG_D = 0x0000;
        //*pFIO_DIR    = 0x0020;
        //*pFIO_FLAG_S = 0x0020;
       
       //EthRx();
       // EthTx(rxPktBuf, 42);
       //DM9000_iow(DM9000_GPR, 0x00);
       *(volatile ushort *)0x20100000 = 0x0000; 
       //	delay(10);
       //DM9000_outb(DM9000_GPR, DM9000_IO);
       *(volatile ushort *)0x20100002 = 0xFFFF;	
	   //DM9000_outb(0x00, DM9000_DATA);
	   //*(volatile uchar *)0x20000000 = 0x010;
	   //DM9000_inb(DM9000_DATA);	
//	     
//	     
//	     
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -