📄 dm9000end.c
字号:
UCHAR tmp;
/*set the internal Phy power-on*/
DM9000_OUT_REG(0x1f,0x00); /*GPR*/
uDelay(20);
/*soft reset */
DM9000_OUT_REG( 0x00, 0x03 );
uDelay(20);
DM9000_OUT_REG( 0x00, 0x03 );
uDelay(20);
/* set the internal PHY power-on, GPIOs normal, and wait 20us */
DM9000_OUT_REG(0x1f,0x01); /*GPR*/
DM9000_OUT_REG(0x1f,0x00); /*GPR*/
uDelay(1000);
uDelay(1000);
uDelay(1000);
uDelay(1000);
/* I/O mode */
DM9000_IN_REG( 0xfe, tmp );
dev->io_mode = (tmp & 0xff) >> 6; /* ISR bit7:6 keeps I/O mode 16bit */
/*Set PHY Mode*/
set_PHY_mode(dev);
}
static void dmfe_config_dm9000( END_DEVICE *dev, int stat)
{
DM9000_OUT_REG( 0x00, 0x08 );
DM9000_OUT_REG( 0x02, 0x00 ); /* TX Polling clear */
DM9000_OUT_REG( 0x2f, 0x00 ); /* Special Mode */
DM9000_OUT_REG( 0x01, 0x2c); /*NSR*/
DM9000_OUT_REG( 0xfe, 0x0f);
DM9000_OUT_REG( 0x08, 0x37 ); /* Less 3Kb, 200us */
DM9000_OUT_REG( 0x09, 0x38 ); /* Flow Control : High/Low Water */
DM9000_OUT_REG( 0x0a, 0x29 ); /* Flow Control wwq?*/
/*Set Physical address and multicast address*/
dmfGetPhyAndMulAdrs( dev );
/*Enable the SRAM read/write pointer*/
DM9000_OUT_REG( 0xff, DM9000_REGFF_OFF );
if( stat == 2 )
{
/* Activate DM9000 */
DM9000_OUT_REG( 0x05, DM9000_REG05 ); /* RX enable */
DM9000_OUT_REG( 0xff, DM9000_REGFF ); /* Enable TX/RX interrupt mask */
}
if( stat == 1 )
{
/* dis-Activate DM9000 */
DM9000_OUT_REG( 0x05, DM9000_REG05_OFF ); /* RX disable */
DM9000_OUT_REG( 0xff, DM9000_REGFF_OFF ); /* Disable TX/RX interrupt mask */
}
/* Init Driver variable */
dev->tx_pkt_cnt = 0;
}
/* Hardware start transmission.
Send a packet to media from the upper layer.
*/
static int dmfe_Copy_TxFrame(END_DEVICE *dev, char *pBuffer, int TxLen )
{
int i, lastone;
int tmplen;
USHORT * pTxBuff;
/*define for debug,wwq*/
char * pBufferTx;
pBufferTx = pBuffer;
if( (TxLen == 0) || (pBuffer == NULL) )
{
logMsg("dm9000Send: TxLen == 0 or pBuffer == NULL\n", 0, 0, 0, 0, 0, 0);
return ERROR;
}
/* Move data to DM9000 TX RAM */
DM9000_OUT_ADDR( 0xf8 );
if( dev->io_mode == 2 )
{ /* Byte mode */
for( i = 0; i < TxLen; i++ )
DM9000_OUT_BYTE( (*pBuffer++) );
}
else if(dev->io_mode == 0)
{ /* Word mode */
tmplen = (TxLen+ 1) / 2;
pTxBuff = (USHORT*)pBuffer;
for( i = 0; i < tmplen; i++ )
{
DM9000_OUT_WORD( *pTxBuff++ );
}
}else
{ /*Dwors mode*/
printf("dword error!\n");
return ERROR;
}
if(dev->tx_pkt_cnt == 0){
dev->tx_pkt_cnt ++;
/* Set TX length to DM9000 */
DM9000_OUT_REG( 0xfd, (TxLen >> 8) & 0xff );
DM9000_OUT_REG( 0xfc, TxLen & 0xff );
/* Issue TX polling command */
DM9000_OUT_REG( 0x2, 0x01 ); /* Cleared after TX complete */
}else{
dev->queue_pkt_len = TxLen;
dev->tx_pkt_cnt ++;
}
return OK;
}
/*************************************************
*
*/
static UCHAR dmfe_Get_NextPacket(void)
{
UCHAR Rxbyte;
/* Check packet ready or not */
DM9000_IN_REG( 0xf0, Rxbyte ); /* Dummy read */
DM9000_IN_REG( 0xf0, Rxbyte ); /* Got most updated data */
Rxbyte &= 0xff;
return (Rxbyte);
}
/**************************************************
* Received a packet and pass to upper layer
*
* return ERROR or received packet length
*/
static int dmfe_Copy_RxFrame(END_DEVICE *dev, char *pBuffer, UCHAR rxbyte)
{
UCHAR tmp1,tmp2;
UCHAR RecvDataU8;
USHORT RecvDataU16;
USHORT* pRxBuff;
USHORT i, GoodPacket, tmplen;
USHORT RxStatus = 0, RxLen = 0;
UCHAR* pBufferRx;
pBufferRx = pBuffer;
#ifdef DM_DEBUG_PRINT
logMsg ("dmfe_Copy_RxFrame: packet_rec( rxbyte=%d).\n", rxbyte, 0, 0, 0, 0, 0);
#endif
/* packet ready to receive check */
if( rxbyte == DM9000_PKT_RDY )
{
/* A packet ready now & Get status/length */
GoodPacket = TRUE;
switch(dev->io_mode)
{
case 2:
/* Byte mode */
DM9000_IN_REG( 0xf2, tmp1 );
DM9000_IN_REG( 0xf2, tmp2 );
RxStatus = tmp1 + (tmp2 << 8);
DM9000_IN_REG( 0xf2, tmp1 );
DM9000_IN_REG( 0xf2, tmp2 );
RxLen = tmp1 + (tmp2<<8);
break;
case 0:
/* Word mode */
DM9000_OUT_ADDR( 0xf2 );
DM9000_IN_WORD( RxStatus );
DM9000_IN_WORD( RxLen );
break;
default:
break;
}
/*dm9000 receive packet length error*/
if( RxLen < 0x40){
logMsg("dm9000Recv: packet too small !\n", 0, 0, 0, 0, 0, 0);
GoodPacket = FALSE;
}
/*dm9000 receive packet is bad packet*/
if( RxStatus & 0xbf00)
{
GoodPacket = FALSE;
if( RxStatus & 0x100 )
logMsg("dm9000Recv: FIFO Overflow Error!\n ", 0, 0, 0, 0, 0, 0);
if( RxStatus & 0x200 )
logMsg("dm9000Recv: CRC Error!\n", 0, 0, 0, 0, 0, 0);
if( RxStatus & 0x8000 )
logMsg("dm9000Recv: received frame is smaller than 64B!\n ", 0, 0, 0, 0, 0, 0);
}
/* Move data from DM9000 */
if( GoodPacket ){
/* Read received packet from RX SARM */
if (dev->io_mode == 2){
/* Byte mode */
for( i=0; i<RxLen; i++ )
DM9000_IN_BYTE(*pBuffer++ );
}else if(dev->io_mode == 0){
/* Word mode */
tmplen = (RxLen + 1) / 2;
pRxBuff = (USHORT*)pBuffer;
for( i = 0; i < tmplen; i++)
DM9000_IN_WORD(*pRxBuff++);
}else{
/*Dword mode*/
return (ERROR);
}
#ifdef DM_DEBUG_PRINT
logMsg("RxLen = 0x%x\n",RxLen, 0, 0, 0, 0, 0 );
#endif
return (RxLen);
}else{
if( dev->io_mode == 2 ){
/* Byte mode */
for( i = 0; i < RxLen; i++ )
DM9000_IN_BYTE( RecvDataU8 );
}else{
/* Word mode */
tmplen = (RxLen + 1) / 2;
for( i = 0; i < tmplen; i++ )
DM9000_IN_WORD( RecvDataU16 );
}
return ERROR;
}
}
/* Status check: this byte must be 0 or 1 */
if( rxbyte > DM9000_PKT_RDY )
{
DM9000_OUT_REG( 0xff, DM9000_REGFF_OFF); /* Stop INT request */
DM9000_OUT_REG(0xfe, 0x0f); /*clear ISR status*/
DM9000_OUT_REG( 0x05, DM9000_REG05_OFF); /* Stop Rx function */
logMsg ("dm9000Recv;The rxbyte=%d, Rx need reset.\n", rxbyte, 0, 0, 0, 0, 0);
dm9000Reset( dev );
dm9000Config( dev );
}
}
/**************************************************
*Stop the interface.
*The interface is stopped when it is brought.
*/
static int dmfe_Stop_Chip( END_DEVICE *dev)
{
#ifdef DM_DEBUG_PRINT
logMsg("dmfe_Stop_Chip()\n", 0, 0, 0, 0, 0, 0);
#endif
/* RESET devie */
phy_write( dev, 0x00, 0x8000 ); /* PHY RESET */
DM9000_OUT_REG( 0x1f, DM9000_PHY_OFF ); /* Power-Down PHY */
DM9000_OUT_REG( 0xff, DM9000_REGFF_OFF ); /* Disable all interrupt */
DM9000_OUT_REG( 0x05, DM9000_REG05_OFF ); /* Disable RX */
return 0;
}
/************************************************
*Set PHY operationg mode
*/
static void set_PHY_mode( END_DEVICE *dev )
{
USHORT phy_reg4 = 0x01e1, phy_reg0=0x1000;
DM9000_OUT_REG( 0x1e, 0x01 );
DM9000_OUT_REG( 0x1f, DM9000_PHY_OFF ); /* disable PHY */
#ifdef DM_DEBUG_PRINT
logMsg ("set_PHY_mode()\n", 0, 0, 0, 0, 0, 0);
#endif
if ( !(dev->op_mode & DM9000_AUTO) )
{
switch(dev->op_mode)
{
case DM9008A:
case DM9000_10MHD:
phy_reg4 = 0x21;
phy_reg0 = 0x0000;
break;
case DM9000_10MFD:
phy_reg4 = 0x41;
phy_reg0 = 0x0100;
#ifdef DM_DEBUG_PRINT
logMsg ("set_PHY_mode: set DM9000_10MFD.\n", 0, 0, 0, 0, 0, 0);
#endif
break;
case DM9000_100MHD:
phy_reg4 = 0x81;
phy_reg0 = 0x2000;
break;
case DM9000_100MFD:
phy_reg4 = 0x101;
phy_reg0 = 0x3100;
break;
case DM900xA_PCEL:
phy_reg4 = 0x101;
phy_reg0 = 0x2100;
break;
default:
break;
}
}
/*phy_write(dev, 0, 0x8000);*/ /* Tmp */
if(dev->op_mode == DM900xA_PCEL) phy_write(dev, 16, 0x4014);
if(dev->op_mode == DM9008A) phy_write(dev, 20, 0x0010);
phy_write(dev, 0, 0x8000);
phy_write(dev, 0, phy_reg0); /* Tmp */
phy_write(dev, 4, 0x400|phy_reg4); /* Set PHY media mode */
DM9000_OUT_REG( 0x1f, DM9000_PHY_ON ); /* Enable PHY */
}
/*******************************************************
*Set DM9000 multicast address
* Set DM9000 Physical Address
*/
static void dmfGetPhyAndMulAdrs(END_DEVICE *dev)
{
/* Set Node address */
DM9000_OUT_REG( 0x10, dev->enetAddr[0]);
uDelay( 20 );
DM9000_OUT_REG( 0x11, dev->enetAddr[1]);
uDelay( 20 );
DM9000_OUT_REG( 0x12, dev->enetAddr[2]);
uDelay( 20 );
DM9000_OUT_REG( 0x13, dev->enetAddr[3]);
uDelay( 20 );
DM9000_OUT_REG( 0x14, dev->enetAddr[4]);
uDelay( 20 );
DM9000_OUT_REG( 0x15, dev->enetAddr[5]);
uDelay( 20 );
}
/***************************************************
* Read a word from phyxcer
*/
static USHORT phy_read( END_DEVICE *dev, int reg )
{
UCHAR tmp1, tmp2;
/* Fill the phyxcer register into REG_0C */
DM9000_OUT_REG( 0x0c, DM9000_PHY | reg );
DM9000_OUT_REG( 0x0b, 0x0c ); /* Issue phyxcer read command */
do
{
uDelay(100); /* Wait read complete */
DM9000_IN_REG( 0x0b, tmp1 );
}while( tmp1 & 0x01 );
DM9000_OUT_REG( 0x0b, 0x0 ); /* Clear phyxcer read command */
/* The read data keeps on REG_0D & REG_0E */
DM9000_IN_REG( 0x0e , tmp1 );
DM9000_IN_REG( 0x0d , tmp2 );
return ( (tmp1 << 8 ) | tmp2 );
}
/********************************************************
* Write a word to phyxcer
*/
static void phy_write( END_DEVICE *dev, int reg, USHORT value)
{
UCHAR tmp1;
/* Fill the phyxcer register into REG_0C */
DM9000_OUT_REG( 0x0c, DM9000_PHY | reg );
/* Fill the written data into REG_0D & REG_0E */
DM9000_OUT_REG( 0x0d, (value & 0xff) );
DM9000_OUT_REG( 0x0e, ( (value >> 8) & 0xff) );
DM9000_OUT_REG( 0x0b, 0x0a ); /* Issue phyxcer write command */
do
{
uDelay(100); /* Wait read complete */
DM9000_IN_REG( 0x0b, tmp1 );
}while( tmp1 & 0x01 );
DM9000_OUT_REG( 0x0b, 0x00 ); /* Clear phyxcer write command */
}
/******************************************************
*Delay N us
*/
static void uDelay( int us )
{
taskDelay(us/10);
}
LOCAL void s3cExtIntPinEnable (void)
{
rpGPFCON = (rpGPFCON & ~(3)) | 2;
rpGPFUP |= 1;
rpINTMSK = rpINTMSK & (~1);
}
/***********************************************************
*
*/
static void dm9000Chack(void)
{
if(1)
{
UCHAR data;
UINT vpid;
DM9000_IN_REG( 0x28, data);
vpid=data;
DM9000_IN_REG( 0x29, data);
vpid |= (data<<8);
DM9000_IN_REG( 0x2a, data);
vpid |= (data<<16);
DM9000_IN_REG( 0x2b, data);
vpid |= (data<<24);
#ifdef DM_DEBUG_PRINT
logMsg("dm9000Chack: DM9000PID: 0x%8x\n",vpid,2,3,4,5,6);
#endif
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -