📄 lpc_enet.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 + -