263 lines
7.8 KiB
C
263 lines
7.8 KiB
C
#include "includes.h"
|
||
#include "Lan8720.h"
|
||
#include "gd32f4xx.h"
|
||
//#include "gd32f4xx_gpio.h"
|
||
#include "pdebug.h"
|
||
#include "bsp_os.h"
|
||
//#include "gd32f4xx_enet.h"
|
||
#include "gd32f4xx_it.h"
|
||
#include "lwip/tcpip.h"
|
||
#include "lwip/raw.h"
|
||
#include "lwip/icmp.h"
|
||
#include "lwip/dhcp.h"
|
||
#include "lwip/netif.h"
|
||
#include "lwip/sys.h"
|
||
#include "lwip/timers.h"
|
||
#include "lwip/inet_chksum.h"
|
||
#include "lwip/init.h"
|
||
#include "netif/etharp.h"
|
||
|
||
unsigned char g_local_ip[4] = {192,168,8,200}; //本地默认ip
|
||
unsigned char g_local_mac[] = {0x42, 0x00, 0x00, 0x00, 0x00, 0x01}; //默认mac地址42:00:00:00:00:01
|
||
unsigned char g_netmask[4] = {255,255,255,0}; //子网掩码
|
||
unsigned char g_gateway[4] = {172,16,19,254}; //网关
|
||
|
||
//unsigned char gCfgLoca_MAC[] = {0x02, 0x0A, 0x0D, 0x0E, 0x0F, 0x06};
|
||
unsigned char gCfgLoca_MAC[] = {0x42, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||
|
||
uint8_t gCfgLoca_MAC[];
|
||
|
||
__IO uint32_t enet_init_status = 0;//用于以太网初始化状态判断
|
||
char Enet_init_status;
|
||
struct netif fsl_netif0;
|
||
extern err_t ethernetif_init(struct netif *netif);
|
||
|
||
extern err_t ethernetif_input(struct netif *netif);
|
||
|
||
|
||
//初始化交换机
|
||
static void Lan8720_gpio_Init(void)
|
||
{
|
||
//IO总线时钟使能
|
||
rcu_periph_clock_enable(RCU_GPIOA);
|
||
rcu_periph_clock_enable(RCU_GPIOB);
|
||
rcu_periph_clock_enable(RCU_GPIOC);
|
||
rcu_periph_clock_enable(RCU_GPIOD);
|
||
rcu_periph_clock_enable(RCU_GPIOG);
|
||
rcu_periph_clock_enable(RCU_GPIOH);
|
||
rcu_periph_clock_enable(RCU_GPIOI);
|
||
//使能系统时钟
|
||
rcu_periph_clock_enable(RCU_SYSCFG);
|
||
|
||
//选择RMII模式
|
||
syscfg_enet_phy_interface_config(SYSCFG_ENET_PHY_RMII);
|
||
|
||
//PA1:REF_CLK 时钟引脚,外部PHY提供50M
|
||
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
|
||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1);
|
||
|
||
//PA2: ETH_MDIO
|
||
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
|
||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2);
|
||
|
||
//PA7: ETH_RMII_CRS_DV
|
||
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_7);
|
||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
|
||
//引脚复用
|
||
gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_1);
|
||
gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_2);
|
||
gpio_af_set(GPIOA, GPIO_AF_11, GPIO_PIN_7);
|
||
|
||
//PB11: ETH_RMII_TX_EN
|
||
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_11);
|
||
|
||
//PB12: ETH_RMII_TXD0
|
||
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_12);
|
||
|
||
//PB13: ETH_RMII_TXD1
|
||
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13);
|
||
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13);
|
||
|
||
gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_11);
|
||
gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_12);
|
||
gpio_af_set(GPIOB, GPIO_AF_11, GPIO_PIN_13);
|
||
|
||
//PC1: ETH_MDC
|
||
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_1);
|
||
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1);
|
||
|
||
//PC4: ETH_RMII_RXD0
|
||
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4);
|
||
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
|
||
|
||
//PC5: ETH_RMII_RXD1
|
||
gpio_mode_set(GPIOC, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
|
||
gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
|
||
|
||
gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_1);
|
||
gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_4);
|
||
gpio_af_set(GPIOC, GPIO_AF_11, GPIO_PIN_5);
|
||
}
|
||
|
||
//初始化MAC/DMA
|
||
static void Enet_MAC_DMA_config(void)
|
||
{
|
||
ErrStatus reval_state = ERROR;
|
||
|
||
rcu_periph_clock_enable(RCU_ENET);//使能以太网总线时钟
|
||
rcu_periph_clock_enable(RCU_ENETTX);//使能发送时钟
|
||
rcu_periph_clock_enable(RCU_ENETRX);//使能接收时钟
|
||
|
||
enet_deinit();//复位总线时钟AHB
|
||
|
||
reval_state = enet_software_reset();//等待时钟复位完成
|
||
if(ERROR == reval_state){//复位失败
|
||
while(1){
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//以太网设备初始化
|
||
#ifdef CHECKSUM_BY_HARDWARE//不定义
|
||
enet_init_status = enet_init(ENET_AUTO_NEGOTIATION, ENET_AUTOCHECKSUM_DROP_FAILFRAMES, ENET_BROADCAST_FRAMES_PASS);
|
||
#else //PHY自动协商、禁用IP帧校验功能、地址过滤器通过所有接收到的广播帧 ENET_100M_FULLDUPLEX/ENET_AUTO_NEGOTIATION
|
||
enet_init_status = enet_init(ENET_AUTO_NEGOTIATION, ENET_NO_AUTOCHECKSUM, ENET_BROADCAST_FRAMES_PASS);
|
||
#endif /* CHECKSUM_BY_HARDWARE */
|
||
/*注:当前使用的LAN8720PHY芯片只能使用自动协商模式,手动模式无法通信(LAN8720自身bug)*/
|
||
}
|
||
|
||
|
||
|
||
//中断嵌套向量配置
|
||
static void Nvic_configuration(void)
|
||
{
|
||
//配置中断嵌套基地址,,,使用Flash base address基地址,偏移量位应用程序偏移量(待boot使用后使能)
|
||
// nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x0);
|
||
//使能以太网中断请求
|
||
nvic_irq_enable(ENET_IRQn, 2, 3);
|
||
}
|
||
|
||
|
||
void Lan8720_Init(void)
|
||
{
|
||
|
||
// 中断嵌套向量配置
|
||
Nvic_configuration();
|
||
|
||
// RMII模式、时钟、引脚配置
|
||
Lan8720_gpio_Init();
|
||
|
||
//MAC/DMA配置
|
||
Enet_MAC_DMA_config();
|
||
|
||
if(0 == enet_init_status){//初始化DMA失败
|
||
Enet_init_status = 0;
|
||
term_printf("\n Lan8720 Init fail 0 \r\n\r\n");
|
||
}else{
|
||
term_printf("\n Lan8720 Init success 1 \r\n\r\n");
|
||
Enet_init_status = 1;
|
||
}
|
||
//以太网正常中断启用
|
||
enet_interrupt_enable(ENET_DMA_INT_NIE);
|
||
//接收中断使能
|
||
enet_interrupt_enable(ENET_DMA_INT_RIE);
|
||
|
||
BSP_IntVectSet(77,ENET_IRQHandler);
|
||
BSP_IntEn(77);
|
||
|
||
}
|
||
|
||
|
||
|
||
unsigned int Lwip_init(void)
|
||
{
|
||
ip_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw;
|
||
pdebug(DEBUG_LEVEL_INFO,"tcp ip init begin!\r\n");
|
||
tcpip_init(NULL, NULL);
|
||
OSTimeDlyHMSM(0, 0, 0, 100);
|
||
pdebug(DEBUG_LEVEL_INFO,"tcp ip init ok!\r\n");
|
||
|
||
#if LWIP_DHCP
|
||
fsl_netif0_ipaddr.addr=0;
|
||
fsl_netif0_netmask.addr=0;
|
||
fsl_netif0_gw.addr=0;
|
||
#else
|
||
IP4_ADDR(&fsl_netif0_ipaddr, g_local_ip[0],g_local_ip[1],g_local_ip[2],g_local_ip[3]);
|
||
IP4_ADDR(&fsl_netif0_netmask, g_netmask[0],g_netmask[1],g_netmask[2],g_netmask[3]);
|
||
IP4_ADDR(&fsl_netif0_gw, g_gateway[0],g_gateway[1],g_gateway[2],g_gateway[3]);
|
||
|
||
u8_t *ip = (u8_t*)&fsl_netif0_ipaddr.addr;
|
||
pdebug(DEBUG_LEVEL_INFO,"set net ip: %u.%u.%u.%u \r\n",ip[0], ip[1],ip[2], ip[3]);
|
||
|
||
ip = (u8_t*)&fsl_netif0_netmask.addr;
|
||
pdebug(DEBUG_LEVEL_INFO,"set net mask: %u.%u.%u.%u \r\n",ip[0], ip[1],ip[2], ip[3]);
|
||
|
||
ip = (u8_t*)&fsl_netif0_gw.addr;
|
||
pdebug(DEBUG_LEVEL_INFO,"set net gw: %u.%u.%u.%u \r\n",ip[0], ip[1],ip[2], ip[3]);
|
||
#endif
|
||
|
||
netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, NULL, ethernetif_init, ethernet_input);
|
||
netif_set_default(&fsl_netif0);
|
||
netif_set_up(&fsl_netif0);
|
||
#if LWIP_DHCP
|
||
dhcp_start(&fsl_netif0);
|
||
int i = sys_now();
|
||
int time = 0;
|
||
while((fsl_netif0.dhcp->offered_ip_addr.addr == 0) || (fsl_netif0.dhcp->offered_gw_addr.addr == 0) || (fsl_netif0.dhcp->offered_sn_mask.addr == 0))
|
||
{
|
||
if(sys_now()- i > 8000) {
|
||
i = sys_now();
|
||
dhcp_start(&fsl_netif0);
|
||
// 超时3次
|
||
time++;
|
||
if (time > 3) {
|
||
break;
|
||
}
|
||
}
|
||
OSTimeDlyHMSM(0, 0, 0, 100);
|
||
}
|
||
|
||
dhcp_fine_tmr();
|
||
netif_set_addr(&fsl_netif0, &(fsl_netif0.dhcp->offered_ip_addr), &(fsl_netif0.dhcp->offered_sn_mask), &(fsl_netif0.dhcp->offered_gw_addr));
|
||
netif_set_default(&fsl_netif0);
|
||
netif_set_up(&fsl_netif0);
|
||
|
||
u8_t *ip = (u8_t*)&fsl_netif0.ip_addr.addr;
|
||
ip = (u8_t*)&fsl_netif0.dhcp->offered_sn_mask;
|
||
ip = (u8_t*)&fsl_netif0.dhcp->offered_gw_addr;
|
||
|
||
#endif
|
||
term_printf("\n Lwip Init success \r\n\r\n");
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/// 以太网模块初始化
|
||
///
|
||
/// 初始化底层mac控制器,phy芯片,OSLwip,创建任务
|
||
/// @param none
|
||
/// @param none
|
||
/// @return none
|
||
/// @note 修改日志
|
||
/// gkl与2017-05-26创建
|
||
/// LH于2022-05-12修改
|
||
void init_enet_module()
|
||
{
|
||
// 初始化mac控制器,phy芯片
|
||
Lan8720_Init();
|
||
// 初始化Lwip_Init相关功能模块
|
||
Lwip_init();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|