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

📄 91x_enet.c

📁 STR912 arm9实现的以太网通信程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************** (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&regValue) >> 31);
  TxStatus->ByteCount          = (u16)((ENET_MTS_BC&regValue) >> 18);
  TxStatus->CollisionCount     = (u8)((ENET_MTS_CC&regValue) >> 10);
  TxStatus->LateCollisionObserved = (FlagStatus)((ENET_MTS_LCO&regValue) >> 9);
  TxStatus->Deffered           = (FlagStatus)((ENET_MTS_DEF&regValue) >> 8);
  TxStatus->UnderRun           = (FlagStatus)((ENET_MTS_UR&regValue) >> 7);
  TxStatus->ExcessiveCollision = (FlagStatus)((ENET_MTS_EC&regValue) >> 6);
  TxStatus->LateCollision      = (FlagStatus)((ENET_MTS_LC&regValue) >> 5);
  TxStatus->ExcessiveDefferal  = (FlagStatus)((ENET_MTS_ED&regValue) >> 4);
  TxStatus->LossOfCarrier      = (FlagStatus)((ENET_MTS_LOC&regValue) >> 3);
  TxStatus->NoCarrier          = (FlagStatus)((ENET_MTS_NC&regValue) >> 2);
  TxStatus->FrameAborted       = (FlagStatus)(ENET_MTS_FA&regValue);
}

/*******************************************************************************
* 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 + -