📄 91x_enet.c
字号:
/******************** (C) COPYRIGHT 2007 STMicroelectronics ********************
* File Name : 91x_enet.c
* Author : MCD Application Team
* Version : V2.0
* Date : 12/07/2007
* Description : This file provides all the ENET software functions.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
* CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS
* A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT
* OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
* OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
* CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "91x_lib.h"
#include "string.h" //include when using memcpy function
/* Include of other module interface headers ---------------------------------*/
/* Local includes ------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Rx & Tx DMA Descriptors */
ENET_DMADSCRBase dmaRxDscrBase[ENET_RXBUFNB], dmaTxDscrBase[ENET_TXBUFNB];
/* ENET buffers */
u8 RxBuff[ENET_RXBUFNB][ENET_MAX_PACKET_SIZE], TxBuff[ENET_TXBUFNB][ENET_MAX_PACKET_SIZE];
/* Rx & Tx Buffers Counters */
vu8 RxBC = 0, TxBC = 0;
/* Rx Frame status */
ENET_RxStatus RxStatus;
/* Private function prototypes -----------------------------------------------*/
extern MEMCOPY_L2S_BY4();
static void ENET_MACControlConfig(ENET_MACConfig *MAC_Config);
static void ENET_RxDscrInit(void);
static void ENET_TxDscrInit(void);
/* Interface functions -------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : ENET_MACControlConfig(ENET_MACConfig * MAC_Config)
* Description : MAC Control Register Configuration.
* Input : MAC_Config structure.
* Output : None
* Return : None
*******************************************************************************/
void ENET_MACControlConfig(ENET_MACConfig *MAC_Config)
{
ENET_MAC->MCR = 0;
/* ReceiveALL bit */
if (MAC_Config->ReceiveALL == ENABLE)
{
ENET_MAC->MCR |= ENET_MCR_RA;
}
else
{
ENET_MAC->MCR &= ~ENET_MCR_RA;
}
/* MIIPrescaler */
ENET_MAC->MCR &= ~ENET_MCR_PS;
if ((MAC_Config->MIIPrescaler) == MIIPrescaler_2)
{
ENET_MAC->MCR |=0x1<<24;
}
/* Loopback mode: enable frame reception during transmission*/
if (MAC_Config->LoopbackMode == ENABLE)
{
ENET_MAC->MCR |= ENET_MCR_LM;
ENET_MAC->MCR &= ~ENET_MCR_DRO;
}
else
{
ENET_MAC->MCR |= ENET_MCR_DRO;
}
/* Address filtering mode */
ENET_MAC->MCR |= MAC_Config->AddressFilteringMode;
/* VLAN Filtering Mode */
ENET_MAC->MCR |= (MAC_Config->VLANFilteringMode << 15);
/*Wrong Frame Pass */
if (MAC_Config->PassWrongFrame == ENABLE)
{
ENET_MAC->MCR |= ENET_MCR_PWF;
}
else
{
ENET_MAC->MCR &= ~ENET_MCR_PWF;
}
/* Late Collision Retransmission*/
if (MAC_Config->LateCollision == ENABLE)
{
ENET_MAC->MCR |= ENET_MCR_ELC;
}
else
{
ENET_MAC->MCR &= ~ENET_MCR_ELC;
}
/* Broadcast Frame Reception */
if (MAC_Config->BroadcastFrameReception == ENABLE)
{
ENET_MAC->MCR &= ~ENET_MCR_DBF;
}
else
{
ENET_MAC->MCR |=ENET_MCR_DBF;
}
/* PacketRetry */
if (MAC_Config->PacketRetry == ENABLE)
{
ENET_MAC->MCR &= ~ENET_MCR_DPR;
}
else
{
ENET_MAC->MCR |= ENET_MCR_DPR;
}
/* RxFrameFiltering */
if (MAC_Config->RxFrameFiltering == ENABLE)
{
ENET_MAC->MCR |= ENET_MCR_RVFF;
}
else
{
ENET_MAC->MCR &= ~ENET_MCR_RVFF;
}
/* AutomaticPadRemoval */
if (MAC_Config->AutomaticPadRemoval == ENABLE)
{
ENET_MAC->MCR |= ENET_MCR_APR;
}
else
{
ENET_MAC->MCR &= ~ENET_MCR_APR;
}
/* DefferalCheck */
if (MAC_Config->DeferralCheck == ENABLE)
{
ENET_MAC->MCR |= ENET_MCR_DCE;
}
else
{
ENET_MAC->MCR &= ~ENET_MCR_DCE;
}
}
/*******************************************************************************
* Function Name : ENET_GetRxStatus
* Description : Get Rx status flags.
* Input : RxStatus : pointer to structure of type ENET_RxStatus.
* Output : None
* Return : None
*******************************************************************************/
void ENET_GetRxStatus(ENET_RxStatus * RxStatus)
{
u32 regValue;
regValue = ENET_MAC->MRS;
RxStatus->FrameAborted = (FlagStatus)((ENET_MRS_FA & regValue) >> 31);
RxStatus->PacketFilter = (FlagStatus)((ENET_MRS_PF & regValue) >> 30);
RxStatus->FilteringFail = (FlagStatus)((ENET_MRS_FF & regValue) >> 29);
RxStatus->BroadCastFrame = (FlagStatus)((ENET_MRS_BF & regValue) >> 28);
RxStatus->MulticastFrame = (FlagStatus)((ENET_MRS_MCF & regValue) >> 27);
RxStatus->UnsupportedControFrame = (FlagStatus)((ENET_MRS_UCF & regValue) >> 26);
RxStatus->ControlFrame = (FlagStatus)((ENET_MRS_CF & regValue) >> 25);
RxStatus->LengthError = (FlagStatus)((ENET_MRS_LE & regValue) >> 24);
RxStatus->Vlan2Tag = (FlagStatus)((ENET_MRS_VL2 & regValue) >> 23);
RxStatus->Vlan1Tag = (FlagStatus)((ENET_MRS_VL1 & regValue) >> 22);
RxStatus->CRCError = (FlagStatus)((ENET_MRS_CE & regValue) >> 21);
RxStatus->ExtraBit = (FlagStatus)((ENET_MRS_EB & regValue) >> 20);
RxStatus->MIIError = (FlagStatus)((ENET_MRS_ME & regValue) >> 19);
RxStatus->FrameType = (FlagStatus)((ENET_MRS_FT & regValue) >> 18);
RxStatus->LateCollision = (FlagStatus)((ENET_MRS_LC & regValue) >> 17);
RxStatus->OverLength = (FlagStatus)((ENET_MRS_OL & regValue) >> 16);
RxStatus->RuntFrame = (FlagStatus)((ENET_MRS_RF & regValue) >> 15);
RxStatus->WatchDogTimout = (FlagStatus)((ENET_MRS_WT & regValue) >> 14);
RxStatus->FalseCarrierIndication = (FlagStatus)((ENET_MRS_FCI & regValue) >> 13);
RxStatus->FrameLength = (u16)(ENET_MRS_FL & regValue);
}
/*******************************************************************************
* Function Name : ENET_GetTxStatus
* Description : Get Tx status flags.
* Input : TxStatus: pointer on structure of type ENET_TxStatus.
* Output : None
* Return : None
*******************************************************************************/
void ENET_GetTxStatus(ENET_TxStatus * TxStatus)
{
u32 regValue;
regValue = ENET_MAC->MTS;
TxStatus->PacketRetry = (FlagStatus)((ENET_MTS_PR®Value) >> 31);
TxStatus->ByteCount = (u16)((ENET_MTS_BC®Value) >> 18);
TxStatus->CollisionCount = (u8)((ENET_MTS_CC®Value) >> 10);
TxStatus->LateCollisionObserved = (FlagStatus)((ENET_MTS_LCO®Value) >> 9);
TxStatus->Deffered = (FlagStatus)((ENET_MTS_DEF®Value) >> 8);
TxStatus->UnderRun = (FlagStatus)((ENET_MTS_UR®Value) >> 7);
TxStatus->ExcessiveCollision = (FlagStatus)((ENET_MTS_EC®Value) >> 6);
TxStatus->LateCollision = (FlagStatus)((ENET_MTS_LC®Value) >> 5);
TxStatus->ExcessiveDefferal = (FlagStatus)((ENET_MTS_ED®Value) >> 4);
TxStatus->LossOfCarrier = (FlagStatus)((ENET_MTS_LOC®Value) >> 3);
TxStatus->NoCarrier = (FlagStatus)((ENET_MTS_NC®Value) >> 2);
TxStatus->FrameAborted = (FlagStatus)(ENET_MTS_FA®Value);
}
/*******************************************************************************
* Function Name : ENET_SetOperatingMode
* Description : Sets the Operating mode.
* Input : ENET_OperatingMode: the operating mode of MAC. This parameter
* can be any the following values:
* - AUTO_NEGOTIATION
* - FULLDUPLEX_100M
* - HALFDUPLEX_100M
* - FULLDUPLEX_10M
* - HALFDUPLEX_10M
* Output : None
* Return : None
*******************************************************************************/
void ENET_SetOperatingMode(u32 ENET_OperatingMode)
{
u32 regValue;
if(ENET_OperatingMode == AUTO_NEGOTIATION)
{
/* The Link Status bit is a Latching High bit, so we need to read twice to get the real value */
ENET_MIIReadReg (PHY_ADDRESS, PHY_XSR);
/* We wait for linked satus... */
while( !(ENET_MIIReadReg (PHY_ADDRESS, PHY_XSR) & PHY_Linked_Status) );
/* Enable Auto-Negotiation */
ENET_MIIWriteReg (PHY_ADDRESS, PHY_XCR, PHY_AutoNegotiation);
/* Wait until the autonegotiation will be completed */
while( !(ENET_MIIReadReg (PHY_ADDRESS, PHY_XSR) & PHY_AutoNego_Complete) );
/* Read the result of the autonegotiation */
regValue = ENET_MIIReadReg (PHY_ADDRESS, PHY_XCIIS);
/* Configure the MAC with the Duplex Mode fixed by the autonegotiation process */
if( regValue & PHY_Configured_Speed)
{
ENET_MAC->MCR |=ENET_MCR_FDM; /* Full Duplex Mode */
ENET_MAC->MCR &=~ENET_MCR_DRO; /* Enable frame reception during transmission */
}
else
{
ENET_MAC->MCR &=~ENET_MCR_FDM; /* Half Duplex Mode */
ENET_MAC->MCR |=ENET_MCR_DRO; /* Disable frame reception during transmission */
}
}
else
{
if (ENET_OperatingMode==PHY_FULLDUPLEX_100M ||ENET_OperatingMode==PHY_FULLDUPLEX_10M )
{
ENET_MAC->MCR |=ENET_MCR_FDM; /* Full Duplex Mode */
ENET_MAC->MCR &=~ENET_MCR_DRO; /* Enable Frame Reception During Transmission */
}
else
{
ENET_MAC->MCR &=~ENET_MCR_FDM; /* Half Duplex Mode */
ENET_MAC->MCR |=ENET_MCR_DRO; /* Disable Frame Reception During Transmission */
}
/* Set the operating mode in the PHY device */
ENET_MIIWriteReg(PHY_ADDRESS,PHY_XCR, ENET_OperatingMode);
}
}
/*******************************************************************************
* Function Name : ENET_MIIWriteReg
* Description : Writes a value on the PHY registers.
* Input : - phyDev PHY device address.
* - phyReg PHY register to be written.
* - phyVal PHY register value.
* Output : None
* Return : None
*******************************************************************************/
void ENET_MIIWriteReg (u8 phyDev, u8 phyReg, u32 phyVal)
{
u32 address;
u32 result; /* temporary result for address register status */
u32 timeout;
/* Prepare the MII register address */
address = 0;
address |= ((phyDev<<11) & ENET_MIIA_PADDR); /* set the PHY address */
address |= ((phyReg<<6) & ENET_MIIA_RADDR); /* select the corresponding register */
address |= ENET_MIIA_WR; /* in write mode */
address |= ENET_MIIA_BUSY;
/* Check for the Busy flag */
timeout=0;
do
{
timeout++;
result = ENET_MAC->MIIA;
} while ((result & ENET_MIIA_BUSY) && (timeout < (u32 )MII_WRITE_TO));
/* Give the value to the MII data register */
ENET_MAC->MIID = (phyVal & ENET_MIID_RDATA);
/* Write the result value into the MII Address register */
ENET_MAC->MIIA = address;
/* Check for the Busy flag */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -