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

📄 dm9000.c

📁 cayman提供的PXA270 wince下的bsp源码包
💻 C
📖 第 1 页 / 共 2 页
字号:
	int		nResetCounts)
{
	U32		val;
	
	// reset member varialbes
	m_uLastAddressPort = (U32)-1;
	
	DeviceWritePort(0x1f, 0x00);
	Wait(20);

	// software reset the device
	DeviceWritePort(DM9_NCR, 0x03);
	Wait(20);

	DeviceWritePort(DM9_NCR, 0x03);
	Wait(20);
	
	// read the io orgnization
	// ISR<7:6> == x1, dword
	// ISR<7:6> == 0x, word
	// ISR<7:6> == 10, byte mode
	val = DeviceReadPort(DM9_ISR);
	if(val & MAKE_MASK(6))
	{
		m_nIoMode = DWORD_MODE;
		m_nIoMaxPad = 3;
	}
	else if(!(val & MAKE_MASK(7)))
	{
		m_nIoMode = WORD_MODE;
		m_nIoMaxPad = 1;
	}
	else
	{
		m_nIoMode = BYTE_MODE;
		m_nIoMaxPad = 0;
	}		
	
	// activate internal phy
	// select GPIO 0<0>, set it to output
	DeviceWritePort(DM9_GPCR, (1<<0));
	Wait(20);
	// output zero to activate internal phy
	DeviceWritePort(DM9_GPR,  0x00);
	Wait(20);
	// Enable memory chain
	DeviceWritePort(DM9_IMR, (1<<7));
	Wait(20);	

	DeviceWritePort( DM9_TXCR, 0);		/* TX Polling clear */
	Wait(20);	
	DeviceWritePort( DM9_BACKTH, 0x3f);	/* Less 3kb, 600us */
	Wait(20);	
	DeviceWritePort( DM9_SMCR, 0);		/* Special Mode */
	Wait(20);	
	DeviceWritePort( DM9_NSR, 0x2c);	/* clear TX status */
	Wait(20);	
	DeviceWritePort( DM9_ISR, 0x0f); 	/* Clear interrupt status */
	Wait(20);	

	OALMSG("val =%X, m_nIoMode:%X  m_nIoMaxPad:%X\r\n",val,m_nIoMode,m_nIoMaxPad);	

	DeviceWritePort(DM9_PAR0+0,(U32)0xc000);
	DeviceWritePort(DM9_PAR0+1,(U32)0x2826);		
	DeviceWritePort(DM9_PAR0+2,(U32)0x3096);	

	/* Activate DM9000A/DM9010 */
	DeviceWritePort(DM9_RXCR, 0x30 | 1 | MAKE_MASK(1) );	/* RX enable */
//	DeviceWritePort(DM9_RXCR,  1 | MAKE_MASK(1) );	/* RX enable */	
	DeviceWritePort(DM9_IMR, 0x80); 	// Enable TX/RX interrupt mask
}


//------------------------------------------------------------------------------
//
//  Function:  DM9000AInit
//
BOOL DM9000AInit(BYTE *pAddress, DWORD dwMultiplier, USHORT mac[3])
{
	U32	val;

	OALMSG("+DM9000AInit(0x%X, %B:%B:%B:%B:%B:%B)\r\n",pAddress, mac[0]&0xFF, mac[0]>>8, mac[1]&0xFF, mac[1]>>8,mac[2]&0xFF, mac[2]>>8);

	// Save address
	g_pDM9000 = (volatile DM9000_REGS*)pAddress;
	g_pDM9000Frank = pAddress;	

//	DebugSegment7(0x08);			

	val  		= 	DeviceReadPort(0x2a);
	val 		|= 	DeviceReadPort(0x2b)	<<	8;
	val 		|= 	DeviceReadPort(0x28)	<<	16;
	val 		|= 	DeviceReadPort(0x29)	<<	24;

	OALMSG("[dm9: Chip signature is 0x%X\r\n", val);

	if( 	(	DeviceReadPort(DM9_VIDL) 	!= LOW_BYTE(DM9000_VID)	) 	||
		(	DeviceReadPort(DM9_VIDH) 	!= HIGH_BYTE(DM9000_VID)	) 	||
		(	DeviceReadPort(DM9_PIDL) 	!= LOW_BYTE(DM9000_PID)	) 	||
		(	DeviceReadPort(DM9_PIDH) 	!= HIGH_BYTE(DM9000_PID)	) 	)
	{
		OALMSG("Unknown device\n");
//		DebugSegment7(0x09);				
	}
	
//	DebugSegment7(0x0a);	   

//	EDeviceLoadEeprom();

	EDeviceInitialize(0);
	
	return TRUE;

}

PU8		DeviceWriteString(PU8		ptrBuffer,	int		nLength)
{
#if 1	
	int		count;
	PU16	pcurr=(PU16)ptrBuffer;
	
//	count = (nLength + m_nIoMaxPad) / m_nIoMode;

	switch (m_nIoMode)
	{
		case BYTE_MODE:
			break;
			
		case WORD_MODE:
		{
			#if 0
			int i;
			OALMSG("Len is %X  \n",nLength);
			
			for(i=0;i<nLength;i++,pcurr++)
			{
				OALMSG("%X  ", *pcurr);
			}
			OALMSG("\n");			
			#endif
			
			count = (nLength+1)/2;
			
			pcurr=(PU16)ptrBuffer;
			*(U16*)(g_pDM9000Frank + DM9000_ADDR_OFFSET)  =(U16)(DM9_MWCMD);
			for(;count--;pcurr++)
			{
				*(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET) = *pcurr;
			}
		}
			break;

		case DWORD_MODE:
			break;
		
		default:
			break;
	} // of switch
#endif	
	
	return ptrBuffer;
}


//------------------------------------------------------------------------------
//
//  Function:  DM9000ASendFrame
//
UINT16 DM9000ASendFrame(BYTE *pData, DWORD length)
{
	/* fill data */
	DeviceWriteString(pData,length);

	DeviceWritePort(DM9_TXLENH,HIGH_BYTE(length));
	DeviceWritePort(DM9_TXLENL,LOW_BYTE(length));
		
	// TXCR<0>, issue TX request
	DeviceWritePort(DM9_TXCR, MAKE_MASK(0));


	return 0;
}

U8 check_rx_ready(U8 rxbyte)
{
	if (!(rxbyte & 0x01))
		return 0;
	return ((rxbyte >> 4) | 0x01);
}

#pragma pack(push, 1)
typedef struct _RX_DESC
{
	U8 rxbyte;
	U8 status;
	U16 length;
}RX_DESC;

typedef union{
	U8 buf[4];
	RX_DESC desc;
} rx_t;
#pragma pack(pop)


#define	DM9_SETUP_FRAME	0xBadBeef0
#define	DM9_MULTICAST_LIST	64

typedef	struct	{
	U8		bState;
	U8		bStatus;
	U16		nLength;
} DM9_RX_DESCRIPTOR, *PDM9_RX_DESCRIPTOR;

#define ETH_MAX_FRAME_SIZE  1514
#define ETH_HEADER_SIZE     14
#define ETH_ADDRESS_LENGTH  6
#define ETH_CRC_SIZE     	4
#define	MAX_MULTICAST_LIST	64
#define	DRIVER_BUFFER_SIZE	0x5F0

PU8		DeviceReadString(	PU8		ptrBuffer,	int		nLength)
{
#if 1	
	int		count;
	
//	count = (nLength + m_nIoMaxPad) / m_nIoMode;
	
	VALIDATE_ADDR_PORT(DM9_MRCMD);

	switch (m_nIoMode)
	{
		case BYTE_MODE:
			break;
			
		case WORD_MODE:
		{
			PU16 pcurr=(PU16)ptrBuffer;
			count = (nLength+1)/2;

			for(;count--;pcurr++)
			{
				 *pcurr = *(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);
			}
		}
		break;

		case DWORD_MODE:
			break;
		
		default:
			break;
	} // of switch
#endif	

	
	return ptrBuffer;
}

U32		DeviceReadData(void)
{
	U32		value;

	return	*(PU32)DeviceReadString((PU8)&value,sizeof(value));
}

U32		DeviceReadDataWithoutIncrement(void)
{
	U32		value;

	VALIDATE_ADDR_PORT(DM9_MRCMDX);

	switch (m_nIoMode)
	{
		case BYTE_MODE:
			break;

		case WORD_MODE:
			value = *(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);			
			break;
				
		case DWORD_MODE:

			break;
				
		default:
			break;
	} // of switch
	
	return value;
}


//------------------------------------------------------------------------------
//
//  Function:  DM9000AGetFrame
//
//   	OALMSG("+DM9000AGetFrame(0x%X, %d)\r\n", pData, *pLength);	
//OALMSG("-DM9000AGetFrame(length = %d)\r\n", *pLength);
UINT16 DM9000AGetFrame(UINT8 *pData, UINT16 *pLength)
{
	int 	errors=0;
	
	U32 	desc;
	PDM9_RX_DESCRIPTOR	pdesc;
	
	//OALMSG("+DM9000AGetFrame(0x%X, %d)\r\n", pData, *pLength);	

	//OALMSG("DM9_RXSR is %x\r\n",DeviceReadPort(DM9_RXSR));

	//OALMSG("DM9_ROCR is %x\r\n",DeviceReadPort(DM9_ROCR));
	DeviceReadPort(DM9_RXSR);
	DeviceReadPort(DM9_ROCR);	
		
	for(pdesc=(PDM9_RX_DESCRIPTOR)&desc;;)
	{
		// probe first byte
		desc = DeviceReadDataWithoutIncrement();
		//OALMSG("desc is %X\r\n",desc);	
	
		// check if packet available, 01h means available, 00h means no data
		if(pdesc->bState != 0x01)
		{
			*pLength = 0;
			break;
		}

		// get the data descriptor again
		desc = DeviceReadData();
		//OALMSG("desc is %X\r\n",desc);			

		// read out the data to buffer
		// Performance issue: maybe we may discard the data
		// just add the rx address.
		// if the length is greater than buffer size, ...
		if((pdesc->nLength > *pLength))
		{
			OALMSG("AID_LARGE_INCOME_PACKET\r\n");	
			break;
		}

		DeviceReadString((PU8)pData,pdesc->nLength);

		// check status, as specified in DM9_RXSR,
		// the following bits are error
		// <3> PLE
		// <2> AE
		// <1> CE
		// <0> FOE
		if(pdesc->bStatus & MAKE_MASK4(3,2,1,0))
		{
			errors++;
			OALMSG("errors = %d\r\n", errors);			
			continue;
		} // of error happens
		
		*pLength =pdesc->nLength;
		{
#if 0
			int i;
			PU8 pcurr =(PU8) pData;
			OALMSG("Len is %X  \n",*pLength);
			
			for(i=0;i<*pLength;i++,pcurr++)
			{
				OALMSG("%B	", *pcurr);
				if(((i+1)%8)==0)OALMSG("\r\n");
	
			}
			OALMSG("\r\n"); 		
#endif
	
		}
		break;
	} // of forever read loop

	//OALMSG("-DM9000AGetFrame(length = %d)\r\n", *pLength);	

	return *pLength;
}


#if 0
UINT16 DM9000AGetFrame(UINT8 *pData, UINT16 *pLength)
{
	U8 rxbyte, val;
	U16 i, GoodPacket, tmplen = 0, MDRAH, MDRAL;
	U32 tmpdata;

	U16 * ptr = (U16*)pData;
	PU16	pcurr=(PU16)pData;
	U8* rdptr =(U8*)pData;
	rx_t * rx_p = (rx_t*)pData;
   	OALMSG("+DM9000AGetFrame(0x%X, %d)\r\n", pData, *pLength);	

	do {
		/*store the value of Memory Data Read address register*/
		MDRAH=DeviceReadPort( DM9_MDRAH);
		MDRAL=DeviceReadPort( DM9_MDRAL);
		
		//DeviceReadPort( DM9_MRCMDX);		/* Dummy read */
		rxbyte =(U16) DeviceReadPort( DM9_MRCMDX);;	/* Got most updated data */

		/* packet ready to receive check */
		if(!(val = check_rx_ready(rxbyte))) break;

		/* A packet ready now  & Get status/length */
		GoodPacket = TRUE;
		*(U16*)(g_pDM9000Frank + DM9000_ADDR_OFFSET)  =(U16)(DM9_MRCMD);
	
		/* Read packet status & length */
		switch (m_nIoMode) 
			{
			  case BYTE_MODE: 
					break;
			  case WORD_MODE:
					*ptr = *(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);
					*(ptr+1)	= *(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);
					break;
			  case DWORD_MODE:
					break;
			  default:
					break;
			}

		/* Packet status check */
		if (rx_p->desc.status & 0xbf)
		{
			GoodPacket = FALSE;
			if (rx_p->desc.status & 0x01) 
			{
				OALMSG("<RX FIFO error>\n");
			}
			if (rx_p->desc.status & 0x02) 
			{
				OALMSG("<RX CRC error>\n");
			}
			if (rx_p->desc.status & 0x80) 
			{
				OALMSG("<RX Length error>\n");
			}
			if (rx_p->desc.status & 0x08)
				OALMSG("<Physical Layer error>\n");
		}

		if (!GoodPacket)
		{
			// drop this packet!!!
			switch (m_nIoMode)
			{
				case BYTE_MODE:
					break;
				case WORD_MODE:
					tmplen = (rx_p->desc.length + 1) / 2;
					for (i = 0; i < tmplen; i++)
						tmpdata= *(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);
					break;
				case DWORD_MODE:
					break;
			}
			continue;/*next the packet*/
		}
		/* Read received packet from RX SARM */
		switch (m_nIoMode)
		{
			case BYTE_MODE:
				break;
			case WORD_MODE:
				tmplen = (rx_p->desc.length + 1) / 2;
				for (i = 0; i < tmplen; i++)
					((U16 *)rdptr)[i] =*(U16*)(g_pDM9000Frank + DM9000_DATA_OFFSET);
				break;
			case DWORD_MODE:
				break;
		}	
		*pLength = rx_p->desc.length;

		OALMSG("Len is %X  \n",*pLength);
		
		pcurr = (U16*)pData;
		tmplen = (rx_p->desc.length + 1) / 2;

		for(i=0;i<tmplen;i++,pcurr++)
		{
			OALMSG("%X  ", *pcurr);
		}
		OALMSG("\n");			

		break;
		
	}while(rxbyte == 0x01);
	OALMSG("-DM9000AGetFrame(length = %d)\r\n", *pLength);

	return *pLength;
	
}
#endif

//------------------------------------------------------------------------------
//
//  Function:  DM9000AEnableInts
//
VOID DM9000AEnableInts(void)
{

	OALMSG("+DM9000AEnableInts\r\n");
	// bits to turn on interrupt latch
	// <7> buffer chain enable
	// <3> rx overflow count overflow
	// <2> rx overflow
	// <1> tx completed indication
	// <0> rx completed indication
	DeviceWritePort(DM9_IMR,((1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0)));
	OALMSG("-DM9000AEnableInts\r\n");
}

//------------------------------------------------------------------------------
//
//  Function:  DM9000ADisableInts
//
VOID DM9000ADisableInts(void)
{
	OALMSG("+DM9000ADisableInts\r\n");
	DeviceWritePort(DM9_IMR,(1<<7));
	OALMSG("-DM9000ADisableInts\r\n");
}

//------------------------------------------------------------------------------
//
//  Function:  DM9000ACurrentPacketFilter
//
VOID DM9000ACurrentPacketFilter(UINT32 filter)
{
    OALMSG("+DM9000ACurrentPacketFilter(0x%X)\r\n", filter);
    g_filter = filter;

    OALMSG("-DM9000ACurrentPacketFilter\r\n");
}

//------------------------------------------------------------------------------
//
//  Function:  DM9000AMulticastList
//
BOOL DM9000AMulticastList(UINT8 *pAddresses, UINT32 count)
{
    OALMSG("+RTL8139MulticastList(0x%X, %d)\r\n", pAddresses, count);

    OALMSG("-DM9000AMulticastList(rc = 1)\r\n");
    return TRUE;
}

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

static UINT16 ReadPacketPage(UINT16 address)
{
    g_pDM9000->PAGEIX = address;
    return g_pDM9000->PAGE0;
}

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

static VOID WritePacketPage(UINT16 address, UINT16 data)
{
    g_pDM9000->PAGEIX = address;
    g_pDM9000->PAGE0  = data;
}

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

static UINT32 ComputeCRC(UINT8 *pBuffer, UINT32 length)
{
    UINT32 crc, carry, i, j;
    UINT8 byte;

    crc = 0xffffffff;
    for (i = 0; i < length; i++)
    {
        byte = pBuffer[i];
        for (j = 0; j < 8; j++) 
        {
            carry = ((crc & 0x80000000) ? 1 : 0) ^ (byte & 0x01);
            crc <<= 1;
            byte >>= 1;
            if (carry) crc = (crc ^ 0x04c11db6) | carry;
        }
    }
    return crc;
}

void DM9000AStoreMACAddress(WORD macAddressP[3])
{
	//WritePacketPage(INDIVIDUAL_ADDRESS + 0, macAddressP[0]);
	//WritePacketPage(INDIVIDUAL_ADDRESS + 2, macAddressP[1]);
	//WritePacketPage(INDIVIDUAL_ADDRESS + 4, macAddressP[2]);	
	DeviceWriteEeprom(0, macAddressP[0]);
	DeviceWriteEeprom(2, macAddressP[1]);
	DeviceWriteEeprom(4, macAddressP[2]);	
}

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

⌨️ 快捷键说明

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