MW22-02A/BSP/Driver/lan8720/Lan8720.c

263 lines
7.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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