/*******************************************************************************/

#include "includes_all.h"

/*******************************************************************************
* 函数名称:	 void Ethernet_Configuration(void)
* 函数说明： 以太网MII/RMII接口配置
* 输入参数： 无
* 返回参数： 无
*******************************************************************************/
void STM32_Ethernet_Configuration(void)
{
	ETH_InitTypeDef 	ETH_InitStructure;
#ifdef MII_MODE 
	GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_MII);	//MII  Media 接口选择
	RCC_MCOConfig(RCC_MCO_HSE);									//输出时钟给PHY HSE clock = 25MHz 在 PA8 pin (MCO)
#elif defined RMII_MODE 
	GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_RMII);//RMII Media 接口选择
	RCC_PLL3Config(RCC_PLL3Mul_10);								//设置PLL3 输出50MHz (25MHz /5 *10 =50MHz)
	RCC_PLL3Cmd(ENABLE);										//使能PLL3 倍频
	while (RCC_GetFlagStatus(RCC_FLAG_PLL3RDY) == RESET);		//等待PLL3 倍频稳定
	RCC_MCOConfig(RCC_MCO_PLL3CLK);								//倍频后输出时钟给 50 MHz 在 PA8 pin (MCO)
#endif
	ETH_DeInit();												//初始化以太网控制器默认配置 Reset ETHERNET on AHB Bus
	ETH_SoftwareReset();										//以太网控制器软件复位
	while (ETH_GetSoftwareResetStatus() == SET);				//等待以太网控制器软件复位成功

	/* ETHERNET Configuration */
	ETH_StructInit(&ETH_InitStructure);
	/*------------------------   MAC   -----------------------------------*/
	ETH_InitStructure.ETH_AutoNegotiation 			= ETH_AutoNegotiation_Enable;
	ETH_InitStructure.ETH_LoopbackMode 				= ETH_LoopbackMode_Disable;
	ETH_InitStructure.ETH_RetryTransmission 		= ETH_RetryTransmission_Disable;
	ETH_InitStructure.ETH_AutomaticPadCRCStrip 		= ETH_AutomaticPadCRCStrip_Disable;
	ETH_InitStructure.ETH_ReceiveAll 				= ETH_ReceiveAll_Disable;
	ETH_InitStructure.ETH_BroadcastFramesReception 	= ETH_BroadcastFramesReception_Enable;
	ETH_InitStructure.ETH_PromiscuousMode 			= ETH_PromiscuousMode_Disable;
	ETH_InitStructure.ETH_MulticastFramesFilter 	= ETH_MulticastFramesFilter_Perfect;
	ETH_InitStructure.ETH_UnicastFramesFilter 		= ETH_UnicastFramesFilter_Perfect;
//#ifdef CHECKSUM_BY_HARDWARE
	ETH_InitStructure.ETH_ChecksumOffload 			= ETH_ChecksumOffload_Enable; 
//#endif
	/*------------------------   DMA   -----------------------------------*/  

	/* When we use the Checksum offload feature, we need to enable the Store and Forward mode: 
	the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum, 
	if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
	ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame 	= ETH_DropTCPIPChecksumErrorFrame_Enable; 
	ETH_InitStructure.ETH_ReceiveStoreForward 			= ETH_ReceiveStoreForward_Enable;         
	ETH_InitStructure.ETH_TransmitStoreForward 			= ETH_TransmitStoreForward_Enable;     
	ETH_InitStructure.ETH_ForwardErrorFrames 			= ETH_ForwardErrorFrames_Disable;       
	ETH_InitStructure.ETH_ForwardUndersizedGoodFrames 	= ETH_ForwardUndersizedGoodFrames_Disable;   
	ETH_InitStructure.ETH_SecondFrameOperate 			= ETH_SecondFrameOperate_Enable;                                                          
	ETH_InitStructure.ETH_AddressAlignedBeats 			= ETH_AddressAlignedBeats_Enable;      
	ETH_InitStructure.ETH_FixedBurst 					= ETH_FixedBurst_Enable;                
	ETH_InitStructure.ETH_RxDMABurstLength 				= ETH_RxDMABurstLength_32Beat;          
	ETH_InitStructure.ETH_TxDMABurstLength 				= ETH_TxDMABurstLength_32Beat;                                                                 
	ETH_InitStructure.ETH_DMAArbitration 				= ETH_DMAArbitration_RoundRobin_RxTx_2_1;

	ETH_Init(&ETH_InitStructure, PHY_ADDRESS);

	ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R, ENABLE);		//使能以太网接收中断
}

/*******************************************************************************
* 函数名称:	 void STM32_Ethernet_Init(void)
* 函数说明： STM32F107以太网接口及配置初始化
* 输入参数： 无
* 返回参数： 无
*******************************************************************************/
void STM32_Ethernet_Init(void)
{
	GPIO_InitTypeDef 	GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ETH_MAC | RCC_AHBPeriph_ETH_MAC_Tx | RCC_AHBPeriph_ETH_MAC_Rx, ENABLE);		//使能以太网时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO , ENABLE); //使能GPIO时钟
       
	/* ETHERNET 接口引脚配置*/
	/* AF Output Push Pull:
	- ETH_RMII_MDIO: 	PA2
	- ETH_RMII_MDC: 	PC1
	- ETH_RMII_TX_EN: 	PB11
	- ETH_RMII_TXD0: 	PB12
	- ETH_RMII_TXD1: 	PB13
	- ETH_RMII_PPS_OUT: PB5*/
    
	/* Configure PA2 as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Configure PC1 as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF_PP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	/* Configure PB5, PB11, PB12 and PB13 as alternate function push-pull */
//	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_5 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	// /* Input (Reset Value):
	// - ETH_RMII_REF_CLK: 	PA1
	// - ETH_RMII_CRS_DV: 	PA7
	// - ETH_RMII_RXD0: 	PC4
	// - ETH_RMII_RXD1: 	PC5
	
	// /* Configure PA1 and PA7 as input */
	// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_7;
	// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	// GPIO_Init(GPIOA, &GPIO_InitStructure);

	// /* Configure PC4 and PC5 as input */
	// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	// GPIO_Init(GPIOC, &GPIO_InitStructure); 

	/*****************************重映射以太网引脚*****************************/
	/* Input (Reset Value):
	- ETH_RMII_REF_CLK: PA1
	- ETH_RMII_CRS_DV: 	PD8
	- ETH_RMII_RXD0: 	PD9
	- ETH_RMII_RXD1: 	PD10*/
	GPIO_PinRemapConfig(GPIO_Remap_ETH, ENABLE);

	/* Configure PA1 as input */
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_1 ;
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	/* Configure PD8, PD9, PD10 as input */
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOD, &GPIO_InitStructure); 	
	/*************************重映射以太网引脚结束*****************************/
	
	/* MCO 引脚配置 */
	/* Configure MCO (PA8) as alternate function push-pull */
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	STM32_Ethernet_Configuration();
}

/***********************************FILE END***********************************/

