esp_eth: add support for multiple Ethernets modules at a time

Ethernet driver events properly bounded with ESP NETIF actions to support multiple Ethernet modules used at a time.

Components using Ethernet updated to conform with new API.

Closes https://github.com/espressif/esp-idf/issues/7318
This commit is contained in:
Ondrej Kosta
2021-08-03 13:34:52 +02:00
parent 59aa60d52a
commit ef30384902
12 changed files with 564 additions and 256 deletions
+8 -1
View File
@@ -17,12 +17,19 @@ If you have a new Ethernet application to go (for example, connect to IoT cloud
To run this example, it's recommended that you have an official ESP32 Ethernet development board - [ESP32-Ethernet-Kit](https://docs.espressif.com/projects/esp-idf/en/latest/hw-reference/get-started-ethernet-kit.html). This example should also work for 3rd party ESP32 board as long as it's integrated with a supported Ethernet PHY chip. Up until now, ESP-IDF supports up to four Ethernet PHY: `LAN8720`, `IP101`, `DP83848` and `RTL8201`, additional PHY drivers should be implemented by users themselves.
Besides that, `esp_eth` component can drive third-party Ethernet module which integrates MAC and PHY and provides common communication interface (e.g. SPI, USB, etc). This example will take the **DM9051** as an example, illustrating how to install the Ethernet driver in the same manner.
Besides that, `esp_eth` component can drive third-party Ethernet module which integrates MAC and PHY and provides common communication interface (e.g. SPI, USB, etc). This example will take the `DM9051`, `W5500` or `KSZ8851SNL` SPI modules as an example, illustrating how to install the Ethernet driver in the same manner.
The ESP-IDF supports the usage of multiple Ethernet interfaces at a time when external modules are utilized which is also demonstrated by this example. There are several options you can combine:
* Internal EMAC and one SPI Ethernet module.
* Two SPI Ethernet modules of the same type connected to single SPI interface and accessed by switching appropriate CS.
* Internal EMAC and two SPI Ethernet modules of the same type.
#### Pin Assignment
See common pin assignments for Ethernet examples from [upper level](../README.md#common-pin-assignments).
When using two Ethernet SPI modules at a time, they are to be connected to single SPI interface. Both modules then share data (MOSI/MISO) and CLK signals. However, the CS, interrupt and reset pins need to be connected to separate GPIO for each Ethernet SPI module.
### Configure the project
```
+144 -84
View File
@@ -1,46 +1,21 @@
menu "Example Configuration"
config EXAMPLE_USE_SPI_ETHERNET
bool
config EXAMPLE_GPIO_RANGE_MIN
int
default 0
choice EXAMPLE_ETHERNET_TYPE
prompt "Ethernet Type"
default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32
default EXAMPLE_USE_W5500
config EXAMPLE_GPIO_RANGE_MAX
int
default 33 if IDF_TARGET_ESP32
default 46 if IDF_TARGET_ESP32S2
default 19 if IDF_TARGET_ESP32C3
config EXAMPLE_USE_INTERNAL_ETHERNET
depends on IDF_TARGET_ESP32
select ETH_USE_ESP32_EMAC
bool "Internal EMAC"
help
Select which kind of Ethernet will be used in the example.
config EXAMPLE_USE_INTERNAL_ETHERNET
depends on IDF_TARGET_ESP32
select ETH_USE_ESP32_EMAC
bool "Internal EMAC"
help
Select internal Ethernet MAC controller.
config EXAMPLE_USE_DM9051
bool "DM9051 Module"
select EXAMPLE_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_DM9051
help
Select external SPI-Ethernet module (DM9051).
config EXAMPLE_USE_W5500
bool "W5500 Module"
select EXAMPLE_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_W5500
help
Select external SPI-Ethernet module (W5500).
config EXAMPLE_USE_KSZ8851SNL
bool "KSZ8851SNL Module"
select EXAMPLE_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_KSZ8851SNL
help
Select external SPI-Ethernet module (KSZ8851SNL).
endchoice # EXAMPLE_ETHERNET_TYPE
Use internal Ethernet MAC controller.
if EXAMPLE_USE_INTERNAL_ETHERNET
choice EXAMPLE_ETH_PHY_MODEL
@@ -95,18 +70,75 @@ menu "Example Configuration"
config EXAMPLE_ETH_MDC_GPIO
int "SMI MDC GPIO number"
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 23
help
Set the GPIO number used by SMI MDC.
config EXAMPLE_ETH_MDIO_GPIO
int "SMI MDIO GPIO number"
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 18
help
Set the GPIO number used by SMI MDIO.
config EXAMPLE_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
range -1 EXAMPLE_GPIO_RANGE_MAX
default 5
help
Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset.
config EXAMPLE_ETH_PHY_ADDR
int "PHY Address"
range 0 31
default 1
help
Set PHY address according your board schematic.
endif # EXAMPLE_USE_INTERNAL_ETHERNET
config EXAMPLE_USE_SPI_ETHERNET
bool "SPI Ethernet"
default y
select ETH_USE_SPI_ETHERNET
help
Use external SPI-Ethernet module(s).
if EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_SPI_ETHERNETS_NUM
int "Number of SPI Ethernet modules to use at a time"
range 1 2
default 1
help
Set the number of SPI Ethernet modules you want to use at a time. Multiple SPI modules can be connected
to one SPI interface and can be separately accessed based on state of associated Chip Select (CS).
choice EXAMPLE_ETHERNET_TYPE_SPI
prompt "Ethernet SPI"
default EXAMPLE_USE_W5500
help
Select which kind of Ethernet will be used in the example.
config EXAMPLE_USE_DM9051
bool "DM9051 Module"
select ETH_SPI_ETHERNET_DM9051
help
Select external SPI-Ethernet module (DM9051).
config EXAMPLE_USE_KSZ8851SNL
bool "KSZ8851SNL Module"
select ETH_SPI_ETHERNET_KSZ8851SNL
help
Select external SPI-Ethernet module (KSZ8851SNL).
config EXAMPLE_USE_W5500
bool "W5500 Module"
select ETH_SPI_ETHERNET_W5500
help
Select external SPI-Ethernet module (W5500).
endchoice
config EXAMPLE_ETH_SPI_HOST
int "SPI Host Number"
range 0 2
@@ -116,48 +148,31 @@ menu "Example Configuration"
config EXAMPLE_ETH_SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range 0 34 if IDF_TARGET_ESP32
range 0 46 if IDF_TARGET_ESP32S2
range 0 19 if IDF_TARGET_ESP32C3
default 18 if IDF_TARGET_ESP32
default 20 if IDF_TARGET_ESP32S2
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 14 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2
default 6 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI SCLK.
config EXAMPLE_ETH_SPI_MOSI_GPIO
int "SPI MOSI GPIO number"
range 0 34 if IDF_TARGET_ESP32
range 0 46 if IDF_TARGET_ESP32S2
range 0 19 if IDF_TARGET_ESP32C3
default 23 if IDF_TARGET_ESP32
default 19 if IDF_TARGET_ESP32S2
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 13 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2
default 7 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI MOSI.
config EXAMPLE_ETH_SPI_MISO_GPIO
int "SPI MISO GPIO number"
range 0 34 if IDF_TARGET_ESP32
range 0 46 if IDF_TARGET_ESP32S2
range 0 19 if IDF_TARGET_ESP32C3
default 19 if IDF_TARGET_ESP32
default 18 if IDF_TARGET_ESP32S2
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 12 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32S2
default 2 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI MISO.
config EXAMPLE_ETH_SPI_CS_GPIO
int "SPI CS GPIO number"
range 0 34 if IDF_TARGET_ESP32
range 0 46 if IDF_TARGET_ESP32S2
range 0 19 if IDF_TARGET_ESP32C3
default 16 if IDF_TARGET_ESP32
default 21 if IDF_TARGET_ESP32S2
default 10 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI CS.
config EXAMPLE_ETH_SPI_CLOCK_MHZ
int "SPI clock speed (MHz)"
range 5 80
@@ -166,25 +181,70 @@ menu "Example Configuration"
help
Set the clock speed (MHz) of SPI interface.
config EXAMPLE_ETH_SPI_INT_GPIO
int "Interrupt GPIO number"
default 17 if IDF_TARGET_ESP32
default 4 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
config EXAMPLE_ETH_SPI_CS0_GPIO
int "SPI CS0 GPIO number for SPI Ethernet module #1"
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 15 if IDF_TARGET_ESP32
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
help
Set the GPIO number used by the SPI Ethernet module interrupt line.
Set the GPIO number used by SPI CS0, i.e. Chip Select associated with the first SPI Eth module).
config EXAMPLE_ETH_SPI_CS1_GPIO
depends on EXAMPLE_SPI_ETHERNETS_NUM > 1
int "SPI CS1 GPIO number for SPI Ethernet module #2"
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 32 if IDF_TARGET_ESP32
default 7 if IDF_TARGET_ESP32S2
default 8 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI CS1, i.e. Chip Select associated with the second SPI Eth module.
config EXAMPLE_ETH_SPI_INT0_GPIO
int "Interrupt GPIO number SPI Ethernet module #1"
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
help
Set the GPIO number used by the first SPI Ethernet module interrupt line.
config EXAMPLE_ETH_SPI_INT1_GPIO
depends on EXAMPLE_SPI_ETHERNETS_NUM > 1
int "Interrupt GPIO number SPI Ethernet module #2"
range EXAMPLE_GPIO_RANGE_MIN EXAMPLE_GPIO_RANGE_MAX
default 33 if IDF_TARGET_ESP32
default 5 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3
help
Set the GPIO number used by the second SPI Ethernet module interrupt line.
config EXAMPLE_ETH_SPI_PHY_RST0_GPIO
int "PHY Reset GPIO number of SPI Ethernet Module #1"
range -1 EXAMPLE_GPIO_RANGE_MAX
default -1
help
Set the GPIO number used to reset PHY chip on the first SPI Ethernet module.
Set to -1 to disable PHY chip hardware reset.
config EXAMPLE_ETH_SPI_PHY_RST1_GPIO
depends on EXAMPLE_SPI_ETHERNETS_NUM > 1
int "PHY Reset GPIO number of SPI Ethernet Module #2"
range -1 EXAMPLE_GPIO_RANGE_MAX
default -1
help
Set the GPIO number used to reset PHY chip on the second SPI Ethernet module.
Set to -1 to disable PHY chip hardware reset.
config EXAMPLE_ETH_SPI_PHY_ADDR0
int "PHY Address of SPI Ethernet Module #1"
range 0 31
default 1
help
Set the first SPI Ethernet module PHY address according your board schematic.
config EXAMPLE_ETH_SPI_PHY_ADDR1
depends on EXAMPLE_SPI_ETHERNETS_NUM > 1
int "PHY Address of SPI Ethernet Module #2"
range 0 31
default 1
help
Set the second SPI Ethernet module PHY address according your board schematic.
endif # EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
default 5
help
Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset.
config EXAMPLE_ETH_PHY_ADDR
int "PHY Address"
range 0 31
default 1
help
Set PHY address according your board schematic.
endmenu
@@ -22,6 +22,23 @@
static const char *TAG = "eth_example";
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
#define INIT_SPI_ETH_MODULE_CONFIG(eth_module_config, num) \
do { \
eth_module_config[num].spi_cs_gpio = CONFIG_EXAMPLE_ETH_SPI_CS ##num## _GPIO; \
eth_module_config[num].int_gpio = CONFIG_EXAMPLE_ETH_SPI_INT ##num## _GPIO; \
eth_module_config[num].phy_reset_gpio = CONFIG_EXAMPLE_ETH_SPI_PHY_RST ##num## _GPIO; \
eth_module_config[num].phy_addr = CONFIG_EXAMPLE_ETH_SPI_PHY_ADDR ##num; \
} while(0)
typedef struct {
uint8_t spi_cs_gpio;
uint8_t int_gpio;
int8_t phy_reset_gpio;
uint8_t phy_addr;
}spi_eth_module_config_t;
#endif
/** Event handler for Ethernet events */
static void eth_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
@@ -72,19 +89,18 @@ void app_main(void)
ESP_ERROR_CHECK(esp_netif_init());
// Create default event loop that running in background
ESP_ERROR_CHECK(esp_event_loop_create_default());
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
// Create new default instance of esp-netif for Ethernet
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
esp_netif_t *eth_netif = esp_netif_new(&cfg);
// Set default handlers to process TCP/IP stuffs
ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif));
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
// Init MAC and PHY configs to default
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR;
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO;
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
mac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
mac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
@@ -101,9 +117,43 @@ void app_main(void)
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ8081
esp_eth_phy_t *phy = esp_eth_phy_new_ksz8081(&phy_config);
#endif
#elif CONFIG_ETH_USE_SPI_ETHERNET
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
/* attach Ethernet driver to TCP/IP stack */
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
#endif //CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
// Create instance(s) of esp-netif for SPI Ethernet(s)
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
esp_netif_config_t cfg_spi = {
.base = &esp_netif_config,
.stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
};
esp_netif_t *eth_netif_spi[CONFIG_EXAMPLE_SPI_ETHERNETS_NUM] = { NULL };
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
itoa(i, num_str, 10);
strcat(strcpy(if_key_str, "ETH_SPI_"), num_str);
strcat(strcpy(if_desc_str, "eth"), num_str);
esp_netif_config.if_key = if_key_str;
esp_netif_config.if_desc = if_desc_str;
esp_netif_config.route_prio = 30 - i;
eth_netif_spi[i] = esp_netif_new(&cfg_spi);
}
// Init MAC and PHY configs to default
eth_mac_config_t mac_config_spi = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config_spi = ETH_PHY_DEFAULT_CONFIG();
// Install GPIO ISR handler to be able to service SPI Eth modlues interrupts
gpio_install_isr_service(0);
spi_device_handle_t spi_handle = NULL;
// Init SPI bus
spi_device_handle_t spi_handle[CONFIG_EXAMPLE_SPI_ETHERNETS_NUM] = { NULL };
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
@@ -111,66 +161,121 @@ void app_main(void)
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1));
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
// Init specific SPI Ethernet module configuration from Kconfig (CS GPIO, Interrupt GPIO, etc.)
spi_eth_module_config_t spi_eth_module_config[CONFIG_EXAMPLE_SPI_ETHERNETS_NUM];
INIT_SPI_ETH_MODULE_CONFIG(spi_eth_module_config, 0);
#if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM > 1
INIT_SPI_ETH_MODULE_CONFIG(spi_eth_module_config, 1);
#endif
// Configure SPI interface and Ethernet driver for specific SPI module
esp_eth_mac_t *mac_spi[CONFIG_EXAMPLE_SPI_ETHERNETS_NUM];
esp_eth_phy_t *phy_spi[CONFIG_EXAMPLE_SPI_ETHERNETS_NUM];
esp_eth_handle_t eth_handle_spi[CONFIG_EXAMPLE_SPI_ETHERNETS_NUM] = { NULL };
#if CONFIG_EXAMPLE_USE_KSZ8851SNL
spi_device_interface_config_t devcfg = {
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
.queue_size = 20
};
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
/* KSZ8851SNL ethernet driver is based on spi driver */
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_handle);
ksz8851snl_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_ksz8851snl(&ksz8851snl_config, &mac_config);
esp_eth_phy_t *phy = esp_eth_phy_new_ksz8851snl(&phy_config);
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
// Set SPI module Chip Select GPIO
devcfg.spics_io_num = spi_eth_module_config[i].spi_cs_gpio;
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle[i]));
// KSZ8851SNL ethernet driver is based on spi driver
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(spi_handle[i]);
// Set remaining GPIO numbers and configuration used by the SPI module
ksz8851snl_config.int_gpio_num = spi_eth_module_config[i].int_gpio;
phy_config_spi.phy_addr = spi_eth_module_config[i].phy_addr;
phy_config_spi.reset_gpio_num = spi_eth_module_config[i].phy_reset_gpio;
mac_spi[i] = esp_eth_mac_new_ksz8851snl(&ksz8851snl_config, &mac_config_spi);
phy_spi[i] = esp_eth_phy_new_ksz8851snl(&phy_config_spi);
}
#elif CONFIG_EXAMPLE_USE_DM9051
spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 7,
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
.queue_size = 20
};
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
/* dm9051 ethernet driver is based on spi driver */
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle);
dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
esp_eth_phy_t *phy = esp_eth_phy_new_dm9051(&phy_config);
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
// Set SPI module Chip Select GPIO
devcfg.spics_io_num = spi_eth_module_config[i].spi_cs_gpio;
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle[i]));
// dm9051 ethernet driver is based on spi driver
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(spi_handle[i]);
// Set remaining GPIO numbers and configuration used by the SPI module
dm9051_config.int_gpio_num = spi_eth_module_config[i].int_gpio;
phy_config_spi.phy_addr = spi_eth_module_config[i].phy_addr;
phy_config_spi.reset_gpio_num = spi_eth_module_config[i].phy_reset_gpio;
mac_spi[i] = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config_spi);
phy_spi[i] = esp_eth_phy_new_dm9051(&phy_config_spi);
}
#elif CONFIG_EXAMPLE_USE_W5500
spi_device_interface_config_t devcfg = {
.command_bits = 16, // Actually it's the address phase in W5500 SPI frame
.address_bits = 8, // Actually it's the control phase in W5500 SPI frame
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO,
.queue_size = 20
};
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle));
/* w5500 ethernet driver is based on spi driver */
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
esp_eth_phy_t *phy = esp_eth_phy_new_w5500(&phy_config);
#endif
#endif // CONFIG_ETH_USE_SPI_ETHERNET
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
esp_eth_handle_t eth_handle = NULL;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
#if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
/* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually.
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
// Set SPI module Chip Select GPIO
devcfg.spics_io_num = spi_eth_module_config[i].spi_cs_gpio;
ESP_ERROR_CHECK(spi_bus_add_device(CONFIG_EXAMPLE_ETH_SPI_HOST, &devcfg, &spi_handle[i]));
// w5500 ethernet driver is based on spi driver
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle[i]);
// Set remaining GPIO numbers and configuration used by the SPI module
w5500_config.int_gpio_num = spi_eth_module_config[i].int_gpio;
phy_config_spi.phy_addr = spi_eth_module_config[i].phy_addr;
phy_config_spi.reset_gpio_num = spi_eth_module_config[i].phy_reset_gpio;
mac_spi[i] = esp_eth_mac_new_w5500(&w5500_config, &mac_config_spi);
phy_spi[i] = esp_eth_phy_new_w5500(&phy_config_spi);
}
#endif //CONFIG_EXAMPLE_USE_W5500
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
esp_eth_config_t eth_config_spi = ETH_DEFAULT_CONFIG(mac_spi[i], phy_spi[i]);
ESP_ERROR_CHECK(esp_eth_driver_install(&eth_config_spi, &eth_handle_spi[i]));
/* The SPI Ethernet module might not have a burned factory MAC address, we cat to set it manually.
02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.
*/
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
0x02, 0x00, 0x00, 0x12, 0x34, 0x56
}));
#endif
/* attach Ethernet driver to TCP/IP stack */
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
*/
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle_spi[i], ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
0x02, 0x00, 0x00, 0x12, 0x34, 0x56 + i
}));
// attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netif_spi[i], esp_eth_new_netif_glue(eth_handle_spi[i])));
}
#endif // CONFIG_ETH_USE_SPI_ETHERNET
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));
/* start Ethernet driver state machine */
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
#endif // CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
ESP_ERROR_CHECK(esp_eth_start(eth_handle_spi[i]));
}
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
}