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

📄 lpc177x_8x_emac.c

📁 LPC1788的USBHOST的FATFS移植
💻 C
📖 第 1 页 / 共 3 页
字号:
/**********************************************************************
* $Id$		lpc177x_8x_emac.c			2011-06-02
*//**
* @file		lpc177x_8x_emac.c
* @brief	Contains all functions support for Ethernet MAC firmware
*			library on LPC177x_8x
* @version	1.0
* @date		02. June. 2011
* @author	NXP MCU SW Application Team
* 
* Copyright(C) 2011, NXP Semiconductor
* All rights reserved.
*
***********************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
**********************************************************************/

#include "lpc177x_8x_emac.h"
#include "lpc177x_8x_clkpwr.h"
#include "lpc177x_8x_pinsel.h"


/************************** PRIVATE VARIABLES *************************/
/* MII Mgmt Configuration register - Clock divider setting */
const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28 };

/* EMAC local DMA Descriptors */


/* EMAC call-back function pointer data */
static EMAC_IntCBSType *_pfnIntCbDat[10];

/***************************** PRIVATE FUNCTION *****************************/
/*--------------------------- rx_descr_init ---------------------------------*/
/*********************************************************************//**
 * @brief
 * @param[in]
 * @return
 **********************************************************************/
void write_PHY (int PhyReg, int Value)
{
	unsigned int tout;

	LPC_EMAC->MADR = EMAC_PHY_DEFAULT_ADDR | PhyReg;
	LPC_EMAC->MWTD = Value;

	/* Wait utill operation completed */
	tout = 0;

	for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++)
	{
		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0)
		{
			break;
		}
	}
}

/*********************************************************************//**
 * @brief
 * @param[in]
 * @return
 **********************************************************************/
uint16_t read_PHY (uint8_t PhyReg)
{
	unsigned int tout;

	LPC_EMAC->MADR = EMAC_PHY_DEFAULT_ADDR | PhyReg;
	LPC_EMAC->MCMD = EMAC_MCMD_READ;

	/* Wait until operation completed */
	tout = 0;
	for (tout = 0; tout < EMAC_MII_RD_TOUT; tout++)
	{
		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0)
		{
			break;
		}
	}

	LPC_EMAC->MCMD = 0;
	return (LPC_EMAC->MRDD);
}


/*********************************************************************//**
 * @brief
 * @param[in]
 * @return
 **********************************************************************/
void rx_descr_init (void)
{
	unsigned int i;

	for (i = 0; i < EMAC_NUM_RX_FRAG; i++)
	{
		RX_DESC_PACKET(i)  = RX_BUF(i);
		RX_DESC_CTRL(i)    = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN-1);
		RX_STAT_INFO(i)    = 0;
		RX_STAT_HASHCRC(i) = 0;
	}

	/* Set EMAC Receive Descriptor Registers. */
	LPC_EMAC->RxDescriptor    = RX_DESC_BASE;
	LPC_EMAC->RxStatus        = RX_STAT_BASE;
	LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG-1;

	/* Rx Descriptors Point to 0 */
	LPC_EMAC->RxConsumeIndex  = 0;
}

/*********************************************************************//**
 * @brief
 * @param[in]
 * @return
 **********************************************************************/
void tx_descr_init (void)
{
	unsigned int i;

	for (i = 0; i < EMAC_NUM_TX_FRAG; i++)
	{
		TX_DESC_PACKET(i) = TX_BUF(i);
		TX_DESC_CTRL(i)   = 0;
		TX_STAT_INFO(i)   = 0;
	}

	/* Set EMAC Transmit Descriptor Registers. */
	LPC_EMAC->TxDescriptor    = TX_DESC_BASE;
	LPC_EMAC->TxStatus        = TX_STAT_BASE;
	LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG-1;

	/* Tx Descriptors Point to 0 */
	LPC_EMAC->TxProduceIndex  = 0;
}

/*********************************************************************//**
 * @brief		Set Station MAC address for EMAC module
 * @param[in]	abStationAddr Pointer to Station address that contains 6-bytes
 * 				of MAC address.
 * @return		None
 **********************************************************************/
void setEmacAddr(uint8_t abStationAddr[])
{
	/* Set the Ethernet MAC Address registers */
	LPC_EMAC->SA0 = ((uint32_t)abStationAddr[5] << 8) | (uint32_t)abStationAddr[4];
	LPC_EMAC->SA1 = ((uint32_t)abStationAddr[3] << 8) | (uint32_t)abStationAddr[2];
	LPC_EMAC->SA2 = ((uint32_t)abStationAddr[1] << 8) | (uint32_t)abStationAddr[0];
}


/************************** GLOBAL/PUBLIC FUNCTIONS *************************/

/** @defgroup EMAC_Public_Functions
 * @{
 */


/*********************************************************************//**
 * @brief		Initializes the EMAC peripheral according to the specified
*               parameters in the EMAC_ConfigStruct.
 * @param[in]	EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure
*                    that contains the configuration information for the
*                    specified EMAC peripheral.
 * @return		None
 *
 * Note: This function will initialize EMAC module according to procedure below:
 *  - Remove the soft reset condition from the MAC
 *  - Configure the PHY via the MIIM interface of the MAC
 *  - Select RMII mode
 *  - Configure the transmit and receive DMA engines, including the descriptor arrays
 *  - Configure the host registers (MAC1,MAC2 etc.) in the MAC
 *  - Enable the receive and transmit data paths
 *  In default state after initializing, only Rx Done and Tx Done interrupt are enabled,
 *  all remain interrupts are disabled
 *  (Ref. from LPC17xx UM)
 **********************************************************************/
int32_t EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
{
	/* Initialize the EMAC Ethernet controller. */
	int32_t regv,tout, tmp;

	/* Set up power for Ethernet module */
	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);

	/* Enable P1 Ethernet Pins. */

	/* Reset all EMAC internal modules */
	LPC_EMAC->MAC1    = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX |
					EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES;

	LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES | EMAC_CR_PASS_RUNT_FRM;

	/* A short delay after reset. */
	for (tout = 100; tout; tout--);

	/* Initialize MAC control registers. */
	LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
	LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN;
	LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
	/*
	 * Find the clock that close to desired target clock
	 */
	tmp = CLKPWR_GetCLK(CLKPWR_CLKTYPE_CPU)/ EMAC_MCFG_MII_MAXCLK;
	for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++)
	{
		if (EMAC_clkdiv[tout] >= tmp)
			break;
	}

	tout++;

	// Write to MAC configuration register and reset
	LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII;

	// release reset
	LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII);
	LPC_EMAC->CLRT = EMAC_CLRT_DEF;
	LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF;

	/* Enable Reduced MII interface. */
	LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM;

	/* Reset Reduced MII Logic. */
	LPC_EMAC->SUPP = EMAC_SUPP_RES_RMII;

	for (tout = 100; tout; tout--);

	LPC_EMAC->SUPP = 0;

	/* Put the DP83848C in reset mode */
	write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_RESET);

	/* Wait for hardware reset to end. */
	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--)
	{
		regv = read_PHY (EMAC_PHY_REG_BMCR);

		if (!(regv & (EMAC_PHY_BMCR_RESET | EMAC_PHY_BMCR_POWERDOWN)))
		{
			/* Reset complete, device not Power Down. */
			break;
		}

		if (tout == 0)
		{
			// Time out, return ERROR
			return (ERROR);
		}
	}

	// Set PHY mode
	if (EMAC_SetPHYMode(EMAC_ConfigStruct->Mode) < 0)
	{
		return (ERROR);
	}

	// Set EMAC address
	setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr);

	/* Initialize Tx and Rx DMA Descriptors */
	rx_descr_init ();
	tx_descr_init ();

	// Set Receive Filter register: enable broadcast and multicast
	LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;

	/* Enable Rx Done and Tx Done interrupt for EMAC */
	LPC_EMAC->IntEnable = EMAC_INT_RX_DONE | EMAC_INT_TX_DONE;

	/* Reset all interrupts */
	LPC_EMAC->IntClear  = 0xFFFF;

	/* Enable receive and transmit mode of MAC Ethernet core */
	LPC_EMAC->Command  |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
	LPC_EMAC->MAC1     |= EMAC_MAC1_REC_EN;

	return SUCCESS;
}


/*********************************************************************//**
 * @brief		De-initializes the EMAC peripheral registers to their
*                  default reset values.
 * @param[in]	None
 * @return 		None
 **********************************************************************/
void EMAC_DeInit(void)
{
	// Disable all interrupt
	LPC_EMAC->IntEnable = 0x00;

	// Clear all pending interrupt
	LPC_EMAC->IntClear = (0xFF) | (EMAC_INT_SOFT_INT | EMAC_INT_WAKEUP);

	/* TurnOff power for Ethernet module */
	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE);
}

/*********************************************************************//**
 * @brief		EMAC TX API modules
 * @param[in]	None
 * @return 		None
 **********************************************************************/
void EMAC_TxEnable( void )
{
	LPC_EMAC->Command |= 0x02;
	return;
}


/*********************************************************************//**
 * @brief		EMAC RX API modules
 * @param[in]	None
 * @return 		None
 **********************************************************************/
void EMAC_TxDisable( void )
{
	LPC_EMAC->Command &= ~0x02;
	return;
}

/*********************************************************************//**
 * @brief		EMAC RX API modules
 * @param[in]	None
 * @return 		None
 **********************************************************************/
void EMAC_RxEnable( void )
{
	LPC_EMAC->Command |= 0x01;
	LPC_EMAC->MAC1 |= 0x01;
	return;
}

/*********************************************************************//**
 * @brief		EMAC RX API modules
 * @param[in]	None
 * @return 		None
 **********************************************************************/
void EMAC_RxDisable( void )
{
	LPC_EMAC->Command &= ~0x01;
	LPC_EMAC->MAC1 &= ~0x01;
	return;
}


/*********************************************************************//**
 * @brief		Check specified PHY status in EMAC peripheral
 * @param[in]	ulPHYState	Specified PHY Status Type, should be:
 * 							- EMAC_PHY_STAT_LINK: Link Status
 * 							- EMAC_PHY_STAT_SPEED: Speed Status
 * 							- EMAC_PHY_STAT_DUP: Duplex Status
 * @return		Status of specified PHY status (0 or 1).
 * 				(-1) if error.
 *
 * Note:
 * For EMAC_PHY_STAT_LINK, return value:
 * - 0: Link Down
 * - 1: Link Up
 * For EMAC_PHY_STAT_SPEED, return value:
 * - 0: 10Mbps
 * - 1: 100Mbps
 * For EMAC_PHY_STAT_DUP, return value:
 * - 0: Half-Duplex
 * - 1: Full-Duplex
 **********************************************************************/
int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState)
{
	int32_t regv, tmp;

	regv = read_PHY (EMAC_PHY_REG_BMSR);

⌨️ 快捷键说明

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