📄 stm32_eth.c
字号:
ETH_InitStruct->ETH_DeferralCheck);
/* Write to ETHERNET MACCR */
ETH->MACCR = (uint32_t)tmpreg;
/*----------------------- ETHERNET MACFFR Configuration --------------------*/
/* Set the RA bit according to ETH_ReceiveAll value */
/* Set the SAF and SAIF bits according to ETH_SourceAddrFilter value */
/* Set the PCF bit according to ETH_PassControlFrames value */
/* Set the DBF bit according to ETH_BroadcastFramesReception value */
/* Set the DAIF bit according to ETH_DestinationAddrFilter value */
/* Set the PR bit according to ETH_PromiscuousMode value */
/* Set the PM, HMC and HPF bits according to ETH_MulticastFramesFilter value */
/* Set the HUC and HPF bits according to ETH_UnicastFramesFilter value */
/* Write to ETHERNET MACFFR */
ETH->MACFFR = (uint32_t)(ETH_InitStruct->ETH_ReceiveAll |
ETH_InitStruct->ETH_SourceAddrFilter |
ETH_InitStruct->ETH_PassControlFrames |
ETH_InitStruct->ETH_BroadcastFramesReception |
ETH_InitStruct->ETH_DestinationAddrFilter |
ETH_InitStruct->ETH_PromiscuousMode |
ETH_InitStruct->ETH_MulticastFramesFilter |
ETH_InitStruct->ETH_UnicastFramesFilter);
/*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
/* Write to ETHERNET MACHTHR */
ETH->MACHTHR = (uint32_t)ETH_InitStruct->ETH_HashTableHigh;
/* Write to ETHERNET MACHTLR */
ETH->MACHTLR = (uint32_t)ETH_InitStruct->ETH_HashTableLow;
/*----------------------- ETHERNET MACFCR Configuration --------------------*/
/* Get the ETHERNET MACFCR value */
tmpreg = ETH->MACFCR;
/* Clear xx bits */
tmpreg &= MACFCR_CLEAR_Mask;
/* Set the PT bit according to ETH_PauseTime value */
/* Set the DZPQ bit according to ETH_ZeroQuantaPause value */
/* Set the PLT bit according to ETH_PauseLowThreshold value */
/* Set the UP bit according to ETH_UnicastPauseFrameDetect value */
/* Set the RFE bit according to ETH_ReceiveFlowControl value */
/* Set the TFE bit according to ETH_TransmitFlowControl value */
tmpreg |= (uint32_t)((ETH_InitStruct->ETH_PauseTime << 16) |
ETH_InitStruct->ETH_ZeroQuantaPause |
ETH_InitStruct->ETH_PauseLowThreshold |
ETH_InitStruct->ETH_UnicastPauseFrameDetect |
ETH_InitStruct->ETH_ReceiveFlowControl |
ETH_InitStruct->ETH_TransmitFlowControl);
/* Write to ETHERNET MACFCR */
ETH->MACFCR = (uint32_t)tmpreg;
/*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
/* Set the ETV bit according to ETH_VLANTagComparison value */
/* Set the VL bit according to ETH_VLANTagIdentifier value */
ETH->MACVLANTR = (uint32_t)(ETH_InitStruct->ETH_VLANTagComparison |
ETH_InitStruct->ETH_VLANTagIdentifier);
/*-------------------------------- DMA Config ------------------------------*/
/*----------------------- ETHERNET DMAOMR Configuration --------------------*/
/* Get the ETHERNET DMAOMR value */
tmpreg = ETH->DMAOMR;
/* Clear xx bits */
tmpreg &= DMAOMR_CLEAR_Mask;
/* Set the DT bit according to ETH_DropTCPIPChecksumErrorFrame value */
/* Set the RSF bit according to ETH_ReceiveStoreForward value */
/* Set the DFF bit according to ETH_FlushReceivedFrame value */
/* Set the TSF bit according to ETH_TransmitStoreForward value */
/* Set the TTC bit according to ETH_TransmitThresholdControl value */
/* Set the FEF bit according to ETH_ForwardErrorFrames value */
/* Set the FUF bit according to ETH_ForwardUndersizedGoodFrames value */
/* Set the RTC bit according to ETH_ReceiveThresholdControl value */
/* Set the OSF bit according to ETH_SecondFrameOperate value */
tmpreg |= (uint32_t)(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame |
ETH_InitStruct->ETH_ReceiveStoreForward |
ETH_InitStruct->ETH_FlushReceivedFrame |
ETH_InitStruct->ETH_TransmitStoreForward |
ETH_InitStruct->ETH_TransmitThresholdControl |
ETH_InitStruct->ETH_ForwardErrorFrames |
ETH_InitStruct->ETH_ForwardUndersizedGoodFrames |
ETH_InitStruct->ETH_ReceiveThresholdControl |
ETH_InitStruct->ETH_SecondFrameOperate);
/* Write to ETHERNET DMAOMR */
ETH->DMAOMR = (uint32_t)tmpreg;
/*----------------------- ETHERNET DMABMR Configuration --------------------*/
/* Set the AAL bit according to ETH_AddressAlignedBeats value */
/* Set the FB bit according to ETH_FixedBurst value */
/* Set the RPBL and 4*PBL bits according to ETH_RxDMABurstLength value */
/* Set the PBL and 4*PBL bits according to ETH_TxDMABurstLength value */
/* Set the DSL bit according to ETH_DesciptorSkipLength value */
/* Set the PR and DA bits according to ETH_DMAArbitration value */
ETH->DMABMR = (uint32_t)(ETH_InitStruct->ETH_AddressAlignedBeats |
ETH_InitStruct->ETH_FixedBurst |
ETH_InitStruct->ETH_RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
ETH_InitStruct->ETH_TxDMABurstLength |
(ETH_InitStruct->ETH_DescriptorSkipLength << 2) |
ETH_InitStruct->ETH_DMAArbitration |
ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
/* Return Ethernet configuration success */
return ETH_SUCCESS;
}
/**
* @brief Fills each ETH_InitStruct member with its default value.
* @param ETH_InitStruct: pointer to a ETH_InitTypeDef structure
* which will be initialized.
* @retval : None
*/
void ETH_StructInit(ETH_InitTypeDef* ETH_InitStruct)
{
/* ETH_InitStruct members default value */
/*------------------------ MAC -----------------------------------*/
ETH_InitStruct->ETH_AutoNegotiation = ETH_AutoNegotiation_Disable;
ETH_InitStruct->ETH_Watchdog = ETH_Watchdog_Enable;
ETH_InitStruct->ETH_Jabber = ETH_Jabber_Enable;
ETH_InitStruct->ETH_InterFrameGap = ETH_InterFrameGap_96Bit;
ETH_InitStruct->ETH_CarrierSense = ETH_CarrierSense_Enable;
ETH_InitStruct->ETH_Speed = ETH_Speed_10M;
ETH_InitStruct->ETH_ReceiveOwn = ETH_ReceiveOwn_Enable;
ETH_InitStruct->ETH_LoopbackMode = ETH_LoopbackMode_Disable;
ETH_InitStruct->ETH_Mode = ETH_Mode_HalfDuplex;
ETH_InitStruct->ETH_ChecksumOffload = ETH_ChecksumOffload_Disable;
ETH_InitStruct->ETH_RetryTransmission = ETH_RetryTransmission_Enable;
ETH_InitStruct->ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
ETH_InitStruct->ETH_BackOffLimit = ETH_BackOffLimit_10;
ETH_InitStruct->ETH_DeferralCheck = ETH_DeferralCheck_Disable;
ETH_InitStruct->ETH_ReceiveAll = ETH_ReceiveAll_Disable;
ETH_InitStruct->ETH_SourceAddrFilter = ETH_SourceAddrFilter_Disable;
ETH_InitStruct->ETH_PassControlFrames = ETH_PassControlFrames_BlockAll;
ETH_InitStruct->ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable;
ETH_InitStruct->ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal;
ETH_InitStruct->ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
ETH_InitStruct->ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
ETH_InitStruct->ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
ETH_InitStruct->ETH_HashTableHigh = 0x0;
ETH_InitStruct->ETH_HashTableLow = 0x0;
ETH_InitStruct->ETH_PauseTime = 0x0;
ETH_InitStruct->ETH_ZeroQuantaPause = ETH_ZeroQuantaPause_Disable;
ETH_InitStruct->ETH_PauseLowThreshold = ETH_PauseLowThreshold_Minus4;
ETH_InitStruct->ETH_UnicastPauseFrameDetect = ETH_UnicastPauseFrameDetect_Disable;
ETH_InitStruct->ETH_ReceiveFlowControl = ETH_ReceiveFlowControl_Disable;
ETH_InitStruct->ETH_TransmitFlowControl = ETH_TransmitFlowControl_Disable;
ETH_InitStruct->ETH_VLANTagComparison = ETH_VLANTagComparison_16Bit;
ETH_InitStruct->ETH_VLANTagIdentifier = 0x0;
/*------------------------ DMA -----------------------------------*/
ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Disable;
ETH_InitStruct->ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Enable;
ETH_InitStruct->ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Disable;
ETH_InitStruct->ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
ETH_InitStruct->ETH_TransmitThresholdControl = ETH_TransmitThresholdControl_64Bytes;
ETH_InitStruct->ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;
ETH_InitStruct->ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Disable;
ETH_InitStruct->ETH_ReceiveThresholdControl = ETH_ReceiveThresholdControl_64Bytes;
ETH_InitStruct->ETH_SecondFrameOperate = ETH_SecondFrameOperate_Disable;
ETH_InitStruct->ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable;
ETH_InitStruct->ETH_FixedBurst = ETH_FixedBurst_Disable;
ETH_InitStruct->ETH_RxDMABurstLength = ETH_RxDMABurstLength_1Beat;
ETH_InitStruct->ETH_TxDMABurstLength = ETH_TxDMABurstLength_1Beat;
ETH_InitStruct->ETH_DescriptorSkipLength = 0x0;
ETH_InitStruct->ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_1_1;
}
/**
* @brief Enables ENET MAC and DMA reception/transmission
* @param None
* @retval : None
*/
void ETH_Start(void)
{
/* Enable transmit state machine of the MAC for transmission on the MII */
ETH_MACTransmissionCmd(ENABLE);
/* Flush Transmit FIFO */
ETH_FlushTransmitFIFO();
/* Enable receive state machine of the MAC for reception from the MII */
ETH_MACReceptionCmd(ENABLE);
/* Start DMA transmission */
ETH_DMATransmissionCmd(ENABLE);
/* Start DMA reception */
ETH_DMAReceptionCmd(ENABLE);
}
/**
* @brief Transmits a packet, from application buffer, pointed by ppkt.
* @param ppkt: pointer to application packet buffer to transmit.
* @param FrameLength: Tx Packet size.
* @retval : ETH_ERROR: in case of Tx desc owned by DMA
* ETH_SUCCESS: for correct transmission
*/
uint32_t ETH_HandleTxPkt(uint8_t *ppkt, uint16_t FrameLength)
{
uint32_t offset = 0;
/* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET)
{
/* Return ERROR: OWN bit set */
return ETH_ERROR;
}
/* Copy the frame to be sent into memory pointed by the current ETHERNET DMA Tx descriptor */
for(offset=0; offset<FrameLength; offset++)
{
(*(__IO uint8_t *)((DMATxDescToSet->Buffer1Addr) + offset)) = (*(ppkt + offset));
}
/* Setting the Frame Length: bits[12:0] */
DMATxDescToSet->ControlBufferSize = (FrameLength & ETH_DMATxDesc_TBS1);
/* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
/* When Tx Buffer unavailable flag is set: clear it and resume transmission */
if ((ETH->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)
{
/* Clear TBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_TBUS;
/* Resume DMA transmission*/
ETH->DMATPDR = 0;
}
/* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
/* Chained Mode */
if((DMATxDescToSet->Status & ETH_DMATxDesc_TCH) != (uint32_t)RESET)
{
/* Selects the next DMA Tx descriptor list for next buffer to send */
DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);
}
else /* Ring Mode */
{
if((DMATxDescToSet->Status & ETH_DMATxDesc_TER) != (uint32_t)RESET)
{
/* Selects the first DMA Tx descriptor for next buffer to send: last Tx descriptor was used */
DMATxDescToSet = (ETH_DMADESCTypeDef*) (ETH->DMATDLAR);
}
else
{
/* Selects the next DMA Tx descriptor list for next buffer to send */
DMATxDescToSet = (ETH_DMADESCTypeDef*) ((uint32_t)DMATxDescToSet + 0x10 + ((ETH->DMABMR & ETH_DMABMR_DSL) >> 2));
}
}
/* Return SUCCESS */
return ETH_SUCCESS;
}
/**
* @brief Receives a packet and copies it to memory pointed by ppkt.
* @param ppkt: pointer to application packet receive buffer.
* @retval : ETH_ERROR: if there is error in reception
* framelength: received packet size if packet reception is correct
*/
uint32_t ETH_HandleRxPkt(uint8_t *ppkt)
{
uint32_t offset = 0, framelength = 0;
/* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
if((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) != (uint32_t)RESET)
{
/* Return error: OWN bit set */
return ETH_ERROR;
}
if(((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET))
{
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
framelength = ((DMARxDescToGet->Status & ETH_DMARxDesc_FL) >> ETH_DMARxDesc_FrameLengthShift) - 4;
/* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */
for(offset=0; offset<framelength; offset++)
{
(*(ppkt + offset)) = (*(__IO uint8_t *)((DMARxDescToGet->Buffer1Addr) + offset));
}
}
else
{
/* Return ERROR */
framelength = ETH_ERROR;
}
/* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA */
DMARxDescToGet->Status = ETH_DMARxDesc_OWN;
/* When Rx Buffer unavailable flag is set: clear it and resume reception */
if ((ETH->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
ETH->DMARPDR = 0;
}
/* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor */
/* Chained Mode */
if((DMARxDescToGet->ControlBufferSize & ETH_DMARxDesc_RCH) != (uint32_t)RESET)
{
/* Selects the next DMA Rx descriptor list for next buffer to read */
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
}
else /* Ring Mode */
{
if((DMARxDescToGet->ControlBufferSize & ETH_DMARxDesc_RER) != (uint32_t)RESET)
{
/* Selects the first DMA Rx descriptor for next buffer to read: last Rx descriptor was used */
DMARxDescToGet = (ETH_DMADESCTypeDef*) (ETH->DMARDLAR);
}
else
{
/* Selects the next DMA Rx descriptor list for next buffer to read */
DMARxDescToGet = (ETH_DMADESCTypeDef*) ((uint32_t)DMARxDescToGet + 0x10 + ((ETH->DMABMR & ETH_DMABMR_DSL) >> 2));
}
}
/* Return Frame Length/ERROR */
return (framelength);
}
/**
* @brief Get the size of received the received packet.
* @param None
* @retval : framelength: received packet size
*/
uint32_t ETH_GetRxPktSize(void)
{
uint32_t frameLength = 0;
if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET) &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -