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

📄 emac.c

📁 NXP产品LPC23XX的开发板的源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *   emac.c:  Ethernet module file for NXP LPC230x Family Microprocessors
 *
 *   Copyright(C) 2006, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2006.09.01  ver 1.00    Prelimnary version, first Release
 *
******************************************************************************/
// #include <string.h>
#include "LPC23xx.H"                        /* LPC21xx definitions */
#include "type.h"
#include "irq.h"
#include "emac.h"

volatile DWORD Duplex;
volatile DWORD Speed;

volatile DWORD RXOverrunCount = 0;
volatile DWORD RXErrorCount = 0;

volatile DWORD TXUnderrunCount = 0;
volatile DWORD TXErrorCount = 0;
volatile DWORD RxFinishedCount = 0;
volatile DWORD TxFinishedCount = 0;
volatile DWORD TxDoneCount = 0;
volatile DWORD RxDoneCount = 0;

volatile DWORD CurrentRxPtr = EMAC_RX_BUFFER_ADDR;
volatile DWORD ReceiveLength = 0;
volatile DWORD PacketReceived = FALSE;

#if ENABLE_WOL
volatile DWORD WOLCount = 0;
volatile DWORD WOLArrived = FALSE;
#endif

/******************************************************************************
** Function name:		EMAC_TxEnable/EMAC_TxDisable
**
** Descriptions:		EMAC TX API modules
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void EMAC_TxEnable( void )
{
    MAC_COMMAND |= 0x02;
    return;
}

void EMAC_TxDisable( void )
{
    MAC_COMMAND &= ~0x02;
    return;
}

/******************************************************************************
** Function name:		EMAC_RxEnable/EMAC_RxDisable
**
** Descriptions:		EMAC RX API modules
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void EMAC_RxEnable( void )
{
    MAC_COMMAND |= 0x01;
    MAC_MAC1 |= 0x01;
    return;    
}

void EMAC_RxDisable( void )
{
    MAC_COMMAND &= ~0x01;
    MAC_MAC1 &= ~0x01;
    return;
}

/******************************************************************************
** Function name:		EMACHandler
**
** Descriptions:		EMAC interrupt handler
**
** parameters:			None
** Returned value:		None
** 
******************************************************************************/
void EMACHandler (void) __irq 
{
    volatile DWORD IntStatus;
    DWORD *rxptr;

    IENABLE;				/* handles nested interrupt */

    IntStatus = MAC_INTSTATUS;    
    if ( IntStatus != 0 )	/* At least one interrupt */
    {
#if ENABLE_WOL
		if ( IntStatus & EMAC_INT_WOL )
		{
	    	MAC_INTCLEAR = EMAC_INT_WOL;
	    	WOLCount++;
	    	WOLArrived = TRUE;
	    	/* the packet will be lost, no need to anything else, bail out */
			IDISABLE;
	    	VICVectAddr = 0;		/* Acknowledge Interrupt */
	    	return;
		}
#endif
		if ( IntStatus & EMAC_INT_RXOVERRUN )
		{
	    	MAC_INTCLEAR = EMAC_INT_RXOVERRUN;
			RXOverrunCount++;
			IDISABLE;
			VICVectAddr = 0;		/* Acknowledge Interrupt */
			return;
		}

		if ( IntStatus & EMAC_INT_RXERROR )
		{
			MAC_INTCLEAR = EMAC_INT_RXERROR;
			RXErrorCount++;
			IDISABLE;
			VICVectAddr = 0;		/* Acknowledge Interrupt */
			return;
		}
	
		if ( IntStatus & EMAC_INT_RXFINISHED )
		{
	    	MAC_INTCLEAR = EMAC_INT_RXFINISHED;
	    	RxFinishedCount++;
	    	/* Below should never happen or RX is seriously wrong */
	    	while ( MAC_RXPRODUCEINDEX != (MAC_RXCONSUMEINDEX - 1) );
		}

		if ( IntStatus & EMAC_INT_RXDONE )
		{
	    	MAC_INTCLEAR = EMAC_INT_RXDONE;
	    	ReceiveLength = EMACReceive( rxptr );
	    	PacketReceived = TRUE;
	    	RxDoneCount++;
		}

		if ( IntStatus & EMAC_INT_TXUNDERRUN )
		{
			MAC_INTCLEAR = EMAC_INT_TXUNDERRUN;
			TXUnderrunCount++;
			IDISABLE;
			VICVectAddr = 0;		/* Acknowledge Interrupt */
			return;
		}
	
		if ( IntStatus & EMAC_INT_TXERROR )
		{
			MAC_INTCLEAR = EMAC_INT_TXERROR;
			TXErrorCount++;
			IDISABLE;
			VICVectAddr = 0;		/* Acknowledge Interrupt */
			return;
		}

		if ( IntStatus & EMAC_INT_TXFINISHED )
		{
	    	MAC_INTCLEAR = EMAC_INT_TXFINISHED;
	    	TxFinishedCount++;
		}

		if ( IntStatus & EMAC_INT_TXDONE )
		{
	    	MAC_INTCLEAR = EMAC_INT_TXDONE;
	    	TxDoneCount++;
		}
    }   
    IDISABLE;
    VICVectAddr = 0;		/* Acknowledge Interrupt */
	return;
}

/*****************************************************************************
** Function name:		WritePHY
**
** Descriptions:		Write Data to the PHY port
**
** parameters:			PHY register, write data
** Returned value:		None
** 
*****************************************************************************/
void WritePHY( DWORD PHYReg, DWORD PHYData )
{
    MAC_MCMD = 0x0000;			/* write command */
    MAC_MADR = PHY_ADDR | PHYReg;	/* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */
    MAC_MWTD = PHYData;
    while ( MAC_MIND != 0 );
    return;
}

/*****************************************************************************
** Function name:		ReadPHY
**
** Descriptions:		Read data from the PHY port
**
** parameters:			PHY register
** Returned value:		PHY data
** 
*****************************************************************************/
DWORD ReadPHY( DWORD PHYReg )
{
    MAC_MCMD = 0x0001;			/* read command */
    MAC_MADR = PHY_ADDR | PHYReg;	/* [12:8] == PHY addr, [4:0]=0x00(BMCR) register addr */ 
    while ( MAC_MIND != 0 );
    MAC_MCMD = 0x0000;
    return( MAC_MRDD );
}

/*****************************************************************************
** Function name:		PHYInit
**
** Descriptions:		initialize PHY port
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
DWORD PHYInit( void )
{
    DWORD i, regValue;
    DWORD timeout;

    /* MII configuration, I may just need to do either RMII or MII configuration, not both. */
    MAC_MCFG = 0x0018;	/* host clock divided by 20, no suppress preamble, no scan increment */
    
#if RMII 
    /* RMII configuration */
    MAC_COMMAND |= 0x0200; 
    MAC_SUPP = 0x0900;	/* RMII setting, PHY support: [8]=0 ->10 Mbps mode, =1 -> 100 Mbps mode */
    /*  (note bit 4 was set in original test, although spec says its unused) */
    for ( i = 0; i < 0x20; i++ );	/* short delay */
    MAC_SUPP = 0x0100;
#else
    MAC_COMMAND &= ~0x0200;
    MAC_SUPP = 0x0000;
#endif

    WritePHY( PHY_BMCR, BMCR_RESET );
    for ( i = 0; i < 0x20; i++ );	/* short delay */

    timeout = MII_BMSR_TIMEOUT * 4;
    while ( timeout != 0 )
    {
		regValue = ReadPHY( PHY_BMCR );
		if ( (regValue & BMCR_RESET) == 0x0000 )	
		{
	    	break;		/* Reset self cleaned once the reset process is complete */	
		}
		timeout--;	
    }
    if ( timeout == 0 )
    {
		return ( FALSE );
    }

	/* check PHY IDs to make sure the reset takes place and PHY
	is in its default state. See National PHY DP83848 Users Manual 
	for more details */
    regValue = ReadPHY( PHY_PHYIDR1 );
    if ( (regValue & 0x2000) != 0x2000 )
    {
		return ( FALSE );
    }

    regValue = ReadPHY( PHY_PHYIDR2 );
    if ( (regValue & 0x5C90) != 0x5C90 )
    {
		return ( FALSE );
    }

    WritePHY( PHY_BMCR, BMCR_AN | BMCR_RE_AN ); /* auto negotiation, restart AN */
    timeout = MII_BMSR_TIMEOUT;
    while ( timeout != 0 )
    {
		regValue = ReadPHY( PHY_PHYSTS );
		if ( (regValue & 0x0011) == 0x0011 )	
		{
	    	break;		/* link established if bit 0 is set */
		}
		timeout--;
    }

    if ( timeout == 0 )
    {
		return ( FALSE );
    }

    /* Link established from here on */
    if ( regValue & 0x04 )
		Duplex = FULL_DUPLEX;
    else
		Duplex = HALF_DUPLEX;

    if ( regValue & 0x02 )
		Speed = SPEED_10;
    else
		Speed = SPEED_100;

    return ( TRUE );
}

/*****************************************************************************
** Function name:		EMACTxDesciptorInit
**
** Descriptions:		initialize EMAC TX descriptor table
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
void EMACTxDescriptorInit( void )
{
    DWORD i;
    DWORD *tx_desc_addr, *tx_status_addr;
   
    /*-----------------------------------------------------------------------------      
     * setup the Tx status,descriptor registers -- 
     * Note, the actual tx packet data is loaded into the ahb2_sram16k memory as part
     * of the simulation
     *----------------------------------------------------------------------------*/ 
    MAC_TXDESCRIPTOR = TX_DESCRIPTOR_ADDR;	/* Base addr of tx descriptor array */
    MAC_TXSTATUS = TX_STATUS_ADDR;		/* Base addr of tx status */
    MAC_TXDESCRIPTORNUM = EMAC_TX_DESCRIPTOR_COUNT - 1;	/* number of tx descriptors, 16 */

    for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
    {
		tx_desc_addr = (DWORD *)(TX_DESCRIPTOR_ADDR + i * 8);	/* two words at a time, packet and control */
		*tx_desc_addr = (DWORD)(EMAC_TX_BUFFER_ADDR + i * EMAC_BLOCK_SIZE);
		*(tx_desc_addr+1) = (DWORD)(EMAC_TX_DESC_INT | (EMAC_BLOCK_SIZE - 1));	/* set size only */
    }
    
    for ( i = 0; i < EMAC_TX_DESCRIPTOR_COUNT; i++ )
    {
		tx_status_addr = (DWORD *)(TX_STATUS_ADDR + i * 4);	/* TX status, one word only, status info. */
		*tx_status_addr = (DWORD)0;		/* initially, set status info to 0 */
    }
    MAC_TXPRODUCEINDEX = 0x0;	/* TX descriptors point to zero */
    return;
}

/*****************************************************************************
** Function name:		EMACRxDesciptorInit
**
** Descriptions:		initialize EMAC RX descriptor table
**
** parameters:			None
** Returned value:		None
** 
*****************************************************************************/
void EMACRxDescriptorInit( void )
{
    DWORD i;
    DWORD *rx_desc_addr, *rx_status_addr;
   
    /*-----------------------------------------------------------------------------      
     * setup the Rx status,descriptor registers -- 
     * Note, the actual rx packet data is loaded into the ahb2_sram16k memory as part
     * of the simulation
     *----------------------------------------------------------------------------*/ 
    MAC_RXDESCRIPTOR = RX_DESCRIPTOR_ADDR;	/* Base addr of rx descriptor array */
    MAC_RXSTATUS = RX_STATUS_ADDR;			/* Base addr of rx status */
    MAC_RXDESCRIPTORNUM = EMAC_RX_DESCRIPTOR_COUNT - 1;	/* number of rx descriptors, 16 */

    for ( i = 0; i < EMAC_RX_DESCRIPTOR_COUNT; i++ )

⌨️ 快捷键说明

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