#include "driver/gpio.h" #include "esp_eth.h" #include "esp_eth_driver.h" #include "esp_event.h" #include "esp_log.h" #include "esp_mac.h" #include "esp_netif.h" #include "sdkconfig.h" /* App */ #include "app_net.h" #define APP_ETHERNET_PHY_ADDR 0 #define APP_ETHERNET_PHY_PIN_MDIO 18 #define APP_ETHERNET_PHY_PIN_MDC 23 #define APP_ETHERNET_PHY_PIN_RST 5 #define APP_ETHERNET_PHY_PIN_POWER 4 #define APP_NET_EVENT_ID_ETHERNET ((void *)0) #define APP_NET_EVENT_ID_IP ((void *)1) static const char *LOG_TAG = "APP_ETH"; static esp_eth_handle_t s_eth_handle = NULL; static esp_err_t app_ethernet_init(void); static void app_net_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); esp_err_t app_net_init(void) { if (app_ethernet_init() != ESP_OK) { ESP_LOGE(LOG_TAG, "Failed to initialize Ethernet driver."); return ESP_FAIL; } if (esp_netif_init() != ESP_OK) { ESP_LOGE(LOG_TAG, "Failed to initialize TCP/IP interface."); return ESP_FAIL; } if (esp_event_loop_create_default() != ESP_OK) { ESP_LOGE(LOG_TAG, "Failed to create default event loop."); goto esp_event_loop_fail; } esp_netif_config_t netif_config = ESP_NETIF_DEFAULT_ETH(); esp_netif_t *eth_netif = esp_netif_new(&netif_config); if (esp_netif_attach(eth_netif, esp_eth_new_netif_glue(s_eth_handle)) != ESP_OK) { ESP_LOGE(LOG_TAG, "Failed to attach Ethernet interface."); goto esp_netif_fail; } esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, app_net_event_handler, APP_NET_EVENT_ID_ETHERNET); esp_event_handler_register(ETH_EVENT, IP_EVENT_ETH_GOT_IP, app_net_event_handler, APP_NET_EVENT_ID_IP); if (esp_eth_start(s_eth_handle) != ESP_OK) { ESP_LOGE(LOG_TAG, "Failed to start Ethernet interface."); goto esp_netif_fail; } return ESP_OK; esp_netif_fail: esp_event_loop_delete_default(); esp_event_loop_fail: esp_netif_deinit(); return ESP_FAIL; } static void app_ethernet_phy_power_init(void) { gpio_config_t io_cfg = { .pin_bit_mask = (1U << APP_ETHERNET_PHY_PIN_POWER), .mode = GPIO_MODE_OUTPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE, }; gpio_config(&io_cfg); } static void app_ethernet_phy_power(bool on) { if (on) { gpio_set_level(APP_ETHERNET_PHY_PIN_POWER, 1); } else { gpio_set_level(APP_ETHERNET_PHY_PIN_POWER, 0); } vTaskDelay(pdMS_TO_TICKS(250)); } static esp_err_t app_ethernet_init(void) { eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); eth_esp32_emac_config_t esp_mac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); esp_mac_config.smi_mdio_gpio_num = APP_ETHERNET_PHY_PIN_MDIO; esp_mac_config.smi_mdc_gpio_num = APP_ETHERNET_PHY_PIN_MDC; esp_mac_config.clock_config.rmii.clock_mode = EMAC_CLK_OUT; esp_mac_config.clock_config.rmii.clock_gpio = EMAC_APPL_CLK_OUT_GPIO; phy_config.phy_addr = APP_ETHERNET_PHY_ADDR; phy_config.reset_gpio_num = APP_ETHERNET_PHY_PIN_RST; app_ethernet_phy_power_init(); app_ethernet_phy_power(true); esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp_mac_config, &mac_config); if (mac == NULL) { ESP_LOGE(LOG_TAG, "Failed to create ESP ETH MAC."); return ESP_FAIL; } esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config); if (phy == NULL) { ESP_LOGE(LOG_TAG, "Failed to create ETH PHY."); goto err_phy; } esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy); if (esp_eth_driver_install(ð_config, &s_eth_handle) != ESP_OK) { ESP_LOGE(LOG_TAG, "Failed to install Ethernet driver."); goto err_driver_fail; } return ESP_OK; err_driver_fail: if (s_eth_handle) { esp_eth_driver_uninstall(s_eth_handle); } if (phy) { phy->del(phy); } err_phy: if (mac) { mac->del(mac); } return ESP_FAIL; } static void app_net_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { if (arg == APP_NET_EVENT_ID_ETHERNET) { uint8_t mac_addr[6] = {0}; esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data; ESP_LOGI(LOG_TAG, "Ethernet event:"); switch (event_id) { case ETHERNET_EVENT_CONNECTED: esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr); ESP_LOGI(LOG_TAG, "Link up: MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); break; case ETHERNET_EVENT_DISCONNECTED: ESP_LOGI(LOG_TAG, "Link down"); break; case ETHERNET_EVENT_START: ESP_LOGI(LOG_TAG, "Started"); break; case ETHERNET_EVENT_STOP: ESP_LOGI(LOG_TAG, "Stopped"); break; default: break; } } else if (arg == APP_NET_EVENT_ID_IP) { ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; const esp_netif_ip_info_t *ip_info = &event->ip_info; ESP_LOGI(LOG_TAG, "Interface IP event:"); ESP_LOGI(LOG_TAG, "IP Address:" IPSTR, IP2STR(&ip_info->ip)); ESP_LOGI(LOG_TAG, "Netmask:" IPSTR, IP2STR(&ip_info->netmask)); ESP_LOGI(LOG_TAG, "Gateway:" IPSTR, IP2STR(&ip_info->gw)); } }