Exemplo n.º 1
0
void vEMACInit( void )
{
int iData;
extern int periph_clk_khz;
const unsigned portCHAR ucMACAddress[] =
{
	configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5
};

	/* Enable the ENET clock. */
	SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;

	/* Allow concurrent access to MPU controller to avoid bus errors. */
	MPU_CESR = 0;

	prvInitialiseDescriptors();

	/* Reset and enable. */
	ENET_ECR = ENET_ECR_RESET_MASK;
	
	/* Wait at least 8 clock cycles */
	vTaskDelay( 2 );
	
	/* Start the MII interface*/
	mii_init( 0, periph_clk_khz / 1000L );

	/* Configure the transmit interrupt. */
	set_irq_priority( emacTX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
	enable_irq( emacTX_INTERRUPT_NO );

	/* Configure the receive interrupt. */
	set_irq_priority( emacRX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
	enable_irq( emacRX_INTERRUPT_NO );

	/* Configure the error interrupt. */
	set_irq_priority( emacERROR_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
	enable_irq( emacERROR_INTERRUPT_NO );

	/* Configure the pins to the PHY - RMII mode used. */
	PORTB_PCR0  = PORT_PCR_MUX( 4 ); /* RMII0_MDIO / MII0_MDIO. */
	PORTB_PCR1  = PORT_PCR_MUX( 4 ); /* RMII0_MDC / MII0_MDC */
	PORTA_PCR14 = PORT_PCR_MUX( 4 ); /* RMII0_CRS_DV / MII0_RXDV */
	PORTA_PCR12 = PORT_PCR_MUX( 4 ); /* RMII0_RXD1 / MII0_RXD1 */
	PORTA_PCR13 = PORT_PCR_MUX( 4 ); /* RMII0_RXD0/MII0_RXD0 */
	PORTA_PCR15 = PORT_PCR_MUX( 4 ); /* RMII0_TXEN/MII0_TXEN */
	PORTA_PCR16 = PORT_PCR_MUX( 4 ); /* RMII0_TXD0/MII0_TXD0 */
	PORTA_PCR17 = PORT_PCR_MUX( 4 ); /* RMII0_TXD1/MII0_TXD1 */

	/* Is there communication with the PHY? */
	do
	{
		vTaskDelay( emacLINK_DELAY );
		iData = 0xFFFF;
		mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &iData );
	
	} while( iData == 0xFFFF );

	/* Start to auto negotiate. */
	mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
	
	/* Wait for auto negotiate to complete. */
	do
	{
		vTaskDelay( emacLINK_DELAY );
		mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &iData );
	
	} while( !( iData & PHY_BMSR_AN_COMPLETE ) );

	/* A link has been established.  What was negotiated? */
	iData = 0;
	mii_read( 0, configPHY_ADDRESS, emacPHY_STATUS, &iData );

	/* Clear the Individual and Group Address Hash registers */
	ENET_IALR = 0;
	ENET_IAUR = 0;
	ENET_GALR = 0;
	ENET_GAUR = 0;

	/* Set the Physical Address for the selected ENET */
	enet_set_address( 0, ucMACAddress );

	ENET_RCR = ENET_RCR_MAX_FL( UIP_BUFSIZE ) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;

	/* Clear the control registers. */
	ENET_TCR = 0;

	if( iData & emacPHY_DUPLEX_STATUS )
	{
		/* Full duplex */
		ENET_RCR &= ( unsigned long )~ENET_RCR_DRT_MASK;
		ENET_TCR |= ENET_TCR_FDEN_MASK;
	}
	else
	{
		/* Half duplex */
		ENET_RCR |= ENET_RCR_DRT_MASK;
		ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK;
	}

	if( iData & emacPHY_SPEED_STATUS )
	{
		/* 10Mbps */
		ENET_RCR |= ENET_RCR_RMII_10T_MASK;
	}

    ENET_ECR = ENET_ECR_EN1588_MASK;

	/* Store and forward checksum. */
	ENET_TFWR = ENET_TFWR_STRFWD_MASK;

	/* Set Rx Buffer Size */
	ENET_MRBR = ( unsigned short ) UIP_BUFSIZE;
	
	/* Point to the start of the circular Rx buffer descriptor queue */
	ENET_RDSR = ( unsigned long ) &( xRxDescriptors[ 0 ] );
	
	/* Point to the start of the circular Tx buffer descriptor queue */
	ENET_TDSR = ( unsigned long ) &( xTxDescriptors[ 0 ] );
	
	/* Clear all ENET interrupt events */
	ENET_EIR = ( unsigned long ) -1;
	
	/* Enable interrupts. */
	ENET_EIMR = 0
			/*rx irqs*/
			| ENET_EIMR_RXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_RXB_MASK*/
			/*xmit irqs*/
			| ENET_EIMR_TXF_MASK/* only for complete frame, not partial buffer descriptor | ENET_EIMR_TXB_MASK*/
			/*enet irqs*/
			| ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK
			;
	
	/* Enable the MAC itself. */
	ENET_ECR |= ENET_ECR_ETHEREN_MASK;
	
	/* Indicate that there have been empty receive buffers produced */
	ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
Exemplo n.º 2
0
/* ===================================================================*/
LDD_TDeviceData* ETH1_Init(LDD_TUserData *UserDataPtr)
{
  ETH1_TDeviceData *DeviceDataPrv;
  ETH1_TTxQueueItem *TxQueueItemPtr;
  ETH1_TRxQueueItem *RxQueueItemPtr;
  uint8_t* MemPtr;
  /* Allocate internal device data structure */
  /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */
  DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC;

  DeviceDataPrv->DuplexMode = LDD_ETH_FULL_DUPLEX; /* Store duplex mode configuration */
  DeviceDataPrv->FilterMode = LDD_ETH_ACCEPT_BC; /* Store filter mode configuration */
  DeviceDataPrv->SleepMode = LDD_ETH_DISABLED; /* Store sleep mode configuration */
  DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */
  DeviceDataPrv->Index = 0U;           /* Set the component instance index */
  DeviceDataPrv->EventMask =           /* Initialize the event mask */
    LDD_ETH_ON_FRAME_TRANSMITTED |
    LDD_ETH_ON_FRAME_RECEIVED |
    LDD_ETH_ON_FATAL_ERROR |0U;
  DeviceDataPrv->EnabledMode = TRUE;   /* Enable the device clock configuration */
  /* SIM_SCGC2: ENET=1 */
  SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;
  ENET_PDD_DisableDevice(ENET_BASE_PTR);
  DeviceDataPrv->Enabled = FALSE;
  ENET_PDD_EnableMIBCounters(ENET_BASE_PTR, FALSE); /* Disable statistic counters */
  ENET_PDD_ClearMIBCounters(ENET_BASE_PTR); /* Clear statistic  counters */
  ENET_PDD_EnableMIBCounters(ENET_BASE_PTR, TRUE); /* Enable statistic counters */
  /* Set pin assignments */
  /* PORTB_PCR1: ISF=0,MUX=4 */
  PORTB_PCR1 = (uint32_t)((PORTB_PCR1 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));
  /* PORTB_PCR0: ISF=0,MUX=4 */
  PORTB_PCR0 = (uint32_t)((PORTB_PCR0 & (uint32_t)~(uint32_t)(
                PORT_PCR_ISF_MASK |
                PORT_PCR_MUX(0x03)
               )) | (uint32_t)(
                PORT_PCR_MUX(0x04)
               ));
  /* PORTA_PCR18: ISF=0,MUX=0 */
  PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07)));
  /* PORTA_PCR16: ISF=0,MUX=4 */
  PORTA_PCR16 = (uint32_t)((PORTA_PCR16 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x03)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x04)
                ));
  /* PORTA_PCR17: ISF=0,MUX=4 */
  PORTA_PCR17 = (uint32_t)((PORTA_PCR17 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x03)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x04)
                ));
  /* PORTA_PCR15: ISF=0,MUX=4 */
  PORTA_PCR15 = (uint32_t)((PORTA_PCR15 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x03)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x04)
                ));
  /* PORTA_PCR14: ISF=0,MUX=4 */
  PORTA_PCR14 = (uint32_t)((PORTA_PCR14 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x03)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x04)
                ));
  /* PORTA_PCR13: ISF=0,MUX=4 */
  PORTA_PCR13 = (uint32_t)((PORTA_PCR13 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x03)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x04)
                ));
  /* PORTA_PCR12: ISF=0,MUX=4 */
  PORTA_PCR12 = (uint32_t)((PORTA_PCR12 & (uint32_t)~(uint32_t)(
                 PORT_PCR_ISF_MASK |
                 PORT_PCR_MUX(0x03)
                )) | (uint32_t)(
                 PORT_PCR_MUX(0x04)
                ));
  /* Set interrupt priorities */
  /* NVICIP76: PRI76=0x80 */
  NVICIP76 = NVIC_IP_PRI76(0x80);
  /* NVICISER2: SETENA|=0x1000 */
  NVICISER2 |= NVIC_ISER_SETENA(0x1000);
  /* NVICIP77: PRI77=0x80 */
  NVICIP77 = NVIC_IP_PRI77(0x80);
  /* NVICISER2: SETENA|=0x2000 */
  NVICISER2 |= NVIC_ISER_SETENA(0x2000);
  /* NVICIP78: PRI78=0x80 */
  NVICIP78 = NVIC_IP_PRI78(0x80);
  /* NVICISER2: SETENA|=0x4000 */
  NVICISER2 |= NVIC_ISER_SETENA(0x4000);
  /* Set interrupt mask */
  /* ENET_EIMR: ??=0,BABR=0,BABT=0,GRA=0,TXF=1,TXB=0,RXF=1,RXB=0,MII=0,EBERR=1,LC=0,RL=0,UN=0,PLR=0,WAKEUP=0,TS_AVAIL=0,TS_TIMER=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
  ENET_EIMR = (ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK);
  /* Clear interrupt flags */
  /* ENET_EIR: ??=1,BABR=1,BABT=1,GRA=1,TXF=1,TXB=1,RXF=1,RXB=1,MII=1,EBERR=1,LC=1,RL=1,UN=1,PLR=0,WAKEUP=0,TS_AVAIL=0,TS_TIMER=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */
  ENET_EIR = ENET_EIR_BABR_MASK |
             ENET_EIR_BABT_MASK |
             ENET_EIR_GRA_MASK |
             ENET_EIR_TXF_MASK |
             ENET_EIR_TXB_MASK |
             ENET_EIR_RXF_MASK |
             ENET_EIR_RXB_MASK |
             ENET_EIR_MII_MASK |
             ENET_EIR_EBERR_MASK |
             ENET_EIR_LC_MASK |
             ENET_EIR_RL_MASK |
             ENET_EIR_UN_MASK |
             0x80000000U;
  /* Allocate the transmit frame interrupt vector */
  /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */
  INT_ENET_Transmit__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv;
  /* Allocate the receive frame interrupt vector */
  /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */
  INT_ENET_Receive__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv;
  /* Allocate the shared interrupt vector */
  /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */
  INT_ENET_Error__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv;
  /* Set MAC address */
  /* ENET_PALR: PADDR1=0x43EF783A */
  ENET_PALR = ENET_PALR_PADDR1(0x43EF783A);
  /* ENET_PAUR: PADDR2=0x2E19,TYPE=0 */
  ENET_PAUR = (ENET_PAUR_PADDR2(0x2E19) | ENET_PAUR_TYPE(0x00));
  /* Set unicast address hash table */
  /* ENET_IAUR: IADDR1=0 */
  ENET_IAUR = ENET_IAUR_IADDR1(0x00);
  /* ENET_IALR: IADDR2=0 */
  ENET_IALR = ENET_IALR_IADDR2(0x00);
  /* Set multicast address hash table */
  /* ENET_GAUR: GADDR1=0 */
  ENET_GAUR = ENET_GAUR_GADDR1(0x00);
  /* ENET_GALR: GADDR2=0 */
  ENET_GALR = ENET_GALR_GADDR2(0x00);
  /* Set PAUSE frame duration */
  /* ENET_OPD: OPCODE=0,PAUSE_DUR=0 */
  ENET_OPD = (ENET_OPD_OPCODE(0x00) | ENET_OPD_PAUSE_DUR(0x00));
  /* Set transmit control register */
  /* ENET_TCR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CRCFWD=0,ADDINS=0,ADDSEL=0,RFC_PAUSE=0,TFC_PAUSE=0,FDEN=1,??=0,GTS=0 */
  ENET_TCR = (ENET_TCR_ADDSEL(0x00) | ENET_TCR_FDEN_MASK);
  /* Set transmit accelerator function configuration register */
  /* ENET_TACC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PROCHK=0,IPCHK=0,??=0,??=0,SHIFT16=0 */
  ENET_TACC = 0x00U;
  /* Set receive control register */
  /* ENET_RCR: GRS=0,NLC=0,MAX_FL=0x05EE,CFEN=0,CRCFWD=0,PAUFWD=1,PADEN=0,??=0,??=0,RMII_10T=0,RMII_MODE=1,??=0,??=0,FCE=1,BC_REJ=0,PROM=0,MII_MODE=1,DRT=0,LOOP=0 */
  ENET_RCR = ENET_RCR_MAX_FL(0x05EE) |
             ENET_RCR_PAUFWD_MASK |
             ENET_RCR_RMII_MODE_MASK |
             ENET_RCR_FCE_MASK |
             ENET_RCR_MII_MODE_MASK;
  /* Set receive accelerator function configuration register */
  /* ENET_RACC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,SHIFT16=0,LINEDIS=0,??=0,??=0,??=0,PRODIS=0,IPDIS=0,PADREM=0 */
  ENET_RACC = 0x00U;
  /* Set transmit inter-packet gap */
  /* ENET_TIPG: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,IPG=8 */
  ENET_TIPG = ENET_TIPG_IPG(0x08);
  /* Set frame truncation length */
  /* ENET_FTRL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TRUNC_FL=0x0800 */
  ENET_FTRL = ENET_FTRL_TRUNC_FL(0x0800);
  /* Set transmit FIFO watermark */
  /* ENET_TFWR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,STRFWD=1,??=0,??=0,TFWR=0 */
  ENET_TFWR = (ENET_TFWR_STRFWD_MASK | ENET_TFWR_TFWR(0x00));
  /* Set transmit FIFO section empty threshold */
  /* ENET_TSEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_SECTION_EMPTY=0 */
  ENET_TSEM = ENET_TSEM_TX_SECTION_EMPTY(0x00);
  /* Set transmit FIFO almost empty threshold */
  /* ENET_TAEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_ALMOST_EMPTY=8 */
  ENET_TAEM = ENET_TAEM_TX_ALMOST_EMPTY(0x08);
  /* Set transmit FIFO almost full threshold */
  /* ENET_TAFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TX_ALMOST_FULL=8 */
  ENET_TAFL = ENET_TAFL_TX_ALMOST_FULL(0x08);
  /* Set receive FIFO section full threshold */
  /* ENET_RSFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_SECTION_FULL=0 */
  ENET_RSFL = ENET_RSFL_RX_SECTION_FULL(0x00);
  /* Set receive FIFO section empty threshold */
  /* ENET_RSEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_SECTION_EMPTY=0 */
  ENET_RSEM = ENET_RSEM_RX_SECTION_EMPTY(0x00);
  /* Set receive FIFO almost empty threshold */
  /* ENET_RAEM: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_ALMOST_EMPTY=8 */
  ENET_RAEM = ENET_RAEM_RX_ALMOST_EMPTY(0x08);
  /* Set receive FIFO almost full threshold */
  /* ENET_RAFL: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,RX_ALMOST_FULL=8 */
  ENET_RAFL = ENET_RAFL_RX_ALMOST_FULL(0x08);
  /* Set MII speed control register */
  /* ENET_MSCR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,HOLDTIME=7,DIS_PRE=1,MII_SPEED=3,??=0 */
  ENET_MSCR = ENET_MSCR_HOLDTIME(0x07) |
              ENET_MSCR_DIS_PRE_MASK |
              ENET_MSCR_MII_SPEED(0x03);
  /* Set receive buffer size */
  /* ENET_MRBR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,R_BUF_SIZE=0,??=0,??=0,??=0,??=0 */
  ENET_MRBR = ENET_MRBR_R_BUF_SIZE(0x00);
  /* Initialize the transmit frame buffer queue */
  LDD_QUEUE_INIT(ETH1_TTxQueueItem, DeviceDataPrv->TxQueue, ETH1_QUEUE_MEM_ALIGN); /* Initialize the queue data structure */
  TxQueueItemPtr = LDD_QUEUE_GET_DATA_START(DeviceDataPrv->TxQueue);
  while (TxQueueItemPtr != (LDD_QUEUE_GET_DATA_END(DeviceDataPrv->TxQueue) + 1)) {
    /* Clear queue item */
    for (MemPtr = (uint8_t*)(uint32_t)TxQueueItemPtr; MemPtr != (uint8_t*)(uint32_t)(TxQueueItemPtr + 1); MemPtr++) {
      *MemPtr = 0U;
    }
    TxQueueItemPtr++;                  /* Move to the next queue item */
  }
  setReg32(ENET_TDSR, LDD_QUEUE_GET_DATA_START(DeviceDataPrv->TxQueue));
  /* Initialize the receive frame buffer queue */
  LDD_QUEUE_INIT(ETH1_TRxQueueItem, DeviceDataPrv->RxQueue, ETH1_QUEUE_MEM_ALIGN); /* Initialize the queue data structure */
  RxQueueItemPtr = LDD_QUEUE_GET_DATA_START(DeviceDataPrv->RxQueue);
  while (RxQueueItemPtr != (LDD_QUEUE_GET_DATA_END(DeviceDataPrv->RxQueue) + 1)) {
    /* Clear queue item */
    for (MemPtr = (uint8_t*)(uint32_t)RxQueueItemPtr; MemPtr != (uint8_t*)(uint32_t)(RxQueueItemPtr + 1); MemPtr++) {
      *MemPtr = 0U;
    }
    RxQueueItemPtr++;                  /* Move to the next queue item */
  }
  setReg32(ENET_RDSR, LDD_QUEUE_GET_DATA_START(DeviceDataPrv->RxQueue));
  /* ENET_ECR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DBSWP=0,STOPEN=0,DBGEN=0,??=0,EN1588=0,SLEEP=0,MAGICEN=0,ETHEREN=0,RESET=0 */
  ENET_ECR = 0x00U;
  /* Enable the device */
  ENET_PDD_EnableDevice(ENET_BASE_PTR);
  DeviceDataPrv->Enabled = TRUE;
  /* Registration of the device structure */
  PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_ETH1_ID,DeviceDataPrv);
  return (LDD_TDeviceData*)DeviceDataPrv;
}
Exemplo n.º 3
0
void
imxenet_init(struct imxenet_softc *sc)
{
	struct ifnet *ifp = &sc->sc_ac.ac_if;
	int speed = 0;
	uint32_t rate = clk_get_rate(clk_get("enet_ref"));

	/* reset the controller */
	HWRITE4(sc, ENET_ECR, ENET_ECR_RESET);
	while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET);

	/* set hw address */
	HWRITE4(sc, ENET_PALR,
	    (sc->sc_ac.ac_enaddr[0] << 24) |
	    (sc->sc_ac.ac_enaddr[1] << 16) |
	    (sc->sc_ac.ac_enaddr[2] << 8) |
	     sc->sc_ac.ac_enaddr[3]);
	HWRITE4(sc, ENET_PAUR,
	    (sc->sc_ac.ac_enaddr[4] << 24) |
	    (sc->sc_ac.ac_enaddr[5] << 16));

	/* clear outstanding interrupts */
	HWRITE4(sc, ENET_EIR, 0xffffffff);

	/* set address filter */
	HWRITE4(sc, ENET_GAUR, 0);
	HWRITE4(sc, ENET_GALR, 0);

	/* set max receive buffer size, 3-0 bits always zero for alignment */
	HWRITE4(sc, ENET_MRBR, ENET_MAX_PKT_SIZE);

	/* init descriptor */
	imxenet_init_txd(sc);
	imxenet_init_rxd(sc);

	/* set descriptor */
	HWRITE4(sc, ENET_TDSR, sc->txdma.dma_paddr);
	HWRITE4(sc, ENET_RDSR, sc->rxdma.dma_paddr);

	/* set it to full-duplex */
	HWRITE4(sc, ENET_TCR, ENET_TCR_FDEN);

	/*
	 * Set max frame length to 1518 or 1522 with VLANs,
	 * pause frames and promisc mode.
	 * XXX: RGMII mode - phy dependant
	 */
	HWRITE4(sc, ENET_RCR,
	    ENET_RCR_MAX_FL(1522) | ENET_RCR_RGMII_MODE | ENET_RCR_MII_MODE |
	    ENET_RCR_FCE);

	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ENET_MSCR,
	    (((rate + (ENET_MII_CLK << 2) - 1) / (ENET_MII_CLK << 2)) << 1) | 0x100);

	/* RX FIFO treshold and pause */
	HWRITE4(sc, ENET_RSEM, 0x84);
	HWRITE4(sc, ENET_RSFL, 16);
	HWRITE4(sc, ENET_RAEM, 8);
	HWRITE4(sc, ENET_RAFL, 8);
	HWRITE4(sc, ENET_OPD, 0xFFF0);

	/* do store and forward, only i.MX6, needs to be set correctly else */
	HWRITE4(sc, ENET_TFWR, ENET_TFWR_STRFWD);

	/* enable gigabit-ethernet and set it to support little-endian */
	switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
	case IFM_1000_T:  /* Gigabit */
		speed |= ENET_ECR_SPEED;
		break;
	default:
		speed &= ~ENET_ECR_SPEED;
		break;
	}
	HWRITE4(sc, ENET_ECR, ENET_ECR_ETHEREN | speed | ENET_ECR_DBSWP);

#ifdef ENET_ENHANCED_BD
	HSET4(sc, ENET_ECR, ENET_ECR_EN1588);
#endif

	/* rx descriptors are ready */
	HWRITE4(sc, ENET_RDAR, ENET_RDAR_RDAR);

	/* Indicate we are up and running. */
	ifp->if_flags |= IFF_RUNNING;
	ifp->if_flags &= ~IFF_OACTIVE;

	/* enable interrupts for tx/rx */
	HWRITE4(sc, ENET_EIMR, ENET_EIR_TXF | ENET_EIR_RXF);
	HWRITE4(sc, ENET_EIMR, 0xffffffff);

	imxenet_start(ifp);
}
/*
 * LPLD_ENET_Init
 * ENET模块初始化,包括PHY收发器初始化,MAC初始化,BD初始化
 * 
 * 参数:
 *    *MACAddress--MAC地址指针
 *
 * 输出:
 *    无
 */
void LPLD_ENET_Init(const uint8* MACAddress)
{
 
  uint16 usData;
 
  //使能ENET时钟
  SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;

  //允许并发访问MPU控制器
  MPU_CESR = 0;         
        
  //缓冲区描述符初始化
  LPLD_ENET_BDInit();
  
  //复位ENET
  ENET_ECR = ENET_ECR_RESET_MASK;

  //等待至少8个时钟周期
  for( usData = 0; usData < 10; usData++ )
  {
    asm( "NOP" );
  }
    
  //初始化MII接口
  LPLD_ENET_MiiInit(periph_clk_khz/1000/*MHz*/);       
        
  //使能中断并设置优先级
  set_irq_priority (76, 6);
  enable_irq(76);           //ENET发送中断
  set_irq_priority (77, 6);
  enable_irq(77);           //ENET接收中断
  //set_irq_priority (78, 6);
  //enable_irq(78);           //ENET错误及其他中断

  //使能GPIO引脚复用功能
  PORTB_PCR0  = PORT_PCR_MUX(4);  //GPIO;//RMII0_MDIO/MII0_MDIO
  PORTB_PCR1  = PORT_PCR_MUX(4);  //GPIO;//RMII0_MDC/MII0_MDC    
  PORTA_PCR14 = PORT_PCR_MUX(4);  //RMII0_CRS_DV/MII0_RXDV
  PORTA_PCR12 = PORT_PCR_MUX(4);  //RMII0_RXD1/MII0_RXD1
  PORTA_PCR13 = PORT_PCR_MUX(4);  //RMII0_RXD0/MII0_RXD0
  PORTA_PCR15 = PORT_PCR_MUX(4);  //RMII0_TXEN/MII0_TXEN
  PORTA_PCR16 = PORT_PCR_MUX(4);  //RMII0_TXD0/MII0_TXD0
  PORTA_PCR17 = PORT_PCR_MUX(4);  //RMII0_TXD1/MII0_TXD1
  
    
  //等待PHY收发器复位完成
  do
  {
    LPLD_ENET_Delay( ENET_LINK_DELAY );
    usData = 0xffff;
    LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_PHYIDR1, &usData );
        
  } while( usData == 0xffff );

#ifdef PHY_PRINT_REG
  printf("PHY_PHYIDR1=0x%X\r\n",usData);
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_PHYIDR2, &usData );
  printf("PHY_PHYIDR2=0x%X\r\n",usData); 
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_ANLPAR, &usData );
  printf("PHY_ANLPAR=0x%X\r\n",usData);
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_ANLPARNP, &usData );
  printf("PHY_ANLPARNP=0x%X\r\n",usData);
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_PHYSTS, &usData );
  printf("PHY_PHYSTS=0x%X\r\n",usData);
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_MICR, &usData );
  printf("PHY_MICR=0x%X\r\n",usData);
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_MISR, &usData );
  printf("PHY_MISR=0x%X\r\n",usData);
#endif 
  
  //开始自动协商
  LPLD_ENET_MiiWrite(CFG_PHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );

#ifdef PHY_PRINT_REG
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_BMCR, &usData );
  printf("PHY_BMCR=0x%X\r\n",usData);
#endif 
  
  //等待自动协商完成
  do
  {
    LPLD_ENET_Delay( ENET_LINK_DELAY );
    LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_BMSR, &usData );

  } while( !( usData & PHY_BMSR_AN_COMPLETE ) );

#ifdef PHY_PRINT_REG
    printf("PHY_BMSR=0x%X\r\n",usData);
#endif 
    
  //根据协商结果设置ENET模块
  LPLD_ENET_MiiRead(CFG_PHY_ADDRESS, PHY_STATUS, &usData );  

#ifdef PHY_PRINT_REG
  printf("PHY_STATUS=0x%X\r\n",usData);
#endif 
  
  //清除单独和组地址哈希寄存器
  ENET_IALR = 0;
  ENET_IAUR = 0;
  ENET_GALR = 0;
  ENET_GAUR = 0;
  
  //设置ENET模块MAC地址
  LPLD_ENET_SetAddress(MACAddress);
    
  //设置接收控制寄存器,最大长度、RMII模式、接收CRC校验等
  ENET_RCR = ENET_RCR_MAX_FL(CFG_ENET_MAX_PACKET_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;

  //清除发送接收控制
  ENET_TCR = 0;
        
  //通讯方式设置
  if( usData & PHY_DUPLEX_STATUS )
  {
    //全双工
    ENET_RCR &= (unsigned long)~ENET_RCR_DRT_MASK;
    ENET_TCR |= ENET_TCR_FDEN_MASK;
  }
  else
  {
    //半双工
    ENET_RCR |= ENET_RCR_DRT_MASK;
    ENET_TCR &= (unsigned long)~ENET_TCR_FDEN_MASK;
  }
  
  //通信速率设置
  if( usData & PHY_SPEED_STATUS )
  {
    //10Mbps
    ENET_RCR |= ENET_RCR_RMII_10T_MASK;
  }

  //使用非增强型缓冲区描述符
  ENET_ECR = 0;
  
  
  //设置接收缓冲区长度
  ENET_MRBR = (unsigned short) CFG_ENET_RX_BUFFER_SIZE;

  //指向环形接收缓冲区描述符序列的头地址
  ENET_RDSR = ( unsigned long ) &( xENETRxDescriptors[ 0 ] );

  //指向环形发送缓冲区描述符序列的头地址
  ENET_TDSR = ( unsigned long ) xENETTxDescriptors;

  //清除ENET中断事件
  ENET_EIR = ( unsigned long ) -1;

  //使能中断
  ENET_EIMR = 0 
            | ENET_EIMR_RXF_MASK  //接收中断
            | ENET_EIMR_TXF_MASK  //发送中断
            //ENET中断
            | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK
            | ENET_EIMR_RXB_MASK
            ;

  //使能ENET模块
  ENET_ECR |= ENET_ECR_ETHEREN_MASK;

  //表明接收缓冲区为空
  ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
Exemplo n.º 5
0
//========================================================================
//函数名称:hw_mac_init                                                         
//功能概要:初始化链路层                                              
//参数说明:ucMACAddress:MAC地址                                                                                                                                     
//函数返回:无                                           
//========================================================================  
void hw_mac_init(uint8 ucMACAddress[])
{
    uint16 usData;
    //初始化缓冲区
    prvInitialiseENETBuffers();   
   
    //查询物理层自动协商的结果,根据自动协商的结果配置链路层
    usData = 0;
    mii_read(PHY_ADDRESS, PHY_STATUS, &usData );
   
    //清除单独和组地址哈希寄存器
    ENET_IALR = 0;
    ENET_IAUR = 0;
    ENET_GALR = 0xFFFFFFFF;
    ENET_GAUR = 0xFFFFFFFF;
    
    //设置MAC地址
    enet_set_address(ucMACAddress);                          
    ENET_RCR = ENET_RCR_MAX_FL(configENET_BUFFER_SIZE) //最大帧长
                              | ENET_RCR_MII_MODE_MASK //必须置1
                              | ENET_RCR_CRCFWD_MASK   //接受时取出CRC校验码
                              | ENET_RCR_RMII_MODE_MASK;//RMII模式使能   
    //清除发送寄存器
    ENET_TCR = 0;  
    //设置半双工,全双工
    if( usData & PHY_DUPLEX_STATUS )
    {
          //全双工
          ENET_RCR &= (uint16)~ENET_RCR_DRT_MASK;
          ENET_TCR |= ENET_TCR_FDEN_MASK;
    }
    else
    {
          //半双工
          ENET_RCR |= ENET_RCR_DRT_MASK;
          ENET_TCR &= (uint16)~ENET_TCR_FDEN_MASK;
    }
    //设置速度(默认100M)
    if( usData & PHY_SPEED_STATUS )
    {
          //10M
          ENET_RCR |= ENET_RCR_RMII_10T_MASK;
    }
    ENET_ECR = 0;//使用非增强型缓冲区描述符

    
    //设置接受缓冲区大小
    ENET_MRBR = (uint16) configENET_BUFFER_SIZE;      
    //接受描述符激活寄存器只想第一个接受缓冲区
    ENET_RDSR = (uint32) &( xENETRxDescriptors[ 0 ] );
    //接发送描述符激活寄存器只想第一个发送缓冲区
    ENET_TDSR = (uint32) pxENETTxDescriptor;
    //清除所有以太网中断标志
    ENET_EIR = (uint32) -1;
    
    //使能中断
    ENET_EIMR = ENET_EIR_TXF_MASK | 
                  ENET_EIMR_RXF_MASK
                | ENET_EIMR_RXB_MASK
                | ENET_EIMR_UN_MASK
                | ENET_EIMR_RL_MASK
                | ENET_EIMR_LC_MASK 
                | ENET_EIMR_BABT_MASK
                | ENET_EIMR_BABR_MASK
                | ENET_EIMR_EBERR_MASK;
    //使能以太网模块
    ENET_ECR |= ENET_ECR_ETHEREN_MASK;
    //只是有空的接受缓冲区生成
    ENET_RDAR = ENET_RDAR_RDAR_MASK;
}
Exemplo n.º 6
0
/**
 * In this function, the hardware should be initialized.
 * Called from ethernetif_init().
 *
 * @param netif the already initialized lwip network interface structure
 *        for this ethernetif
 */
static void low_level_init(struct netif *netif) {
    StatusType result;
    int data;

    /* set MAC hardware address length */
    netif->hwaddr_len = ETHARP_HWADDR_LEN;
    
    /* set MAC hardware address */
    netif->hwaddr[0] = MAC_ADDR0;
    netif->hwaddr[1] = MAC_ADDR1;
    netif->hwaddr[2] = MAC_ADDR2;
    netif->hwaddr[3] = MAC_ADDR3;
    netif->hwaddr[4] = MAC_ADDR4;
    netif->hwaddr[5] = MAC_ADDR5;
    
    /* maximum transfer unit */
    netif->mtu = ENET_MAX_PKT_SIZE - 20;
    
    /* device capabilities */
    /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
    
    /* enable the ENET clock */
    SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;
    
    /* allow concurrent access to MPU controller. Example: ENET uDMA to SRAM, otherwise bus error */
    MPU_CESR = 0;         
    
    init_enet_bufs();
    
    /* create semaphores */
    sem_rx = CoCreateSem(NUM_ENET_TX_BUFS, NUM_ENET_TX_BUFS, 1);
    sem_tx = CoCreateSem(0, NUM_ENET_RX_BUFS, 1);
    
    /* Set the Reset bit and clear the Enable bit */
    ENET_ECR = ENET_ECR_RESET_MASK;
    
    /* Wait at least 8 clock cycles */
    for (data = 0; data < 10; data++) {
        asm("NOP");
    }
    
    /* start MII interface */
    mii_init(50/*BUS_CLOCK*/);       
    
    // enet tx interrupt
    NVIC_SetPriority(ENET_Transmit_IRQn, 6);
    NVIC_EnableIRQ(ENET_Transmit_IRQn);
    
    // enet rx interrupt
    NVIC_SetPriority(ENET_Receive_IRQn, 6);
    NVIC_EnableIRQ(ENET_Receive_IRQn);
    
    //enet error interrupt
    NVIC_SetPriority(ENET_Error_IRQn, 6);
    NVIC_EnableIRQ(ENET_Error_IRQn);
    
    /* Make sure the external interface signals are enabled */
    PORTB_PCR0  = PORT_PCR_MUX(4);      //RMII0_MDIO/MII0_MDIO
    PORTB_PCR1  = PORT_PCR_MUX(4);      //RMII0_MDC/MII0_MDC    
    
#if USE_MII_MODE
    PORTA_PCR14 = PORT_PCR_MUX(4);      //RMII0_CRS_DV/MII0_RXDV
    //PORTA_PCR5  = PORT_PCR_MUX(4);      //RMII0_RXER/MII0_RXER
    PORTA_PCR12 = PORT_PCR_MUX(4);      //RMII0_RXD1/MII0_RXD1
    PORTA_PCR13 = PORT_PCR_MUX(4);      //RMII0_RXD0/MII0_RXD0
    PORTA_PCR15 = PORT_PCR_MUX(4);      //RMII0_TXEN/MII0_TXEN
    PORTA_PCR16 = PORT_PCR_MUX(4);      //RMII0_TXD0/MII0_TXD0
    PORTA_PCR17 = PORT_PCR_MUX(4);      //RMII0_TXD1/MII0_TXD1
    PORTA_PCR11 = PORT_PCR_MUX(4);      //MII0_RXCLK
    PORTA_PCR25 = PORT_PCR_MUX(4);      //MII0_TXCLK
    PORTA_PCR9  = PORT_PCR_MUX(4);      //MII0_RXD3
    PORTA_PCR10 = PORT_PCR_MUX(4);      //MII0_RXD2  
    PORTA_PCR28 = PORT_PCR_MUX(4);      //MII0_TXER
    PORTA_PCR24 = PORT_PCR_MUX(4);      //MII0_TXD2
    PORTA_PCR26 = PORT_PCR_MUX(4);      //MII0_TXD3
    PORTA_PCR27 = PORT_PCR_MUX(4);      //MII0_CRS
    PORTA_PCR29 = PORT_PCR_MUX(4);      //MII0_COL
#else
    PORTA_PCR14 = PORT_PCR_MUX(4);      //RMII0_CRS_DV/MII0_RXDV
//    PORTA_PCR5  = PORT_PCR_MUX(4);      //RMII0_RXER/MII0_RXER
    PORTA_PCR12 = PORT_PCR_MUX(4);      //RMII0_RXD1/MII0_RXD1
    PORTA_PCR13 = PORT_PCR_MUX(4);      //RMII0_RXD0/MII0_RXD0
    PORTA_PCR15 = PORT_PCR_MUX(4);      //RMII0_TXEN/MII0_TXEN
    PORTA_PCR16 = PORT_PCR_MUX(4);      //RMII0_TXD0/MII0_TXD0
    PORTA_PCR17 = PORT_PCR_MUX(4);      //RMII0_TXD1/MII0_TXD1
#endif /* USE_MII_MODE */
    
    /* Can we talk to the PHY? */
    do {
        CoTickDelay(PHY_LINK_DELAY);
        data = 0xffff;
        mii_read(PHY_ADDR, MII_PHYID1, (uint16_t*)&data); 
    } while (data == 0xffff);
    
    /* Start auto negotiate. */
    mii_write(PHY_ADDR, MII_BMCR, (MII_BMCR_ANRESTART | MII_BMCR_ANENABLE));
    
    /* Wait for auto negotiate to complete. */
    do {
        CoTickDelay(PHY_LINK_DELAY);
        mii_read(PHY_ADDR, MII_BMSR, (uint16_t*)&data);
    } while (!(data & MII_BMSR_ANEGCOMPLETE));
    
    /* When we get here we have a link - find out what has been negotiated. */
    data = 0;
    mii_read(PHY_ADDR, PHY_STATUS, (uint16_t*)&data);  

    /* Set the Physical Address for the selected ENET */
    ENET_PALR = (uint32_t)((netif->hwaddr[0] << 24) | (netif->hwaddr[1] << 16) | (netif->hwaddr[2] << 8) | netif->hwaddr[3]);
    ENET_PAUR = (uint32_t)((netif->hwaddr[4] << 24) | (netif->hwaddr[5] << 16));
    
    /* Clear the Individual and Group Address Hash registers */
    ENET_IALR = 0;
    ENET_IAUR = 0;
    ENET_GALR = 0;
    ENET_GAUR = 0;
    
#if USE_MII_MODE        
    /* various mode/status setup */
    ENET_RCR = ENET_RCR_MAX_FL(ENET_MAX_PKT_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK;
#else
    ENET_RCR = ENET_RCR_MAX_FL(ENET_MAX_PKT_SIZE) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;
#endif
    
    /* clear rx/tx control registers */
    ENET_TCR = 0;
    
    /* setup half or full duplex */
    if (data & PHY_DUPLEX_STATUS) {
        /* full duplex */
        ENET_RCR &= ~ENET_RCR_DRT_MASK;
        ENET_TCR |= ENET_TCR_FDEN_MASK;
    }
    else {
        /* half duplex */
        ENET_RCR |= ENET_RCR_DRT_MASK;
        ENET_TCR &= ~ENET_TCR_FDEN_MASK;
    }
    
    /* Setup speed */
    if (data & PHY_SPEED_STATUS) {
        /* 10Mbps */
        ENET_RCR |= ENET_RCR_RMII_10T_MASK;
    }
    
#if USE_PROMISCUOUS_MODE
    ENET_RCR |= ENET_RCR_PROM_MASK;
#endif
    
#ifdef ENHANCED_BD
    ENET_ECR = ENET_ECR_EN1588_MASK;
#else
    ENET_ECR = 0;
#endif
    
#if ENET_HARDWARE_CHECKSUM
    /* enable discard on wrong protocol checksum and other nice features */
    ENET_RACC = ENET_RACC_IPDIS_MASK | ENET_RACC_PRODIS_MASK
        | ENET_RACC_LINEDIS_MASK | ENET_RACC_IPDIS_MASK | ENET_RACC_PADREM_MASK;
    
    /* enable protocol checksum insertion */
    ENET_TACC = ENET_TACC_IPCHK_MASK | ENET_TACC_PROCHK_MASK;
#endif
    
    ENET_TFWR = ENET_TFWR_STRFWD_MASK;
    
#if ENET_HARDWARE_SHIFT
    /* enable ethernet header alignment for rx */
    ENET_RACC |= ENET_RACC_SHIFT16_MASK;
    
    /* enable ethernet header alignment for tx */
    ENET_TACC |= ENET_TACC_SHIFT16_MASK;
#endif
    
    /* set rx buffer size */
    ENET_MRBR = ENET_RX_BUF_SIZE;
    
    /* point to the start of the circular rx buffer descriptor queue */
    ENET_RDSR = (uint32_t)rx_bd;
    
    /* point to the start of the circular tx buffer descriptor queue */
    ENET_TDSR = (uint32_t)tx_bd;
    
    /* clear all ENET interrupt events */
    ENET_EIR = -1u;
    
    /* enable interrupts */
    ENET_EIMR = 0
        /* rx irqs */
        | ENET_EIMR_RXF_MASK    /* only for complete frame, not partial buffer descriptor */
        /* tx irqs */
        | ENET_EIMR_TXF_MASK    /* only for complete frame, not partial buffer descriptor */
        /* others enet irqs */
        | ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK;
    
    /* create the task that handles the MAC ENET */
    result = CoCreateTask((FUNCPtr)ethernetif_input, (void *)netif, TASK_ETHIF_PRIO, &stack[TASK_ETHIF_STACK_SIZE - 1], TASK_ETHIF_STACK_SIZE);
    
    if (result == E_CREATE_FAIL) {
        LWIP_DEBUGF(NETIF_DEBUG,("Task for ETH recive created failed !\n\r "));
    };
    
    /* Enable the MAC itself */
    ENET_ECR |= ENET_ECR_ETHEREN_MASK;
    
    /* Indicate that there have been empty receive buffers produced */
    ENET_RDAR = ENET_RDAR_RDAR_MASK;
}