#include <Net_Config.h>
#include <stm32f4xx.h>
#include "ETH_STM32F4xx.h"
#include "stdio.h"
// LAN8720 RMII管脚定义
/*
PA1/ETH_RMII_RX_CLK
PA2/ETH_MDIO
PA7/RMII_CRS_DV
PC1/ETH_MDC
PC4/ETH_RMII_RX_D0
PC5/ETH_RMII_RX_D1
PG11/ETH_RMII_TX_EN
PG13/FSMC_A24/ETH_RMII_TXD0
PG14/ETH_RMII_TXD1
PD3 /ETH_RESET
*/
/*
*********************************************************************************************************
* 用于本文件的调试
*********************************************************************************************************
*/
#if 1
#define printf_eth printf
#else
#define printf_eth(...)
#endif
/*
*********************************************************************************************************
* 宏定义
*********************************************************************************************************
*/
/*
默认情况下,我们选择是自动识别,即使用PHY芯片支持的Auto-Negotiation实现自适应10Mbps网络或者100Mbps网络
但是这种时间稍长,如果用户确定了使用的网络是10Mbps还是100Mbps,直接通过下面的宏定义选择即可,如果使用的
自适应,两个都不需要选择。
*/
//#define _10MBIT_
//#define _100MBIT_
/*
*********************************************************************************************************
* 变量
*********************************************************************************************************
*/
__IO uint8_t g_ucEthLinkStatus = 0; /* 以太网连接状态,0 表示未连接,1 表示连接 */
extern U8 own_hw_adr[]; /* 在文件Net_Config.c里面定义 */
static U8 TxBufIndex;
static U8 RxBufIndex;
static RX_Desc Rx_Desc[NUM_RX_BUF]; /* DMA接收描述符 */
static TX_Desc Tx_Desc[NUM_TX_BUF]; /* DMA发送描述符 */
static U32 rx_buf[NUM_RX_BUF][ETH_BUF_SIZE>>2]; /* DMA接收描述符缓冲 */
static U32 tx_buf[NUM_TX_BUF][ETH_BUF_SIZE>>2]; /* DMA发送描述符缓冲 */
/*
*********************************************************************************************************
* 变量
*********************************************************************************************************
*/
/*
底层驱动有两种方式,一种是查询的,一种是中断的,我们这里是采用的中断方式。
a. 查询方式需要的函数: - void init_ethernet ()
- void send_frame (OS_FRAME *frame)
- void poll_ethernet (void)
b. 中断方式需要的函数: - void init_ethernet ()
- void send_frame (OS_FRAME *frame)
- void int_enable_eth ()
- void int_disable_eth ()
- interrupt function
*/
static void rx_descr_init (void);
static void tx_descr_init (void);
static void write_PHY (U32 PhyReg, U16 Value);
static U16 read_PHY (U32 PhyReg);
//static void Eth_Link_EXTIConfig(void);
/*
*********************************************************************************************************
* 函 数 名: init_ethernet
* 功能说明: 初始化以太网RMII方式引脚,驱动PHY,配置MAC及其DMA方式。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
#define ETH_NRST_GPIO_CLK RCC_AHB1Periph_GPIOD
#define ETH_NRST_PORT GPIOD
#define ETH_NRST_PIN GPIO_Pin_3
/* ETH_MDIO */
#define ETH_MDIO_GPIO_CLK RCC_AHB1Periph_GPIOA
#define ETH_MDIO_PORT GPIOA
#define ETH_MDIO_PIN GPIO_Pin_2
#define ETH_MDIO_AF GPIO_AF_ETH
#define ETH_MDIO_SOURCE GPIO_PinSource2
/* ETH_MDC */
#define ETH_MDC_GPIO_CLK RCC_AHB1Periph_GPIOC
#define ETH_MDC_PORT GPIOC
#define ETH_MDC_PIN GPIO_Pin_1
#define ETH_MDC_AF GPIO_AF_ETH
#define ETH_MDC_SOURCE GPIO_PinSource1
/* ETH_RMII_REF_CLK */
#define ETH_RMII_REF_CLK_GPIO_CLK RCC_AHB1Periph_GPIOA
#define ETH_RMII_REF_CLK_PORT GPIOA
#define ETH_RMII_REF_CLK_PIN GPIO_Pin_1
#define ETH_RMII_REF_CLK_AF GPIO_AF_ETH
#define ETH_RMII_REF_CLK_SOURCE GPIO_PinSource1
/* ETH_RMII_CRS_DV */
#define ETH_RMII_CRS_DV_GPIO_CLK RCC_AHB1Periph_GPIOA
#define ETH_RMII_CRS_DV_PORT GPIOA
#define ETH_RMII_CRS_DV_PIN GPIO_Pin_7
#define ETH_RMII_CRS_DV_AF GPIO_AF_ETH
#define ETH_RMII_CRS_DV_SOURCE GPIO_PinSource7
/* ETH_RMII_RXD0 */
#define ETH_RMII_RXD0_GPIO_CLK RCC_AHB1Periph_GPIOC
#define ETH_RMII_RXD0_PORT GPIOC
#define ETH_RMII_RXD0_PIN GPIO_Pin_4
#define ETH_RMII_RXD0_AF GPIO_AF_ETH
#define ETH_RMII_RXD0_SOURCE GPIO_PinSource4
/* ETH_RMII_RXD1 */
#define ETH_RMII_RXD1_GPIO_CLK RCC_AHB1Periph_GPIOC
#define ETH_RMII_RXD1_PORT GPIOC
#define ETH_RMII_RXD1_PIN GPIO_Pin_5
#define ETH_RMII_RXD1_AF GPIO_AF_ETH
#define ETH_RMII_RXD1_SOURCE GPIO_PinSource5
/* ETH_RMII_TX_EN */
#define ETH_RMII_TX_EN_GPIO_CLK RCC_AHB1Periph_GPIOG
#define ETH_RMII_TX_EN_PORT GPIOG
#define ETH_RMII_TX_EN_PIN GPIO_Pin_11
#define ETH_RMII_TX_EN_AF GPIO_AF_ETH
#define ETH_RMII_TX_EN_SOURCE GPIO_PinSource11
/* ETH_RMII_TXD0 */
#define ETH_RMII_TXD0_GPIO_CLK RCC_AHB1Periph_GPIOG
#define ETH_RMII_TXD0_PORT GPIOG
#define ETH_RMII_TXD0_PIN GPIO_Pin_13
#define ETH_RMII_TXD0_AF GPIO_AF_ETH
#define ETH_RMII_TXD0_SOURCE GPIO_PinSource13
/* ETH_RMII_TXD1 */
#define ETH_RMII_TXD1_GPIO_CLK RCC_AHB1Periph_GPIOG
#define ETH_RMII_TXD1_PORT GPIOG
#define ETH_RMII_TXD1_PIN GPIO_Pin_14
#define ETH_RMII_TXD1_AF GPIO_AF_ETH
#define ETH_RMII_TXD1_SOURCE GPIO_PinSource14
void init_ethernet (void)
{
U32 regv,tout,conn;
GPIO_InitTypeDef GPIO_InitStructure;
//初始化RMII IO口
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOG , ENABLE);//使能GPIO时钟 RMII接口
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //使能SYSCFG时钟
SYSCFG_ETH_MediaInterfaceConfig(SYSCFG_ETH_MediaInterface_RMII); //MAC和PHY之间使用RMII接口
/*网络引脚设置 RMII接口
ETH_MDIO -------------------------> PA2
ETH_MDC --------------------------> PC1
ETH_RMII_REF_CLK------------------> PA1
ETH_RMII_CRS_DV ------------------> PA7
ETH_RMII_RXD0 --------------------> PC4
ETH_RMII_RXD1 --------------------> PC5
ETH_RMII_TX_EN -------------------> PG11
ETH_RMII_TXD0 --------------------> PG13
ETH_RMII_TXD1 --------------------> PG14
ETH_RESET-------------------------> PD3*/
//配置PA1 PA2 PA7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_ETH); //引脚复用到网络接口上
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_ETH);
//配置PC1,PC4 and PC5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_ETH); //引脚复用到网络接口上
GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_ETH);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource5, GPIO_AF_ETH);