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; }
//======================================================================== //函数名称: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; }