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

📄 main.c

📁 ARM2410+DM9000的驱动与寄存器配置代码
💻 C
字号:
#include "includes.h"
#include "eth.h"
#include "arp.h"

#define PUBLIC
#define PRIVATE static

static void uDelay(int iUSecs);

typedef unsigned short USHORT;
typedef unsigned char UCHAR;
typedef UCHAR BYTE;

typedef enum {
	FALSE = 0,
	TRUE = -1
}BOOL;

#define DM9000IOBASE (0x08000000 + 0x300)

// I/O mode register mapping
#define IO_PACKET_PAGE_POINTER      0x0000
#define IO_PACKET_PAGE_DATA         0x0004
#define IO_RX_TX_DATA		    0x0000


// Bus interface registers
// 		PKT	分区知识表
#define PKTPG_PRDCT_ID_H        	0x002b
#define PKTPG_PRDCT_ID_L        	0x002a
#define PKTPG_VNDR_ID_H        		0x0029
#define PKTPG_VNDR_ID_L      	  	0x0028

//
#define DM9000_PRDCT_ID				0x9000
#define DM9000_VNDR_ID				0x0A46

#define DM9000_IO_MODE				0x00	//16bit

/*
 * Status and control registers
 */
#define PKTPG_NCR_00         		    0x0000
#define PKTPG_NSR_01          		    0x0001
#define PKTPG_TCR_02          		    0x0002
#define PKTPG_BPTR_08         		    0x0008
#define PKTPG_FCTR_09         		    0x0009
#define PKTPG_FCR_0A          		    0x000a
#define PKTPG_GPCR_1E         		    0x001e
#define PKTPG_GPR_1F          		    0x001f
#define PKTPG_SMCR_2F         		    0x002f
#define PKTPG_ISR_FE          		    0x00fe
#define PKTPG_IMR_FF          		    0x00ff

/*
 * Bit masks .Set Values
 */
#define NCR_RESET             		0x0001
#define NCR_CLEAR      		     	0x0000
#define GPCR_PHY_ON					0x0001
#define GPR_PHY_ON					0x0000
#define NCR_INIT      		     	0x0000
#define NSR_INIT      		     	0x002c


//读/写数据
#define IOREAD(o)	((USHORT)(*((volatile USHORT *)(DM9000IOBASE + (o))) & 0x00ff))
#define IOREADw(o)	((USHORT)*((volatile USHORT *)(DM9000IOBASE + (o))))

#define IOWRITE(o, d)	*((volatile USHORT *)(DM9000IOBASE + (o))) = (d & 0x00ff)
#define IOWRITEw(o, d)	*((volatile USHORT *)(DM9000IOBASE + (o))) = (USHORT)(d)

//读/写寄存器
#define READ_REG1 ReadReg
#define WRITE_REG1 WriteReg





PRIVATE USHORT 
ReadReg(USHORT offset)
{
	IOWRITE(IO_PACKET_PAGE_POINTER, offset);
	return IOREAD(IO_PACKET_PAGE_DATA);
}

PRIVATE void 
WriteReg(USHORT offset, USHORT data)
{
	IOWRITE(IO_PACKET_PAGE_POINTER, offset);
	IOWRITE(IO_PACKET_PAGE_DATA , data);
}


BOOL dm9000Probe(void)
{
	USHORT id_vendor, id_product;

	CONSOL_Printf("\n [DM9000 Test]\n");
	id_vendor = READ_REG1(PKTPG_VNDR_ID_L);
	id_vendor |= READ_REG1(PKTPG_VNDR_ID_H)<<8;

	if (id_vendor != DM9000_VNDR_ID)
	{
		CONSOL_Printf("VENDOR ID Error (0x%04x != 0x%04x)\n", DM9000_VNDR_ID, id_vendor);
		return FALSE;
	}
	else
		CONSOL_Printf("VENDOR ID = 0x%04x\n", id_vendor);

	id_product = READ_REG1(PKTPG_PRDCT_ID_L);
	id_product |= READ_REG1(PKTPG_PRDCT_ID_H)<<8;
	if ((id_product & DM9000_PRDCT_ID) != DM9000_PRDCT_ID)
	{
		CONSOL_Printf("Product ID Error (0x%04x != 0x%04x)\n", DM9000_PRDCT_ID, id_product);
		return FALSE;
	}
	else
		CONSOL_Printf("Product ID = 0x%04x\n", id_product);
	return TRUE;
}


PRIVATE BOOL dm9000Reset(void)
{
	WRITE_REG1(0,1);
	uDelay(100);
	return TRUE;
}


PRIVATE BOOL dm9000Init(void)
{
	//Get IO Mode
	UCHAR uchTemp;
	USHORT ushTemp;
	struct eth_addr ethaddr;
    //bit6bit7 = 00  16bit 
	if ((uchTemp=(READ_REG1(PKTPG_ISR_FE)>>6)&0xff) != DM9000_IO_MODE)
	{
		CONSOL_Printf("\nDM9000's io mode error.	io_mode=%c .\n",uchTemp);
		return FALSE;
	}

	//Active  PHY 
	WRITE_REG1(PKTPG_GPCR_1E,GPCR_PHY_ON);
	WRITE_REG1(PKTPG_GPR_1F,GPR_PHY_ON);
    //Reset DM9000
	WRITE_REG1(0x0000,0);
	//TX Control Register   Default 
	WRITE_REG1(0x0002,0);
	//Back Pressure Threshold Register  Default+600us
	WRITE_REG1(0x0008,0x003f);
	//Flow Control Threshold Register  Default
	WRITE_REG1(0x0009,0x0038);
	//RX/TX Flow Control Register   Default +  Back Pressure mode
	WRITE_REG1(0x000a,0x0008);
	//Special Mode Control Register  Default
	WRITE_REG1(0x002f,0);
	//Interrupt Status Register  bit6bit7 = 00  16bit
	WRITE_REG1(0x00fe,0x000f);
	//
	ethaddr = getethaddr();
	//write Node address  设定Physical Address 位置 
	for (ushTemp=0; ushTemp<6; ushTemp++)
	{
		WRITE_REG1(ushTemp+0x0010, (USHORT)(ethaddr.addr[ushTemp]));
	}
	//insert hash table   设定Multicast 设置
	for (ushTemp=0x0016; ushTemp<0x001e; ushTemp+=2)
	{
		WRITE_REG1(ushTemp, 0xff);
		WRITE_REG1(ushTemp+1, 0xff);
	}
	
	//Rx Controll Register   Rx Enable 
	WRITE_REG1(0x0005,0x0031);
	//将DM9000 中断功能关闭
	WRITE_REG1(0x00ff,0x0080);

	CONSOL_Printf("\nDM9000_Init OK.\n");
	return TRUE;
}


PRIVATE USHORT 
TransmitPkt(BYTE *pbData, USHORT slen)
{
	USHORT   ushlen;

	/* Send Command */
	//Disable INT
	//WRITE_REG1(0x00ff,0x0080);
	IOWRITE(0x0000,0x00f8);//trigger MWCMD(Reg_f8)

	ushlen = slen;
	//Used the 16 io_mode,so convert byte len to word len
	for(; slen>0 ; slen-=2, pbData+=2)
	{
		if(slen >= 2)//   DM9000IOBASE  + IO_PACKET_PAGE_DATA  读/写数据
			IOWRITEw(IO_PACKET_PAGE_DATA, *((USHORT*)pbData));
		else
			IOWRITEw(IO_PACKET_PAGE_DATA, (USHORT)(*pbData));
	}
	
	//Write the transmittion length
	WRITE_REG1(0x00fc,ushlen & 0xff);
	WRITE_REG1(0x00fd,(ushlen>>8) & 0xff);
	//Start to transmit
	WRITE_REG1(0x0002,1);
	
	//Enable INT
	//WRITE_REG1(0x00ff,0x83);

	return 0;
}



PRIVATE USHORT
RcvPkt(BYTE *pbData, USHORT dwLength)
{
					/* use int rather than short for the reason of performance	*/
	USHORT   length;
	USHORT   rlen = 0;
	USHORT   *bp;
	USHORT	 data,ushStatus;

	//Check status
	IOWRITE(0, 0x00f2);			/* Discard RxStatus */
	//ushStatus = IOREAD(0x00f2);
	ushStatus = IOREADw(IO_PACKET_PAGE_DATA) & 0xff00;
	length = IOREADw(IO_PACKET_PAGE_DATA);

	if (length > dwLength) length = 0;

	bp    = (USHORT *)pbData;

	rlen = length;

	while (rlen)
	{
		data = IOREADw(IO_PACKET_PAGE_DATA);

		if (rlen == 1)
		{
			*((BYTE *)bp) = (BYTE)data;
			rlen--;
		}
		else
		{
			*bp++ = data;
			rlen -= 2;
		}
	}

	return length;
}


PUBLIC BOOL
DM9000DBG_IsReceivedPacket(void)
{
	USHORT event;
	BOOL   r = FALSE;

	//event = IOREAD(IO_ISQ);			
	event = READ_REG1(0x00f0);
	event = READ_REG1(0x00f0);
	if (event == 0x01) 
	{
		r = TRUE;
	}

	//event >1 ,Error status then reset
	if (event > 0x01)
	{
		WRITE_REG1(0x0005,0x00);
		WRITE_REG1(0x00fe,0x80);	//clear isr
		CONSOL_Printf("\nRecieve packet error.");
		while(1)
		{
			CONSOL_Printf("\nReset()\n");
			if(dm9000Reset() && dm9000Init())
				break;
		}
	}
	return r;
}

/*::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
PUBLIC USHORT
DM9000DBG_GetFrame(BYTE *pbData, USHORT *pwLength)
{
	if (DM9000DBG_IsReceivedPacket()) 
	{
		return RcvPkt(pbData, *pwLength);
	}
	return 0;
}

PUBLIC USHORT
DM9000DBG_SendFrame(BYTE *pbData, USHORT slen)
{
	return TransmitPkt(pbData, slen);
}


   static BYTE out_data[1024];
   static BYTE in_data[2048];

void APP_vMain(void)
{
	int i;
	USHORT len;
	struct eth_addr ethaddr;

	for(i=0; i<sizeof(out_data); i++)
	out_data[i] = (BYTE)i;
	while(1)
	{
		dm9000Probe();
		dm9000Reset();
		dm9000Init();
		//getipaddr() 返回u32_t  小端IP  192 168 0 118 = 0xc0 0xA8 0x00 0x76   
		//转换后得 0x760x000xA80xc0   0x7600A8c0 
		arp_getethaddr(getipaddr(), &ethaddr);//免费ARP
		 CONSOL_Printf("ethaddr:0X%x0X%x0X%x0X%x0X%x0X%x\n",ethaddr.addr[0],ethaddr.addr[1],
		 ethaddr.addr[2],ethaddr.addr[3],ethaddr.addr[4],ethaddr.addr[5]);
	     
		while(1)
		{
			if(CONSOL_GetChar((char*)&i))
			{
				if((i&0xff) == 0x1b)//27
					break;
			}
			
			len = sizeof(in_data);
			len = DM9000DBG_GetFrame(in_data, &len);
			if(len > 0)
			{
				eth_input(in_data, len);
				CONSOL_Printf("\n\nRecieve packet len=%d", len);
				for(i=0; len>0; len--,i++)
					CONSOL_Printf((i%16)==0 ? "\n%02x ": "%02x ", in_data[i]);
		}
		}
	}
}

static void uDelay(int iUSecs) 
{
	int i;
	int iScaledSecs = (iUSecs * 200);
	for(i=0;i<iScaledSecs;i++);
}


⌨️ 快捷键说明

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