feat(esp_eth): added example to deinit Ethernet

This commit is contained in:
Ondrej Kosta 2024-04-23 16:49:51 +02:00
parent d15a9c2c48
commit 5e7cbdb4da
4 changed files with 88 additions and 19 deletions

View File

@ -1,3 +1,3 @@
idf_component_register(SRCS "ethernet_init.c"
PRIV_REQUIRES driver esp_eth
PRIV_REQUIRES esp_driver_gpio esp_eth
INCLUDE_DIRS ".")

View File

@ -9,11 +9,9 @@
#include "esp_mac.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif // CONFIG_ETH_USE_SPI_ETHERNET
static const char *TAG = "example_eth_init";
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
#if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM
#define SPI_ETHERNETS_NUM CONFIG_EXAMPLE_SPI_ETHERNETS_NUM
@ -45,6 +43,12 @@ typedef struct {
uint8_t *mac_addr;
}spi_eth_module_config_t;
static const char *TAG = "example_eth_init";
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
static bool gpio_isr_svc_init_by_eth = false; // indicates that we initialized the GPIO ISR service
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
/**
* @brief Internal ESP32 Ethernet initialization
@ -128,17 +132,19 @@ static esp_err_t spi_bus_init(void)
{
esp_err_t ret = ESP_OK;
#if (CONFIG_EXAMPLE_ETH_SPI_INT0_GPIO >= 0) || (CONFIG_EXAMPLE_ETH_SPI_INT1_GPIO > 0)
// Install GPIO ISR handler to be able to service SPI Eth modules interrupts
ret = gpio_install_isr_service(0);
if (ret != ESP_OK) {
if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGW(TAG, "GPIO ISR handler has been already installed");
ret = ESP_OK; // ISR handler has been already installed so no issues
} else {
ESP_LOGE(TAG, "GPIO ISR handler install failed");
goto err;
}
if (ret == ESP_OK) {
gpio_isr_svc_init_by_eth = true;
} else if (ret == ESP_ERR_INVALID_STATE) {
ESP_LOGW(TAG, "GPIO ISR handler has been already installed");
ret = ESP_OK; // ISR handler has been already installed so no issues
} else {
ESP_LOGE(TAG, "GPIO ISR handler install failed");
goto err;
}
#endif
// Init SPI bus
spi_bus_config_t buscfg = {
@ -283,7 +289,7 @@ esp_err_t example_eth_init(esp_eth_handle_t *eth_handles_out[], uint8_t *eth_cnt
ESP_GOTO_ON_FALSE(eth_handles[eth_cnt], ESP_FAIL, err, TAG, "SPI Ethernet init failed");
eth_cnt++;
}
#endif // CONFIG_ETH_USE_SPI_ETHERNET
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
#else
ESP_LOGD(TAG, "no Ethernet device selected to init");
#endif // CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET || CONFIG_EXAMPLE_USE_SPI_ETHERNET
@ -297,3 +303,36 @@ err:
return ret;
#endif
}
esp_err_t example_eth_deinit(esp_eth_handle_t *eth_handles, uint8_t eth_cnt)
{
ESP_RETURN_ON_FALSE(eth_handles != NULL, ESP_ERR_INVALID_ARG, TAG, "array of Ethernet handles cannot be NULL");
for (int i = 0; i < eth_cnt; i++) {
esp_eth_mac_t *mac = NULL;
esp_eth_phy_t *phy = NULL;
if (eth_handles[i] != NULL) {
esp_eth_get_mac_instance(eth_handles[i], &mac);
esp_eth_get_phy_instance(eth_handles[i], &phy);
ESP_RETURN_ON_ERROR(esp_eth_driver_uninstall(eth_handles[i]), TAG, "Ethernet %p uninstall failed", eth_handles[i]);
}
if (mac != NULL) {
mac->del(mac);
}
if (phy != NULL) {
phy->del(phy);
}
}
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
spi_bus_free(CONFIG_EXAMPLE_ETH_SPI_HOST);
#if (CONFIG_EXAMPLE_ETH_SPI_INT0_GPIO >= 0) || (CONFIG_EXAMPLE_ETH_SPI_INT1_GPIO > 0)
// We installed the GPIO ISR service so let's uninstall it too.
// BE CAREFUL HERE though since the service might be used by other functionality!
if (gpio_isr_svc_init_by_eth) {
ESP_LOGW(TAG, "uninstalling GPIO ISR service!");
gpio_uninstall_isr_service();
}
#endif
#endif //CONFIG_EXAMPLE_USE_SPI_ETHERNET
free(eth_handles);
return ESP_OK;
}

View File

@ -0,0 +1,9 @@
menu "Example Configuration"
config EXAMPLE_ETH_DEINIT_AFTER_S
int "Stop and deinit Ethernet after elapsing number of secs"
range -1 300
default -1
help
This option is for demonstration purposes only to demonstrate deinitialization of the Ethernet driver.
Set to -1 to not deinitialize.
endmenu

View File

@ -75,14 +75,18 @@ void app_main(void)
// Create default event loop that running in background
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_t *eth_netifs[eth_port_cnt];
esp_eth_netif_glue_handle_t eth_netif_glues[eth_port_cnt];
// Create instance(s) of esp-netif for Ethernet(s)
if (eth_port_cnt == 1) {
// Use ESP_NETIF_DEFAULT_ETH when just one Ethernet interface is used and you don't need to modify
// default esp-netif configuration parameters.
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&cfg);
eth_netifs[0] = esp_netif_new(&cfg);
eth_netif_glues[0] = esp_eth_new_netif_glue(eth_handles[0]);
// Attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[0])));
ESP_ERROR_CHECK(esp_netif_attach(eth_netifs[0], eth_netif_glues[0]));
} else {
// Use ESP_NETIF_INHERENT_DEFAULT_ETH when multiple Ethernet interfaces are used and so you need to modify
// esp-netif configuration parameters for each interface (name, priority, etc.).
@ -101,10 +105,10 @@ void app_main(void)
esp_netif_config.if_key = if_key_str;
esp_netif_config.if_desc = if_desc_str;
esp_netif_config.route_prio -= i*5;
esp_netif_t *eth_netif = esp_netif_new(&cfg_spi);
eth_netifs[i] = esp_netif_new(&cfg_spi);
eth_netif_glues[i] = esp_eth_new_netif_glue(eth_handles[0]);
// Attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i])));
ESP_ERROR_CHECK(esp_netif_attach(eth_netifs[i], eth_netif_glues[i]));
}
}
@ -116,4 +120,21 @@ void app_main(void)
for (int i = 0; i < eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
}
#if CONFIG_EXAMPLE_ETH_DEINIT_AFTER_S >= 0
// For demonstration purposes, wait and then deinit Ethernet network
vTaskDelay(pdMS_TO_TICKS(CONFIG_EXAMPLE_ETH_DEINIT_AFTER_S * 1000));
ESP_LOGI(TAG, "stop and deinitialize Ethernet network...");
// Stop Ethernet driver state machine and destroy netif
for (int i = 0; i < eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_stop(eth_handles[i]));
ESP_ERROR_CHECK(esp_eth_del_netif_glue(eth_netif_glues[i]));
esp_netif_destroy(eth_netifs[i]);
}
esp_netif_deinit();
ESP_ERROR_CHECK(example_eth_deinit(eth_handles, eth_port_cnt));
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
ESP_ERROR_CHECK(esp_event_loop_delete_default());
#endif // EXAMPLE_ETH_DEINIT_AFTER_S > 0
}