#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(); }