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

📄 dm9000.c

📁 cayman提供的PXA270 wince下的bsp源码包
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  DM9000.c
//
#include <windows.h>
#include <ceddk.h>
#include <ethdbg.h>
#include <DM9000.h>

extern void Wait(unsigned);

//------------------------------------------------------------------------------

#define DM9000A_EISA_NUMBER         0x630e
#define RETRY_COUNT                 0x00100000


//------------------------------------------------------------------------------
volatile DM9000_REGS *g_pDM9000;
volatile BYTE *g_pDM9000Frank;

static UINT16 g_hash[4];
static UINT32 g_filter;
DWORD dwConfigOptions;
//------------------------------------------------------------------------------

static UINT16 ReadPacketPage(UINT16 address);
static VOID WritePacketPage(UINT16 address, UINT16 data);
static UINT32 ComputeCRC(UINT8 *pBuffer, UINT32 length);

/*add by frank*/
#define DM9000_VID		0x0A46
#define	DM9000_PID		0x9000

#define	DM9000_ADDR_OFFSET		0x00
//#define	DM9000_DATA_OFFSET		0x04
#define	DM9000_DATA_OFFSET		0x4000

typedef	enum {
	DM9_NCR = 0,
	DM9_NSR,	/* 0x01 */
	DM9_TXCR,	/* 0x02 */
	DM9_TXSR1,	/* 0x03 */
	DM9_TXSR2,	/* 0x04 */
	DM9_RXCR,	/* 0x05 */
	DM9_RXSR,	/* 0x06 */
	DM9_ROCR,	/* 0x07 */
	DM9_BACKTH,	/* 0x08 */
	DM9_PAUSETH,/* 0x09 */
	DM9_FLOW,	/* 0x0s */
	DM9_EPCNTL,	/* 0x0B */
	DM9_EPADDR,	/* 0x0c */
	DM9_EPLOW,	/* 0x0d */
	DM9_EPHIGH,	/* 0x0e */
	DM9_WCR,	/* 0x0f */
	
	DM9_PAR0 = 0x10,
	DM9_PAR1,	/* 0x11 */
	DM9_PAR2,	/* 0x12 */
	DM9_PAR3,	/* 0x13 */
	DM9_PAR4,	/* 0x14 */
	DM9_PAR5,	/* 0x15 */

	DM9_MAR0 = 0x16,
	DM9_MAR1,	/* 0x17 */
	DM9_MAR2,	/* 0x18 */
	DM9_MAR3,	/* 0x19 */
	DM9_MAR4,	/* 0x1a */
	DM9_MAR5,	/* 0x1b */
	DM9_MAR6,	/* 0x1c */
	DM9_MAR7,	/* 0x1d */
		
	DM9_GPCR = 0x1E,
	DM9_GPR,	/* 0x1f */

	DM9_TRAL = 0x22,
	DM9_TRAH = 0x23,
	
	DM9_VIDL = 0x28,
	DM9_VIDH,	/* 0x29 */
	DM9_PIDL,	/* 0x2a */
	DM9_PIDH,	/* 0x2b */
	DM9_SMCR = 0x2f,
	
	DM9_MRCMDX = 0xF0,
	DM9_MRCMD = 0xF2,
	DM9_MDRAH = 0xF4,
	DM9_MDRAL,	/* 0xf5 */
	

	DM9_MWCMDX = 0xF6,
	DM9_MWCMD = 0xF8,
	DM9_MDWAL = 0xFA,
	DM9_MDWAH = 0xFB,
	
	DM9_TXLENL = 0xFC,
	DM9_TXLENH,	/* 0xfd */

	DM9_ISR = 0xFE,
	DM9_IMR		/* 0xff */
		
} DM9000_REGISTER_TYPE;


typedef	unsigned long	U32;
typedef	unsigned long	*PU32;
typedef	unsigned short	U16;
typedef	unsigned short	*PU16;
typedef	unsigned char	U8;
typedef	unsigned char	*PU8;

#define	DIM(a)	(sizeof(a) / sizeof(a[0]))
#define	MINI(a,b)	(((a)<(b)) ? (a):(b))
#define	MAXI(a,b)	(((a)>(b)) ? (a):(b))

#define	MAKE_MASK(a)		MAKE_MASK1(a)
#define	MAKE_MASK1(a)		(1<<(a))
#define	MAKE_MASK2(a,b)		(MAKE_MASK1(a)|MAKE_MASK1(b))
#define	MAKE_MASK3(a,b,c)	(MAKE_MASK2(a,b)|MAKE_MASK1(c))
#define	MAKE_MASK4(a,b,c,d)	(MAKE_MASK2(a,b)|MAKE_MASK2(c,d))
#define	MAKE_MASK6(a,b,c,d,e,f)	\
	(MAKE_MASK4(a,b,c,d)|MAKE_MASK2(e,f))
#define	MAKE_MASK7(a,b,c,d,e,f,g)	\
	(MAKE_MASK4(a,b,c,d)|MAKE_MASK3(e,f,g))
#define	MAKE_MASK8(a,b,c,d,e,f,g,h)	\
	(MAKE_MASK4(a,b,c,d)|MAKE_MASK4(e,f,g,h))

#define	HIGH_BYTE(n)	(((n)&0xFF00)>>8)
#define	LOW_BYTE(n)		((n)&0x00FF)
#define	HIGH_WORD(n)	(((n)&0xFFFF0000)>>16)
#define	LOW_WORD(n)		((n)&0x0000FFFF)

#define	MAKE_WORD(l,h)	( ((h)<<8) | ((l)&0xff) )
#define	MAKE_DWORD(ll,lh,hl,hh)	\
	( (MAKE_WORD(hl,hh) << 16 ) | MAKE_WORD(ll,lh) )



U32 		m_uLastAddressPort = 0;
int		m_nIoMode;
int		m_nIoMaxPad;

/**/

#define	VALIDATE_ADDR_PORT(p) \
	if( m_uLastAddressPort != (p) ) \
		{ \
			/*OALMSG("Writ 0x%X  to port 0x%X \r\n", p, (g_pDM9000Frank + DM9000_ADDR_OFFSET) );*/	\
			*(U16*)(g_pDM9000Frank + DM9000_ADDR_OFFSET)  =(U16)(p);\
			m_uLastAddressPort = (p);\
		}


static U32	DeviceReadPort(	U32		uPort);
static U32	DeviceWritePort(U32		uPort,	U32		uValue);


static U32	DeviceReadPort(	U32		uPort)
{
	U16 	val;
	
	VALIDATE_ADDR_PORT(uPort)

	val = *(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);

	val &= 0xffff;

	//OALMSG("Read port 0x%X is 0x%X\r\n", (g_pDM9000Frank + DM9000_DATA_OFFSET),val);	
	
	return (U32)val;
}

static U32	DeviceWritePort(
	U32		uPort,
	U32		uValue)
{
	VALIDATE_ADDR_PORT(uPort)

	//OALMSG("Writ 0x%X  to port 0x%X \r\n", uValue, (g_pDM9000Frank + DM9000_DATA_OFFSET) );

	*(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET) = 	(U16)uValue;

	return uValue;
}

DWORD DM9000AGetPendingInterrupts(void)
{
	OALMSG("+DM9000AGetPendingInterrupts\r\n");
	OALMSG("-DM9000AGetPendingInterrupts\r\n");

	return 0;
}

BOOL DM9000AReadEEPROM( UINT16 EEPROMAddress , UINT16 *pwVal)
{
	OALMSG("+DM9000AReadEEPROM\r\n");
	OALMSG("-DM9000AReadEEPROM\r\n");

	return FALSE;
}

BOOL DM9000AWriteEEPROM( UINT16 EEPROMAddress, UINT16 Data )
{
	OALMSG("+DM9000AWriteEEPROM\r\n");
	OALMSG("-DM9000AWriteEEPROM\r\n");

	return FALSE;
}

DWORD DM9000ASetOptions(DWORD dwOptions)
{
    DWORD dwOldOptions = dwConfigOptions;
    dwConfigOptions = dwOptions;
	OALMSG("+DM9000ASetOptions\r\n");
	OALMSG("-DM9000ASetOptions\r\n");
	
    return dwOldOptions;

}
void DebugDelay(int i)
{
	while(i--);
}

void DebugSegment7(unsigned long value)
{
#define CACHED_TO_UNCACHED_OFFSET		0x20000000
#define  SEGMENT7_BASE_PHYSICAL	 		0x12000000
#define SEGMENT7_BASE_C_VIRTUAL  	 		0x9E800000
#define SEGMENT7_BASE_U_VIRTUAL  	 		(SEGMENT7_BASE_C_VIRTUAL + CACHED_TO_UNCACHED_OFFSET)	

	volatile unsigned long *v_pSegment7=(volatile unsigned long *)SEGMENT7_BASE_U_VIRTUAL;
	unsigned char seg7table[16] = {
#if 0		
		//0  	1		2		3		4		5		6		7
		0xc0,	0xf9,	0xa4,	0xb0,	0x99,	0x92,	0x82,	0xf8,
		//8		9		a		b		c		d		e		f
		0x80,	0x90,	0x88,	0x83,	0xc5,	0xa1,	0x86,	0x8e
#else
		//0 		1		2		3		4		5		6		7
		0x24,	0xF5,	0x07,	0x45,	0xD4,	0x4C,	0x0C,	0xE4,
		//8 		9		a		b		c		d		e		f
		0x04,	0x44,	0x84,	0x1C,	0x2E,	0x15,	0x0E,	0x8e
#endif
	};

	unsigned char low = (unsigned char)(value &0xf);
	unsigned char high = (unsigned char)((value & 0xf0)>>4);

	unsigned new_value = (seg7table[high]<<8) + seg7table[low];

	if(value == 0xffFFffFF)
		new_value = 0xffff;

	*v_pSegment7 = new_value;
}

	
void DebugLed(void)
{
	typedef unsigned long		   XLLP_UINT32_T,  *P_XLLP_UINT32_T;
	typedef volatile XLLP_UINT32_T XLLP_VUINT32_T, *P_XLLP_VUINT32_T;
	/**
	  GPIO Register Definitions
	**/
	typedef struct 
	{
		XLLP_VUINT32_T GPLR0;			/* Level Detect Reg. Bank 0 */
		XLLP_VUINT32_T GPLR1;			/* Level Detect Reg. Bank 1 */
		XLLP_VUINT32_T GPLR2;			/* Level Detect Reg. Bank 2 */
		XLLP_VUINT32_T GPDR0;			/* Data Direction Reg. Bank 0 */
		XLLP_VUINT32_T GPDR1;			/* Data Direction Reg. Bank 1 */
		XLLP_VUINT32_T GPDR2;			/* Data Direction Reg. Bank 2 */
		XLLP_VUINT32_T GPSR0;			/* Pin Output Set Reg. Bank 0 */
		XLLP_VUINT32_T GPSR1;			/* Pin Output Set Reg. Bank 1 */
		XLLP_VUINT32_T GPSR2;			/* Pin Output Set Reg. Bank 2 */
		XLLP_VUINT32_T GPCR0;			/* Pin Output Clr Reg. Bank 0 */
		XLLP_VUINT32_T GPCR1;			/* Pin Output Clr Reg. Bank 1 */
		XLLP_VUINT32_T GPCR2;			/* Pin Output Clr Reg. Bank 2 */
		XLLP_VUINT32_T GRER0;			/* Ris. Edge Detect Enable Reg. Bank 0 */
		XLLP_VUINT32_T GRER1;			/* Ris. Edge Detect Enable Reg. Bank 1 */
		XLLP_VUINT32_T GRER2;			/* Ris. Edge Detect Enable Reg. Bank 2 */
		XLLP_VUINT32_T GFER0;			/* Fal. Edge Detect Enable Reg. Bank 0 */
		XLLP_VUINT32_T GFER1;			/* Fal. Edge Detect Enable Reg. Bank 1 */
		XLLP_VUINT32_T GFER2;			/* Fal. Edge Detect Enable Reg. Bank 2 */
		XLLP_VUINT32_T GEDR0;			/* Edge Detect Status Reg. Bank 0 */
		XLLP_VUINT32_T GEDR1;			/* Edge Detect Status Reg. Bank 1 */
		XLLP_VUINT32_T GEDR2;			/* Edge Detect Status Reg. Bank 2 */
		XLLP_VUINT32_T GAFR0_L; 		/* Alt. Function Select Reg.[  0:15 ] */
		XLLP_VUINT32_T GAFR0_U; 		/* Alt. Function Select Reg.[ 16:31 ] */
		XLLP_VUINT32_T GAFR1_L; 		/* Alt. Function Select Reg.[ 32:47 ] */
		XLLP_VUINT32_T GAFR1_U; 		/* Alt. Function Select Reg.[ 48:63 ] */
		XLLP_VUINT32_T GAFR2_L; 		/* Alt. Function Select Reg.[ 64:79 ] */
		XLLP_VUINT32_T GAFR2_U; 		/* Alt. Function Select Reg.[ 80:95 ] */
		XLLP_VUINT32_T GAFR3_L; 		/* Alt. Function Select Reg.[ 96:111] */
		XLLP_VUINT32_T GAFR3_U; 		/* Alt. Function Select Reg.[112:120] */
		XLLP_VUINT32_T RESERVED1[35];	/* addr. offset 0x074-0x0fc */
		XLLP_VUINT32_T GPLR3;			/* Level Detect Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED2[2];	/* addr. offset 0x104-0x108 */
		XLLP_VUINT32_T GPDR3;			/* Data Direction Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED3[2];	/* addr. offset 0x110-0x114 */
		XLLP_VUINT32_T GPSR3;			/* Pin Output Set Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED4[2];	/* addr. offset 0x11c-0x120 */
		XLLP_VUINT32_T GPCR3;			/* Pin Output Clr Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED5[2];	/* addr. offset 0x128-0x12c */
		XLLP_VUINT32_T GRER3;			/* Ris. Edge Detect Enable Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED6[2];	/* addr. offset 0x134-0x138 */
		XLLP_VUINT32_T GFER3;			/* Fal. Edge Detect Enable Reg. Bank 3 */
		XLLP_VUINT32_T RESERVED7[2];	/* addr. offset 0x140-0x144 */
		XLLP_VUINT32_T GEDR3;			/* Edge Detect Status Reg. Bank 3 */
	
	} XLLP_GPIO_T, *P_XLLP_GPIO_T;

#define PERIF_BASE_C_VIRTUAL		0x84000000	
#define CACHED_TO_UNCACHED_OFFSET		0x20000000
#define PERIF_BASE_U_VIRTUAL		(PERIF_BASE_C_VIRTUAL+CACHED_TO_UNCACHED_OFFSET)
#define GPIO_OFFSET                     0x00E00000      // GPIO
#define GPIO_BASE_U_VIRTUAL             (PERIF_BASE_U_VIRTUAL + GPIO_OFFSET)

	volatile XLLP_GPIO_T *v_pGPIOReg;

	v_pGPIOReg = (volatile XLLP_GPIO_T *)GPIO_BASE_U_VIRTUAL;

	while(1)
	{
		int i=1;
		
		v_pGPIOReg->GPSR1 = 0x80;
		while(i<0xffffff)i++;
		
		v_pGPIOReg->GPCR1 = 0x80;		
		i=1;
		while(i<0xffffff)i++;
		
	}
}

BOOL	DevicePolling(
	U32		uPort,
	U32		uMask,
	U32		uExpected,
	U32		uInterval,	/* in millisecond */
	U32		uRetries)
{
	for(;uRetries;uRetries--)
	{
		if((DeviceReadPort(uPort) & uMask) == uExpected) break;
		Wait(uInterval);
	} // of retry loop
	
	return (BOOL)uRetries;
}


U16	DeviceReadEeprom(	U32		uWordAddress)
{
	U16		highbyte,lowbyte;
	
	// assign the register offset
	DeviceWritePort(DM9_EPADDR,uWordAddress);
	
	// issue EEPROM read command<2>
	DeviceWritePort(DM9_EPCNTL,(1<<2));
	
	// wait until status bit<0> cleared
	// 80 uS, 5 times
	if(!DevicePolling(DM9_EPCNTL,(1<<0),0x00,80,5))
		return (U16)-1;
	
	// stop command
	DeviceWritePort(DM9_EPCNTL,0);

	// retrive data
	lowbyte  = (U16)DeviceReadPort(DM9_EPLOW);
	highbyte = (U16)DeviceReadPort(DM9_EPHIGH);
	
	return ((highbyte<<8) | lowbyte);
}

typedef	enum {
	BYTE_MODE=1,
	WORD_MODE=2,
	DWORD_MODE=4,
} DEVICE_IO_MODE;

typedef	enum {
	NIC_HW_OK,
	NIC_HW_TX_IDLE,
	NIC_HW_TX_BUSY,
} NIC_HW_STATUS_TYPE;

#define	REPORT(evt,val)

#define	CHECK_SHUTDOWN()

/********************************************************************************
 *
 * EEPROM 93C46 Parameters
 *
 ********************************************************************************/
#define	BITS_PER_BYTE	8

#define EEPROM_93C46_BITS				1024
#define EEPROM_93C46_SIZE				(EEPROM_93C46_BITS/BITS_PER_BYTE)
#define EEPROM_93C46_MAX_CYCLES			25
#define	EEPROM_93C46_ADDRESS_BITS		6
#define	EEPROM_93C46_DATA_BITS			16
#define EEPROM_93C46_DELAY				20
typedef	unsigned short EEPROM_93C46_DATA_TYPE;

/********************************************************************************
 *
 * EEPROM Parameters
 *
 ********************************************************************************/

#define	EEPROM_SIZE			EEPROM_93C46_SIZE
#define	EEPROM_MAX_CYCLES	EEPROM_93C46_MAX_CYCLES
#define	EEPROM_DELAY		EEPROM_93C46_DELAY
#define	EEPROM_ADDRESS_BITS EEPROM_93C46_ADDRESS_BITS
#define	EEPROM_DATA_BITS 	EEPROM_93C46_DATA_BITS
#define	EEPROM_DATA_TYPE	EEPROM_93C46_DATA_TYPE

/********************************************************************************
 *
 * PHY Parameters
 *
 ********************************************************************************/

#define MII_INTERNAL_PHY_ADDR		1
#define	MII_PHY_ADDR_LEN	5
#define	MII_REG_ADDR_LEN	5
#define	MII_DELAY			20
#define	MII_PREAMBLES		32

#define MII_OFFSET_BMCR		0x00
#define MII_OFFSET_BMSR		0x01
#define MII_OFFSET_OUI_M	0x02
#define MII_OFFSET_OUI_L	0x03
#define MII_OFFSET_ANAR		0x04
#define MII_OFFSET_ALPAR	0x05

/********************************************************************************
 *
 * Configuration definitions
 *
 ********************************************************************************/

#define CONNECTION_NONE             0x00000000
#define CONNECTION_AUTO             0x00000001
#define CONNECTION_10_HALF          0x00000002
#define CONNECTION_10_FULL          0x00000003
#define CONNECTION_100_HALF         0x00000004
#define CONNECTION_100_FULL         0x00000005
#define CONNECTION_1M8_HPNA         0x00000100
#define CONNECTION_10M8_HPNA        0x00000200


/********************************************************************************
 *
 * CRC32 Routine
 *
 * This routine calculates the CRC based on the following polynominal
 *   x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
 *
 * About the CRC value of one EEPROM
 *
 * eeprom<126-127> = CRC value = (U16)crc32(eeprom<0..125>);
 *
 *
 *
 *******************************************************************************/

U32	DeviceCalculateCRC32(
	PU8		ptrBuffer,
	int		nLength,
	BOOL	bReverse)
{
    U32 	Crc, Carry;
    int		i, j;
    U8		CurByte;

    Crc = 0xffffffff;

    for (i = 0; i < nLength; i++) {

        CurByte = ptrBuffer[i];

        for (j = 0; j < 8; j++) {

            Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);

            Crc <<= 1;

            CurByte >>= 1;

            if (Carry) {

                Crc = (Crc ^ 0x04c11db6) | Carry;

            }

        }

    }

    for (i=0, Carry=0x0L; i < 32 ; i++) {
       Carry <<= 1;
       if (Crc & 0x1) {
          Carry |= 0x1L;
       }
       Crc >>= 1;
    }

    return bReverse?~Carry:Carry;

}


U16	DeviceWriteEeprom(	U32		uWordAddress,	U16		uValue);

void	EDeviceLoadEeprom(void)
{
	int		n;
	static U8		m_szEeprom[EEPROM_SIZE];	
	EEPROM_DATA_TYPE	*pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];

	for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
	{
		*pcurr = DeviceReadEeprom(n);

	} // of for offset n
	
	DeviceCalculateCRC32(&m_szEeprom[0],DIM(m_szEeprom)-2,TRUE);

	pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];

	for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
	{
		OALMSG("%X  ",*pcurr);
		if(((n+1)%8)==0)OALMSG("\n");
	} // of for offset n	
#if 0
	for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++)
	{
		OALMSG("%X  ",DeviceWriteEeprom(n,n+5));
		if(((n+1)%8)==0)OALMSG("\n");		
	} // of for offset n	

	pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];

	for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
	{
		*pcurr = DeviceReadEeprom(n);

	} // of for offset n
	
	DeviceCalculateCRC32(&m_szEeprom[0],DIM(m_szEeprom)-2,TRUE);

	pcurr=(EEPROM_DATA_TYPE*)&m_szEeprom[0];

	for(n=0;n<(DIM(m_szEeprom)/sizeof(EEPROM_DATA_TYPE));n++,pcurr++)
	{
		OALMSG("%X  ",*pcurr);
		if(((n+1)%8)==0)OALMSG("\n");
	} // of for offset n		
#endif	
}

U16	DeviceWriteEeprom(
	U32		uWordAddress,
	U16		uValue)
{
	// assign the register offset
	DeviceWritePort(DM9_EPADDR,uWordAddress);

	// put data
	DeviceWritePort(DM9_EPLOW, LOW_BYTE(uValue));
	DeviceWritePort(DM9_EPHIGH,HIGH_BYTE(uValue));
		
	// issue EEPROM write enable<4> and write command<1>
	DeviceWritePort(DM9_EPCNTL,MAKE_MASK2(4,1));
	
	// wait until status bit<0> cleared
	DevicePolling(DM9_EPCNTL,MAKE_MASK(0),0x00,20,-1);
	
	// stop command
	DeviceWritePort(DM9_EPCNTL,0);

	return uValue;
}

void	EDeviceInitialize(

⌨️ 快捷键说明

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