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

📄 cs8900.c

📁 LPC2292 bios测试程序 说明:YL_LPC229X_BIOS_Data的目录说明
💻 C
字号:
#include "def.h"
#include "config.h"
#include "utils.h"
#include "board.h"

#include "eth.h"
#include "CS8900.h"

#ifdef	TFTP_DOWNLOAD_SUPPORT

//assign nGCS_CS8900 = ! ( (!nGCS3) && (!ADDR[21]) && (!ADDR[22]) && ( ADDR[23]) ) ; 
#define IO_BASE_ADDR   ( 0x83000600 )

static U8 EmacAddr[ETH_ALEN] =
{
	0x00, 0x80, 0x48, 0x12, 0x34, 0x56
};

U16 IOREAD( U32 o ) ;
void IOWRITE( U32 o , U16 d ) ;

#define PUBLIC
#define PRIVATE						static

/*
#define IOREAD(o)					((USHORT)*((volatile USHORT *)(dwEthernetIOBase + (o))))
#define IOWRITE(o, d)				*((volatile USHORT *)(dwEthernetIOBase + (o))) = (USHORT)(d)

#define MEMREAD(o)					((USHORT)*((volatile USHORT *)(dwEthernetMemBase + (o))))
#define MEMWRITE(o, d)				*((volatile USHORT *)(dwEthernetMemBase + (o))) = (USHORT)(d)
*/

//#define	DEBUG

#ifdef	DEBUG
#define	DBGMSG						printf
#else
#define DBGMSG(...)
#endif
#define MAX_COUNT					0x100000

#define CS8900DBG_PROBE				(1 << 0)

PRIVATE DWORD dwEthernetIOBase ;
PRIVATE DWORD dwEthernetMemBase ;

//#define CS8900_MEM_MODE

#ifdef	CS8900_MEM_MODE

#define READ_REG1					ReadReg
#define READ_REG2					MEMREAD

#define WRITE_REG1					WriteReg
#define WRITE_REG2					MEMWRITE

#else

#define READ_REG1					ReadReg
#define READ_REG2					ReadReg

#define WRITE_REG1					WriteReg
#define WRITE_REG2					WriteReg

#endif

PRIVATE	BOOL bIsPacket ;

void IOWRITE( U32 o , U16 d )
{
	//	U16 k = 1 ;
	//IO2CLR = IO2CLR | ( 1 << 27 ) ;		//P227 = 0
	IO0CLR = IO0CLR | ( 1 << 17 ) ;		//P017 = 0
	//	while( k-- ) ;
	*( ( volatile U16 * ) ( dwEthernetIOBase + o ) ) = d ;
	//	k = 2 ;	while( k-- ) ;
	//IO2SET = IO2SET | ( 1 << 27 ) ;		//P227 = 1 
	IO0SET = IO0SET | ( 1 << 17 ) ;		//P017 = 1 
}

U16 IOREAD( U32 o )
{
	U16 m ;
	//	U16 k = 1 ;

	//IO2CLR = IO2CLR | ( 1 << 27 ) ;		//P227 = 0
	IO0CLR = IO0CLR | ( 1 << 17 ) ;		//P017 = 0
	//	while( k-- ) ;
	m = *( ( volatile U16 * ) ( dwEthernetIOBase + o ) ) ;
	//	k = 2 ;	while( k-- ) ;
	//IO2SET = IO2SET | ( 1 << 27 ) ;		//P227 = 1 
	IO0SET = IO0SET | ( 1 << 17 ) ;		//P017 = 1 
	return m ;
}

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

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

PRIVATE BOOL Probe( DWORD iobase , DWORD membase )
{
	BOOL r = FALSE;
	USHORT sig;

	DBGMSG( "::: CS8900 Probe()\n" );

	dwEthernetIOBase = iobase;
	dwEthernetMemBase = membase;

	do
	{
		sig = IOREAD( IO_PACKET_PAGE_POINTER );
		//		sig = IOREAD(IO_PACKET_PAGE_POINTER);
		DBGMSG( "sig=%x\n" , sig );
		if ( ( sig & CS8900_SIGMSK ) != CS8900_SIGNATURE )
		{
			DBGMSG( "Signature Error\n" );
			DBGMSG( "%x\n" , sig );
			//	DBGMSG("%x\n", IOREAD(IO_PACKET_PAGE_POINTER));
			break;
		}

		/* Check the EISA registration number.	*/
		sig = READ_REG1( PKTPG_EISA_NUMBER );
		DBGMSG( "eisa=%x\n" , sig );
		if ( sig != CS8900_EISA_NUMBER )
		{
			DBGMSG( "Eisa Number Error\n" );
			DBGMSG( "%x\n" , sig );
			break;
		}

		/* Check the Product ID.				*/
		sig = READ_REG1( PKTPG_PRDCT_ID_CODE );
		DBGMSG( "PID=%x\n" , sig );
		if ( ( sig & CS8900_PRDCT_ID_MASK ) != CS8900_PRDCT_ID )
		{
			DBGMSG( "Product ID Error\n" );
			break;
		}

		printf( "CS8900 is Detected!\n" ) ;
		r = TRUE;
	}
	while ( 0 );

	return r;
}

PRIVATE BOOL CS8900_Reset( void )
{
	BOOL r = FALSE;
	USHORT dummy;
	int i;
	/* Set RESET bit of SelfCTL register.	*/
	do
	{
		WRITE_REG1( PKTPG_SELF_CTL , SELF_CTL_RESET | SELF_CTL_LOW_BITS );

		/* Wait until INITD bit of SelfST register is set.	*/
		for ( i = 0; i < MAX_COUNT; i++ )
		{
			dummy = READ_REG1( PKTPG_SELF_ST );
			if ( dummy & SELF_ST_INITD )
				break;
		}

		if ( i >= MAX_COUNT )
		{
			DBGMSG( "Reset failed (SelfST) \n" );
			break;
		}

		/* Wait until SIBUSY bit of SelfST register is cleared.		*/
		for ( i = 0; i < MAX_COUNT; i++ )
		{
			dummy = READ_REG1( PKTPG_SELF_ST );
			if ( ( dummy & SELF_ST_SIBUSY ) == 0 )
				break;
		}

		if ( i >= MAX_COUNT )
		{
			DBGMSG( "Reset failed (SIBUSY) \n" );
			break;
		}
		r = TRUE;
		printf( "CS8900 Reset Success!\n" );
	}
	while ( 0 );

	return r;
}


PRIVATE void EnableIRQ( void )
{
	USHORT temp;
	/* If INTERRUPT_NUMBER is 0,							*/
	/*	Interrupt request will be generated from INTRQ0 pin */
	WRITE_REG2( PKTPG_INTERRUPT_NUMBER , INTERRUPT_NUMBER );

	temp = READ_REG2( PKTPG_BUS_CTL ) | BUS_CTL_ENABLE_IRQ;

	WRITE_REG2( PKTPG_BUS_CTL , temp );

	temp = READ_REG2( PKTPG_LINE_CTL ) | LINE_CTL_RX_ON | LINE_CTL_TX_ON;
	WRITE_REG2( PKTPG_LINE_CTL , temp );
}


PRIVATE BOOL Init( USHORT* mac )
{
	USHORT temp;

#ifdef CS8900_MEM_MODE

	WRITE_REG1( PKTPG_MEMORY_BASE_ADDR ,
		( USHORT ) ( dwEthernetMemBase & 0xffff ) );
	WRITE_REG1( PKTPG_MEMORY_BASE_ADDR + 2 ,
		( USHORT ) ( dwEthernetMemBase >> 16 ) );
	WRITE_REG1( PKTPG_BUS_CTL , BUS_CTL_MEMORY_E | BUS_CTL_LOW_BITS );

#endif

	temp = READ_REG2( PKTPG_LINE_CTL ) |
		LINE_CTL_10_BASE_T |
		LINE_CTL_MOD_BACKOFF;
	WRITE_REG2( PKTPG_LINE_CTL , temp );

	WRITE_REG2( PKTPG_RX_CFG , RX_CFG_RX_OK_I_E | RX_CFG_LOW_BITS );

	WRITE_REG2( PKTPG_RX_CTL ,
		RX_CTL_RX_OK_A |
		RX_CTL_IND_ADDR_A |
		RX_CTL_BROADCAST_A |
		RX_CTL_LOW_BITS );

	WRITE_REG2( PKTPG_INDIVISUAL_ADDR + 0 , *mac++ );
	WRITE_REG2( PKTPG_INDIVISUAL_ADDR + 2 , *mac++ );
	WRITE_REG2( PKTPG_INDIVISUAL_ADDR + 4 , *mac );

	WRITE_REG2( PKTPG_TX_CFG , TX_CFG_LOW_BITS );

	EnableIRQ();

	printf( "CS8900 Init OK!\n" );
	return TRUE;
}

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

	/* Discard RxStatus		*/
	data = IOREAD( IO_RX_TX_DATA_0 );
	/* Read the frame's length.		*/
	length = IOREAD( IO_RX_TX_DATA_0 );

	if ( length > dwLength )
		length = 0;

	bp = ( USHORT * ) pbData;

	rlen = length;

	while ( rlen )
	{
		data = IOREAD( IO_RX_TX_DATA_0 );

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

	return length;
}


PRIVATE USHORT TransmitPkt( BYTE* pbData , USHORT slen )
{
	USHORT* bp;
	USHORT data;
	DWORD i;

	/* Send Command */
	IOWRITE( IO_TX_CMD , TX_CMD_START_ALL | TX_CMD_LOW_BITS );
	IOWRITE( IO_TX_LENGTH , slen );

	/* Wait			*/
	for ( i = 0; i < MAX_COUNT; i++ )
	{
		data = READ_REG2( PKTPG_BUS_ST );
		if ( data & BUS_ST_RDY_4_TX_NOW )
			break;
	} 

	if ( i >= MAX_COUNT )
		return 1;

	bp = ( USHORT * ) pbData;

	while ( slen )
	{
		IOWRITE( IO_RX_TX_DATA_0 , *bp++ );
		slen--;

		if ( slen )
			slen--;
	}

	return 0;
}


U16 EVENT ;
PUBLIC BOOL CS8900DBG_IsReceivedPacket( void )
{
	USHORT event;
	BOOL r = FALSE;

	event = IOREAD( IO_ISQ );

	if ( event != EVENT )
	{
		//		DBGMSG("\t%04x", event);
		EVENT = event ;
	}

	if ( ( ( event & ISQ_REG_NUM ) == REG_NUM_RX_EVENT ) &&
		( ( event & RX_EVENT_RX_OK ) == RX_EVENT_RX_OK ) &&
		( ( event & RX_EVENT_IND_ADDR ) | ( event & RX_CTL_BROADCAST_A ) ) )
	{
		r = bIsPacket = TRUE;
		//		DBGMSG("%x\n", event);
	}
	else
		bIsPacket = FALSE;

	return r;
}

int board_eth_init( void )
{
	int r;

	bIsPacket = FALSE;

	DBGMSG( "::: CS8900DBG_Init\r\n" );

	DBGMSG( "CS8900 Mac Address: %x:%x:%x:%x:%x:%x\r\n" , EmacAddr[0] ,
		EmacAddr[1] , EmacAddr[2] , EmacAddr[3] , EmacAddr[4] , EmacAddr[5] );
	r = -1;
	do
	{
		if ( !Probe( IO_BASE_ADDR , 0 ) )
			break;
		if ( !CS8900_Reset() )
			break;
		if ( !Init( ( USHORT * ) EmacAddr ) )
			break;
		r = 0;
	}
	while ( 0 );
	return r;
}

int board_eth_lnk_stat( void )
{
	return 0;
}

int board_eth_send( unsigned char* data , unsigned int len )
{
	return TransmitPkt( ( BYTE * ) data , len );
}

int board_eth_rcv( unsigned char* data , unsigned int* len )
{
	int r = -1;

	if ( CS8900DBG_IsReceivedPacket() )
	{
		U16 size;

		bIsPacket = FALSE;
		//		DBGMSG("%x,", IOREAD(IO_RX_TX_DATA_0));
		//		DBGMSG("%x,", IOREAD(IO_RX_TX_DATA_0));
		size = RcvPkt( ( BYTE * ) data , 1532 );
		*len = size;
		//		DBGMSG("received date %d\n", size);
		//		RcvPkt((BYTE *)data, size);
		r = 0;
	}	

	return r;
}

int board_eth_get_addr( unsigned char* addr )
{
	memcpy( addr , EmacAddr , ETH_ALEN );
	return 0;
}

#endif

⌨️ 快捷键说明

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