📄 cs8900.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 + -