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

📄 dm9000end.c

📁 操作系统中的一找你个的相关的淡淡的码源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -