Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

Revision:
3:f151d08d335c
Parent:
2:1df0b61d3b5a
--- a/libs/LPC17xx/LPC17xxLib/src/lpc17xx_emac.c	Fri Feb 28 18:52:52 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,960 +0,0 @@
-#ifdef __LPC17XX__
-
-/**********************************************************************
-* $Id$		lpc17xx_dac.c				2010-05-21
-*//**
-* @file		lpc17xx_dac.c
-* @brief	Contains all functions support for Ethernet MAC firmware
-* 			library on LPC17xx
-* @version	2.0
-* @date		21. May. 2010
-* @author	NXP MCU SW Application Team
-*
-* Copyright(C) 2010, 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.
-**********************************************************************/
-
-/* Peripheral group ----------------------------------------------------------- */
-/** @addtogroup EMAC
- * @{
- */
-
-/* Includes ------------------------------------------------------------------- */
-#include "lpc17xx_emac.h"
-#include "lpc17xx_clkpwr.h"
-
-/* If this source file built with example, the LPC17xx FW library configuration
- * file in each example directory ("lpc17xx_libcfg.h") must be included,
- * otherwise the default FW library configuration file must be included instead
- */
-#ifdef __BUILD_WITH_EXAMPLE__
-#include "lpc17xx_libcfg.h"
-#else
-#include "lpc17xx_libcfg_default.h"
-#endif /* __BUILD_WITH_EXAMPLE__ */
-
-
-#ifdef _EMAC
-
-/* Private Variables ---------------------------------------------------------- */
-/** @defgroup EMAC_Private_Variables EMAC 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 */
-
-/** Rx Descriptor data array */
-static RX_Desc Rx_Desc[EMAC_NUM_RX_FRAG];
-
-/** Rx Status data array - Must be 8-Byte aligned */
-#if defined ( __CC_ARM   )
-static __align(8) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
-#elif defined ( __ICCARM__ )
-#pragma data_alignment=8
-static RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
-#elif defined   (  __GNUC__  )
-static __attribute__ ((aligned (8))) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
-#endif
-
-/** Tx Descriptor data array */
-static TX_Desc Tx_Desc[EMAC_NUM_TX_FRAG];
-/** Tx Status data array */
-static TX_Stat Tx_Stat[EMAC_NUM_TX_FRAG];
-
-/* EMAC local DMA buffers */
-/** Rx buffer data */
-static uint32_t rx_buf[EMAC_NUM_RX_FRAG][EMAC_ETH_MAX_FLEN>>2];
-/** Tx buffer data */
-static uint32_t tx_buf[EMAC_NUM_TX_FRAG][EMAC_ETH_MAX_FLEN>>2];
-
-/**
- * @}
- */
-
-/* Private Functions ---------------------------------------------------------- */
-static void rx_descr_init (void);
-static void tx_descr_init (void);
-static int32_t write_PHY (uint32_t PhyReg, uint16_t Value);
-static int32_t  read_PHY (uint32_t PhyReg);
-
-static void setEmacAddr(uint8_t abStationAddr[]);
-static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len);
-
-
-/*--------------------------- rx_descr_init ---------------------------------*/
-/*********************************************************************//**
- * @brief 		Initializes RX Descriptor
- * @param[in] 	None
- * @return 		None
- ***********************************************************************/
-static void rx_descr_init (void)
-{
-	/* Initialize Receive Descriptor and Status array. */
-	uint32_t i;
-
-	for (i = 0; i < EMAC_NUM_RX_FRAG; i++) {
-		Rx_Desc[i].Packet  = (uint32_t)&rx_buf[i];
-		Rx_Desc[i].Ctrl    = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN - 1);
-		Rx_Stat[i].Info    = 0;
-		Rx_Stat[i].HashCRC = 0;
-	}
-
-	/* Set EMAC Receive Descriptor Registers. */
-	LPC_EMAC->RxDescriptor       = (uint32_t)&Rx_Desc[0];
-	LPC_EMAC->RxStatus           = (uint32_t)&Rx_Stat[0];
-	LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG - 1;
-
-	/* Rx Descriptors Point to 0 */
-	LPC_EMAC->RxConsumeIndex  = 0;
-}
-
-
-/*--------------------------- tx_descr_init ---- ----------------------------*/
-/*********************************************************************//**
- * @brief 		Initializes TX Descriptor
- * @param[in] 	None
- * @return 		None
- ***********************************************************************/
-static void tx_descr_init (void) {
-	/* Initialize Transmit Descriptor and Status array. */
-	uint32_t i;
-
-	for (i = 0; i < EMAC_NUM_TX_FRAG; i++) {
-		Tx_Desc[i].Packet = (uint32_t)&tx_buf[i];
-		Tx_Desc[i].Ctrl   = 0;
-		Tx_Stat[i].Info   = 0;
-	}
-
-	/* Set EMAC Transmit Descriptor Registers. */
-	LPC_EMAC->TxDescriptor       = (uint32_t)&Tx_Desc[0];
-	LPC_EMAC->TxStatus           = (uint32_t)&Tx_Stat[0];
-	LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG - 1;
-
-	/* Tx Descriptors Point to 0 */
-	LPC_EMAC->TxProduceIndex  = 0;
-}
-
-
-/*--------------------------- write_PHY -------------------------------------*/
-/*********************************************************************//**
- * @brief 		Write value to PHY device
- * @param[in] 	PhyReg: PHY Register address
- * @param[in] 	Value:  Value to write
- * @return 		0 - if success
- * 				1 - if fail
- ***********************************************************************/
-static int32_t write_PHY (uint32_t PhyReg, uint16_t Value)
-{
-	/* Write a data 'Value' to PHY register 'PhyReg'. */
-	uint32_t tout;
-
-	LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
-	LPC_EMAC->MWTD = Value;
-
-	/* Wait until operation completed */
-	tout = 0;
-	for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++) {
-		if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
-			return (0);
-		}
-	}
-	// Time out!
-	return (-1);
-}
-
-
-/*--------------------------- read_PHY --------------------------------------*/
-/*********************************************************************//**
- * @brief 		Read value from PHY device
- * @param[in] 	PhyReg: PHY Register address
- * @return 		0 - if success
- * 				1 - if fail
- ***********************************************************************/
-static int32_t read_PHY (uint32_t PhyReg)
-{
-	/* Read a PHY register 'PhyReg'. */
-	uint32_t tout;
-
-	LPC_EMAC->MADR = EMAC_DEF_ADR | 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) {
-			LPC_EMAC->MCMD = 0;
-			return (LPC_EMAC->MRDD);
-		}
-	}
-	// Time out!
-	return (-1);
-}
-
-/*********************************************************************//**
- * @brief		Set Station MAC address for EMAC module
- * @param[in]	abStationAddr Pointer to Station address that contains 6-bytes
- * 				of MAC address (should be in order from MAC Address 1 to MAC Address 6)
- * @return		None
- **********************************************************************/
-static 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];
-}
-
-
-/*********************************************************************//**
- * @brief		Calculates CRC code for number of bytes in the frame
- * @param[in]	frame_no_fcs	Pointer to the first byte of the frame
- * @param[in]	frame_len		length of the frame without the FCS
- * @return		the CRC as a 32 bit integer
- **********************************************************************/
-static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len)
-{
-	int i; 		// iterator
-	int j; 		// another iterator
-	char byte; 	// current byte
-	int crc; 	// CRC result
-	int q0, q1, q2, q3; // temporary variables
-	crc = 0xFFFFFFFF;
-	for (i = 0; i < frame_len; i++) {
-		byte = *frame_no_fcs++;
-		for (j = 0; j < 2; j++) {
-			if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) {
-				q3 = 0x04C11DB7;
-			} else {
-				q3 = 0x00000000;
-			}
-			if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) {
-				q2 = 0x09823B6E;
-			} else {
-				q2 = 0x00000000;
-			}
-			if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) {
-				q1 = 0x130476DC;
-			} else {
-				q1 = 0x00000000;
-			}
-			if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) {
-				q0 = 0x2608EDB8;
-			} else {
-				q0 = 0x00000000;
-			}
-			crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0;
-			byte >>= 4;
-		}
-	}
-	return crc;
-}
-/* End of Private Functions --------------------------------------------------- */
-
-
-/* Public Functions ----------------------------------------------------------- */
-/** @addtogroup 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)
- **********************************************************************/
-Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
-{
-	/* Initialize the EMAC Ethernet controller. */
-	int32_t regv,tout, tmp;
-
-	/* Set up clock and power for Ethernet module */
-	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);
-
-	/* 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 = SystemCoreClock / EMAC_MCFG_MII_MAXCLK;
-	for (tout = 0; tout < (int32_t) 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 clock and power for Ethernet module */
-	CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE);
-}
-
-
-/*********************************************************************//**
- * @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;
-#ifdef MCB_LPC_1768
-	regv = read_PHY (EMAC_PHY_REG_STS);
-	switch(ulPHYState){
-	case EMAC_PHY_STAT_LINK:
-		tmp = (regv & EMAC_PHY_SR_LINK) ? 1 : 0;
-		break;
-	case EMAC_PHY_STAT_SPEED:
-		tmp = (regv & EMAC_PHY_SR_SPEED) ? 0 : 1;
-		break;
-	case EMAC_PHY_STAT_DUP:
-		tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
-		break;
-#elif defined(IAR_LPC_1768)
-	/* Use IAR_LPC_1768 board:
-	 * FSZ8721BL doesn't have Status Register
-	 * so we read Basic Mode Status Register (0x01h) instead
-	 */
-	regv = read_PHY (EMAC_PHY_REG_BMSR);
-	switch(ulPHYState){
-	case EMAC_PHY_STAT_LINK:
-		tmp = (regv & EMAC_PHY_BMSR_LINK_STATUS) ? 1 : 0;
-		break;
-	case EMAC_PHY_STAT_SPEED:
-		tmp = (regv & EMAC_PHY_SR_100_SPEED) ? 1 : 0;
-		break;
-	case EMAC_PHY_STAT_DUP:
-		tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
-		break;
-#endif
-	default:
-		tmp = -1;
-		break;
-	}
-	return (tmp);
-}
-
-
-/*********************************************************************//**
- * @brief		Set specified PHY mode in EMAC peripheral
- * @param[in]	ulPHYMode	Specified PHY mode, should be:
- * 							- EMAC_MODE_AUTO
- * 							- EMAC_MODE_10M_FULL
- * 							- EMAC_MODE_10M_HALF
- * 							- EMAC_MODE_100M_FULL
- * 							- EMAC_MODE_100M_HALF
- * @return		Return (0) if no error, otherwise return (-1)
- **********************************************************************/
-int32_t EMAC_SetPHYMode(uint32_t ulPHYMode)
-{
-	int32_t id1, id2, tout, regv;
-
-	/* Check if this is a DP83848C PHY. */
-	id1 = read_PHY (EMAC_PHY_REG_IDR1);
-	id2 = read_PHY (EMAC_PHY_REG_IDR2);
-
-#ifdef MCB_LPC_1768
-	if (((id1 << 16) | (id2 & 0xFFF0)) == EMAC_DP83848C_ID) {
-		switch(ulPHYMode){
-		case EMAC_MODE_AUTO:
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
-#elif defined(IAR_LPC_1768) /* Use IAR LPC1768 KickStart board */
-	if (((id1 << 16) | id2) == EMAC_KSZ8721BL_ID) {
-		/* Configure the PHY device */
-		switch(ulPHYMode){
-		case EMAC_MODE_AUTO:
-			/* Use auto-negotiation about the link speed. */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
-//			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_AN);
-#endif
-			/* Wait to complete Auto_Negotiation */
-			for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
-				regv = read_PHY (EMAC_PHY_REG_BMSR);
-				if (regv & EMAC_PHY_BMSR_AUTO_DONE) {
-					/* Auto-negotiation Complete. */
-					break;
-				}
-				if (tout == 0){
-					// Time out, return error
-					return (-1);
-				}
-			}
-			break;
-		case EMAC_MODE_10M_FULL:
-			/* Connect at 10MBit full-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_10M);
-			break;
-		case EMAC_MODE_10M_HALF:
-			/* Connect at 10MBit half-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_10M);
-			break;
-		case EMAC_MODE_100M_FULL:
-			/* Connect at 100MBit full-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_100M);
-			break;
-		case EMAC_MODE_100M_HALF:
-			/* Connect at 100MBit half-duplex */
-			write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_100M);
-			break;
-		default:
-			// un-supported
-			return (-1);
-		}
-	}
-	// It's not correct module ID
-	else {
-		return (-1);
-	}
-
-	// Update EMAC configuration with current PHY status
-	if (EMAC_UpdatePHYStatus() < 0){
-		return (-1);
-	}
-
-	// Complete
-	return (0);
-}
-
-
-/*********************************************************************//**
- * @brief		Auto-Configures value for the EMAC configuration register to
- * 				match with current PHY mode
- * @param[in]	None
- * @return		Return (0) if no error, otherwise return (-1)
- *
- * Note: The EMAC configuration will be auto-configured:
- * 		- Speed mode.
- * 		- Half/Full duplex mode
- **********************************************************************/
-int32_t EMAC_UpdatePHYStatus(void)
-{
-	int32_t regv, tout;
-
-	/* Check the link status. */
-#ifdef MCB_LPC_1768
-	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
-		regv = read_PHY (EMAC_PHY_REG_STS);
-		if (regv & EMAC_PHY_SR_LINK) {
-			/* Link is on. */
-			break;
-		}
-		if (tout == 0){
-			// time out
-			return (-1);
-		}
-	}
-	/* Configure Full/Half Duplex mode. */
-	if (regv & EMAC_PHY_SR_DUP) {
-	/* Full duplex is enabled. */
-			LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
-			LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
-			LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
-	} else {
-		/* Half duplex mode. */
-		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
-	}
-	if (regv & EMAC_PHY_SR_SPEED) {
-	/* 10MBit mode. */
-		LPC_EMAC->SUPP = 0;
-	} else {
-		/* 100MBit mode. */
-		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
-	}
-#elif defined(IAR_LPC_1768)
-	for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
-		regv = read_PHY (EMAC_PHY_REG_BMSR);
-		if (regv & EMAC_PHY_BMSR_LINK_STATUS) {
-			/* Link is on. */
-			break;
-		}
-		if (tout == 0){
-			// time out
-			return (-1);
-		}
-	}
-
-	/* Configure Full/Half Duplex mode. */
-	if (regv & EMAC_PHY_SR_FULL_DUP) {
-		/* Full duplex is enabled. */
-		LPC_EMAC->MAC2    |= EMAC_MAC2_FULL_DUP;
-		LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
-		LPC_EMAC->IPGT     = EMAC_IPGT_FULL_DUP;
-	} else {
-		/* Half duplex mode. */
-		LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
-	}
-
-	/* Configure 100MBit/10MBit mode. */
-	if (!(regv & EMAC_PHY_SR_100_SPEED)) {
-		/* 10MBit mode. */
-		LPC_EMAC->SUPP = 0;
-	} else {
-		/* 100MBit mode. */
-		LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
-	}
-#endif
-	// Complete
-	return (0);
-}
-
-
-/*********************************************************************//**
- * @brief		Enable/Disable hash filter functionality for specified destination
- * 				MAC address in EMAC module
- * @param[in]	dstMAC_addr		Pointer to the first MAC destination address, should
- * 								be 6-bytes length, in order LSB to the MSB
- * @param[in]	NewState		New State of this command, should be:
- *									- ENABLE.
- *									- DISABLE.
- * @return		None
- *
- * Note:
- * The standard Ethernet cyclic redundancy check (CRC) function is calculated from
- * the 6 byte destination address in the Ethernet frame (this CRC is calculated
- * anyway as part of calculating the CRC of the whole frame), then bits [28:23] out of
- * the 32 bits CRC result are taken to form the hash. The 6 bit hash is used to access
- * the hash table: it is used as an index in the 64 bit HashFilter register that has been
- * programmed with accept values. If the selected accept value is 1, the frame is
- * accepted.
- **********************************************************************/
-void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState)
-{
-	volatile uint32_t *pReg;
-	uint32_t tmp;
-	int32_t crc;
-
-	// Calculate the CRC from the destination MAC address
-	crc = emac_CRCCalc(dstMAC_addr, 6);
-	// Extract the value from CRC to get index value for hash filter table
-	crc = (crc >> 23) & 0x3F;
-
-	pReg = (crc > 31) ? ((volatile uint32_t *)&LPC_EMAC->HashFilterH) \
-								: ((volatile uint32_t *)&LPC_EMAC->HashFilterL);
-	tmp = (crc > 31) ? (crc - 32) : crc;
-	if (NewState == ENABLE) {
-		(*pReg) |= (1UL << tmp);
-	} else {
-		(*pReg) &= ~(1UL << tmp);
-	}
-	// Enable Rx Filter
-	LPC_EMAC->Command &= ~EMAC_CR_PASS_RX_FILT;
-}
-
-/*********************************************************************//**
- * @brief		Enable/Disable Filter mode for each specified type EMAC peripheral
- * @param[in]	ulFilterMode	Filter mode, should be:
- * 								- EMAC_RFC_UCAST_EN: all frames of unicast types
- * 								will be accepted
- * 								- EMAC_RFC_BCAST_EN: broadcast frame will be
- * 								accepted
- * 								- EMAC_RFC_MCAST_EN: all frames of multicast
- * 								types will be accepted
- * 								- EMAC_RFC_UCAST_HASH_EN: The imperfect hash
- * 								filter will be applied to unicast addresses
- * 								- EMAC_RFC_MCAST_HASH_EN: The imperfect hash
- * 								filter will be applied to multicast addresses
- * 								- EMAC_RFC_PERFECT_EN: the destination address
- * 								will be compared with the 6 byte station address
- * 								programmed in the station address by the filter
- * 								- EMAC_RFC_MAGP_WOL_EN: the result of the magic
- * 								packet filter will generate a WoL interrupt when
- * 								there is a match
- * 								- EMAC_RFC_PFILT_WOL_EN: the result of the perfect address
- * 								matching filter and the imperfect hash filter will
- * 								generate a WoL interrupt when there is a match
- * @param[in]	NewState	New State of this command, should be:
- * 								- ENABLE
- * 								- DISABLE
- * @return		None
- **********************************************************************/
-void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState)
-{
-	if (NewState == ENABLE){
-		LPC_EMAC->RxFilterCtrl |= ulFilterMode;
-	} else {
-		LPC_EMAC->RxFilterCtrl &= ~ulFilterMode;
-	}
-}
-
-/*********************************************************************//**
- * @brief		Get status of Wake On LAN Filter for each specified
- * 				type in EMAC peripheral, clear this status if it is set
- * @param[in]	ulWoLMode	WoL Filter mode, should be:
- * 								- EMAC_WOL_UCAST: unicast frames caused WoL
- * 								- EMAC_WOL_UCAST: broadcast frame caused WoL
- * 								- EMAC_WOL_MCAST: multicast frame caused WoL
- * 								- EMAC_WOL_UCAST_HASH: unicast frame that passes the
- * 								imperfect hash filter caused WoL
- * 								- EMAC_WOL_MCAST_HASH: multicast frame that passes the
- * 								imperfect hash filter caused WoL
- * 								- EMAC_WOL_PERFECT:perfect address matching filter
- * 								caused WoL
- * 								- EMAC_WOL_RX_FILTER: the receive filter caused WoL
- * 								- EMAC_WOL_MAG_PACKET: the magic packet filter caused WoL
- * @return		SET/RESET
- **********************************************************************/
-FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode)
-{
-	if (LPC_EMAC->RxFilterWoLStatus & ulWoLMode) {
-		LPC_EMAC->RxFilterWoLClear = ulWoLMode;
-		return SET;
-	} else {
-		return RESET;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Write data to Tx packet data buffer at current index due to
- * 				TxProduceIndex
- * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
- * 							data that contain specified information about
- * 							Packet data buffer.
- * @return		None
- **********************************************************************/
-void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
-{
-	uint32_t idx,len;
-	uint32_t *sp,*dp;
-
-	idx = LPC_EMAC->TxProduceIndex;
-	sp  = (uint32_t *)pDataStruct->pbDataBuf;
-	dp  = (uint32_t *)Tx_Desc[idx].Packet;
-	/* Copy frame data to EMAC packet buffers. */
-	for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
-		*dp++ = *sp++;
-	}
-	Tx_Desc[idx].Ctrl = (pDataStruct->ulDataLen - 1) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST);
-}
-
-/*********************************************************************//**
- * @brief		Read data from Rx packet data buffer at current index due
- * 				to RxConsumeIndex
- * @param[in]	pDataStruct		Pointer to a EMAC_PACKETBUF_Type structure
- * 							data that contain specified information about
- * 							Packet data buffer.
- * @return		None
- **********************************************************************/
-void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
-{
-	uint32_t idx, len;
-	uint32_t *dp, *sp;
-
-	idx = LPC_EMAC->RxConsumeIndex;
-	dp = (uint32_t *)pDataStruct->pbDataBuf;
-	sp = (uint32_t *)Rx_Desc[idx].Packet;
-
-	if (pDataStruct->pbDataBuf != NULL) {
-		for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
-			*dp++ = *sp++;
-		}
-	}
-}
-
-/*********************************************************************//**
- * @brief 		Enable/Disable interrupt for each type in EMAC
- * @param[in]	ulIntType	Interrupt Type, should be:
- * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
- * 							- EMAC_INT_RX_ERR: Receive Error
- * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
- * 							- EMAC_INT_RX_DONE: Receive Done
- * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
- * 							- EMAC_INT_TX_ERR: Transmit Error
- * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
- * 							- EMAC_INT_TX_DONE: Transmit Done
- * 							- EMAC_INT_SOFT_INT: Software interrupt
- * 							- EMAC_INT_WAKEUP: Wakeup interrupt
- * @param[in]	NewState	New State of this function, should be:
- * 							- ENABLE.
- * 							- DISABLE.
- * @return		None
- **********************************************************************/
-void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState)
-{
-	if (NewState == ENABLE) {
-		LPC_EMAC->IntEnable |= ulIntType;
-	} else {
-		LPC_EMAC->IntEnable &= ~(ulIntType);
-	}
-}
-
-/*********************************************************************//**
- * @brief 		Check whether if specified interrupt flag is set or not
- * 				for each interrupt type in EMAC and clear interrupt pending
- * 				if it is set.
- * @param[in]	ulIntType	Interrupt Type, should be:
- * 							- EMAC_INT_RX_OVERRUN: Receive Overrun
- * 							- EMAC_INT_RX_ERR: Receive Error
- * 							- EMAC_INT_RX_FIN: Receive Descriptor Finish
- * 							- EMAC_INT_RX_DONE: Receive Done
- * 							- EMAC_INT_TX_UNDERRUN: Transmit Under-run
- * 							- EMAC_INT_TX_ERR: Transmit Error
- * 							- EMAC_INT_TX_FIN: Transmit descriptor finish
- * 							- EMAC_INT_TX_DONE: Transmit Done
- * 							- EMAC_INT_SOFT_INT: Software interrupt
- * 							- EMAC_INT_WAKEUP: Wakeup interrupt
- * @return		New state of specified interrupt (SET or RESET)
- **********************************************************************/
-IntStatus EMAC_IntGetStatus(uint32_t ulIntType)
-{
-	if (LPC_EMAC->IntStatus & ulIntType) {
-		LPC_EMAC->IntClear = ulIntType;
-		return SET;
-	} else {
-		return RESET;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Check whether if the current RxConsumeIndex is not equal to the
- * 				current RxProduceIndex.
- * @param[in]	None
- * @return		TRUE if they're not equal, otherwise return FALSE
- *
- * Note: In case the RxConsumeIndex is not equal to the RxProduceIndex,
- * it means there're available data has been received. They should be read
- * out and released the Receive Data Buffer by updating the RxConsumeIndex value.
- **********************************************************************/
-Bool EMAC_CheckReceiveIndex(void)
-{
-	if (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex) {
-		return TRUE;
-	} else {
-		return FALSE;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Check whether if the current TxProduceIndex is not equal to the
- * 				current RxProduceIndex - 1.
- * @param[in]	None
- * @return		TRUE if they're not equal, otherwise return FALSE
- *
- * Note: In case the RxConsumeIndex is equal to the RxProduceIndex - 1,
- * it means the transmit buffer is available and data can be written to transmit
- * buffer to be sent.
- **********************************************************************/
-Bool EMAC_CheckTransmitIndex(void)
-{
-	uint32_t tmp = LPC_EMAC->TxConsumeIndex -1;
-	if (LPC_EMAC->TxProduceIndex == tmp) {
-		return FALSE;
-	} else {
-		return TRUE;
-	}
-}
-
-
-/*********************************************************************//**
- * @brief		Get current status value of receive data (due to RxConsumeIndex)
- * @param[in]	ulRxStatType	Received Status type, should be one of following:
- * 							- EMAC_RINFO_CTRL_FRAME: Control Frame
- * 							- EMAC_RINFO_VLAN: VLAN Frame
- * 							- EMAC_RINFO_FAIL_FILT: RX Filter Failed
- * 							- EMAC_RINFO_MCAST: Multicast Frame
- * 							- EMAC_RINFO_BCAST: Broadcast Frame
- * 							- EMAC_RINFO_CRC_ERR: CRC Error in Frame
- * 							- EMAC_RINFO_SYM_ERR: Symbol Error from PHY
- * 							- EMAC_RINFO_LEN_ERR: Length Error
- * 							- EMAC_RINFO_RANGE_ERR: Range error(exceeded max size)
- * 							- EMAC_RINFO_ALIGN_ERR: Alignment error
- * 							- EMAC_RINFO_OVERRUN: Receive overrun
- * 							- EMAC_RINFO_NO_DESCR: No new Descriptor available
- * 							- EMAC_RINFO_LAST_FLAG: last Fragment in Frame
- * 							- EMAC_RINFO_ERR: Error Occurred (OR of all error)
- * @return		Current value of receive data (due to RxConsumeIndex)
- **********************************************************************/
-FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType)
-{
-	uint32_t idx;
-	idx = LPC_EMAC->RxConsumeIndex;
-	return (((Rx_Stat[idx].Info) & ulRxStatType) ? SET : RESET);
-}
-
-
-/*********************************************************************//**
- * @brief		Get size of current Received data in received buffer (due to
- * 				RxConsumeIndex)
- * @param[in]	None
- * @return		Size of received data
- **********************************************************************/
-uint32_t EMAC_GetReceiveDataSize(void)
-{
-	uint32_t idx;
-	idx =LPC_EMAC->RxConsumeIndex;
-	return ((Rx_Stat[idx].Info) & EMAC_RINFO_SIZE);
-}
-
-/*********************************************************************//**
- * @brief		Increase the RxConsumeIndex (after reading the Receive buffer
- * 				to release the Receive buffer) and wrap-around the index if
- * 				it reaches the maximum Receive Number
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void EMAC_UpdateRxConsumeIndex(void)
-{
-	// Get current Rx consume index
-	uint32_t idx = LPC_EMAC->RxConsumeIndex;
-
-	/* Release frame from EMAC buffer */
-	if (++idx == EMAC_NUM_RX_FRAG) idx = 0;
-	LPC_EMAC->RxConsumeIndex = idx;
-}
-
-/*********************************************************************//**
- * @brief		Increase the TxProduceIndex (after writting to the Transmit buffer
- * 				to enable the Transmit buffer) and wrap-around the index if
- * 				it reaches the maximum Transmit Number
- * @param[in]	None
- * @return		None
- **********************************************************************/
-void EMAC_UpdateTxProduceIndex(void)
-{
-	// Get current Tx produce index
-	uint32_t idx = LPC_EMAC->TxProduceIndex;
-
-	/* Start frame transmission */
-	if (++idx == EMAC_NUM_TX_FRAG) idx = 0;
-	LPC_EMAC->TxProduceIndex = idx;
-}
-
-
-/**
- * @}
- */
-
-#endif /* _EMAC */
-
-/**
- * @}
- */
-
-/* --------------------------------- End Of File ------------------------------ */
-#endif /* __LPC17XX__ */