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

📄 lpc177x_8x_emac.c

📁 LPC1788的USBHOST的FATFS移植
💻 C
📖 第 1 页 / 共 3 页
字号:
		*dp++ = *sp++;
	}

	TX_DESC_CTRL(idx) = (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_PACKET(idx);

	if (pDataStruct->pbDataBuf != NULL)
	{
		for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--)
		{
			*dp++ = *sp++;
		}
	}

}
/*********************************************************************//**
 * @brief		Configure the TX Descript control and return the address of
 * 				TX_DESC_PACKET buffer
 * @param[in]	FrameSize		The size of frame you want to send
 * @return		Address of the TX_DESC_PACKET buffer
 **********************************************************************/

 uint32_t EMAC_RequestSend(uint16_t FrameSize)
{
	uint32_t idx;
	uint32_t  dp;

	idx = LPC_EMAC->TxProduceIndex;

 	dp = TX_DESC_PACKET(idx);

	TX_DESC_CTRL(idx) = (FrameSize) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST);

	return dp;
}
/*********************************************************************//**
 * @brief		Get the address of TX_DESC_PACKET buffer so that user can access from application
 * @param[in] None
 * @return	Address of the TX_DESC_PACKET buffer
 **********************************************************************/

uint32_t EMAC_GetReadPacketBuffer(void)
{
	uint32_t idx;

	idx = LPC_EMAC->RxConsumeIndex;

  	return RX_DESC_PACKET(idx);
 }
/*********************************************************************//**
 * @brief		Get the address of TX_DESC_PACKET buffer so that user can access from application
 * @param[in] None
 * @return	Address of the TX_DESC_PACKET buffer
 **********************************************************************/

uint32_t EMAC_GetWritePacketBuffer(void)
{
	uint32_t idx;

	idx = LPC_EMAC->TxProduceIndex;

  	return TX_DESC_PACKET(idx);
 }

/*********************************************************************//**
 * @brief		Standard EMAC IRQ Handler. This sub-routine will check
 * 				these following interrupt and call the call-back function
 * 				if they're already installed:
 * 				- Overrun Error interrupt in RX Queue
 * 				- Receive Error interrupt: AlignmentError, RangeError,
 * 				LengthError, SymbolError, CRCError or NoDescriptor or Overrun
 * 				- RX Finished Process Descriptors interrupt (ProduceIndex == ConsumeIndex)
 * 				- Receive Done interrupt
 * 				- Transmit Under-run interrupt
 * 				- Transmit errors interrupt : LateCollision, ExcessiveCollision
 * 				and ExcessiveDefer, NoDescriptor or Under-run
 * 				- TX Finished Process Descriptors interrupt (ProduceIndex == ConsumeIndex)
 * 				- Transmit Done interrupt
 * 				- Interrupt triggered by software
 *				- Interrupt triggered by a Wakeup event detected by the receive filter
 * @param[in]	None
 * @return		None
 **********************************************************************/
void EMAC_StandardIRQHandler(void)
{
	/* EMAC Ethernet Controller Interrupt function. */
	uint32_t n, int_stat;

	// Get EMAC interrupt status
	while ((int_stat = (LPC_EMAC->IntStatus & LPC_EMAC->IntEnable)) != 0)
	{
		// Clear interrupt status
		LPC_EMAC->IntClear = int_stat;
		// Execute call-back function
		for (n = 0; n <= 7; n++)
		{
			if ((int_stat & (1 << n)) && (_pfnIntCbDat[n] != NULL))
			{
				_pfnIntCbDat[n]();
			}
		}

		// Soft interrupt
		if ((int_stat & EMAC_INT_SOFT_INT) && (_pfnIntCbDat[8] != NULL))
		{
			_pfnIntCbDat[8]();
		}

		// WakeUp interrupt
		if ((int_stat & EMAC_INT_WAKEUP) && (_pfnIntCbDat[9] != NULL))
		{
			// Clear WoL interrupt
			LPC_EMAC->RxFilterWoLClear = EMAC_WOL_BITMASK;
			_pfnIntCbDat[9]();
		}
	}
}


/*********************************************************************//**
 * @brief		Setup/register Call-back function for each interrupt type
 * 				in EMAC module.
 * @param[in]	ulIntType	Interrupt type, should be one of the following:
 * 							- 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]	pfnIntCb	Pointer to Call-back function used for this
 * 							interrupt type
 * @return		None
 **********************************************************************/
void EMAC_SetupIntCBS(uint32_t ulIntType, EMAC_IntCBSType *pfnIntCb)
{
	/* EMAC Ethernet Controller Interrupt function. */
	uint32_t n;

	if (ulIntType <= EMAC_INT_TX_DONE)
	{
		for (n = 0; n <= 7; n++)
		{
			// Found it, install cbs now
			if (ulIntType & (1 << n))
			{
				_pfnIntCbDat[n] = pfnIntCb;
				// Don't install cbs any more
				break;
			}
		}
	}
	else if (ulIntType & EMAC_INT_SOFT_INT)
	{
		_pfnIntCbDat[8] = pfnIntCb;
	}
	else if (ulIntType & EMAC_INT_WAKEUP)
	{
		_pfnIntCbDat[9] = pfnIntCb;
	}
}

/*********************************************************************//**
 * @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.
 **********************************************************************/
int32_t 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.
 **********************************************************************/
int32_t 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]	ulRxDatStat	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_INFO(idx)) & 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_INFO(idx)) & 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;
}


/**
 * @}
 */

/**
 * @}
 */

⌨️ 快捷键说明

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