rt-thread/bsp/gd32103c-eval/Libraries/GD32F1xx_standard_peripheral/Source/gd32f10x_eth.c

2588 lines
98 KiB
C
Raw Normal View History

/**
******************************************************************************
* @brief ETH header file of the firmware library.
******************************************************************************
*/
#ifdef GD32F10X_CL
/* Includes ------------------------------------------------------------------*/
#include "gd32f10x_eth.h"
#include "gd32f10x_rcc.h"
/** @addtogroup GD32F10x_Firmware
* @{
*/
/** @defgroup ETH
* @brief ETH driver modules
* @{
*/
/** @defgroup ETH_Private_Defines
* @{
*/
/* Global transmit and receive descriptors pointers */
ETH_DMADESCTypeDef *DMACurrentTxDesc;
ETH_DMADESCTypeDef *DMACurrentRxDesc;
ETH_DMADESCTypeDef *DMACurrentPTPTxDesc;
ETH_DMADESCTypeDef *DMACurrentPTPRxDesc;
/* ETHERNET MAC address offsets */
#define ETH_MAC_ADDR_HBASE (ETH_MAC_BASE + 0x40) /* ETHERNET MAC address high offset */
#define ETH_MAC_ADDR_LBASE (ETH_MAC_BASE + 0x44) /* ETHERNET MAC address low offset */
/* ETHERNET MAC_PHYAR register Mask */
#define MAC_PHYAR_CLR_MASK ((uint32_t)0xFFFFFFE3)
/* ETHERNET MAC_PHYAR register PHY address shift */
#define MAC_PHYAR_PHYADDRSHIFT 11
/* ETHERNET MAC_PHYAR register PHY register shift */
#define MAC_PHYAR_PHYREGSHIFT 6
/* ETHERNET MAC_CFR register Mask */
#define MAC_CFR_CLEAR_MASK ((uint32_t)0xFF20810F)
/* ETHERNET MAC_FCTLR register Mask */
#define MAC_FCTLR_CLEAR_MASK ((uint32_t)0x0000FF41)
/* ETHERNET DMA_CTLR register Mask */
#define DMA_CTLR_CLEAR_MASK ((uint32_t)0xF8DE3F23)
/* ETHERNET Remote Wake-up frame register length */
#define ETH_WAKEUP_REGISTER_LENGTH 8
/* ETHERNET Missed frames counter Shift */
#define ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT 17
/* ETHERNET DMA Tx descriptors Collision Count Shift */
#define ETH_DMATXDESC_COLLISION_COUNTSHIFT 3
/* ETHERNET DMA Tx descriptors size */
#define ETH_DMATXDESC_SIZE 0x10
/* ETHERNET DMA Rx descriptors size */
#define ETH_DMARXDESC_SIZE 0x10
/* ETHERNET DMA Tx descriptors Buffer2 Size Shift */
#define ETH_DMATXDESC_BUFFER2_SIZESHIFT 16
/* ETHERNET DMA Rx descriptors Frame Length Shift */
#define ETH_DMARXDESC_FRAME_LENGTHSHIFT 16
/* ETHERNET DMA Rx descriptors Buffer2 Size Shift */
#define ETH_DMARXDESC_BUFFER2_SIZESHIFT 16
/* ETHERNET errors */
#define ERROR ((uint32_t)0)
#define SUCCESS ((uint32_t)1)
/**
* @}
*/
/** @defgroup ETH_Private_FunctionPrototypes
* @{
*/
#ifndef USE_Delay
static void ETH_Delay(__IO uint32_t nCount);
#endif /* USE_Delay*/
/**
* @}
*/
/** @defgroup ETH_Private_Functions
* @{
*/
/**
* @brief Reset the ETH registers.
* @param None
* @retval None
*/
void ETH_DeInit(void)
{
RCC_AHBPeriphReset_Enable(RCC_AHBPERIPH_ETH_MAC, ENABLE);
RCC_AHBPeriphReset_Enable(RCC_AHBPERIPH_ETH_MAC, DISABLE);
}
/**
* @brief Initialize MDIO parameters.
* @param None
* @retval None
*/
void ETH_MDIOInit(void)
{
uint32_t temp = 0;
RCC_ClocksPara rcc_clocks;
uint32_t hclk;
/* ETHERNET MAC_PHYAR Configuration */
/* Get the ETH_MAC_PHYAR value */
temp = ETH_MAC->PHYAR;
/* Clear Clock Range CLR[2:0] bits */
temp &= MAC_PHYAR_CLR_MASK;
/* Get hclk frequency value */
RCC_GetClocksFreq(&rcc_clocks);
hclk = rcc_clocks.AHB_Frequency;
/* Set CLR bits depending on hclk value */
if ((hclk >= 20000000) && (hclk < 35000000)) {
/* Clock Range between 20-35 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV16;
} else if ((hclk >= 35000000) && (hclk < 60000000)) {
/* Clock Range between 35-60 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV26;
} else if ((hclk >= 60000000) && (hclk < 90000000)) {
/* Clock Range between 60-90 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV42;
}
/* ((hclk >= 90000000)&&(hclk <= 108000000)) */
else {
/* Clock Range between 90-108 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV64;
}
/* Write to ETHERNET MAC PHYAR */
ETH_MAC->PHYAR = (uint32_t)temp;
}
/**
* @brief Initial the ETH parameters.
* @param ETH_InitParaStruct: The ETH_InitPara structure pointer.
* @param PHYAddress: external PHY address
* @retval The Initialize result(ERROR or SUCCESS)
*/
uint32_t ETH_Init(ETH_InitPara *ETH_InitParaStruct, uint16_t PHYAddress)
{
uint32_t RegValue = 0, temp = 0;
__IO uint32_t i = 0;
RCC_ClocksPara rcc_clocks;
uint32_t hclk;
__IO uint32_t timeout = 0;
/* MAC Config */
/* ETH_MAC_PHYAR Configuration */
/* Get the ETH_MAC_PHYAR value */
temp = ETH_MAC->PHYAR;
/* Clear Clock Range CLR[2:0] bits */
temp &= MAC_PHYAR_CLR_MASK;
/* Get hclk frequency value */
RCC_GetClocksFreq(&rcc_clocks);
hclk = rcc_clocks.AHB_Frequency;
/* Set CLR bits depending on hclk value */
if ((hclk >= 20000000) && (hclk < 35000000)) {
/* Clock Range between 20-35 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV16;
} else if ((hclk >= 35000000) && (hclk < 60000000)) {
/* Clock Range between 35-60 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV26;
} else if ((hclk >= 60000000) && (hclk < 90000000)) {
/* Clock Range between 60-90 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV42;
}
/* ((hclk >= 90000000)&&(hclk <= 108000000)) */
else {
/* Clock Range between 90-108 MHz */
temp |= (uint32_t)ETH_MAC_PHYAR_CLR_DIV64;
}
ETH_MAC->PHYAR = (uint32_t)temp;
/* PHY initialization and configuration */
/* Set the PHY into reset mode */
if (!(ETH_SetPHYRegisterValue(PHYAddress, PHY_BCR, PHY_RESET))) {
/* Return ERROR due to write timeout */
return ERROR;
}
/* PHY reset need some time */
_eth_delay_(PHY_RESETDELAY);
if (ETH_InitParaStruct->ETH_MAC_AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE) {
/* Wait for PHY_LINKED_STATUS bit be set */
do {
timeout++;
} while (!(ETH_GetPHYRegisterValue(PHYAddress, PHY_BSR) & PHY_LINKED_STATUS) && (timeout < PHY_READ_TO));
/* Return ERROR due to timeout */
if (timeout == PHY_READ_TO) {
return ERROR;
}
/* Reset Timeout counter */
timeout = 0;
/* Enable Auto-Negotiation */
if (!(ETH_SetPHYRegisterValue(PHYAddress, PHY_BCR, PHY_AUTONEGOTIATION))) {
/* Return ERROR due to write timeout */
return ERROR;
}
/* Wait for the PHY_AUTONEGO_COMPLETE bit be set */
do {
timeout++;
} while (!(ETH_GetPHYRegisterValue(PHYAddress, PHY_BSR) & PHY_AUTONEGO_COMPLETE) && (timeout < (uint32_t)PHY_READ_TO));
/* Return ERROR due to timeout */
if (timeout == PHY_READ_TO) {
return ERROR;
}
/* Reset Timeout counter */
timeout = 0;
/* Read the result of the autonegotiation */
RegValue = ETH_GetPHYRegisterValue(PHYAddress, PHY_SR);
/* Configure the Duplex Mode of MAC following the autonegotiation result */
if ((RegValue & PHY_DUPLEX_STATUS) != (uint32_t)RESET) {
ETH_InitParaStruct->ETH_MAC_Mode = ETH_MODE_FULLDUPLEX;
} else {
ETH_InitParaStruct->ETH_MAC_Mode = ETH_MODE_HALFDUPLEX;
}
/* Configure the Communication speed of MAC following the autonegotiation result */
if (RegValue & PHY_Speed_Status) {
ETH_InitParaStruct->ETH_MAC_Speed = ETH_SPEEDMODE_10M;
} else {
ETH_InitParaStruct->ETH_MAC_Speed = ETH_SPEEDMODE_100M;
}
} else {
if (!ETH_SetPHYRegisterValue(PHYAddress, PHY_BCR, ((uint16_t)(ETH_InitParaStruct->ETH_MAC_Mode >> 3) |
(uint16_t)(ETH_InitParaStruct->ETH_MAC_Speed >> 1)))) {
/* Return ERROR due to write timeout */
return ERROR;
}
/* PHY configuration need some time */
_eth_delay_(PHY_CONFIGDELAY);
}
/* ETH_MAC_CFR Configuration */
/* Get the ETH_MAC_CFR value */
temp = ETH_MAC->CFR;
temp &= MAC_CFR_CLEAR_MASK;
/* Set the WDD bit according to ETH_MAC_Watchdog value */
/* Set the JBD: bit according to ETH_MAC_Jabber value */
/* Set the IG bit according to ETH_MAC_InterFrameGap value */
/* Set the CSD bit according to ETH_MAC_CarrierSense value */
/* Set the SPD bit according to ETH_MAC_Speed value */
/* Set the ROD bit according to ETH_MAC_ReceiveOwn value */
/* Set the LBM bit according to ETH_MAC_LoopbackMode value */
/* Set the DPM bit according to ETH_MAC_Mode value */
/* Set the IP4CO bit according to ETH_MAC_ChecksumOffload value */
/* Set the RTD bit according to ETH_MAC_RetryTransmission value */
/* Set the APCD bit according to ETH_MAC_AutomaticPadCRCDrop value */
/* Set the BOL bit according to ETH_MAC_BackOffLimit value */
/* Set the DFC bit according to ETH_MAC_DeferralCheck value */
temp |= (uint32_t)(ETH_InitParaStruct->ETH_MAC_Watchdog |
ETH_InitParaStruct->ETH_MAC_Jabber |
ETH_InitParaStruct->ETH_MAC_InterFrameGap |
ETH_InitParaStruct->ETH_MAC_CarrierSense |
ETH_InitParaStruct->ETH_MAC_Speed |
ETH_InitParaStruct->ETH_MAC_ReceiveOwn |
ETH_InitParaStruct->ETH_MAC_LoopbackMode |
ETH_InitParaStruct->ETH_MAC_Mode |
ETH_InitParaStruct->ETH_MAC_ChecksumOffload |
ETH_InitParaStruct->ETH_MAC_RetryTransmission |
ETH_InitParaStruct->ETH_MAC_AutomaticPadCRCDrop |
ETH_InitParaStruct->ETH_MAC_BackOffLimit |
ETH_InitParaStruct->ETH_MAC_DeferralCheck);
/* Write to ETH_MAC_CFR */
ETH_MAC->CFR = (uint32_t)temp;
/* ETH_MAC_FRMFR Configuration */
/* Set the FD bit according to ETH_MAC_FilterDisable value */
/* Set the SAFLT and SAIFLT bits according to ETH_MAC_SourceAddrFilter value */
/* Set the PCFRM bit according to ETH_MAC_PassControlFrames value */
/* Set the DBF bit according to ETH_MAC_BroadcastFramesReception value */
/* Set the DAIFLT bit according to ETH_MAC_DestinationAddrFilter value */
/* Set the PM bit according to ETH_MAC_PromiscuousMode value */
/* Set the PM, HMF and HPFLT bits according to ETH_MAC_MulticastFramesFilter value */
/* Set the HUF and HPFLT bits according to ETH_MAC_UnicastFramesFilter value */
/* Write to ETH_MAC_FRMFR */
ETH_MAC->FRMFR = (uint32_t)(ETH_InitParaStruct->ETH_MAC_FilterDisable |
ETH_InitParaStruct->ETH_MAC_SourceAddrFilter |
ETH_InitParaStruct->ETH_MAC_PassControlFrames |
ETH_InitParaStruct->ETH_MAC_BroadcastFramesReception |
ETH_InitParaStruct->ETH_MAC_DestinationAddrFilter |
ETH_InitParaStruct->ETH_MAC_PromiscuousMode |
ETH_InitParaStruct->ETH_MAC_MulticastFramesFilter |
ETH_InitParaStruct->ETH_MAC_UnicastFramesFilter);
/* ETH_MAC_HLHR and MAC_HLLR Configuration */
/* Write to ETHERNET MAC_HLHR */
ETH_MAC->HLHR = (uint32_t)ETH_InitParaStruct->ETH_MAC_HashListHigh;
/* Write to ETHERNET MAC_HLLR */
ETH_MAC->HLLR = (uint32_t)ETH_InitParaStruct->ETH_MAC_HashListLow;
/* ETH_MAC_FCTLR Configuration */
/* Get the ETH_MAC_FCTLR value */
temp = ETH_MAC->FCTLR;
temp &= MAC_FCTLR_CLEAR_MASK;
/* Set the PTM bit according to ETH_MAC_PauseTime value */
/* Set the ZQPD bit according to ETH_MAC_ZeroQuantaPause value */
/* Set the PLTS bit according to ETH_MAC_PauseLowThreshold value */
/* Set the UPFDT bit according to ETH_MAC_UnicastPauseFrameDetect value */
/* Set the RFCEN bit according to ETH_MAC_ReceiveFlowControl value */
/* Set the TFCEN bit according to ETH_MAC_TransmitFlowControl value */
temp |= (uint32_t)((ETH_InitParaStruct->ETH_MAC_PauseTime << 16) |
ETH_InitParaStruct->ETH_MAC_ZeroQuantaPause |
ETH_InitParaStruct->ETH_MAC_PauseLowThreshold |
ETH_InitParaStruct->ETH_MAC_UnicastPauseFrameDetect |
ETH_InitParaStruct->ETH_MAC_ReceiveFlowControl |
ETH_InitParaStruct->ETH_MAC_TransmitFlowControl);
/* Write to ETH_MAC_FCTLR */
ETH_MAC->FCTLR = (uint32_t)temp;
/* ETH_MAC_FCTHR Configuration */
temp = ETH_MAC->FCTHR;
temp |= (uint32_t)(ETH_InitParaStruct->ETH_MAC_FlowControlDeactiveThreshold |
ETH_InitParaStruct->ETH_MAC_FlowControlActiveThreshold);
ETH_MAC->FCTHR = (uint32_t)temp;
/* ETH_MAC_VLTR Configuration */
/* Set the VLTC bit according to ETH_MAC_VLANTagComparison value */
/* Set the VLTI bit according to ETH_MAC_VLANTagIdentifier value */
ETH_MAC->VLTR = (uint32_t)(ETH_InitParaStruct->ETH_MAC_VLANTagComparison |
ETH_InitParaStruct->ETH_MAC_VLANTagIdentifier);
/* DMA Config */
/* ETH_DMA_CTLR Configuration */
/* Get the ETHERNET DMA_CTLR value */
temp = ETH_DMA->CTLR;
temp &= DMA_CTLR_CLEAR_MASK;
/* Set the DTCERFD bit according to ETH_DMA_DropTCPIPChecksumErrorFrame value */
/* Set the RSFD bit according to ETH_DMA_ReceiveStoreForward value */
/* Set the DAFRF bit according to ETH_DMA_FlushReceivedFrame value */
/* Set the TSFD bit according to ETH_DMA_TransmitStoreForward value */
/* Set the TTCH bit according to ETH_DMA_TransmitThresholdControl value */
/* Set the FERF bit according to ETH_DMA_ForwardErrorFrames value */
/* Set the FUF bit according to ETH_DMA_ForwardUndersizedGoodFrames value */
/* Set the RTHC bit according to ETH_DMA_ReceiveThresholdControl value */
/* Set the OSF bit according to ETH_DMA_SecondFrameOperate value */
temp |= (uint32_t)(ETH_InitParaStruct->ETH_DMA_DropTCPIPChecksumErrorFrame |
ETH_InitParaStruct->ETH_DMA_ReceiveStoreForward |
ETH_InitParaStruct->ETH_DMA_FlushReceivedFrame |
ETH_InitParaStruct->ETH_DMA_TransmitStoreForward |
ETH_InitParaStruct->ETH_DMA_TransmitThresholdControl |
ETH_InitParaStruct->ETH_DMA_ForwardErrorFrames |
ETH_InitParaStruct->ETH_DMA_ForwardUndersizedGoodFrames |
ETH_InitParaStruct->ETH_DMA_ReceiveThresholdControl |
ETH_InitParaStruct->ETH_DMA_SecondFrameOperate);
/* Write to ETH_DMA_CTLR */
ETH_DMA->CTLR = (uint32_t)temp;
/* ETH_DMA_BCR Configuration */
/* Set the AA bit according to ETH_DMA_AddressAligned value */
/* Set the FB bit according to ETH_DMA_FixedBurst value */
/* Set the RXDP and 4*PBL bits according to ETH_DMA_RxDMABurstLength value */
/* Set the FPBL and 4*PBL bits according to ETH_DMA_TxDMABurstLength value */
/* Set the DPSL bit according to ETH_DesciptorSkipLength value */
/* Set the RTPR and DAB bits according to ETH_DMA_Arbitration value */
ETH_DMA->BCR = (uint32_t)(ETH_InitParaStruct->ETH_DMA_AddressAligned |
ETH_InitParaStruct->ETH_DMA_FixedBurst |
ETH_InitParaStruct->ETH_DMA_RxDMABurstLength | /* If 4xPBL is selected for Tx or Rx it is applied for the other */
ETH_InitParaStruct->ETH_DMA_TxDMABurstLength |
(ETH_InitParaStruct->ETH_DMA_DescriptorSkipLength << 2) |
ETH_InitParaStruct->ETH_DMA_Arbitration |
ETH_DMA_BCR_UIP); /* Enable use of separate PBL for Rx and Tx */
/* Return Ethernet configuration success */
return SUCCESS;
}
/**
* @brief Initial the sturct ETH_InitPara.
* @param ETH_InitParaStruct: pointer to a ETH_InitPara structure.
* @retval None
*/
void ETH_ParaInit(ETH_InitPara *ETH_InitParaStruct)
{
/* Reset ETH init structure parameters values */
/* MAC */
ETH_InitParaStruct->ETH_MAC_AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE;
ETH_InitParaStruct->ETH_MAC_Watchdog = ETH_WATCHDOG_ENABLE;
ETH_InitParaStruct->ETH_MAC_Jabber = ETH_JABBER_ENABLE;
ETH_InitParaStruct->ETH_MAC_InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
ETH_InitParaStruct->ETH_MAC_CarrierSense = ETH_CARRIERSENSE_ENABLE;
ETH_InitParaStruct->ETH_MAC_Speed = ETH_SPEEDMODE_10M;
ETH_InitParaStruct->ETH_MAC_ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
ETH_InitParaStruct->ETH_MAC_LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
ETH_InitParaStruct->ETH_MAC_Mode = ETH_MODE_HALFDUPLEX;
ETH_InitParaStruct->ETH_MAC_ChecksumOffload = ETH_CHECKSUMOFFLOAD_DISABLE;
ETH_InitParaStruct->ETH_MAC_RetryTransmission = ETH_RETRYTRANSMISSION_ENABLE;
ETH_InitParaStruct->ETH_MAC_AutomaticPadCRCDrop = ETH_AUTOMATICPADCRCDROP_DISABLE;
ETH_InitParaStruct->ETH_MAC_BackOffLimit = ETH_BACKOFFLIMIT_10;
ETH_InitParaStruct->ETH_MAC_DeferralCheck = ETH_DEFERRALCHECK_DISABLE;
ETH_InitParaStruct->ETH_MAC_FilterDisable = ETH_FILTERDISABLE_DISABLE;
ETH_InitParaStruct->ETH_MAC_SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
ETH_InitParaStruct->ETH_MAC_PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
ETH_InitParaStruct->ETH_MAC_BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE;
ETH_InitParaStruct->ETH_MAC_DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
ETH_InitParaStruct->ETH_MAC_PromiscuousMode = ETH_PROMISCUOUSMODE_DISABLE;
ETH_InitParaStruct->ETH_MAC_MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
ETH_InitParaStruct->ETH_MAC_UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
ETH_InitParaStruct->ETH_MAC_HashListHigh = 0x0;
ETH_InitParaStruct->ETH_MAC_HashListLow = 0x0;
ETH_InitParaStruct->ETH_MAC_PauseTime = 0x0;
ETH_InitParaStruct->ETH_MAC_ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
ETH_InitParaStruct->ETH_MAC_PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
ETH_InitParaStruct->ETH_MAC_FlowControlDeactiveThreshold = ETH_RFD_512BYTES;
ETH_InitParaStruct->ETH_MAC_FlowControlActiveThreshold = ETH_RFA_1536BYTES;
ETH_InitParaStruct->ETH_MAC_UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
ETH_InitParaStruct->ETH_MAC_ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
ETH_InitParaStruct->ETH_MAC_TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
ETH_InitParaStruct->ETH_MAC_VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
ETH_InitParaStruct->ETH_MAC_VLANTagIdentifier = 0x0;
/* DMA */
ETH_InitParaStruct->ETH_DMA_DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE;
ETH_InitParaStruct->ETH_DMA_ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
ETH_InitParaStruct->ETH_DMA_FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_DISABLE;
ETH_InitParaStruct->ETH_DMA_TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
ETH_InitParaStruct->ETH_DMA_TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
ETH_InitParaStruct->ETH_DMA_ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
ETH_InitParaStruct->ETH_DMA_ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
ETH_InitParaStruct->ETH_DMA_ReceiveThresholdControl = ETH_RECEIVETHRESHOLDCONTROL_64BYTES;
ETH_InitParaStruct->ETH_DMA_SecondFrameOperate = ETH_SECONDFRAMEOPERATE_DISABLE;
ETH_InitParaStruct->ETH_DMA_AddressAligned = ETH_ADDRESSALIGNED_ENABLE;
ETH_InitParaStruct->ETH_DMA_FixedBurst = ETH_FIXEDBURST_DISABLE;
ETH_InitParaStruct->ETH_DMA_RxDMABurstLength = ETH_RXDMABURSTLENGTH_1BEAT;
ETH_InitParaStruct->ETH_DMA_TxDMABurstLength = ETH_TXDMABURSTLENGTH_1BEAT;
ETH_InitParaStruct->ETH_DMA_DescriptorSkipLength = 0x0;
ETH_InitParaStruct->ETH_DMA_Arbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
}
/**
* @brief Enable or disable the ETH's receive and transmit.
* @param NewValue: ENABLE or DISABLE.
* @retval None
*/
void ETH_Enable(TypeState NewValue)
{
/* Enable or Disable the ETH module */
if (NewValue != DISABLE) {
/* Enable MAC transmit */
ETH_MACTransmission_Enable(ENABLE);
/* Flush ETHERNET DMA Transmit FIFO */
ETH_CleanTransmitFIFO();
/* Enable MAC receive */
ETH_MACReception_Enable(ENABLE);
/* Enable DMA transmission */
ETH_DMATransmission_Enable(ENABLE);
/* Enable DMA reception */
ETH_DMAReception_Enable(ENABLE);
} else {
/* Disable MAC transmit */
ETH_MACTransmission_Enable(DISABLE);
/* Flush ETHERNET DMA Transmit FIFO */
ETH_CleanTransmitFIFO();
/* Disable MAC receive */
ETH_MACReception_Enable(DISABLE);
/* Disable DMA transmission */
ETH_DMATransmission_Enable(DISABLE);
/* Disable DMA reception */
ETH_DMAReception_Enable(DISABLE);
}
}
/**
* @brief Send data of application buffer as a transmit packet.
* @param pbuf: Pointer to the application buffer.
* @param size: the application buffer size.
* @retval The transmission result(ERROR or SUCCESS)
*/
uint32_t ETH_HandleTxPkt(uint8_t *pbuf, uint16_t size)
{
uint32_t offset = 0;
/* Check the busy bit of Tx descriptor status */
if ((DMACurrentTxDesc->Status & ETH_DMATXDESC_BUSY) != (uint32_t)RESET) {
/* Return ERROR: the descriptor is busy due to own by the DMA */
return ERROR;
}
for (offset = 0; offset < size; offset++) {
(*(__IO uint8_t *)((DMACurrentTxDesc->Buffer1Addr) + offset)) = (*(pbuf + offset));
}
/* Setting the Frame Length */
DMACurrentTxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TB1S);
/* Setting the segment of frame (ETH_DMATXDESC_LSG and ETH_DMATXDESC_FSG are SET that frame is transmitted in one descriptor) */
DMACurrentTxDesc->Status |= ETH_DMATXDESC_LSG | ETH_DMATXDESC_FSG;
/* Enable the DMA transmission */
DMACurrentTxDesc->Status |= ETH_DMATXDESC_BUSY;
/* Check Tx Buffer unavailable flag status */
if ((ETH_DMA->STR & ETH_DMA_STR_TBU) != (uint32_t)RESET) {
/* Clear TBU ETHERNET DMA flag */
ETH_DMA->STR = ETH_DMA_STR_TBU;
/* Resume DMA transmission by writing to the TPER register*/
ETH_DMA->TPER = 0;
}
/* Update the ETHERNET DMA current Tx descriptor pointer to the next Tx decriptor in DMA Tx decriptor talbe*/
/* Chained Mode */
if ((DMACurrentTxDesc->Status & ETH_DMATXDESC_TCHM) != (uint32_t)RESET) {
DMACurrentTxDesc = (ETH_DMADESCTypeDef *)(DMACurrentTxDesc->Buffer2NextDescAddr);
}
/* Ring Mode */
else {
if ((DMACurrentTxDesc->Status & ETH_DMATXDESC_TERM) != (uint32_t)RESET) {
DMACurrentTxDesc = (ETH_DMADESCTypeDef *)(ETH_DMA->TDTAR);
} else {
DMACurrentTxDesc = (ETH_DMADESCTypeDef *)((uint32_t)DMACurrentTxDesc + ETH_DMATXDESC_SIZE + ((ETH_DMA->BCR & ETH_DMA_BCR_DPSL) >> 2));
}
}
/* Return SUCCESS */
return SUCCESS;
}
/**
* @brief Receive a packet data to application buffer.
* @param pbuf: Pointer on the application buffer.
* @retval The Receive size(If framelength is equal to ERROR, the receiving unsuccessful)
*/
uint32_t ETH_HandleRxPkt(uint8_t *pbuf)
{
uint32_t offset = 0, size = 0;
/* Check the busy bit of Rx descriptor status */
if ((DMACurrentRxDesc->Status & ETH_DMARXDESC_BUSY) != (uint32_t)RESET) {
/* Return ERROR: the descriptor is busy due to own by the DMA */
return ERROR;
}
if (((DMACurrentRxDesc->Status & ETH_DMARXDESC_ERRS) == (uint32_t)RESET) &&
((DMACurrentRxDesc->Status & ETH_DMARXDESC_LDES) != (uint32_t)RESET) &&
((DMACurrentRxDesc->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET)) {
/* Get the Frame Length exclusive CRC */
size = ((DMACurrentRxDesc->Status & ETH_DMARXDESC_FRML) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT) - 4;
for (offset = 0; offset < size; offset++) {
(*(pbuf + offset)) = (*(__IO uint8_t *)((DMACurrentRxDesc->Buffer1Addr) + offset));
}
} else {
/* Return ERROR */
size = ERROR;
}
/* Enable reception */
DMACurrentRxDesc->Status = ETH_DMARXDESC_BUSY;
/* Check Rx Buffer unavailable flag status */
if ((ETH_DMA->STR & ETH_DMA_STR_RBU) != (uint32_t)RESET) {
/* Clear RBU ETHERNET DMA flag */
ETH_DMA->STR = ETH_DMA_STR_RBU;
/* Resume DMA reception by writing to the RPER register*/
ETH_DMA->RPER = 0;
}
/* Update the ETHERNET DMA current Rx descriptor pointer to the next Rx decriptor in DMA Rx decriptor talbe*/
/* Chained Mode */
if ((DMACurrentRxDesc->ControlBufferSize & ETH_DMARXDESC_RCHM) != (uint32_t)RESET) {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)(DMACurrentRxDesc->Buffer2NextDescAddr);
}
/* Ring Mode */
else {
if ((DMACurrentRxDesc->ControlBufferSize & ETH_DMARXDESC_RERR) != (uint32_t)RESET) {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)(ETH_DMA->RDTAR);
} else {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)((uint32_t)DMACurrentRxDesc + ETH_DMARXDESC_SIZE + ((ETH_DMA->BCR & ETH_DMA_BCR_DPSL) >> 2));
}
}
/* Return Frame size or ERROR */
return (size);
}
/**
* @brief To obtain the received data length
* @param None
* @retval Received frame length.
*/
uint32_t ETH_GetRxPktSize(void)
{
uint32_t size = 0;
if ((DMACurrentRxDesc->Status & ETH_DMARXDESC_BUSY) != (uint32_t)RESET) {
return 0;
}
if (((DMACurrentRxDesc->Status & ETH_DMARXDESC_ERRS) != (uint32_t)RESET) ||
((DMACurrentRxDesc->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET) ||
((DMACurrentRxDesc->Status & ETH_DMARXDESC_FDES) == (uint32_t)RESET)) {
ETH_DropRxPkt();
return 0;
}
if (((DMACurrentRxDesc->Status & ETH_DMARXDESC_BUSY) == (uint32_t)RESET) &&
((DMACurrentRxDesc->Status & ETH_DMARXDESC_ERRS) == (uint32_t)RESET) &&
((DMACurrentRxDesc->Status & ETH_DMARXDESC_LDES) != (uint32_t)RESET) &&
((DMACurrentRxDesc->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET)) {
/* Get the size of the received data including CRC */
size = ETH_GetDMARxDescFrameLength(DMACurrentRxDesc);
}
/* Return Packet size */
return size;
}
/**
* @brief Discard a Received packet
* @param None
* @retval None
*/
void ETH_DropRxPkt(void)
{
/* Enable reception */
DMACurrentRxDesc->Status = ETH_DMARXDESC_BUSY;
/* Chained Mode */
if ((DMACurrentRxDesc->ControlBufferSize & ETH_DMARXDESC_RCHM) != (uint32_t)RESET) {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)(DMACurrentRxDesc->Buffer2NextDescAddr);
}
/* Ring Mode */
else {
if ((DMACurrentRxDesc->ControlBufferSize & ETH_DMARXDESC_RERM) != (uint32_t)RESET) {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)(ETH_DMA->RDTAR);
} else {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)((uint32_t)DMACurrentRxDesc + ETH_DMARXDESC_SIZE + ((ETH_DMA->BCR & ETH_DMA_BCR_DPSL) >> 2));
}
}
}
/* PHY */
/**
* @brief Get PHY of ETHERNET parameters.
* @param PHYAddr: PHY device address, devices number max is 32.
* @param PHYReg: PHY register address, register address max is 32.
* Select one of the follwing values :
* @arg PHY_BCR: Tranceiver Basic Control Register
* @arg PHY_BSR: Tranceiver Basic Status Register
* @arg PHY_SR : Tranceiver Status Register
* @arg More PHY register could be read depending on the used PHY
* @retval value read from the selected PHY register (if timeout return ERROR)
*/
uint16_t ETH_GetPHYRegisterValue(uint16_t PHYAddr, uint16_t PHYReg)
{
uint32_t temp = 0;
__IO uint32_t timeout = 0;
/* Get the ETHERNET MAC_PHYAR value */
temp = ETH_MAC->PHYAR;
temp &= ~MAC_PHYAR_CLR_MASK;
/* Configuration the PHY address register value */
/* Set the PHY device address */
temp |= (((uint32_t)PHYAddr << MAC_PHYAR_PHYADDRSHIFT) & ETH_MAC_PHYAR_PA);
/* Set the PHY register address */
temp |= (((uint32_t)PHYReg << MAC_PHYAR_PHYREGSHIFT) & ETH_MAC_PHYAR_PR);
/* Set the read mode */
temp &= ~ETH_MAC_PHYAR_PW;
/* Set the PHY Busy bit */
temp |= ETH_MAC_PHYAR_PB;
ETH_MAC->PHYAR = temp;
/* Check the PHY Busy flag status */
do {
timeout++;
temp = ETH_MAC->PHYAR;
} while ((temp & ETH_MAC_PHYAR_PB) && (timeout < (uint32_t)PHY_READ_TO));
/* Return ERROR due to timeout */
if (timeout == PHY_READ_TO) {
return (uint16_t)ERROR;
}
/* Return PHY register selected value */
return (uint16_t)(ETH_MAC->PHYDR);
}
/**
* @brief Set PHY of ETHERNET parameters.
* @param PHYAddr: PHY device address, devices number max is 32.
* @param PHYReg: PHY register address, register address max is 32.
* Select one of the follwing values :
* @arg PHY_BCR : Tranceiver Control Register
* @arg More PHY register could be written depending on the used PHY
* @param PHYValue: write to register value
* @retval The Write to the selected PHY register result(ERROR or SUCCESS)
*/
uint32_t ETH_SetPHYRegisterValue(uint16_t PHYAddr, uint16_t PHYReg, uint16_t PHYValue)
{
uint32_t temp = 0;
__IO uint32_t timeout = 0;
/* Get the ETHERNET MAC_PHYAR value */
temp = ETH_MAC->PHYAR;
temp &= ~MAC_PHYAR_CLR_MASK;
/* Configuration the PHY register address value */
/* Set the PHY device address */
temp |= (((uint32_t)PHYAddr << MAC_PHYAR_PHYADDRSHIFT) & ETH_MAC_PHYAR_PA);
/* Set the PHY register address */
temp |= (((uint32_t)PHYReg << MAC_PHYAR_PHYREGSHIFT) & ETH_MAC_PHYAR_PR);
/* Set the write mode */
temp |= ETH_MAC_PHYAR_PW;
/* Set the PHY Busy bit */
temp |= ETH_MAC_PHYAR_PB;
/* Set the PHY selected register value */
ETH_MAC->PHYDR = PHYValue;
ETH_MAC->PHYAR = temp;
/* Check the PHY Busy flag status */
do {
timeout++;
temp = ETH_MAC->PHYAR;
} while ((temp & ETH_MAC_PHYAR_PB) && (timeout < (uint32_t)PHY_WRITE_TO));
/* Return ERROR due to timeout */
if (timeout == PHY_WRITE_TO) {
return ERROR;
}
return SUCCESS;
}
/**
* @brief Enable or disable the PHY loopBack function by write PHY register.
* @param PHYAddr: PHY device address, devices number max is 32.
* @param NewValue: new value of the PHY loopBack mode.
* This parameter can be: ENABLE or DISABLE.
* @retval The Set PHYLoopBack mode result(ERROR or SUCCESS)
*/
uint32_t ETH_PHYLoopBack_Enable(uint16_t PHYAddr, TypeState NewValue)
{
uint16_t temp = 0;
/* Get the PHY BCR register value */
temp = ETH_GetPHYRegisterValue(PHYAddr, PHY_BCR);
if (NewValue != DISABLE) {
/* Enable the PHY loopback mode */
temp |= PHY_LOOPBACK;
} else {
/* Disable the PHY loopback mode (change to normal mode) */
temp &= (uint16_t)(~(uint16_t)PHY_LOOPBACK);
}
/* Set the PHY BCR register with the new value */
if (ETH_SetPHYRegisterValue(PHYAddr, PHY_BCR, temp) != (uint32_t)RESET) {
return SUCCESS;
} else {
return ERROR;
}
}
/* MAC */
/**
* @brief Enable or disable the MAC transmit function.
* @param NewValue: new value of the MAC transmit function.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACTransmission_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the MAC transmission */
ETH_MAC->CFR |= ETH_MAC_CFR_TEN;
} else {
/* Disable the MAC transmission */
ETH_MAC->CFR &= ~ETH_MAC_CFR_TEN;
}
}
/**
* @brief Enable or disable the MAC receive function.
* @param NewValue: new value of the MAC reception.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACReception_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the MAC reception */
ETH_MAC->CFR |= ETH_MAC_CFR_REN;
} else {
/* Disable the MAC reception */
ETH_MAC->CFR &= ~ETH_MAC_CFR_REN;
}
}
/**
* @brief Get the bit flag of the ETHERNET flow control busy status.
* @param None
* @retval current flow control busy bit status
*/
TypeState ETH_GetFlowControlBusyBitState(void)
{
/* Check the flow control busy bit status */
if ((ETH_MAC->FCTLR & ETH_MAC_FCTLR_FLCBBKPA) != (uint32_t)RESET) {
return SET;
} else {
return RESET;
}
}
/**
* @brief Initiate a Pause Frame in Full-duplex mode only.
* @param None
* @retval None
*/
void ETH_PauseFrameInit(void)
{
/* Initiate pause control frame in full duplex mode*/
ETH_MAC->FCTLR |= ETH_MAC_FCTLR_FLCBBKPA;
}
/**
* @brief Enable or disable the BackPressure requests in Half-duplex only.
* @param NewValue: new value of the BackPressure operation requests.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_BackPressureActivation_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the BackPressure requests */
ETH_MAC->FCTLR |= ETH_MAC_FCTLR_FLCBBKPA;
} else {
/* Disable the BackPressure requests */
ETH_MAC->FCTLR &= ~ETH_MAC_FCTLR_FLCBBKPA;
}
}
/**
* @brief Get the status flag of ETH_MAC_ISR register.
* @param ETH_MAC_FLAG: the status flag of ETH_MAC_ISR register.
* Select one of the follwing values :
* @arg ETH_MAC_FLAG_TST : Time stamp trigger flag
* @arg ETH_MAC_FLAG_MSCT : MSC transmit flag
* @arg ETH_MAC_FLAG_MSCR : MSC receive flag
* @arg ETH_MAC_FLAG_MSC : MSC flag
* @arg ETH_MAC_FLAG_WUM : WUM flag
* @retval The current MAC bit selected status(SET or RESET).
*/
TypeState ETH_GetMACBitState(uint32_t ETH_MAC_FLAG)
{
/* Check the ETH_MAC_FLAG status */
if ((ETH_MAC->ISR & ETH_MAC_FLAG) != (uint32_t)RESET) {
return SET;
} else {
return RESET;
}
}
/**
* @brief Get the interrupt flag of ETH_MAC_ISR register.
* @param ETH_MAC_INT: the interrupt flag of ETH_MAC_ISR register.
* Select one of the follwing values :
* @arg ETH_MAC_INT_TST : Time stamp trigger interrupt
* @arg ETH_MAC_INT_MSCT : MSC transmit interrupt
* @arg ETH_MAC_INT_MSCR : MSC receive interrupt
* @arg ETH_MAC_INT_MSC : MSC interrupt
* @arg ETH_MAC_INT_WUM : WUM interrupt
* @retval The current MAC interrupt bit selected status(SET or RESET).
*/
TypeState ETH_GetMACIntBitState(uint32_t ETH_MAC_INT)
{
/* Check the ETH_MAC_INT status */
if ((ETH_MAC->ISR & ETH_MAC_INT) != (uint32_t)RESET) {
return SET;
} else {
return RESET;
}
}
/**
* @brief Enable or disable the ETH_MAC_INT control bit.
* @param ETH_MAC_INT: the interrupt bit flag.
* Select one of the follwing values :
* @arg ETH_MAC_INT_TST : Time stamp trigger interrupt
* @arg ETH_MAC_INT_WUM : WUM interrupt
* @param NewValue: new value of the ETH_MAC_INT value.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACINTConfig(uint32_t ETH_MAC_INT, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the MAC interrupt */
ETH_MAC->IMR &= (~(uint32_t)ETH_MAC_INT);
} else {
/* Disable the MAC interrupt */
ETH_MAC->IMR |= ETH_MAC_INT;
}
}
/**
* @brief Set the MAC address to MAC address register selected.
* @param addr: The MAC address register to selected.
* Select one of the follwing values :
* @arg ETH_MAC_ADDRESS0 : MAC Address0
* @arg ETH_MAC_ADDRESS1 : MAC Address1
* @arg ETH_MAC_ADDRESS2 : MAC Address2
* @arg ETH_MAC_ADDRESS3 : MAC Address3
* @param buf: Pointer to application MAC address buffer(6 bytes).
* @retval None
*/
void ETH_SetMACAddress(uint32_t addr, uint8_t *buf)
{
uint32_t temp;
temp = ((uint32_t)buf[5] << 8) | (uint32_t)buf[4];
/* Set the selectecd MAC address high register */
(*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr)) = temp;
temp = ((uint32_t)buf[3] << 24) | ((uint32_t)buf[2] << 16) | ((uint32_t)buf[1] << 8) | buf[0];
/* Set the selectecd MAC address low register */
(*(__IO uint32_t *)(ETH_MAC_ADDR_LBASE + addr)) = temp;
}
/**
* @brief Get the MAC address from MAC address register selected.
* @param addr: The MAC addres to selected.
* Select one of the follwing values :
* @arg ETH_MAC_ADDRESS0 : MAC Address0
* @arg ETH_MAC_ADDRESS1 : MAC Address1
* @arg ETH_MAC_ADDRESS2 : MAC Address2
* @arg ETH_MAC_ADDRESS3 : MAC Address3
* @param buf: Pointer to application MAC address buffer(6 bytes).
* @retval None
*/
void ETH_GetMACAddress(uint32_t addr, uint8_t *buf)
{
uint32_t temp;
/* Get the selectecd MAC address high register */
temp = (*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr));
buf[5] = ((temp >> 8) & (uint8_t)0xFF);
buf[4] = (temp & (uint8_t)0xFF);
/* Get the selectecd MAC address low register */
temp = (*(__IO uint32_t *)(ETH_MAC_ADDR_LBASE + addr));
buf[3] = ((temp >> 24) & (uint8_t)0xFF);
buf[2] = ((temp >> 16) & (uint8_t)0xFF);
buf[1] = ((temp >> 8) & (uint8_t)0xFF);
buf[0] = (temp & (uint8_t)0xFF);
}
/**
* @brief Enable or disable the Address perfect filtering.
* @param addr: the MAC address register selected for prfect filtering.
* Select one of the follwing values :
* @arg ETH_MAC_ADDRESS1 : MAC Address1
* @arg ETH_MAC_ADDRESS2 : MAC Address2
* @arg ETH_MAC_ADDRESS3 : MAC Address3
* @param NewValue: new value of the MAC address register selected for perfect filtering.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MACAddressPerfectFilter_Enable(uint32_t addr, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the perfect filtering to the MAC address register selected */
(*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr)) |= ETH_MAC_A1HR_AFE;
} else {
/* Disable the perfect filtering to the MAC address register selected */
(*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr)) &= (~(uint32_t)ETH_MAC_A1HR_AFE);
}
}
/**
* @brief Set the selected MAC address filter type mode.
* @param addr: the MAC address to be used for filtering.
* Select one of the follwing values :
* @arg ETH_MAC_ADDRESS1 : MAC Address1
* @arg ETH_MAC_ADDRESS2 : MAC Address2
* @arg ETH_MAC_ADDRESS3 : MAC Address3
* @param Filterfield: the mode of receiving field for comparaison
* Select one of the follwing values :
* @arg ETH_MAC_ADDRESSFILTER_SA : Compare with the SA fields of the received frame.
* @arg ETH_MAC_ADDRESSFILTER_DA : Compare with the DA fields of the received frame.
* @retval None
*/
void ETH_MACAddressFilterConfig(uint32_t addr, uint32_t Filterfield)
{
if (Filterfield != ETH_MAC_ADDRESSFILTER_DA) {
/* Compare with the SA fields of the received frame. */
(*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr)) |= ETH_MAC_A1HR_SAF;
} else {
/* compare with the DA fields of the received frame. */
(*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr)) &= (~(uint32_t)ETH_MAC_A1HR_SAF);
}
}
/**
* @brief Set the selected MAC address filter maskbyte.
* @param addr: the MAC address to be used for filtering
* Select one of the follwing values :
* @arg ETH_MAC_ADDRESS1 : MAC Address1
* @arg ETH_MAC_ADDRESS2 : MAC Address2
* @arg ETH_MAC_ADDRESS3 : MAC Address3
* @param addrmask: the address bytes be selected for address filtering comparaison
* Select one of the follwing values :
* @arg ETH_MAC_ADDRESSMASK_BYTE6 : Mask MAC Address high register bits [15:8].
* @arg ETH_MAC_ADDRESSMASK_BYTE5 : Mask MAC Address high register bits [7:0].
* @arg ETH_MAC_ADDRESSMASK_BYTE4 : Mask MAC Address low register bits [31:24].
* @arg ETH_MAC_ADDRESSMASK_BYTE3 : Mask MAC Address low register bits [23:16].
* @arg ETH_MAC_ADDRESSMASK_BYTE2 : Mask MAC Address low register bits [15:8].
* @arg ETH_MAC_ADDRESSMASK_BYTE1 : Mask MAC Address low register bits [7:0].
* @retval None
*/
void ETH_MACAddressFilterMaskBytesConfig(uint32_t addr, uint32_t addrmask)
{
/* Clear the MB bit of selected MAC address */
(*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr)) &= (~(uint32_t)ETH_MAC_A1HR_MB);
/* Set the mask bytes of selected Filetr */
(*(__IO uint32_t *)(ETH_MAC_ADDR_HBASE + addr)) |= addrmask;
}
/* DMA Tx/Rx Desciptors */
/**
* @brief Initialize the DMA Tx descriptors's parameters in chain mode.
* @param DMATxDescTab: Pointer to the first Tx descriptor table
* @param pTxBuff: Pointer to the first TxBuffer table
* @param TxBuffCnt: the used Tx desc num in the table
* @retval None
*/
void ETH_DMATxDescChainModeInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t *pTxBuff, uint32_t TxBuffCnt)
{
uint32_t num = 0;
ETH_DMADESCTypeDef *DMATxDesc;
DMACurrentTxDesc = DMATxDescTab;
/* Configuration each DMATxDesc descriptor */
for (num = 0; num < TxBuffCnt; num++) {
/* Get the pointer to the next descriptor of the Tx Desc table */
DMATxDesc = DMATxDescTab + num;
/* Set TCH bit with desc status */
DMATxDesc->Status = ETH_DMATXDESC_TCHM;
/* Set Buffer1 address pointer to application buffer */
DMATxDesc->Buffer1Addr = (uint32_t)(&pTxBuff[num * ETH_MAX_FRAME_SIZE]);
if (num < (TxBuffCnt - 1)) {
/* Buffer2NextDescAddr equal to next descriptor address in the Tx Desc table */
DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + num + 1);
} else {
/* When it is the last descriptor, Buffer2NextDescAddr equal to first descriptor address in the Tx Desc table */
DMATxDesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
}
}
ETH_DMA->TDTAR = (uint32_t) DMATxDescTab;
}
/**
* @brief Initialize the DMA Tx descriptors's parameters in ring mode.
* @param DMATxDescTab: Pointer to the first Tx descriptor table
* @param pTxBuff1: Pointer to the first TxBuffer1 table
* @param pTxBuff2: Pointer to the first TxBuffer2 table
* @param TxBuffCnt: the used Tx desc num in the table
* @retval None
*/
void ETH_DMATxDescRingModeInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t *pTxBuff1, uint8_t *pTxBuff2, uint32_t TxBuffCnt)
{
uint32_t num = 0;
ETH_DMADESCTypeDef *DMATxDesc;
DMACurrentTxDesc = DMATxDescTab;
/* Configuration each DMATxDesc descriptor */
for (num = 0; num < TxBuffCnt; num++) {
/* Get the pointer to the next descriptor of the Tx Desc table */
DMATxDesc = DMATxDescTab + num;
/* Set Buffer1 address pointer to application buffer1 */
DMATxDesc->Buffer1Addr = (uint32_t)(&pTxBuff1[num * ETH_MAX_FRAME_SIZE]);
/* Set Buffer2 address pointer to application buffer2 */
DMATxDesc->Buffer2NextDescAddr = (uint32_t)(&pTxBuff2[num * ETH_MAX_FRAME_SIZE]);
if (num == (TxBuffCnt - 1)) {
/* Set ETH_DMATXDESC_TERM bit as transmitting End */
DMATxDesc->Status = ETH_DMATXDESC_TERM;
}
}
ETH_DMA->TDTAR = (uint32_t) DMATxDescTab;
}
/**
* @brief Get the bit flag of ETHERNET DMA Tx Desc.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @param ETH_DMATxDescFlag: the flag of Tx descriptor status.
* Select one of the follwing values :
* @arg ETH_DMATXDESC_BUSY : BUSY bit: descriptor is owned by DMA engine
* @arg ETH_DMATXDESC_INTC : Interrupt on completetion
* @arg ETH_DMATXDESC_LSG : Last Segment
* @arg ETH_DMATXDESC_FSG : First Segment
* @arg ETH_DMATXDESC_DCRC : Disable CRC
* @arg ETH_DMATXDESC_DPAD : Disable Pad
* @arg ETH_DMATXDESC_TTSEN : Transmit Time Stamp Enable
* @arg ETH_DMATXDESC_TERM : Transmit End of Ring
* @arg ETH_DMATXDESC_TCHM : Second Address Chained
* @arg ETH_DMATXDESC_TTMSS : Tx Time Stamp Status
* @arg ETH_DMATXDESC_IPHE : IP Header Error
* @arg ETH_DMATXDESC_ES : Error summary
* @arg ETH_DMATXDESC_JT : Jabber Timeout
* @arg ETH_DMATXDESC_FRMF : Frame Flushed: DMA/MTL flushed the frame due to SW flush
* @arg ETH_DMATXDESC_IPPE : IP Payload Error
* @arg ETH_DMATXDESC_LCA : Loss of Carrier: carrier lost during tramsmission
* @arg ETH_DMATXDESC_NCA : No Carrier: no carrier signal from the tranceiver
* @arg ETH_DMATXDESC_LCO : Late Collision: transmission aborted due to collision
* @arg ETH_DMATXDESC_ECO : Excessive Collision: transmission aborted after 16 collisions
* @arg ETH_DMATXDESC_VFRM : VLAN Frame
* @arg ETH_DMATXDESC_COCNT : Collision Count
* @arg ETH_DMATXDESC_EXD : Excessive Deferral
* @arg ETH_DMATXDESC_UFE : Underflow Error: late data arrival from the memory
* @arg ETH_DMATXDESC_DB : Deferred Bit
* @retval The current ETH_DMATxDescFlag selected bit status(SET or RESET).
*/
TypeState ETH_GetDMATxDescBitState(ETH_DMADESCTypeDef *DMATxDesc, uint32_t ETH_DMATxDescFlag)
{
if ((DMATxDesc->Status & ETH_DMATxDescFlag) != (uint32_t)RESET) {
/* ETH_DMATxDescFlag is set */
return SET;
} else {
/* ETH_DMATxDescFlag is reset */
return RESET;
}
}
/**
* @brief Get the DMA Tx Desc collision count.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @retval The value of Transmit descriptor collision counter.
*/
uint32_t ETH_GetDMATxDescCollisionCount(ETH_DMADESCTypeDef *DMATxDesc)
{
return ((DMATxDesc->Status & ETH_DMATXDESC_COCNT) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT);
}
/**
* @brief Set the DMA Tx Desc Busy bit for DMA or CPU.
* @param DMATxDesc: Pointer on a Transmit descriptor
* @retval None
*/
void ETH_SetDMATxDescBusyBit(ETH_DMADESCTypeDef *DMATxDesc)
{
DMATxDesc->Status |= ETH_DMATXDESC_BUSY;
}
/**
* @brief Enable or disable the ETH_DMATXDESC_INTC control bit.
* @param DMATxDesc: Pointer to a Tx descriptor
* @param NewValue: new value of the ETH_DMATXDESC_INTC control bit.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescTransmitINTConfig(ETH_DMADESCTypeDef *DMATxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMA Tx Desc after the frame has been transmitted Set Transmit interrupt */
DMATxDesc->Status |= ETH_DMATXDESC_INTC;
} else {
/* Disable the DMA Tx Desc after the frame has been transmitted Set Transmit interrupt */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_INTC);
}
}
/**
* @brief Enable or disable the DMATxDesc_FrameSegment control bit.
* @param DMATxDesc: Pointer to a Tx descriptor
* @param DMATxDesc_Segment: the actual Tx buffer contain first or last segment.
* Select one of the follwing values :
* @arg ETH_DMATXDESC_LASTSEGMENT : current Tx desc selected contain last segment
* @arg ETH_DMATXDESC_FIRSTSEGMENT : current Tx desc selected contain first segment
* @retval None
*/
void ETH_SetDMATxDescFrameSegment(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_Segment)
{
DMATxDesc->Status |= DMATxDesc_Segment;
}
/**
* @brief Set the DMA Tx Desc Checksum Insertion mode.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @param DMATxDesc_Checksum: the type of DMA Tx descriptor checksum insertion.
* Select one of the follwing values :
* @arg ETH_DMATXDESC_CHECKSUMDISABLE : Checksum bypass
* @arg ETH_DMATXDESC_CHECKSUMIPV4HEADER : IPv4 header checksum
* @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present
* @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL : TCP/UDP/ICMP checksum fully in hardware including pseudo header
* @retval None
*/
void ETH_SetDMATxDescChecksumInsertion(ETH_DMADESCTypeDef *DMATxDesc, uint32_t DMATxDesc_Checksum)
{
DMATxDesc->Status |= DMATxDesc_Checksum;
}
/**
* @brief Enable or disable the DMA Tx descriptor CRC function.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @param NewValue: new value of the DMA Tx descriptor CRC function.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescCRC_Enable(ETH_DMADESCTypeDef *DMATxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMATxDesc CRC */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_DCRC);
} else {
/* Disable the DMATxDesc CRC */
DMATxDesc->Status |= ETH_DMATXDESC_DCRC;
}
}
/**
* @brief Enable or disable the DMA Tx descriptor end of ring.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @param NewValue: new value of the DMA Tx descriptor end of ring.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescEndOfRing_Enable(ETH_DMADESCTypeDef *DMATxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMATxDesc end of ring */
DMATxDesc->Status |= ETH_DMATXDESC_TERM;
} else {
/* Disable the DMATxDesc end of ring */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_TERM);
}
}
/**
* @brief Enable or disable the DMA Tx descriptor second address chained.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @param NewValue: new value of the DMA Tx descriptor second address chained.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescSecondAddressChained_Enable(ETH_DMADESCTypeDef *DMATxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMATxDesc second address chained */
DMATxDesc->Status |= ETH_DMATXDESC_TCHM;
} else {
/* Disable the DMATxDesc second address chained */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_TCHM);
}
}
/**
* @brief Enable or disable auto padding when transmit frame shorter than 64 bytes.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @param NewValue: new value of the auto padding status.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescShortFramePadding_Enable(ETH_DMADESCTypeDef *DMATxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMATxDesc short frame padding */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_DPAD);
} else {
/* Disable the DMATxDesc short frame padding */
DMATxDesc->Status |= ETH_DMATXDESC_DPAD;
}
}
/**
* @brief Enable or disable the DMA Tx descriptor time stamp function.
* @param DMATxDesc: pointer to a DMA Tx descriptor
* @param NewValue: new value of the DMA Tx descriptor time stamp.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATxDescTimeStamp_Enable(ETH_DMADESCTypeDef *DMATxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMATxDesc time stamp */
DMATxDesc->Status |= ETH_DMATXDESC_TTSEN;
} else {
/* Disable the DMATxDesc time stamp */
DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_TTSEN);
}
}
/**
* @brief Set the frame length by configures the DMA Tx Desc buffer1 and buffer2 sizes.
* @param DMATxDesc: Pointer to a Tx descriptor
* @param Buffer1Size: the Tx buffer1 size.
* @param Buffer2Size: the Tx buffer2 size, set to 0 indicates it is not being used.
* @retval None
*/
void ETH_SetDMATxDescBufferSize(ETH_DMADESCTypeDef *DMATxDesc, uint32_t Buffer1Size, uint32_t Buffer2Size)
{
DMATxDesc->ControlBufferSize |= (Buffer1Size | (Buffer2Size << ETH_DMATXDESC_BUFFER2_SIZESHIFT));
}
/**
* @brief Initialize the DMA Rx descriptors's parameters in chain mode.
* @param DMARxDescTab: Pointer to the first Rx descriptor table
* @param pRxBuff: Pointer to the first RxBuffer table
* @param RxBuffCnt: the used Rx desc num in the table
* @retval None
*/
void ETH_DMARxDescChainModeInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *pRxBuff, uint32_t RxBuffCnt)
{
uint32_t num = 0;
ETH_DMADESCTypeDef *DMARxDesc;
DMACurrentRxDesc = DMARxDescTab;
/* Configuration each DMARxDesc descriptor */
for (num = 0; num < RxBuffCnt; num++) {
/* Get the pointer to the next descriptor of the Rx Desc table */
DMARxDesc = DMARxDescTab + num;
DMARxDesc->Status = ETH_DMARXDESC_BUSY;
/* Set TCH bit and buffer1 size */
DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCHM | (uint32_t)ETH_MAX_FRAME_SIZE;
/* Set Buffer1 address pointer to application buffer */
DMARxDesc->Buffer1Addr = (uint32_t)(&pRxBuff[num * ETH_MAX_FRAME_SIZE]);
if (num < (RxBuffCnt - 1)) {
/* Buffer2NextDescAddr equal to next descriptor address in the Rx Desc table */
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + num + 1);
} else {
/* When it is the last descriptor, Buffer2NextDescAddr equal to first descriptor address in the Rx Desc table */
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
}
}
ETH_DMA->RDTAR = (uint32_t) DMARxDescTab;
}
/**
* @brief Initialize the DMA Rx descriptors's parameters in ring mode.
* @param DMARxDescTab: Pointer to the first Rx descriptor table
* @param pRxBuff1: Pointer to the first RxBuffer1 table
* @param pRxBuff2: Pointer to the first RxBuffer2 table
* @param RxBuffCnt: the used Rx descriptor num in the table
* @retval None
*/
void ETH_DMARxDescRingModeInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *pRxBuff1, uint8_t *pRxBuff2, uint32_t RxBuffCnt)
{
uint32_t num = 0;
ETH_DMADESCTypeDef *DMARxDesc;
DMACurrentRxDesc = DMARxDescTab;
/* Configuration each DMARxDesc descriptor */
for (num = 0; num < RxBuffCnt; num++) {
/* Get the pointer to the next descriptor of the Rx Desc table */
DMARxDesc = DMARxDescTab + num;
DMARxDesc->Status = ETH_DMARXDESC_BUSY;
DMARxDesc->ControlBufferSize = ETH_MAX_FRAME_SIZE;
/* Set Buffer1 address pointer to application buffer1 */
DMARxDesc->Buffer1Addr = (uint32_t)(&pRxBuff1[num * ETH_MAX_FRAME_SIZE]);
/* Set Buffer2 address pointer to application buffer2 */
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(&pRxBuff2[num * ETH_MAX_FRAME_SIZE]);
if (num == (RxBuffCnt - 1)) {
/* Set ETH_DMARXDESC_RERR bit as Receive End */
DMARxDesc->ControlBufferSize |= ETH_DMARXDESC_RERR;
}
}
ETH_DMA->RDTAR = (uint32_t) DMARxDescTab;
}
/**
* @brief Get the bit flag of ETHERNET Rx descriptor.
* @param DMARxDesc: pointer to a DMA Rx descriptor
* @param ETH_DMARxDescFlag: the flag of Rx descriptor status.
* Select one of the follwing values :
* @arg ETH_DMARXDESC_BUSY : Descriptor is owned by DMA engine
* @arg ETH_DMARXDESC_DAFF : DA Filter Fail for the rx frame
* @arg ETH_DMARXDESC_ERRS : Error summary
* @arg ETH_DMARXDESC_DERR : Desciptor error: no more descriptors for receive frame
* @arg ETH_DMARXDESC_SAFF : SA Filter Fail for the received frame
* @arg ETH_DMARXDESC_LERR : Frame size not matching with length field
* @arg ETH_DMARXDESC_OERR : Overflow Error: Frame was damaged due to buffer overflow
* @arg ETH_DMARXDESC_VTAG : VLAN Tag: received frame is a VLAN frame
* @arg ETH_DMARXDESC_FDES : First descriptor of the frame
* @arg ETH_DMARXDESC_LDES : Last descriptor of the frame
* @arg ETH_DMARXDESC_IPHCERR : IPC Checksum Error/Giant Frame: Rx Ipv4 header checksum error
* @arg ETH_DMARXDESC_LCO : Late collision occurred during reception
* @arg ETH_DMARXDESC_FRMT : Frame type - Ethernet, otherwise 802.3
* @arg ETH_DMARXDESC_RWDT : Receive Watchdog Timeout: watchdog timer expired during reception
* @arg ETH_DMARXDESC_RERR : Receive error: error reported by MII interface
* @arg ETH_DMARXDESC_DERR : Dribble bit error: frame contains non int multiple of 8 bits
* @arg ETH_DMARXDESC_CERR : CRC error
* @arg ETH_DMARXDESC_PCERR : Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error
* @retval The current ETH_DMARxDescFlag selected bit status(SET or RESET).
*/
TypeState ETH_GetDMARxDescBitState(ETH_DMADESCTypeDef *DMARxDesc, uint32_t ETH_DMARxDescFlag)
{
if ((DMARxDesc->Status & ETH_DMARxDescFlag) != (uint32_t)RESET) {
/* ETH_DMARxDescFlag is set */
return SET;
} else {
/* ETH_DMARxDescFlag is reset */
return RESET;
}
}
/**
* @brief Set the DMA Rx Desc busy bit for DMA or CPU
* @param DMARxDesc: Pointer to a Rx descriptor
* @retval None
*/
void ETH_SetDMARxDescBusyBit(ETH_DMADESCTypeDef *DMARxDesc)
{
DMARxDesc->Status |= ETH_DMARXDESC_BUSY;
}
/**
* @brief Get the DMA Rx Desc frame length.
* @param DMARxDesc: pointer to a DMA Rx descriptor
* @retval Received frame length of the Rx descriptor selected.
*/
uint32_t ETH_GetDMARxDescFrameLength(ETH_DMADESCTypeDef *DMARxDesc)
{
return ((DMARxDesc->Status & ETH_DMARXDESC_FRML) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT);
}
/**
* @brief Enable or disable the DMA Rx descriptor receive interrupt.
* @param DMARxDesc: Pointer to a Rx descriptor
* @param NewValue: new value of the DMA Rx descriptor interrupt.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMARxDescReceiveINTConfig(ETH_DMADESCTypeDef *DMARxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMARxDesc receive interrupt */
DMARxDesc->ControlBufferSize &= (~(uint32_t)ETH_DMARXDESC_DINTC);
} else {
/* Disable the DMARxDesc receive interrupt */
DMARxDesc->ControlBufferSize |= ETH_DMARXDESC_DINTC;
}
}
/**
* @brief Enable or disable the DMA Rx descriptor end of ring.
* @param DMARxDesc: pointer to a DMA Rx descriptor
* @param NewValue: new value of the DMA Rx descriptor end of ring.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMARxDescEndOfRing_Enable(ETH_DMADESCTypeDef *DMARxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMARxDesc end of ring */
DMARxDesc->ControlBufferSize |= ETH_DMARXDESC_RERR;
} else {
/* Disable the DMARxDesc end of ring */
DMARxDesc->ControlBufferSize &= (~(uint32_t)ETH_DMARXDESC_RERR);
}
}
/**
* @brief Enable or disable the DMA Rx descriptor second address chained.
* @param DMARxDesc: pointer to a DMA Rx descriptor
* @param NewValue: new value of the DMA Rx descriptor second address chained.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMARxDescSecondAddressChained_Enable(ETH_DMADESCTypeDef *DMARxDesc, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the DMARxDesc second address chained */
DMARxDesc->ControlBufferSize |= ETH_DMARXDESC_RCHM;
} else {
/* Disable the DMARxDesc second address chained */
DMARxDesc->ControlBufferSize &= (~(uint32_t)ETH_DMARXDESC_RCHM);
}
}
/**
* @brief Get the ETHERNET DMA Rx Desc buffer size.
* @param DMARxDesc: pointer to a DMA Rx descriptor
* @param DMARxDesc_BufferSelect: the DMA Rx descriptor buffer.
* Select one of the follwing values :
* @arg ETH_DMARXDESC_BUFFER1 : DMA Rx Desc Buffer1
* @arg ETH_DMARXDESC_BUFFER2 : DMA Rx Desc Buffer2
* @retval The Receive descriptor selected buffer size(buffer1 or buffer2).
*/
uint32_t ETH_GetDMARxDescBufferSize(ETH_DMADESCTypeDef *DMARxDesc, uint32_t DMARxDesc_BufferSelect)
{
if (DMARxDesc_BufferSelect != ETH_DMARXDESC_BUFFER1) {
return ((DMARxDesc->ControlBufferSize & ETH_DMARXDESC_RB2S) >> ETH_DMARXDESC_BUFFER2_SIZESHIFT);
} else {
return (DMARxDesc->ControlBufferSize & ETH_DMARXDESC_RB1S);
}
}
/* DMA */
/**
* @brief Resets all MAC subsystem.
* @param None
* @retval None
*/
void ETH_SoftReset(void)
{
ETH_DMA->BCR |= ETH_DMA_BCR_SWR;
}
/**
* @brief Get the bit flag of ETHERNET software reset.
* @param None
* @retval The current DMA Bus Mode register SWR bit status(SET or RESET).
*/
TypeState ETH_GetSoftResetStatus(void)
{
if ((ETH_DMA->BCR & ETH_DMA_BCR_SWR) != (uint32_t)RESET) {
/* The ETH_DMA_BCR_SWR bit is set */
return SET;
} else {
/* The ETH_DMA_BCR_SWR bit is reset */
return RESET;
}
}
/**
* @brief Get the bit flag of specified ETHERNET DMA.
* @param ETH_DMA_FLAG: the flag of ETHERNET DMA_STR register.
* Select one of the follwing values :
* @arg ETH_DMA_FLAG_TST : Time-stamp trigger flag
* @arg ETH_DMA_FLAG_WUM : WUM flag
* @arg ETH_DMA_FLAG_MSC : MSC flag
* @arg ETH_DMA_FLAG_DATATRANSFERERROR : Error bits 0-data buffer, 1-desc. access
* @arg ETH_DMA_FLAG_READWRITEERROR : Error bits 0-write trnsf, 1-read transfr
* @arg ETH_DMA_FLAG_ACCESSERROR : Error bits 0-Rx DMA, 1-Tx DMA
* @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
* @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
* @arg ETH_DMA_FLAG_ER : Early receive flag
* @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
* @arg ETH_DMA_FLAG_ET : Early transmit flag
* @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
* @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
* @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
* @arg ETH_DMA_FLAG_R : Receive flag
* @arg ETH_DMA_FLAG_TU : Underflow flag
* @arg ETH_DMA_FLAG_RO : Overflow flag
* @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
* @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
* @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
* @arg ETH_DMA_FLAG_T : Transmit flag
* @retval The current ETH_DMA_FLAG selected bit status(SET or RESET).
*/
TypeState ETH_GetDMABitState(uint32_t ETH_DMA_FLAG)
{
if ((ETH_DMA->STR & ETH_DMA_FLAG) != (uint32_t)RESET) {
/* ETH_DMA_FLAG is set */
return SET;
} else {
/* ETH_DMA_FLAG is reset */
return RESET;
}
}
/**
* @brief Clear the ETHERNET<EFBFBD><EFBFBD>s DMA bit flag.
* @param ETH_DMA_FLAG: the flag of ETH_DMA_STR register to clear.
* Select one of the follwing values :
* @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
* @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
* @arg ETH_DMA_FLAG_ER : Early receive flag
* @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
* @arg ETH_DMA_FLAG_ETI : Early transmit flag
* @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
* @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
* @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
* @arg ETH_DMA_FLAG_R : Receive flag
* @arg ETH_DMA_FLAG_TU : Transmit Underflow flag
* @arg ETH_DMA_FLAG_RO : Receive Overflow flag
* @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
* @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
* @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
* @arg ETH_DMA_FLAG_T : Transmit flag
* @retval None
*/
void ETH_DMAClearBitState(uint32_t ETH_DMA_FLAG)
{
ETH_DMA->STR = (uint32_t) ETH_DMA_FLAG;
}
/**
* @brief Get the bit flag of DMA interrupt.
* @param ETH_DMA_INT: the interrupt source flag of ETHERNET DMA_STR register.
* Select one of the follwing values :
* @arg ETH_DMA_INT_TST : Time-stamp trigger interrupt
* @arg ETH_DMA_INT_WUM : WUM interrupt
* @arg ETH_DMA_INT_MSC : MSC interrupt
* @arg ETH_DMA_INT_NIS : Normal interrupt summary
* @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
* @arg ETH_DMA_INT_ER : Early receive interrupt
* @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
* @arg ETH_DMA_INT_ET : Early transmit interrupt
* @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
* @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
* @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
* @arg ETH_DMA_INT_R : Receive interrupt
* @arg ETH_DMA_INT_TU : Underflow interrupt
* @arg ETH_DMA_INT_RO : Overflow interrupt
* @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
* @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
* @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
* @arg ETH_DMA_INT_T : Transmit interrupt
* @retval The current ETH_DMA_INT selected bit status(SET or RESET).
*/
TypeState ETH_GetDMAIntBitState(uint32_t ETH_DMA_INT)
{
if ((ETH_DMA->STR & ETH_DMA_INT) != (uint32_t)RESET) {
/* ETH_DMA_INT is set */
return SET;
} else {
/* ETH_DMA_INT is reset */
return RESET;
}
}
/**
* @brief Clear the ETHERNET<EFBFBD><EFBFBD>s DMA IT bit flag.
* @param ETH_DMA_INT: the interrupt source flag of ETH_DMA_STR register to clear.
* Select one of the follwing values :
* @arg ETH_DMA_INT_NIS : Normal interrupt summary
* @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
* @arg ETH_DMA_INT_ER : Early receive interrupt
* @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
* @arg ETH_DMA_INT_ETI : Early transmit interrupt
* @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
* @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
* @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
* @arg ETH_DMA_INT_R : Receive interrupt
* @arg ETH_DMA_INT_TU : Transmit Underflow interrupt
* @arg ETH_DMA_INT_RO : Receive Overflow interrupt
* @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
* @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
* @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
* @arg ETH_DMA_INT_T : Transmit interrupt
* @retval None
*/
void ETH_DMAClearIntBitState(uint32_t ETH_DMA_INT)
{
ETH_DMA->STR = (uint32_t) ETH_DMA_INT;
}
/**
* @brief Get the DMA Transmit Process State.
* @param None
* @retval The current DMA Transmit Process State:
* Select one of the follwing values :
* - ETH_DMA_TransmitProcess_Stopped : Stopped - Reset or Stop Tx Command issued
* - ETH_DMA_TransmitProcess_Fetching : Running - fetching the Tx descriptor
* - ETH_DMA_TransmitProcess_Waiting : Running - waiting for status
* - ETH_DMA_TransmitProcess_Reading : unning - reading the data from host memory
* - ETH_DMA_TransmitProcess_Suspended : Suspended - Tx Desciptor unavailabe
* - ETH_DMA_TransmitProcess_Closing : Running - closing Rx descriptor
*/
uint32_t ETH_GetTransmitProcessState(void)
{
return ((uint32_t)(ETH_DMA->STR & ETH_DMA_STR_TS));
}
/**
* @brief Get the DMA Receive Process State.
* @param None
* @retval The current DMA Receive Process State:
* Select one of the follwing values :
* - ETH_DMA_ReceiveProcess_Stopped : Stopped - Reset or Stop Rx Command issued
* - ETH_DMA_ReceiveProcess_Fetching : Running - fetching the Rx descriptor
* - ETH_DMA_ReceiveProcess_Waiting : Running - waiting for packet
* - ETH_DMA_ReceiveProcess_Suspended : Suspended - Rx Desciptor unavailable
* - ETH_DMA_ReceiveProcess_Closing : Running - closing descriptor
* - ETH_DMA_ReceiveProcess_Queuing : Running - queuing the recieve frame into host memory
*/
uint32_t ETH_GetReceiveProcessState(void)
{
return ((uint32_t)(ETH_DMA->STR & ETH_DMA_STR_RS));
}
/**
* @brief Flush the ETHERNET transmit FIFO.
* @param None
* @retval None
*/
void ETH_CleanTransmitFIFO(void)
{
/* Set the FTF bit for Flushing Transmit FIFO */
ETH_DMA->CTLR |= ETH_DMA_CTLR_FTF;
}
/**
* @brief Get the bit flag of ETHERNET transmit FIFO.
* @param None
* @retval The current ETHERNET flush transmit FIFO bit status(SET or RESET).
*/
TypeState ETH_GetFlushTransmitFIFOStatus(void)
{
if ((ETH_DMA->CTLR & ETH_DMA_CTLR_FTF) != (uint32_t)RESET) {
/* Flush transmit FIFO bit is set */
return SET;
} else {
/* Flush transmit FIFO bit is reset */
return RESET;
}
}
/**
* @brief Enable or disable the DMA transmission function.
* @param NewValue: new value of the DMA transmission status.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMATransmission_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Set the STE bit for Enable the DMA transmission */
ETH_DMA->CTLR |= ETH_DMA_CTLR_STE;
} else {
/* Reset the STE bit for Disable the DMA transmission */
ETH_DMA->CTLR &= ~ETH_DMA_CTLR_STE;
}
}
/**
* @brief Enable or disable the DMA reception function.
* @param NewValue: new value of the DMA reception status.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMAReception_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable DMA reception */
ETH_DMA->CTLR |= ETH_DMA_CTLR_SRE;
} else {
/* Disable DMA reception */
ETH_DMA->CTLR &= ~ETH_DMA_CTLR_SRE;
}
}
/**
* @brief Enable or disable the ETH_DMA_INT control bit.
* @param ETH_DMA_INT: the interrupt source flag of ETH_DMA_IER register.
* Select one of the follwing values :
* @arg ETH_DMA_INT_NIS : Normal interrupt summary
* @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
* @arg ETH_DMA_INT_ER : Early receive interrupt
* @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
* @arg ETH_DMA_INT_ET : Early transmit interrupt
* @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
* @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
* @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
* @arg ETH_DMA_INT_R : Receive interrupt
* @arg ETH_DMA_INT_TU : Underflow interrupt
* @arg ETH_DMA_INT_RO : Overflow interrupt
* @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
* @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
* @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
* @arg ETH_DMA_INT_T : Transmit interrupt
* @param NewValue: new value of the DMA interrupts.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_DMAINTConfig(uint32_t ETH_DMA_INT, TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_DMA_INT control bit */
ETH_DMA->IER |= ETH_DMA_INT;
} else {
/* Disable the ETH_DMA_INT control bit */
ETH_DMA->IER &= (~(uint32_t)ETH_DMA_INT);
}
}
/**
* @brief Get the bit flag of ETHERNET DMA overflow.
* @param ETH_DMA_Overflow: the DMA overflow flag of ETHERNET DMA_MFBOCNT register.
* Select one of the follwing values :
* @arg ETH_DMA_OVERFLOW_RXFIFOCOUNTER : Overflow for FIFO Overflow Counter
* @arg ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER : Overflow for Missed Frame Counter
* @retval The current ETHERNET DMA overflow Flag selected bit status(SET or RESET).
*/
TypeState ETH_GetDMAOverflowStatus(uint32_t ETH_DMA_Overflow)
{
if ((ETH_DMA->MFBOCNT & ETH_DMA_Overflow) != (uint32_t)RESET) {
/* DMA overflow Flag is set */
return SET;
} else {
/* DMA overflow Flag is reset */
return RESET;
}
}
/**
* @brief Get the DMA Rx value of overflow Missed Frame Counter.
* @param None
* @retval The ETH_DMA_MFBOCNT register MFA bit value.
*/
uint32_t ETH_GetRxOverflowMissedFrameCounter(void)
{
return ((uint32_t)((ETH_DMA->MFBOCNT & ETH_DMA_MFBOCNT_MSFA) >> ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT));
}
/**
* @brief Get the DMA value of Buffer unavailable Missed Frame Counter.
* @param None
* @retval The ETH_DMA_MFBOCNT register MFC bit value.
*/
uint32_t ETH_GetBufferUnavailableMissedFrameCounter(void)
{
return ((uint32_t)(ETH_DMA->MFBOCNT) & ETH_DMA_MFBOCNT_MSFC);
}
/**
* @brief Get the DMA value of the current Tx desc start address.
* @param None
* @retval The ETH_DMA_CTDAR register value.
*/
uint32_t ETH_GetCurrentTxDescStartAddress(void)
{
return ((uint32_t)(ETH_DMA->CTDAR));
}
/**
* @brief Get the DMA value of the current Rx desc start address.
* @param None
* @retval The ETH_DMA_CRDAR register value.
*/
uint32_t ETH_GetCurrentRxDescStartAddress(void)
{
return ((uint32_t)(ETH_DMA->CRDAR));
}
/**
* @brief Get the DMA value of the current Tx buffer address.
* @param None
* @retval The ETH_DMA_CTBAR register value.
*/
uint32_t ETH_GetCurrentTxBufferAddress(void)
{
return ((uint32_t)(ETH_DMA->CTBAR));
}
/**
* @brief Get the DMA value of the current Rx buffer address.
* @param None
* @retval The ETH_DMA_CRBAR register value.
*/
uint32_t ETH_GetCurrentRxBufferAddress(void)
{
return ((uint32_t)(ETH_DMA->CRBAR));
}
/**
* @brief Poll the DMA Transmission enable by writing any value to the ETH_DMA_TPER register.
* This will make the DMA to resume transmission.
* @param None
* @retval None.
*/
void ETH_ResumeDMATransmission(void)
{
ETH_DMA->TPER = 0;
}
/**
* @brief Poll the DMA Transmission enable by writing any value to the ETH_DMA_RPER register.
* This will make the DMA to resume reception.
* @param None
* @retval None.
*/
void ETH_ResumeDMAReception(void)
{
ETH_DMA->RPER = 0;
}
/* WUM */
/**
* @brief Reset Wakeup frame filter register pointer.
* @param None
* @retval None
*/
void ETH_WakeUpFrameFilterRegisterReset(void)
{
/* Set WUFFRPR bit for Reseting the ETH_MAC_RWFFR register pointer to 0 */
ETH_MAC->WUMR |= ETH_MAC_WUMR_WUFFRPR;
}
/**
* @brief Set the remote wakeup frame registers.
* @param pBuffer: Pointer to remote WakeUp Frame Filter Register buffer data (8 words).
* @retval None
*/
void ETH_SetWakeUpFrameFilterRegister(uint32_t *pBuffer)
{
uint32_t num = 0;
/* Configuration ETH_MAC_RWFFR register */
for (num = 0; num < ETH_WAKEUP_REGISTER_LENGTH; num++) {
ETH_MAC->RWFFR = pBuffer[num];
}
}
/**
* @brief Enable or disable ETH_MAC_WUMR_GU control bit.
* @param NewValue: new value of the MAC Global Unicast Wake-Up.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_GlobalUnicastWakeUp_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_MAC_WUMR_GU control bit */
ETH_MAC->WUMR |= ETH_MAC_WUMR_GU;
} else {
/* Disable the ETH_MAC_WUMR_GU control bit */
ETH_MAC->WUMR &= ~ETH_MAC_WUMR_GU;
}
}
/**
* @brief Get the bit flag of the WUM.
* @param ETH_WUM_FLAG: the flag of ETH_MAC_WUMR register.
* Select one of the follwing values :
* @arg ETH_WUM_FLAG_WUFFRPR : Wake-Up Frame Filter Register Poniter Reset
* @arg ETH_WUM_FLAG_WUFR : Wake-Up Frame Received
* @arg ETH_WUM_FLAG_MPKR : Magic Packet Received
* @retval The current ETHERNET WUM Flag selected bit status(SET or RESET).
*/
TypeState ETH_GetWUMBitState(uint32_t ETH_WUM_FLAG)
{
if ((ETH_MAC->WUMR & ETH_WUM_FLAG) != (uint32_t)RESET) {
/* WUM Flag is set */
return SET;
} else {
/* WUM Flag is reset */
return RESET;
}
}
/**
* @brief Enable or disable the ETH_MAC_WUMR_WFEN control bit.
* @param NewValue: new value of the ETH_MAC_WUMR_WFEN bit.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_WakeUpFrameDetection_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Active the MAC Wake-Up Frame Detection */
ETH_MAC->WUMR |= ETH_MAC_WUMR_WFEN;
} else {
/* Deactive the MAC Wake-Up Frame Detection */
ETH_MAC->WUMR &= ~ETH_MAC_WUMR_WFEN;
}
}
/**
* @brief Enable or disable the ETH_MAC_WUMR_MPEN control bit.
* @param NewValue: new value of the ETH_MAC_WUMR_MPEN bit.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MagicPacketDetection_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_MAC_WUMR_MPEN control bit */
ETH_MAC->WUMR |= ETH_MAC_WUMR_MPEN;
} else {
/* Disable the ETH_MAC_WUMR_MPEN control bit */
ETH_MAC->WUMR &= ~ETH_MAC_WUMR_MPEN;
}
}
/**
* @brief Enable or disable the ETH_MAC_WUMR_PWD control bit.
* @param NewValue: new value of the ETH_MAC_WUMR_PWD bit.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_PowerDown_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_MAC_WUMR_PWD control bit */
ETH_MAC->WUMR |= ETH_MAC_WUMR_PWD;
} else {
/* Disable the ETH_MAC_WUMR_PWD control bit */
ETH_MAC->WUMR &= ~ETH_MAC_WUMR_PWD;
}
}
/* MSC */
/**
* @brief Enable or disable the ETH_MSC_CTLR_MCFZ control bit.
* @param NewValue: new value of the MSC Counter Freeze.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MSCCounterFreeze_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_MSC_CTLR_MCFZ control bit */
ETH_MSC->CTLR |= ETH_MSC_CTLR_MCFZ;
} else {
/* Disable the ETH_MSC_CTLR_MCFZ control bit */
ETH_MSC->CTLR &= ~ETH_MSC_CTLR_MCFZ;
}
}
/**
* @brief Enable or disable the ETH_MSC_CTLR_RTOR control bit.
* @param NewValue: new value of the MSC Reset On Read.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MSCResetOnRead_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_MSC_CTLR_RTOR control bit */
ETH_MSC->CTLR |= ETH_MSC_CTLR_RTOR;
} else {
/* Disable the ETH_MSC_CTLR_RTOR control bit */
ETH_MSC->CTLR &= ~ETH_MSC_CTLR_RTOR;
}
}
/**
* @brief Enable or disable the ETH_MSC_CTLR_CTSR control bit.
* @param NewValue: new value of the ETH_MSC_CTLR_CTSR bit.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MSCCounterRollover_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_MSC_CTLR_CTSR control bit */
ETH_MSC->CTLR &= ~ETH_MSC_CTLR_CTSR;
} else {
/* Disable the ETH_MSC_CTLR_CTSR control bit */
ETH_MSC->CTLR |= ETH_MSC_CTLR_CTSR;
}
}
/**
* @brief Resets the MSC Counters.
* @param None
* @retval None
*/
void ETH_MSCCountersReset(void)
{
ETH_MSC->CTLR |= ETH_MSC_CTLR_CTR;
}
/**
* @brief Enable or disable the ETH_MSC_INT control bit.
* @param ETH_MSC_INT: the MSC interrupt sources flag of MSC_RIMR and MSC_TIMR.
* This parameter can be any combination of Tx interrupt or
* any combination of Rx interrupt (but not both)of the following values:
* @arg ETH_MSC_INT_TGF : When Tx good frame counter reaches half the maximum value
* @arg ETH_MSC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
* @arg ETH_MSC_INT_TGFSC : When Tx good single col counter reaches half the maximum value
* @arg ETH_MSC_INT_RGUF : When Rx good unicast frames counter reaches half the maximum value
* @arg ETH_MSC_INT_RFAE : When Rx alignment error counter reaches half the maximum value
* @arg ETH_MSC_INT_RFCE : When Rx crc error counter reaches half the maximum value
* @param NewValue: new value of the MSC interrupt sources flag of MSC_RIMR and MSC_TIMR.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_MSCINTConfig(uint32_t ETH_MSC_INT, TypeState NewValue)
{
if ((ETH_MSC_INT & (uint32_t)0x10000000) != (uint32_t)RESET) {
/* Get MSC interrupts souce bit position */
ETH_MSC_INT &= 0xEFFFFFFF;
/* MSC Rx interrupts souce bit selected */
if (NewValue != DISABLE) {
/* Enable the Rx ETH_MSC_INT control bit */
ETH_MSC->RIMR &= (~(uint32_t)ETH_MSC_INT);
} else {
/* Disable the Rx ETH_MSC_INT control bit */
ETH_MSC->RIMR |= ETH_MSC_INT;
}
} else {
/* MSC Tx interrupts souce bit selected */
if (NewValue != DISABLE) {
/* Enable the Tx ETH_MSC_INT control bit */
ETH_MSC->TIMR &= (~(uint32_t)ETH_MSC_INT);
} else {
/* Disable the Tx ETH_MSC_INT control bit */
ETH_MSC->TIMR |= ETH_MSC_INT;
}
}
}
/**
* @brief Get the bit flag of MSC INT.
* @param ETH_MSC_INT: the MSC interrupt flag of ETH_MSC_RISR and ETH_MSC_TISR.
* Select one of the follwing values :
* @arg ETH_MSC_INT_TGF: When Tx good frame counter reaches half the maximum value
* @arg ETH_MSC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
* @arg ETH_MSC_INT_TGFSC: When Tx good single col counter reaches half the maximum value
* @arg ETH_MSC_INT_RGUF: When Rx good unicast frames counter reaches half the maximum value
* @arg ETH_MSC_INT_RFAE : When Rx alignment error counter reaches half the maximum value
* @arg ETH_MSC_INT_RFCE : When Rx crc error counter reaches half the maximum value
* @retval The current ETHERNET MSC IT selected bit status(SET or RESET).
*/
TypeState ETH_GetMSCINTStatus(uint32_t ETH_MSC_INT)
{
if ((ETH_MSC_INT & (uint32_t)0x10000000) != (uint32_t)RESET) {
/* Check if the MSC interrupt flag of ETH_MSC_RISR selected is enabled and occured */
if ((((ETH_MSC->RISR & ETH_MSC_INT) != (uint32_t)RESET)) && ((ETH_MSC->RIMR & ETH_MSC_INT) != (uint32_t)RESET)) {
/* The MSC interrupt flag of ETH_MSC_RISR is set */
return SET;
} else {
/* The MSC interrupt flag of ETH_MSC_RISR is reset */
return RESET;
}
} else {
/* Check if the MSC interrupt flag of ETH_MSC_TISR selected is enabled and occured */
if ((((ETH_MSC->TISR & ETH_MSC_INT) != (uint32_t)RESET)) && ((ETH_MSC->RIMR & ETH_MSC_INT) != (uint32_t)RESET)) {
/* The MSC interrupt flag of ETH_MSC_TISR is set */
return SET;
} else {
/* The MSC interrupt flag of ETH_MSC_TISR is reset */
return RESET;
}
}
}
/**
* @brief Read value of the MSC module register.
* @param ETH_MSC_Register: the MSC module register selected.
* Select one of the follwing values :
* @arg ETH_MSC_CTLR : MSC CR register
* @arg ETH_MSC_RISR : MSC RIR register
* @arg ETH_MSC_TISR : MSC TIR register
* @arg ETH_MSC_RIMR : MSC RIMR register
* @arg ETH_MSC_TIMR : MSC TIMR register
* @arg ETH_MSC_SCCNT : MSC TGFSCCR register
* @arg ETH_MSC_MSCCNT : MSC TGFMSCCR register
* @arg ETH_MSC_TGFCNT : MSC TGFCR register
* @arg ETH_MSC_RFCECNT : MSC RFCECR register
* @arg ETH_MSC_RFAECNT : MSC RFAECR register
* @arg ETH_MSC_RGUFCNT : MSC RGUFCRregister
* @retval MSC module Register selected value.
*/
uint32_t ETH_GetMSCRegister(uint32_t ETH_MSC_Register)
{
/* Return the value of MSC module Register selected */
return (*(__IO uint32_t *)(ETH_MAC_BASE + ETH_MSC_Register));
}
/* PTP */
/**
* @brief Updated the Time Stamp Addend register value to the PTP block(used only when the system time is configured
* for Fine update mode).
* @param None
* @retval None
*/
void ETH_PTPTimeStampAddendUpdate(void)
{
ETH_PTP->TSCTLR |= ETH_PTP_TSCTLR_TMSARU;
}
/**
* @brief Set ETH_PTP_TSCTLR_TMSITEN bit.
* @param NewValue: new value of the MAC reception.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_PTPTimeStampIntTrigger_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable ETH_PTP_TSCTLR_TMSITEN bit */
ETH_PTP->TSCTLR |= ETH_PTP_TSCTLR_TMSITEN;
} else {
/* Disable ETH_PTP_TSCTLR_TMSITEN bit */
ETH_PTP->TSCTLR &= ~ETH_PTP_TSCTLR_TMSITEN;
}
}
/**
* @brief Updated the Time Stamp Update register value to the PTP system time.
* @param NewValue: new value of the MAC reception.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_PTPTimeStampUpdate_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable PTP time stamp update */
ETH_PTP->TSCTLR |= ETH_PTP_TSCTLR_TMSSTU;
} else {
/* Disable PTP time stamp update */
ETH_PTP->TSCTLR &= ~ETH_PTP_TSCTLR_TMSSTU;
}
}
/**
* @brief Initialize the PTP Time Stamp mode
* @param None
* @retval None
*/
void ETH_PTPTimeStampInit(void)
{
ETH_PTP->TSCTLR |= ETH_PTP_TSCTLR_TMSSTI;
}
/**
* @brief Set the PTP Time Stamp Update mode
* @param UpdateMode: the PTP Update mode selected
* Select one of the follwing values :
* @arg ETH_PTP_FINEMODE : Fine Update method
* @arg ETH_PTP_COARSEMODE : Coarse Update method
* @retval None
*/
void ETH_PTPUpdateModeConfig(uint32_t UpdateMode)
{
if (UpdateMode != ETH_PTP_COARSEMODE) {
/* Enable the PTP Fine Update mode */
ETH_PTP->TSCTLR |= ETH_PTP_TSCTLR_TMSFCU;
} else {
/* Disable the PTP Coarse Update mode */
ETH_PTP->TSCTLR &= (~(uint32_t)ETH_PTP_TSCTLR_TMSFCU);
}
}
/**
* @brief Enable or disable ETH_PTP_TSCTLR_TMSEN control bit.
* @param NewValue: new value of the ETH_PTP_TSCTLR_TMSEN control bit
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void ETH_PTPTimeStamp_Enable(TypeState NewValue)
{
if (NewValue != DISABLE) {
/* Enable the ETH_PTP_TSCTLR_TMSEN control bit */
ETH_PTP->TSCTLR |= ETH_PTP_TSCTLR_TMSEN;
} else {
/* Disable the ETH_PTP_TSCTLR_TMSEN control bit */
ETH_PTP->TSCTLR &= (~(uint32_t)ETH_PTP_TSCTLR_TMSEN);
}
}
/**
* @brief Get the bit flag of ETHERNET PTP.
* @param ETH_PTP_FLAG: the flag of PTP_TSCTLR register.
* Select one of the follwing values :
* @arg ETH_PTP_FLAG_TMSARU : Addend Register Update
* @arg ETH_PTP_FLAG_TMSITEN : Time Stamp Interrupt Trigger Enable
* @arg ETH_PTP_FLAG_TMSSTU : Time Stamp Update
* @arg ETH_PTP_FLAG_TMSSTI : Time Stamp Initialize
* @retval The current ETHERNET PTP Flag selected bit status(SET or RESET).
*/
TypeState ETH_GetPTPBitState(uint32_t ETH_PTP_FLAG)
{
if ((ETH_PTP->TSCTLR & ETH_PTP_FLAG) != (uint32_t)RESET) {
/* ETH_PTP_FLAG is set */
return SET;
} else {
/* ETH_PTP_FLAG is reset */
return RESET;
}
}
/**
* @brief Set Each HCLK cycle the system time Sub-Second Increased value.
* @param SubSecond: the PTP_SSINCR Register value.
* @retval None
*/
void ETH_SetPTPSubSecondIncrement(uint32_t SubSecond)
{
ETH_PTP->SSINCR = SubSecond;
}
/**
* @brief Set the system time update sign and values.
* @param Sign: the PTP Time update value sign(positive or negative).
* Select one of the follwing values :
* @arg ETH_PTP_POSITIVETIME : positive time value.
* @arg ETH_PTP_NEGATIVETIME : negative time value.
* @param Second: the PTP Time update value in second part.
* @param SubSecond: the PTP Time update value in sub-second part.
* This parameter is a 31 bit value, bit32 correspond to the sign.
* @retval None
*/
void ETH_SetPTPUpdateTimeValue(uint32_t Sign, uint32_t SecondValue, uint32_t SubSecondValue)
{
/* Set the PTP Time Update High Register with second value*/
ETH_PTP->TMSHUR = SecondValue;
/* Set the PTP Time Update Low Register with subsecond value and sign */
ETH_PTP->TMSLUR = Sign | SubSecondValue;
}
/**
* @brief Set the system time Addend value(used only when the system time is configured
* for Fine update mode).
* @param add: the PTP PTP_TSACNT Register value.
* @retval None
*/
void ETH_SetPTPTimeStampAddend(uint32_t add)
{
ETH_PTP->TSACNT = add;
}
/**
* @brief Set the Target system Time values.
* @param HighReg_Value: the PTP Expected Time High Register value.
* @param LowReg_Value: the PTP Expected Time Low Register value.
* @retval None
*/
void ETH_SetPTPTargetTime(uint32_t HighReg_Value, uint32_t LowReg_Value)
{
/* Set the PTP Expected Time High Register */
ETH_PTP->ETHR = HighReg_Value;
/* Set the PTP Expected Time Low Register */
ETH_PTP->ETLR = LowReg_Value;
}
/**
* @brief Read the value of PTP module register .
* @param ETH_PTPRegister: the PTP module register selected.
* Select one of the follwing values :
* @arg ETH_PTP_TSCTLR : Sub-Second Increment Register
* @arg ETH_PTP_SSINCR : Sub-Second Increment Register
* @arg ETH_PTP_TMSHR : Time Stamp High Register
* @arg ETH_PTP_TMSLR : Time Stamp Low Register
* @arg ETH_PTP_TMSHUR : Time Stamp High Update Register
* @arg ETH_PTP_TMSLUR : Time Stamp Low Update Register
* @arg ETH_PTP_TSACNT : Time Stamp Addend Register
* @arg ETH_PTP_ETHR : Target Time High Register
* @arg ETH_PTP_ETLR : Target Time Low Register
* @retval ETHERNET PTP Register selected value.
*/
uint32_t ETH_GetPTPRegister(uint32_t ETH_PTPRegister)
{
return (*(__IO uint32_t *)(ETH_MAC_BASE + ETH_PTPRegister));
}
/**
* @brief Initialize the DMA Tx descriptors's parameters in chain mode with PTP.
* @param DMATxDescTab: Pointer to the first Tx descriptor table
* @param DMAPTPTxDescTab: Pointer to the first PTP Tx descriptor table
* @param pTxBuff: Pointer to the first TxBuffer table
* @param TxBuffCnt: the used Tx descriptor sum in the table
* @retval None
*/
void ETH_DMAPTPTxDescChainModeInit(ETH_DMADESCTypeDef *DMATxDescTab, ETH_DMADESCTypeDef *DMAPTPTxDescTab,
uint8_t *pTxBuff, uint32_t TxBuffCnt)
{
uint32_t num = 0;
ETH_DMADESCTypeDef *DMATxDesc;
DMACurrentTxDesc = DMATxDescTab;
DMACurrentPTPTxDesc = DMAPTPTxDescTab;
/* Configuration each DMATxDesc descriptor */
for (num = 0; num < TxBuffCnt; num++) {
/* Get the pointer to the next descriptor of the Tx Desc table */
DMATxDesc = DMATxDescTab + num;
/* Set TCH bit and enable PTP with desc status */
DMATxDesc->Status = ETH_DMATXDESC_TCHM | ETH_DMATXDESC_TTSEN;
/* Set Buffer1 address pointer to application buffer */
DMATxDesc->Buffer1Addr = (uint32_t)(&pTxBuff[num * ETH_MAX_FRAME_SIZE]);
if (num < (TxBuffCnt - 1)) {
/* Buffer2NextDescAddr equal to next descriptor address in the Tx Desc table */
DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab + num + 1);
} else {
/* When it is the last descriptor, Buffer2NextDescAddr equal to first descriptor address in the Tx Desc table */
DMATxDesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab;
}
/* Set DMAPTPTxDescTab equal to DMATxDescTab */
(&DMAPTPTxDescTab[num])->Buffer1Addr = DMATxDesc->Buffer1Addr;
(&DMAPTPTxDescTab[num])->Buffer2NextDescAddr = DMATxDesc->Buffer2NextDescAddr;
}
/* When it is the last PTPdescriptor, DMAPTPTxDesc status equal to the first descriptor address in the PTPTx Desc list address */
(&DMAPTPTxDescTab[num - 1])->Status = (uint32_t) DMAPTPTxDescTab;
ETH_DMA->TDTAR = (uint32_t) DMATxDescTab;
}
/**
* @brief Initialize the DMA Rx descriptors's parameters in chain mode with PTP.
* @param DMARxDescTab: Pointer to the first Rx descriptor table
* @param DMAPTPRxDescTab: Pointer to the first PTP Rx descriptor table
* @param pRxBuff: Pointer to the first RxBuffer table
* @param RxBuffCnt: the used Rx descriptor sum in the table
* @retval None
*/
void ETH_DMAPTPRxDescChainModeInit(ETH_DMADESCTypeDef *DMARxDescTab, ETH_DMADESCTypeDef *DMAPTPRxDescTab,
uint8_t *pRxBuff, uint32_t RxBuffCnt)
{
uint32_t num = 0;
ETH_DMADESCTypeDef *DMARxDesc;
DMACurrentRxDesc = DMARxDescTab;
DMACurrentPTPRxDesc = DMAPTPRxDescTab;
/* Configuration each DMARxDesc descriptor */
for (num = 0; num < RxBuffCnt; num++) {
/* Get the pointer to the next descriptor of the Rx Desc table */
DMARxDesc = DMARxDescTab + num;
DMARxDesc->Status = ETH_DMARXDESC_BUSY;
/* Set TCH bit and buffer1 size */
DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RCHM | (uint32_t)ETH_MAX_FRAME_SIZE;
/* Set Buffer1 address pointer to application buffer */
DMARxDesc->Buffer1Addr = (uint32_t)(&pRxBuff[num * ETH_MAX_FRAME_SIZE]);
if (num < (RxBuffCnt - 1)) {
/* Buffer2NextDescAddr equal to next descriptor address in the Rx Desc table */
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + num + 1);
} else {
/* When it is the last descriptor, Buffer2NextDescAddr equal to first descriptor address in the Rx Desc table */
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
}
/* Set DMAPTPRxDescTab equal to DMARxDescTab */
(&DMAPTPRxDescTab[num])->Buffer1Addr = DMARxDesc->Buffer1Addr;
(&DMAPTPRxDescTab[num])->Buffer2NextDescAddr = DMARxDesc->Buffer2NextDescAddr;
}
/* When it is the last PTPdescriptor, DMAPTPRxDesc status equal to the first descriptor address in the PTPRx Desc table address */
(&DMAPTPRxDescTab[num - 1])->Status = (uint32_t) DMAPTPRxDescTab;
/* Update Receive Desciptor Table Address Register */
ETH_DMA->RDTAR = (uint32_t) DMARxDescTab;
}
/**
* @brief Send data with Time Stamp values of application buffer as a transmit packet.
* @param pbuf: pointer to the applicationbuffer.
* @param size: the application buffer size.
* @param PTPTxTab: Pointer to the first PTP Tx table to store Time stamp values.
* @retval The transmission with PTP result(ERROR or SUCCESS)
*/
uint32_t ETH_HandlePTPTxPkt(uint8_t *pbuf, uint16_t size, uint32_t *PTPTxTab)
{
uint32_t offset = 0, timeout = 0;
if ((DMACurrentTxDesc->Status & ETH_DMATXDESC_BUSY) != (uint32_t)RESET) {
/* Return ERROR: the descriptor is busy due to own by the DMA */
return ERROR;
}
for (offset = 0; offset < size; offset++) {
(*(__IO uint8_t *)((DMACurrentPTPTxDesc->Buffer1Addr) + offset)) = (*(pbuf + offset));
}
/* Setting the Frame Length */
DMACurrentTxDesc->ControlBufferSize = (size & (uint32_t)0x1FFF);
/* Setting the segment of frame (ETH_DMATXDESC_LSG and ETH_DMATXDESC_FSG are SET that frame is transmitted in one descriptor) */
DMACurrentTxDesc->Status |= ETH_DMATXDESC_LSG | ETH_DMATXDESC_FSG;
/* Enable the DMA transmission */
DMACurrentTxDesc->Status |= ETH_DMATXDESC_BUSY;
/* Check Tx Buffer unavailable flag status */
if ((ETH_DMA->STR & ETH_DMA_STR_TBU) != (uint32_t)RESET) {
/* Clear TBU ETHERNET DMA flag */
ETH_DMA->STR = ETH_DMA_STR_TBU;
/* Resume DMA transmission by writing to the TPER register*/
ETH_DMA->TPER = 0;
}
/* Wait for ETH_DMATXDESC_TTMSS flag to be set unless timeout */
do {
timeout++;
} while (!(DMACurrentTxDesc->Status & ETH_DMATXDESC_TTMSS) && (timeout < 0xFFFF));
/* Return ERROR due to timeout */
if (timeout == PHY_READ_TO) {
return ERROR;
}
/* Clear the DMACurrentTxDesc status register TTSS flag */
DMACurrentTxDesc->Status &= ~ETH_DMATXDESC_TTMSS;
*PTPTxTab++ = DMACurrentTxDesc->Buffer1Addr;
*PTPTxTab = DMACurrentTxDesc->Buffer2NextDescAddr;
/* Update the ETHERNET DMA current Tx descriptor pointer to the next Tx decriptor in DMA Tx decriptor talbe*/
/* Chained Mode */
if ((DMACurrentTxDesc->Status & ETH_DMATXDESC_TCHM) != (uint32_t)RESET) {
DMACurrentTxDesc = (ETH_DMADESCTypeDef *)(DMACurrentPTPTxDesc->Buffer2NextDescAddr);
if (DMACurrentPTPTxDesc->Status != 0) {
DMACurrentPTPTxDesc = (ETH_DMADESCTypeDef *)(DMACurrentPTPTxDesc->Status);
} else {
DMACurrentPTPTxDesc++;
}
}
/* Ring Mode */
else {
if ((DMACurrentTxDesc->Status & ETH_DMATXDESC_TERM) != (uint32_t)RESET) {
DMACurrentTxDesc = (ETH_DMADESCTypeDef *)(ETH_DMA->TDTAR);
DMACurrentPTPTxDesc = (ETH_DMADESCTypeDef *)(ETH_DMA->TDTAR);
} else {
DMACurrentTxDesc = (ETH_DMADESCTypeDef *)((uint32_t)DMACurrentTxDesc + ETH_DMATXDESC_SIZE + ((ETH_DMA->BCR & ETH_DMA_BCR_DPSL) >> 2));
DMACurrentPTPTxDesc = (ETH_DMADESCTypeDef *)((uint32_t)DMACurrentPTPTxDesc + ETH_DMATXDESC_SIZE + ((ETH_DMA->BCR & ETH_DMA_BCR_DPSL) >> 2));
}
}
return SUCCESS;
}
/**
* @brief Receive a packet data with Time Stamp values to application buffer.
* @param pbuf: Pointer on the application buffer.
* @param PTPRxTab: Pointer to the first PTP Rx table to store Time stamp values.
* @retval The Receive frame length with PTP(If size is equal to ERROR, the receiving unsuccessful)
*/
uint32_t ETH_HandlePTPRxPkt(uint8_t *pbuf, uint32_t *PTPRxTab)
{
uint32_t offset = 0, size = 0;
if ((DMACurrentRxDesc->Status & ETH_DMARXDESC_BUSY) != (uint32_t)RESET) {
/* Return ERROR: the descriptor is busy due to own by the DMA */
return ERROR;
}
if (((DMACurrentRxDesc->Status & ETH_DMARXDESC_ERRS) == (uint32_t)RESET) &&
((DMACurrentRxDesc->Status & ETH_DMARXDESC_LDES) != (uint32_t)RESET) &&
((DMACurrentRxDesc->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET)) {
/* Get the Frame Length exclusive CRC */
size = ((DMACurrentRxDesc->Status & ETH_DMARXDESC_FRML) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT) - 4;
for (offset = 0; offset < size; offset++) {
(*(pbuf + offset)) = (*(__IO uint8_t *)((DMACurrentPTPRxDesc->Buffer1Addr) + offset));
}
} else {
/* Return ERROR */
size = ERROR;
}
/* Check Rx Buffer unavailable flag status */
if ((ETH_DMA->STR & ETH_DMA_STR_RBU) != (uint32_t)RESET) {
/* Clear RBU ETHERNET DMA flag */
ETH_DMA->STR = ETH_DMA_STR_RBU;
/* Resume DMA reception by writing to the RPER register*/
ETH_DMA->RPER = 0;
}
*PTPRxTab++ = DMACurrentRxDesc->Buffer1Addr;
*PTPRxTab = DMACurrentRxDesc->Buffer2NextDescAddr;
/* Enable reception */
DMACurrentRxDesc->Status |= ETH_DMARXDESC_BUSY;
/* Update the ETHERNET DMA current Rx descriptor pointer to the next Rx decriptor in DMA Rx decriptor talbe*/
/* Chained Mode */
if ((DMACurrentRxDesc->ControlBufferSize & ETH_DMARXDESC_RCHM) != (uint32_t)RESET) {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)(DMACurrentPTPRxDesc->Buffer2NextDescAddr);
if (DMACurrentPTPRxDesc->Status != 0) {
DMACurrentPTPRxDesc = (ETH_DMADESCTypeDef *)(DMACurrentPTPRxDesc->Status);
} else {
DMACurrentPTPRxDesc++;
}
}
/* Ring Mode */
else {
if ((DMACurrentRxDesc->ControlBufferSize & ETH_DMARXDESC_RERR) != (uint32_t)RESET) {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)(ETH_DMA->RDTAR);
} else {
DMACurrentRxDesc = (ETH_DMADESCTypeDef *)((uint32_t)DMACurrentRxDesc + ETH_DMARXDESC_SIZE + ((ETH_DMA->BCR & ETH_DMA_BCR_DPSL) >> 2));
}
}
/* Return Frame size or ERROR */
return (size);
}
#ifndef USE_Delay
/**
* @brief Insert a delay time.
* @param nCount: specifies the delay time length.
* @retval None
*/
static void ETH_Delay(__IO uint32_t nCount)
{
__IO uint32_t time = 0;
for (time = nCount; time != 0; time--) {
}
}
#endif /* USE_Delay */
#endif /* GD32F10X_CL */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/