コード例 #1
0
ファイル: EMAC.c プロジェクト: Dzenik/FreeRTOS_TEST
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;
}
コード例 #2
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;
}