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

📄 lpc_enet.c

📁 NXP LPC系列AMR7的开发程序源码(LCD
💻 C
字号:
/*************************************************************************
 *
 *    Used with ICCARM and AARM.
 *
 *    (c) Copyright IAR Systems 2006
 *
 *    File name   : lpc_enet.c
 *    Description : MAC/DMA Controller with DMA (ENET) driver
 *
 *    History :
 *    1. Date        : Stanimir Bonev
 *       Author      :
 *       Description : Create
 *
 *    $Revision: 7118 $
 **************************************************************************/
#include "lpc_enet.h"

#pragma data_alignment=16
EnetDmaDesc_t EnetDmaRx;

#pragma data_alignment=16
EnetDmaDesc_t EnetDmaTx;

#pragma data_alignment=4
Int8U RxBuff[1520];
#pragma data_alignment=4
Int8U TxBuff[1520];

/*******************************************************************************
* Function Name  : ENET_RxDscrInit
* Description    : Initializes the Rx ENET descriptor chain. Single Descriptor
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/

void ENET_RxDscrInit(void)
{
  /* Initialization */
  /* Assign temp Rx array to the ENET buffer */
  EnetDmaRx.Rx.pBuffer = (pInt32U)RxBuff;

  /* Initialize RX ENET Status and control */
  EnetDmaRx.Rx.EnetRxCR.Data = 0;

  /* Initialize the next descriptor- In our case its single descriptor */
  EnetDmaRx.Rx.EnetDmaNextDesc = &EnetDmaRx;

  /* Setting the RX NEXT Descriptor Register inside the ENET */
  ENET_RXNDAR = (Int32U)&EnetDmaRx;

  /* Set the max packet size  */
  EnetDmaRx.Rx.EnetRxCR.DMA_XFERCOUNT = EMAC_MAX_PACKET_SIZE;

  /* Setting the VALID bit */
  EnetDmaRx.Rx.EnetRxSR.Valid = 1;

}

/*******************************************************************************
* Function Name  : ENET_TxDscrInit
* Description    : Initializes the Tx ENET descriptor chain with single descriptor
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/

void ENET_TxDscrInit(void)
{

  /* ENET Start Address */
  EnetDmaTx.Tx.pBuffer = (pInt32U)TxBuff;

  /* Next Descriptor Address */
  EnetDmaTx.Tx.EnetDmaNextDesc = &EnetDmaTx;

  /* Initialize ENET status and control */
  EnetDmaTx.Tx.EnetTxCR.Data = 0;

  /* Tx next set to Tx decriptor base */
  ENET_TXNDAR = (Int32U)&EnetDmaTx;

  /* Enable next enable */
  ENET_TXNDAR_bit.NPOL_EN = 1;

}
/*************************************************************************
 * Function Name:
 * Parameters: None
 *
 * Return: None
 *
 * Description: Init  MAC/DMA Controller
 *
 *************************************************************************/
void tapdev_init(void)
{
volatile Int32U i;

  EnetDmaTx.Tx.EnetTxSR.Valid = 0;
  EnetDmaRx.Rx.EnetRxSR.Valid = 0;
  // Init Sys
  SCU_PRR0_bit.RST_MAC    = 0;    // Reset
  SCU_PCGR0_bit.MAC       = 1;    // Clock enable
  SCU_PRR0_bit.RST_MAC    = 1;    // Reset release
  SCU_CLKCNTR_bit.PHYSEL  = 1;    // MII_PHYCLK Enable
  ENET_SCR_bit.SRESET     = 1;    // MAC DMA Software reset

  // Assign pins to the MII interface
  SCU_PCGR1_bit.GPIO0     = 1;    // GPIO0 Port clock runing
  SCU_PRR1_bit.RST_GPIO0  = 1;    // GPIO0 out from reset
  SCU_GPIOIN0   = 0;              // GPIO0 All pins Default Input function
  SCU_GPIOOUT1  = 0;              // GPIO0 All pins Default Input function
  SCU_PCGR1_bit.GPIO1     = 1;    // GPIO1 Port clock runing
  SCU_PRR1_bit.RST_GPIO1  = 1;    // GPIO1 out from reset
  SCU_GPIOTYPE1&= ~0x9E;          // GPIO1 1,2,3,4,7 Push-Pull outputs
  SCU_GPIOOUT1 &=~0xC3FC;         // GPIO1 1,2,3,4,7 Alt func 2
  SCU_GPIOOUT1 |= 0x82A8;         // GPIO1 1,2,3,4,7 Alt func 2
  SCU_PCGR1_bit.GPIO5     = 1;    // GPIO5 Port clock runing
  SCU_PRR1_bit.RST_GPIO5  = 1;    // GPIO5 out from reset
  SCU_GPIOTYPE5 &=~0x0C;           // GPIO5 2,3 Push-Pull outputs
  SCU_GPIOOUT5 &=~0x00F0;         // GPIO5 2,3 Alt func 2
  SCU_GPIOOUT5 |= 0x00A0;         // GPIO5 2,3 Alt func 2

  ENET_SCR_bit.SRESET = 0;        // MAC DMA Software reset release
  ENET_CCR_bit.SEL_CLK =\
    (PER_CLK == AHB_CLK)?0:1;     // Clock configuration
 // MAC Control Register
  ENET_MCR_bit.RA = 0;            // Receive filtering depend of Address filtering mode
  ENET_MCR_bit.EN = 0;            // little endian mode
  ENET_MCR_bit.PS =\
    (AHB_CLK < 50000000)?0:1;     // Prescaler bits
  ENET_MCR_bit.RCFA = 0;          // bits transmission order right to left
  ENET_MCR_bit.DRO  = 0;          // Enable the MAC controller to receive all the incoming packets
  ENET_MCR_bit.LM   = 0;          // Loopback Mode - Normal mode
  ENET_MCR_bit.FDM  = 1;          // Full duplex mode
  ENET_MCR_bit.AFM  = 0;          // MAC address perfect filtering for physical and multicast addresses
  ENET_MCR_bit.PWF  = 0;          // Wrong frames are filtered
  ENET_MCR_bit.VFM  = 0;          // VLAN Filtering Mode
  ENET_MCR_bit.ELC  = 0;          // Disable Late Collision
  ENET_MCR_bit.DBF  = 0;          // Broadcast frame reception enabled
  ENET_MCR_bit.DPR  = 0;          // Enable Packet Retry
  ENET_MCR_bit.RVFF = 1;          // Enable VCI Rx Frame filtering
  ENET_MCR_bit.APR  = 1;          // Automatic Pad Removal
  ENET_MCR_bit.BL   = 1;          // 01: #bits used from LFSR to initialize the slot-time counter = 8
  ENET_MCR_bit.DCE  = 1;          // Deferral Check Enable
  ENET_MCR_bit.RVBE = 1;          // Reception VCI Burst Enable
  ENET_MCR_bit.RCFA = 0;          // Reverse Control Frame Address disable
  // DMA Status/Control Register
  ENET_SCR_bit.RX_MAX_BURST_SIZE = 0; // 16-beat incrementing burst (INCR16)
  ENET_SCR_bit.RX_MAX_BURST_SIZE = 3; // Single transfers only (SINGLE)
  // Set MAC Physical address
  *(pInt32U)&ENET_MAL = (Int32U)(UIP_ETHADDR3 << 24) +\
             (UIP_ETHADDR2 << 16) +\
             (UIP_ETHADDR1 << 8)  +\
             UIP_ETHADDR0;
  ENET_MAH = (UIP_ETHADDR5 << 8) + UIP_ETHADDR4;
  // Put the PHY in reset mode
  ENET_MIIWriteRegister(MII_PHY_ADDR,MAC_MII_REG_XCR, 0x8000);
  // Delay to assure PHY reset
  for(i=0; i<0xFFFFF; i++);
  // Set PHY operation mode
  ENET_MIIWriteRegister(MII_PHY_ADDR,MAC_MII_REG_XCR, PHY_OPR_MODE);

  // Init Rx and Tx DMA descriptors
  ENET_TxDscrInit();
  ENET_RxDscrInit();

  // Disable DMA
  ENET_RXSTR_bit.DMA_EN = 0; // RX DMA fetching descriptors
  ENET_TXSTR_bit.DMA_EN = 0; // TX DMA fetching descriptors

  /* Reset all interrupts */
  ENET_ISR = 0xFFFFFFFF;

  /* Setup Descriptor Fetch ENET_PhyDelay for Receive Block */
  ENET_RXSTR_bit.DFETCH_DLY = 0x0100;

  /* Setup Descriptor Fetch ENET_PhyDelay for Transmit Block */
  ENET_TXSTR_bit.DFETCH_DLY = 0x0100;

  /* Set Tx underrun bit */
  ENET_TXSTR_bit.UNDER_RUN = 1;

  /* Clear the interrupts */
  ENET_IER = 0x0;

  // Enable
  ENET_MCR |= 0xc;                // Reception and Transmission Enable
  ENET_RXSTR_bit.START_FETCH = 1; // Start RX DMA fetching descriptors
}
/*************************************************************************
 * Function Name: tapdev_read
 * Parameters:
 * Return:
 *
 * Description: Read data for MAC/DMA Controller
 *
 *************************************************************************/
Int32U tapdev_read(void * pPacket)
{
  Int32U size;
  Int32U value;

  /*check for validity*/
  if(!EnetDmaRx.Rx.EnetRxSR.Valid)
  {
    /*Get the size of the packet*/
    size = ((EnetDmaRx.Rx.EnetRxSR.FrameLength) - 4);
    //MEMCOPY_L2S_BY4((u8*)ppkt, RxBuff, size); /*optimized memcopy function*/
    memcpy(pPacket, RxBuff, size);   //string.h library*/
  }
  else
  {
    return(ENET_NOK);
  }
  /* Give the buffer back to ENET */
  EnetDmaRx.Rx.EnetRxSR.Valid = 1;
  /* Start the receive operation */
  ENET_RXSTR_bit.START_FETCH = 1;
  /* Return no error */
  return size;
}
/*************************************************************************
 * Function Name: tapdev_send
 * Parameters:
 * Return:
 *
 * Description: Send data to MAC/DMA Controller
 *
 *************************************************************************/
void tapdev_send(void *pPacket, Int32U size)
{
  /* Copy the  application buffer to the driver buffer
     Using this MEMCOPY_L2L_BY4 makes the copy routine faster
     than memcpy */
  //MEMCOPY_L2S_BY4((u8*)TxBuff, (u8*)ppkt, size);
  memcpy(TxBuff, pPacket, size);

  /* Assign ENET address to Temp Tx Array */
  EnetDmaTx.Tx.pBuffer = (pInt32U)TxBuff;

  /* Setting the Frame Length*/
  EnetDmaTx.Tx.EnetTxCR.DMA_XFERCOUNT = (size&0xFFF);

  /* Start the ENET by setting the VALID bit in dmaPackStatus of current descr*/
  EnetDmaTx.Tx.EnetTxSR.Valid = 1;

  /* Start the receive operation */
  ENET_TXSTR_bit.START_FETCH = 1;
}

⌨️ 快捷键说明

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