📄 lpc17xx_emac.c.svn-base
字号:
**********************************************************************/
void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState)
{
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) ? ((uint32_t *)&LPC_EMAC->HashFilterH) \
: ((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 ------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -