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

📄 91x_enet.c

📁 STR912 arm9实现的以太网通信程序
💻 C
📖 第 1 页 / 共 3 页
字号:
  timeout=0;
  do
  {
    timeout++;
    result = ENET_MAC->MIIA;
  } while ((result & ENET_MIIA_BUSY) && (timeout < (u32 )MII_WRITE_TO));

}

/*******************************************************************************
* Function Name  : ENET_MIIReadReg
* Description    : Writes a value on the PHY
* Input          : - phyDev PHY device address
*                  - phyReg PHY register to be read
* Output         : None
* Return         : The read value (16 bits)
*******************************************************************************/
u32 ENET_MIIReadReg (u8 phyDev, u8 phyReg )
{
  u32 regValue;
  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 read 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_READ_TO));

  /* write the result value into the MII Address register */
  ENET_MAC->MIIA = address;

  /* Check for the Busy flag */
  timeout = 0;

  do
  {
    timeout++;
    result = ENET_MAC->MIIA;
  } while ((result & ENET_MIIA_BUSY) && (timeout < (u32 )MII_READ_TO));

  /* Read the result value from data register*/
  regValue = ENET_MAC->MIID;

  return (regValue & ENET_MIID_RDATA);
}

/*******************************************************************************
* Function Name  : ENET_RxDscrInit
* Description    : Initializes the Rx ENET descriptor chain.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void ENET_RxDscrInit(void)
{
  int i;
  
  for(i=0; i < ENET_RXBUFNB; )
  {
    /* Assign temp Rx array to the ENET buffer */
    dmaRxDscrBase[i].dmaAddr = (u32)&RxBuff[i][0];
    
    /* Initialize ENET RX Control */
    dmaRxDscrBase[i].dmaCntl = ENET_MAX_PACKET_SIZE | ENET_RXCR_NXTEN;
    
    /* Setting the VALID bit */
    dmaRxDscrBase[i].dmaPackStatus = ENET_DSCR_RX_STATUS_VALID_MSK;

    /* Initialize the next descriptor with the Next Descriptor Polling Enable */
    if(i < ENET_RXBUFNB-1)
    {
      dmaRxDscrBase[i].dmaNext = (u32) &dmaRxDscrBase[i+1] | ENET_RXNDAR_NPOL_EN;
    }
    else
    {
      dmaRxDscrBase[i].dmaNext = (u32) &dmaRxDscrBase[0] | ENET_RXNDAR_NPOL_EN;
    }
    
    i++;
  }
  
  /* Setting the RX NEXT Descriptor Register inside the ENET with the Next Descriptor Polling Enable*/
  ENET_DMA->RXNDAR = ((u32)&dmaRxDscrBase[0]) | ENET_RXNDAR_NPOL_EN;
  
}

/*******************************************************************************
* Function Name  : ENET_TxDscrInit
* Description    : Initializes the Tx ENET descriptor chain
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void ENET_TxDscrInit(void)
{
  int i;
  
  for(i=0; i < ENET_TXBUFNB; )
  {
    /* ENET DMA Start Address */
    dmaTxDscrBase[i].dmaAddr = (u32)TxBuff[i];

    /* Initialize ENET TX Control */
    dmaTxDscrBase[i].dmaCntl = ENET_TXCR_NXTEN;
  
    /* Initialize the Packet Status */
    dmaTxDscrBase[i].dmaPackStatus = 0;
  
    /* Initialize the next descriptor with the Next Descriptor Polling Enable */
    if(i < ENET_TXBUFNB-1)
    {
      dmaTxDscrBase[i].dmaNext = (u32) &dmaTxDscrBase[i+1] | ENET_TXNDAR_NPOL_EN;
    }
    else
    {
      dmaTxDscrBase[i].dmaNext = (u32) &dmaTxDscrBase[0] | ENET_TXNDAR_NPOL_EN;
    }
    
    i++;
  }

  /* Setting the TX NEXT Descriptor Register inside the ENET with the Next Descriptor Polling Enable*/
  ENET_DMA->TXNDAR = ((u32)dmaTxDscrBase) | ENET_TXNDAR_NPOL_EN;
  
}

/*******************************************************************************
* Function Name  : ENET_Init
* Description    : ENET MAC, DMA and PHY device initializations
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void ENET_Init (ENET_MACConfig *MAC_Config)
{

  u32 i;
  u32 regValue;
  u32 macAddrLow, macAddrHigh;
  
  /* MAC initialization ------------------------------------------------------*/
  
  /* De-assert the SRESET bit of ENET + MAC devices */
  ENET_DMA->SCR &= ~ENET_SCR_SRESET;
 
  /* Configure MAC control register */
  ENET_MACControlConfig(MAC_Config);
  
  /* MAC address low setting */
  macAddrLow  = (MAC_ADDR3 << 24) + (MAC_ADDR2 << 16) + \
                (MAC_ADDR1 << 8) + MAC_ADDR0;
                                        
  /* MAC address high setting */                    
  macAddrHigh = (MAC_ADDR5 << 8) + MAC_ADDR4;
                                          
  /* Write the MAC address Low Register */
  ENET_MAC->MAH = macAddrHigh;                  
                                            
  /* Write the MAC address High Register */ 
  ENET_MAC->MAL = macAddrLow;
  
  /* Multicast address low setting */
  macAddrLow  = (MCAST_ADDR3 << 24) + (MCAST_ADDR2 << 16) + \
                (MCAST_ADDR1 << 8) + MCAST_ADDR0;
                                        
  /* Multicast address high setting */                    
  macAddrHigh = (MCAST_ADDR5 << 8) + MCAST_ADDR4;
                                          
  /* Write the Multicast address Low Register */
  ENET_MAC->MCHA = macAddrHigh;                  
                                            
  /* Write the Multicast address High Register */ 
  ENET_MAC->MCLA = macAddrLow;
  
  /* VLAN initialization */
  ENET_MAC->VL1 = (VLANID1 << 16) | VLANTAG1;
  ENET_MAC->VL2 = (VLANID2 << 16) | VLANTAG2;
    
  /* ENET DMA initialisation -------------------------------------------------*/ 
  
  /* Read the ENET DMA Status and Control Register */
  regValue = ENET_DMA->SCR;

  /* Setup Tx Max burst size */
  regValue &= ~(u32)ENET_SCR_TX_MAX_BURST_SZ;
  regValue |= (u32)ENET_SCR_TX_MAX_BURST_SZ_VAL;

  /* Setup Rx Max Burst size */
  regValue &= ~(u32)ENET_SCR_RX_MAX_BURST_SZ;
  regValue |= (u32)ENET_SCR_RX_MAX_BURST_SZ_VAL;

  /* Write Tx & Rx burst size to the ENET status and control register */
  ENET_DMA->SCR = regValue;

  /* Initialize Rx and Tx descriptors in memory */
  ENET_TxDscrInit();
  ENET_RxDscrInit();                                          
 
  /* PHY DEVICE initialization and OPERATING MODE setting --------------------*/
  
  /* Put the PHY in reset mode */
  ENET_MIIWriteReg(PHY_ADDRESS,PHY_XCR, PHY_Reset_Control);

  /* Delay to assure PHY reset */
  for(i=PHY_ResetDelay; i!=0; i--)
  {
    regValue = (u32) i;
  }

}

/*******************************************************************************
* Function Name  : ENET_Start
* Description    : Enables ENET MAC reception / transmission & starts DMA fetch
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void  ENET_Start ( void)
{
  u32 regValue;
  
  /* Force a ENET abort by software for the receive block */
   ENET_DMA->RXSTR &= ~ENET_RXSTR_DMA_EN;

  /* Force a ENET abort by software for the transmit block */
   ENET_DMA->TXSTR &= ~ENET_TXSTR_DMA_EN;

  /* Reset all interrupts */
  ENET_DMA->ISR = ENET_IT_All;

  /* Setup Descriptor Fetch ENET_PhyDelay for Receive Block */
  regValue = ENET_DMA->RXSTR;
  regValue &= ~ENET_RXSTR_DFETCH_DLY;
  regValue |= ENET_RXSTR_DFETCH_DEFAULT;
  ENET_DMA->RXSTR=  regValue;

  /* Setup Descriptor Fetch ENET_PhyDelay for Transmit Block */
  regValue = ENET_DMA->TXSTR;
  regValue &= ~ENET_TXSTR_DFETCH_DLY;
  regValue |= ENET_TXSTR_DFETCH_DEFAULT;
  ENET_DMA->TXSTR = regValue;

  /* Set Tx underrun bit */
  regValue &= ~ENET_TXSTR_URUN;
  regValue |= ENET_TXSTR_URUN;
  ENET_DMA->TXSTR = regValue;

  /* Clear the interrupts */
  ENET_DMA->IER = ~ENET_IT_All;

  /* MAC TX enable */
  ENET_MAC->MCR|= ENET_MCR_TE;

  /* MAC RX enable */
  ENET_MAC->MCR|= ENET_MCR_RE;

  /* Start the RX DMA Fetch */
  ENET_DMA->RXSTR|= ENET_RXSTR_FETCH;
  
}

/*******************************************************************************
* Function Name  : ENET_RxBuff_Free
* Description    : Gives the current buffer back to ENET DMA
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void ENET_UpdateRxDscr(void)
{
  /* Give the buffer back to ENET */
  dmaRxDscrBase[RxBC].dmaPackStatus = ENET_DSCR_RX_STATUS_VALID_MSK;
  
  /* Update the Rx Buffers Counter */
  RxBC++;
  if( RxBC >=ENET_RXBUFNB ) 
  {
    RxBC=0;
  }
}

/********************************************************************************
* Function Name  : ENET_HandleRxPkt
* Description    : Receives a packet and copies it to memory pointed by ppkt.
* Input          : ppkt: pointer on application receive buffer.
* Output         : None
* Return         : ERROR - If there is no packet
*                : The size of the received packet  - If there is a packet
*******************************************************************************/
u32 ENET_HandleRxPkt ( void *ppkt)
{ 
  u16 size;

  /* Check if the descriptor is owned by the ENET or CPU */
  if(dmaRxDscrBase[RxBC].dmaPackStatus & ENET_DSCR_RX_STATUS_VALID_MSK)
  {
    /* Return error */
    return ERROR;
  }
  
  /* Get the size of the packet */
  size = ((dmaRxDscrBase[RxBC].dmaPackStatus & 0x7ff) - 4);
  
  /* Get the status of the packet */
  ENET_GetRxStatus(&RxStatus);
    
  if((size!=0) && (RxStatus.FrameAborted==RESET))
  {
    /* Copy the received frame into the ENET DMA current Rx buffer */
      MEMCOPY_L2S_BY4((u8*)ppkt, RxBuff[RxBC], size); /* optimized memcopy function */ 
    //memcpy(ppkt, RxBuff[RxBC], size); /* string.h library */
  }
  else
  {
    size = ERROR;
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -