Ethernet examples: added new common init for Ethernet drivers

This commit is contained in:
Ondrej Kosta 2022-07-22 17:13:04 +02:00
parent 20e253e663
commit 20e668259e
29 changed files with 501 additions and 1434 deletions

View File

@ -1,17 +1,7 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
examples/ethernet:
disable:
- if: IDF_TARGET == "esp32c2"
temporary: true
reason: target esp32c2 is not supported yet
examples/ethernet/iperf:
disable:
- if: IDF_TARGET == "esp32c2"
temporary: true
reason: target esp32c2 is not supported yet
disable_test:
- if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3"]
- if: IDF_TARGET in ["esp32c3", "esp32c2", "esp32s2", "esp32s3"]
temporary: true
reason: lack of runners

View File

@ -56,7 +56,7 @@ Please consult Espressif Technical reference manual along with datasheet for spe
## Common Configurations
1. In the `Example Configuration` menu:
1. In the `Example Ethernet Configuration` menu:
* Choose the kind of Ethernet.
* If `Internal EMAC` is selected:
* Choose PHY device under `Ethernet PHY Device`, by default, the **ESP32-Ethernet-Kit** has an `IP101` on board.

View File

@ -1,16 +1,17 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# Ethernet Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## Overview
This example demonstrates basic usage of `Ethernet driver` together with `esp_netif`. The work flow of the example could be as follows:
This example demonstrates basic usage of `Ethernet driver` together with `esp_netif`. Initialization of the `Ethernet driver` is wrapped in separate [sub-component](./components/ethernet_init/ethernet_init.c) of this project to clearly distinguish between the driver's and `esp_netif` initializations. The work flow of the example could be as follows:
1. Install Ethernet driver
2. Send DHCP requests and wait for a DHCP lease
3. If get IP address successfully, then you will be able to ping the device
2. Attach the driver to `esp_netif`
3. Send DHCP requests and wait for a DHCP lease
4. If get IP address successfully, then you will be able to ping the device
If you have a new Ethernet application to go (for example, connect to IoT cloud via Ethernet), try this as a basic template, then add your own code.

View File

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

View File

@ -1,10 +1,11 @@
menu "Example Configuration"
menu "Example Ethernet Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config EXAMPLE_USE_INTERNAL_ETHERNET
depends on IDF_TARGET_ESP32
depends on SOC_EMAC_SUPPORTED
select ETH_USE_ESP32_EMAC
default y
bool "Internal EMAC"
help
Use internal Ethernet MAC controller.
@ -89,7 +90,7 @@ menu "Example Configuration"
config EXAMPLE_USE_SPI_ETHERNET
bool "SPI Ethernet"
default y
default n
select ETH_USE_SPI_ETHERNET
help
Use external SPI-Ethernet module(s).
@ -192,7 +193,7 @@ menu "Example Configuration"
config EXAMPLE_ETH_SPI_INT0_GPIO
int "Interrupt GPIO number SPI Ethernet module #1"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
default 4 if IDF_TARGET_ESP32C2
help
Set the GPIO number used by the first SPI Ethernet module interrupt line.

View File

@ -0,0 +1,289 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "ethernet_init.h"
#include "esp_log.h"
#include "esp_check.h"
#include "esp_mac.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif // CONFIG_ETH_USE_SPI_ETHERNET
static const char *TAG = "example_eth_init";
#if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM
#define SPI_ETHERNETS_NUM CONFIG_EXAMPLE_SPI_ETHERNETS_NUM
#else
#define SPI_ETHERNETS_NUM 0
#endif
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#define INTERNAL_ETHERNETS_NUM 1
#else
#define INTERNAL_ETHERNETS_NUM 0
#endif
#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;
uint8_t *mac_addr;
}spi_eth_module_config_t;
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
/**
* @brief Internal ESP32 Ethernet initialization
*
* @param[out] mac_out optionally returns Ethernet MAC object
* @param[out] phy_out optionally returns Ethernet PHY object
* @return
* - esp_eth_handle_t if init succeeded
* - NULL if init failed
*/
static esp_eth_handle_t eth_init_internal(esp_eth_mac_t **mac_out, esp_eth_phy_t **phy_out)
{
esp_eth_handle_t ret = NULL;
// Init common 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();
// Update PHY config based on board specific configuration
phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR;
phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO;
// Init vendor specific MAC config to default
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
// Update vendor specific MAC config based on board configuration
esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
// Create new ESP32 Ethernet MAC instance
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
// Create new PHY instance based on board configuration
#if CONFIG_EXAMPLE_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
#endif
// Init Ethernet driver to default and install it
esp_eth_handle_t eth_handle = NULL;
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
ESP_GOTO_ON_FALSE(esp_eth_driver_install(&config, &eth_handle) == ESP_OK, NULL,
err, TAG, "Ethernet driver install failed");
if (mac_out != NULL) {
*mac_out = mac;
}
if (phy_out != NULL) {
*phy_out = phy;
}
return eth_handle;
err:
if (eth_handle != NULL) {
esp_eth_driver_uninstall(eth_handle);
}
if (mac != NULL) {
mac->del(mac);
}
if (phy != NULL) {
phy->del(phy);
}
return ret;
}
#endif // CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
/**
* @brief SPI bus initialization (to be used by Ethernet SPI modules)
*
* @return
* - ESP_OK on success
*/
static esp_err_t spi_bus_init(void)
{
esp_err_t ret = ESP_OK;
// 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;
}
}
// Init SPI bus
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_GOTO_ON_ERROR(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO),
err, TAG, "SPI host #%d init failed", CONFIG_EXAMPLE_ETH_SPI_HOST);
err:
return ret;
}
/**
* @brief Ethernet SPI modules initialization
*
* @param[in] spi_eth_module_config specific SPI Ethernet module configuration
* @param[out] mac_out optionally returns Ethernet MAC object
* @param[out] phy_out optionally returns Ethernet PHY object
* @return
* - esp_eth_handle_t if init succeeded
* - NULL if init failed
*/
static esp_eth_handle_t eth_init_spi(spi_eth_module_config_t *spi_eth_module_config, esp_eth_mac_t **mac_out, esp_eth_phy_t **phy_out)
{
esp_eth_handle_t ret = NULL;
// Init common 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();
// Update PHY config based on board specific configuration
phy_config.phy_addr = spi_eth_module_config->phy_addr;
phy_config.reset_gpio_num = spi_eth_module_config->phy_reset_gpio;
// Configure SPI interface for specific SPI module
spi_device_interface_config_t spi_devcfg = {
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.queue_size = 20,
.spics_io_num = spi_eth_module_config->spi_cs_gpio
};
// Init vendor specific MAC config to default, and create new SPI Ethernet MAC instance
// and new PHY instance based on board configuration
#if CONFIG_EXAMPLE_USE_KSZ8851SNL
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
ksz8851snl_config.int_gpio_num = spi_eth_module_config->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);
#elif CONFIG_EXAMPLE_USE_DM9051
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
dm9051_config.int_gpio_num = spi_eth_module_config->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);
#elif CONFIG_EXAMPLE_USE_W5500
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
w5500_config.int_gpio_num = spi_eth_module_config->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 //CONFIG_EXAMPLE_USE_W5500
// Init Ethernet driver to default and install it
esp_eth_handle_t eth_handle = NULL;
esp_eth_config_t eth_config_spi = ETH_DEFAULT_CONFIG(mac, phy);
ESP_GOTO_ON_FALSE(esp_eth_driver_install(&eth_config_spi, &eth_handle) == ESP_OK, NULL, err, TAG, "SPI Ethernet driver install failed");
// The SPI Ethernet module might not have a burned factory MAC address, we can set it manually.
if (spi_eth_module_config->mac_addr != NULL) {
ESP_GOTO_ON_FALSE(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, spi_eth_module_config->mac_addr) == ESP_OK,
NULL, err, TAG, "SPI Ethernet MAC address config failed");
}
if (mac_out != NULL) {
*mac_out = mac;
}
if (phy_out != NULL) {
*phy_out = phy;
}
return eth_handle;
err:
if (eth_handle != NULL) {
esp_eth_driver_uninstall(eth_handle);
}
if (mac != NULL) {
mac->del(mac);
}
if (phy != NULL) {
phy->del(phy);
}
return ret;
}
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
esp_err_t example_eth_init(esp_eth_handle_t *eth_handles_out[], uint8_t *eth_cnt_out)
{
esp_err_t ret = ESP_OK;
esp_eth_handle_t *eth_handles = NULL;
uint8_t eth_cnt = 0;
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET || CONFIG_EXAMPLE_USE_SPI_ETHERNET
ESP_GOTO_ON_FALSE(eth_handles_out != NULL && eth_cnt_out != NULL, ESP_ERR_INVALID_ARG,
err, TAG, "invalid arguments: initialized handles array or number of interfaces");
eth_handles = calloc(SPI_ETHERNETS_NUM + INTERNAL_ETHERNETS_NUM, sizeof(esp_eth_handle_t));
ESP_GOTO_ON_FALSE(eth_handles != NULL, ESP_ERR_NO_MEM, err, TAG, "no memory");
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
eth_handles[eth_cnt] = eth_init_internal(NULL, NULL);
ESP_GOTO_ON_FALSE(eth_handles[eth_cnt], ESP_FAIL, err, TAG, "internal Ethernet init failed");
eth_cnt++;
#endif //CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
ESP_GOTO_ON_ERROR(spi_bus_init(), err, TAG, "SPI bus init failed");
// 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] = { 0 };
INIT_SPI_ETH_MODULE_CONFIG(spi_eth_module_config, 0);
// The SPI Ethernet module(s) might not have a burned factory MAC address, hence use manually configured address(es).
// In this example, Locally Administered MAC address derived from ESP32x base MAC address is used.
// Note that Locally Administered OUI range should be used only when testing on a LAN under your control!
uint8_t base_mac_addr[ETH_ADDR_LEN];
ESP_GOTO_ON_ERROR(esp_efuse_mac_get_default(base_mac_addr), err, TAG, "get EFUSE MAC failed");
u_int8_t local_mac_1[ETH_ADDR_LEN];
esp_derive_local_mac(local_mac_1, base_mac_addr);
spi_eth_module_config[0].mac_addr = local_mac_1;
#if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM > 1
INIT_SPI_ETH_MODULE_CONFIG(spi_eth_module_config, 1);
u_int8_t local_mac_2[ETH_ADDR_LEN];
base_mac_addr[ETH_ADDR_LEN - 1] += 1;
esp_derive_local_mac(local_mac_2, base_mac_addr);
spi_eth_module_config[1].mac_addr = local_mac_2;
#endif
#if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM > 2
#error Maximum number of supported SPI Ethernet devices is currently limited to 2 by this example.
#endif
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
eth_handles[eth_cnt] = eth_init_spi(&spi_eth_module_config[i], NULL, NULL);
ESP_GOTO_ON_FALSE(eth_handles[eth_cnt], ESP_FAIL, err, TAG, "SPI Ethernet init failed");
eth_cnt++;
}
#endif // CONFIG_ETH_USE_SPI_ETHERNET
#else
ESP_LOGD(TAG, "no Ethernet device selected to init");
#endif // CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET || CONFIG_EXAMPLE_USE_SPI_ETHERNET
*eth_handles_out = eth_handles;
*eth_cnt_out = eth_cnt;
return ret;
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET || CONFIG_EXAMPLE_USE_SPI_ETHERNET
err:
free(eth_handles);
return ret;
#endif
}

View File

@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#pragma once
#include "esp_eth_driver.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize Ethernet driver based on Espressif IoT Development Framework Configuration
*
* @param[out] eth_handles_out array of initialized Ethernet driver handles
* @param[out] eth_cnt_out number of initialized Ethernets
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_ARG when passed invalid pointers
* - ESP_ERR_NO_MEM when there is no memory to allocate for Ethernet driver handles array
* - ESP_FAIL on any other failure
*/
esp_err_t example_eth_init(esp_eth_handle_t *eth_handles_out[], uint8_t *eth_cnt_out);
#ifdef __cplusplus
}
#endif

View File

@ -1,239 +0,0 @@
menu "Example Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config EXAMPLE_USE_INTERNAL_ETHERNET
depends on IDF_TARGET_ESP32
select ETH_USE_ESP32_EMAC
bool "Internal EMAC"
help
Use internal Ethernet MAC controller.
if EXAMPLE_USE_INTERNAL_ETHERNET
choice EXAMPLE_ETH_PHY_MODEL
prompt "Ethernet PHY Device"
default EXAMPLE_ETH_PHY_IP101
help
Select the Ethernet PHY device to use in the example.
config EXAMPLE_ETH_PHY_IP101
bool "IP101"
help
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
config EXAMPLE_ETH_PHY_RTL8201
bool "RTL8201/SR8201"
help
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
config EXAMPLE_ETH_PHY_LAN87XX
bool "LAN87xx"
help
Below chips are supported:
LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
with HP Auto-MDIX and flexPWR® Technology.
LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
Goto https://www.microchip.com for more information about them.
config EXAMPLE_ETH_PHY_DP83848
bool "DP83848"
help
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
Goto http://www.ti.com/product/DP83848J for more information about it.
config EXAMPLE_ETH_PHY_KSZ80XX
bool "KSZ80xx"
help
With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX
Ethernet Physical Layer Tranceivers (PHY).
The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041,
KSZ8051, KSZ8061, KSZ8081, KSZ8091
Goto https://www.microchip.com for more information about them.
endchoice # EXAMPLE_ETH_PHY_MODEL
config EXAMPLE_ETH_MDC_GPIO
int "SMI MDC GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 23
help
Set the GPIO number used by SMI MDC.
config EXAMPLE_ETH_MDIO_GPIO
int "SMI MDIO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_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 ENV_GPIO_OUT_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
default 1
help
Set the SPI host used to communicate with the SPI Ethernet Controller.
config EXAMPLE_ETH_SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 14 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 13 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 12 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 2 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI MISO.
config EXAMPLE_ETH_SPI_CLOCK_MHZ
int "SPI clock speed (MHz)"
range 5 80
default 12 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
default 36 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
Set the clock speed (MHz) of SPI interface.
config EXAMPLE_ETH_SPI_CS0_GPIO
int "SPI CS0 GPIO number for SPI Ethernet module #1"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 15 if IDF_TARGET_ESP32
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
help
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 ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 32 if IDF_TARGET_ESP32
default 7 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 33 if IDF_TARGET_ESP32
default 5 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
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 ENV_GPIO_OUT_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 ENV_GPIO_OUT_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
endmenu

View File

@ -14,31 +14,11 @@
#include "esp_eth.h"
#include "esp_event.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "ethernet_init.h"
#include "sdkconfig.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif // CONFIG_ETH_USE_SPI_ETHERNET
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)
@ -85,146 +65,55 @@ static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
void app_main(void)
{
// Initialize TCP/IP network interface (should be called only once in application)
// Initialize Ethernet driver
uint8_t eth_port_cnt = 0;
esp_eth_handle_t *eth_handles;
ESP_ERROR_CHECK(example_eth_init(&eth_handles, &eth_port_cnt));
// Initialize TCP/IP network interface aka the esp-netif (should be called only once in application)
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);
// 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);
// Attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[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.).
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
};
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
for (int i = 0; i < eth_port_cnt; i++) {
itoa(i, num_str, 10);
strcat(strcpy(if_key_str, "ETH_"), 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 -= i*5;
esp_netif_t *eth_netif = esp_netif_new(&cfg_spi);
// 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;
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
#if CONFIG_EXAMPLE_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
#endif
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);
// Attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i])));
}
}
// 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);
// Init SPI bus
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -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 };
spi_device_interface_config_t spi_devcfg = {
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.queue_size = 20
};
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
// Set SPI module Chip Select GPIO
spi_devcfg.spics_io_num = spi_eth_module_config[i].spi_cs_gpio;
// Set remaining GPIO numbers and configuration used by the SPI module
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;
#if CONFIG_EXAMPLE_USE_KSZ8851SNL
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
ksz8851snl_config.int_gpio_num = spi_eth_module_config[i].int_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
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
dm9051_config.int_gpio_num = spi_eth_module_config[i].int_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
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
w5500_config.int_gpio_num = spi_eth_module_config[i].int_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
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_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]));
// Start Ethernet driver state machine
for (int i = 0; i < eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
}
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
}

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# ENC28J60 Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
@ -17,7 +17,7 @@ If you have a more complicated application to go (for example, connect to some I
### Hardware Required
To run this example, you need to prepare following hardwares:
* [ESP32 dev board](https://www.espressif.com/en/products/devkits?id=ESP32) (e.g. ESP32-PICO, ESP32 DevKitC, etc)
* [ESP32 dev board](https://www.espressif.com/en/products/devkits) (e.g. ESP32-PICO, ESP32 DevKitC, etc)
* ENC28J60 Ethernet module (the latest revision should be 6)
* **!! IMPORTANT !!** Proper input power source since ENC28J60 is quite power consuming device (it consumes more than 200 mA in peaks when transmitting). If improper power source is used, input voltage may drop and ENC28J60 may either provide nonsense response to host controller via SPI (fail to read registers properly) or it may enter to some strange state in the worst case. There are several options how to resolve it:
* Power ESP32 dev board from `USB 3.0`, if the dev board is used as source of power to the ENC28J60 module.

View File

@ -14,7 +14,7 @@ menu "Example Configuration"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 14 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 6 if IDF_TARGET_ESP32C3
default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2
help
Set the GPIO number used by SPI SCLK.
@ -23,7 +23,7 @@ menu "Example Configuration"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 13 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 7 if IDF_TARGET_ESP32C3
default 7 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2
help
Set the GPIO number used by SPI MOSI.
@ -32,7 +32,7 @@ menu "Example Configuration"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 12 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 2 if IDF_TARGET_ESP32C3
default 2 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2
help
Set the GPIO number used by SPI MISO.
@ -40,7 +40,7 @@ menu "Example Configuration"
int "SPI CS GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 15 if IDF_TARGET_ESP32
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C2
help
Set the GPIO number used by SPI CS.
@ -55,6 +55,7 @@ menu "Example Configuration"
int "Interrupt GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
default 4 if IDF_TARGET_ESP32C2
help
Set the GPIO number used by ENC28J60 interrupt.

View File

@ -1,4 +1,6 @@
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/ethernet/basic/components/ethernet_init)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(eth2ap)

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# eth2ap Example
(See the README.md file in the upper level 'examples' directory for more information about examples. To try a more complex application about Ethernet to WiFi data forwarding, please go to [iot-solution](https://github.com/espressif/esp-iot-solution/tree/release/v1.0/examples/eth2wifi).)

View File

@ -1,186 +1,5 @@
menu "Example Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config EXAMPLE_USE_SPI_ETHERNET
bool
choice EXAMPLE_ETHERNET_TYPE
prompt "Ethernet Type"
default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32
default EXAMPLE_USE_W5500
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
if EXAMPLE_USE_INTERNAL_ETHERNET
choice EXAMPLE_ETH_PHY_MODEL
prompt "Ethernet PHY Device"
default EXAMPLE_ETH_PHY_IP101
help
Select the Ethernet PHY device to use in the example.
config EXAMPLE_ETH_PHY_IP101
bool "IP101"
help
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
config EXAMPLE_ETH_PHY_RTL8201
bool "RTL8201/SR8201"
help
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
config EXAMPLE_ETH_PHY_LAN87XX
bool "LAN87xx"
help
Below chips are supported:
LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
with HP Auto-MDIX and flexPWR® Technology.
LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
Goto https://www.microchip.com for more information about them.
config EXAMPLE_ETH_PHY_DP83848
bool "DP83848"
help
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
Goto http://www.ti.com/product/DP83848J for more information about it.
config EXAMPLE_ETH_PHY_KSZ80XX
bool "KSZ80xx"
help
With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX
Ethernet Physical Layer Tranceivers (PHY).
The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041,
KSZ8051, KSZ8061, KSZ8081, KSZ8091
Goto https://www.microchip.com for more information about them.
endchoice # EXAMPLE_ETH_PHY_MODEL
config EXAMPLE_ETH_MDC_GPIO
int "SMI MDC GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 23
help
Set the GPIO number used by SMI MDC.
config EXAMPLE_ETH_MDIO_GPIO
int "SMI MDIO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18
help
Set the GPIO number used by SMI MDIO.
endif # EXAMPLE_USE_INTERNAL_ETHERNET
if EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_ETH_SPI_HOST
int "SPI Host Number"
range 0 2
default 1
help
Set the SPI host used to communicate with the SPI Ethernet Controller.
config EXAMPLE_ETH_SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 14 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 13 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 12 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 15 if IDF_TARGET_ESP32
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
help
Set the GPIO number used by SPI CS.
config EXAMPLE_ETH_SPI_CLOCK_MHZ
int "SPI clock speed (MHz)"
range 5 80
default 12 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
default 36 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
Set the clock speed (MHz) of SPI interface.
config EXAMPLE_ETH_SPI_INT_GPIO
int "Interrupt GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
help
Set the GPIO number used by the SPI Ethernet module interrupt line.
endif # EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
range -1 ENV_GPIO_OUT_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.
config EXAMPLE_WIFI_SSID
string "Wi-Fi SSID"
default "eth2ap"

View File

@ -18,12 +18,9 @@
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "esp_private/wifi.h"
#include "driver/gpio.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif
#include "ethernet_init.h"
static const char *TAG = "eth_example";
static const char *TAG = "eth2ap_example";
static esp_eth_handle_t s_eth_handle = NULL;
static QueueHandle_t flow_control_queue = NULL;
static bool s_sta_is_connected = false;
@ -152,75 +149,19 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base,
static void initialize_ethernet(void)
{
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler, NULL));
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
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
#if CONFIG_EXAMPLE_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
#endif
#elif CONFIG_ETH_USE_SPI_ETHERNET
gpio_install_isr_service(0);
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
spi_device_interface_config_t spi_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
};
#if CONFIG_EXAMPLE_USE_KSZ8851SNL
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
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);
#elif CONFIG_EXAMPLE_USE_DM9051
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
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);
#elif CONFIG_EXAMPLE_USE_W5500
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
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);
config.stack_input = pkt_eth2wifi;
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_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.
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(s_eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) {
0x02, 0x00, 0x00, 0x12, 0x34, 0x56
}));
#endif
uint8_t eth_port_cnt = 0;
esp_eth_handle_t *eth_handles;
ESP_ERROR_CHECK(example_eth_init(&eth_handles, &eth_port_cnt));
if (eth_port_cnt > 1) {
ESP_LOGW(TAG, "multiple Ethernet devices detected, the first initialized is to be used!");
}
s_eth_handle = eth_handles[0];
free(eth_handles);
ESP_ERROR_CHECK(esp_eth_update_input_path(s_eth_handle, pkt_eth2wifi, NULL));
bool eth_promiscuous = true;
esp_eth_ioctl(s_eth_handle, ETH_CMD_S_PROMISCUOUS, &eth_promiscuous);
esp_eth_start(s_eth_handle);
ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_PROMISCUOUS, &eth_promiscuous));
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler, NULL));
ESP_ERROR_CHECK(esp_eth_start(s_eth_handle));
}
static void initialize_wifi(void)

View File

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/system/console/advanced/components
$ENV{IDF_PATH}/examples/common_components/iperf
$ENV{IDF_PATH}/examples/ethernet/enc28j60/components/eth_enc28j60)
$ENV{IDF_PATH}/examples/ethernet/basic/components/ethernet_init)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ethernet_iperf)

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# Ethernet iperf Example

View File

@ -26,7 +26,7 @@ except ImportError:
# Only used for type annotations
pass
NO_BANDWIDTH_LIMIT = -1 # iperf send bandwith is not limited
NO_BANDWIDTH_LIMIT = -1 # iperf send bandwidth is not limited
class IperfTestUtilityEth(IperfUtility.IperfTestUtility):

View File

@ -1,7 +1,5 @@
menu "Example Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config EXAMPLE_STORE_HISTORY
bool "Store command history in flash"
default y
@ -9,212 +7,4 @@ menu "Example Configuration"
Linenoise line editing library provides functions to save and load
command history. If this option is enabled, initalizes a FAT filesystem
and uses it to store command history.
config EXAMPLE_USE_SPI_ETHERNET
bool
choice EXAMPLE_ETHERNET_TYPE
prompt "Ethernet Type"
default EXAMPLE_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32
default EXAMPLE_USE_W5500
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).
config EXAMPLE_USE_ENC28J60
bool "ENC28J60 Module"
select EXAMPLE_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_ENC28J60
help
Select external SPI-Ethernet module (ENC28J60).
endchoice # EXAMPLE_ETHERNET_TYPE
if EXAMPLE_USE_INTERNAL_ETHERNET
choice EXAMPLE_ETH_PHY_MODEL
prompt "Ethernet PHY Device"
default EXAMPLE_ETH_PHY_IP101
help
Select the Ethernet PHY device to use in the example.
config EXAMPLE_ETH_PHY_IP101
bool "IP101"
help
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
config EXAMPLE_ETH_PHY_RTL8201
bool "RTL8201/SR8201"
help
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
config EXAMPLE_ETH_PHY_LAN87XX
bool "LAN87xx"
help
Below chips are supported:
LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
with HP Auto-MDIX and flexPWR® Technology.
LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
Goto https://www.microchip.com for more information about them.
config EXAMPLE_ETH_PHY_DP83848
bool "DP83848"
help
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
Goto http://www.ti.com/product/DP83848J for more information about it.
config EXAMPLE_ETH_PHY_KSZ80XX
bool "KSZ80xx"
help
With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX
Ethernet Physical Layer Tranceivers (PHY).
The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041,
KSZ8051, KSZ8061, KSZ8081, KSZ8091
Goto https://www.microchip.com for more information about them.
endchoice # EXAMPLE_ETH_PHY_MODEL
config EXAMPLE_ETH_MDC_GPIO
int "SMI MDC GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 23
help
Set the GPIO number used by SMI MDC.
config EXAMPLE_ETH_MDIO_GPIO
int "SMI MDIO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18
help
Set the GPIO number used by SMI MDIO.
endif # EXAMPLE_USE_INTERNAL_ETHERNET
if EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_ETH_SPI_HOST
int "SPI Host Number"
range 0 2
default 1
help
Set the SPI host used to communicate with the SPI Ethernet Controller.
config EXAMPLE_ETH_SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 14 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 13 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 12 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
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 ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 15 if IDF_TARGET_ESP32
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
help
Set the GPIO number used by SPI CS.
config EXAMPLE_ETH_SPI_CLOCK_MHZ
int "SPI clock speed (MHz)"
range 5 80
default 8 if EXAMPLE_USE_ENC28J60
default 12 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
default 36 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
Set the clock speed (MHz) of SPI interface.
config EXAMPLE_ETH_SPI_INT_GPIO
int "Interrupt GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
help
Set the GPIO number used by the SPI Ethernet module interrupt line.
endif # EXAMPLE_USE_SPI_ETHERNET
config EXAMPLE_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
range -1 ENV_GPIO_OUT_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.
if EXAMPLE_USE_ENC28J60
choice EXAMPLE_ENC28J60_DUPLEX_MODE
prompt "Duplex Mode"
default EXAMPLE_ENC28J60_DUPLEX_HALF
help
Select ENC28J60 Duplex operation mode.
config EXAMPLE_ENC28J60_DUPLEX_FULL
bool "Full Duplex"
help
Set ENC28J60 to Full Duplex mode. Do not forget to manually set the remote node (switch, router
or Ethernet controller) to full-duplex operation mode too.
config EXAMPLE_ENC28J60_DUPLEX_HALF
bool "Half Duplex"
help
Set ENC28J60 to Half Duplex mode.
endchoice # EXAMPLE_ENC28J60_DUPLEX_MODE
endif # ETH_SPI_ETHERNET_ENC28J60
endmenu

View File

@ -10,29 +10,25 @@
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "sys/socket.h" // for INADDR_ANY
#include "esp_netif.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_event.h"
#include "esp_eth.h"
#include "esp_mac.h"
#include "driver/gpio.h"
#include "esp_bit_defs.h"
#include "argtable3/argtable3.h"
#include "ethernet_init.h"
#include "iperf.h"
#include "sdkconfig.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#if CONFIG_EXAMPLE_USE_ENC28J60
#include "esp_eth_enc28j60.h"
#endif //CONFIG_EXAMPLE_USE_ENC28J60
#endif // CONFIG_ETH_USE_SPI_ETHERNET
static esp_netif_ip_info_t ip;
static bool started = false;
static EventGroupHandle_t eth_event_group;
static const int GOTIP_BIT = BIT0;
static esp_eth_handle_t eth_handle = NULL;
static esp_netif_t *eth_netif = NULL;
static esp_eth_handle_t *s_eth_handles = NULL;
static uint8_t s_eth_port_cnt = 0;
static esp_netif_t **s_eth_netifs = NULL;
/* "ethernet" command */
static struct {
@ -50,12 +46,16 @@ static int eth_cmd_control(int argc, char **argv)
if (!strncmp(eth_control_args.control->sval[0], "info", 4)) {
uint8_t mac_addr[6];
esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
printf("HW ADDR: " MACSTR "\r\n", MAC2STR(mac_addr));
esp_netif_get_ip_info(eth_netif, &ip);
printf("ETHIP: " IPSTR "\r\n", IP2STR(&ip.ip));
printf("ETHMASK: " IPSTR "\r\n", IP2STR(&ip.netmask));
printf("ETHGW: " IPSTR "\r\n", IP2STR(&ip.gw));
esp_netif_ip_info_t ip;
for(uint32_t i = 0; i < s_eth_port_cnt; i++) {
printf("%s:\r\n", esp_netif_get_desc(s_eth_netifs[i]));
esp_eth_ioctl(s_eth_handles[i], ETH_CMD_G_MAC_ADDR, mac_addr);
printf(" HW ADDR: " MACSTR "\r\n", MAC2STR(mac_addr));
esp_netif_get_ip_info(s_eth_netifs[i], &ip);
printf(" ETHIP: " IPSTR "\r\n", IP2STR(&ip.ip));
printf(" ETHMASK: " IPSTR "\r\n", IP2STR(&ip.netmask));
printf(" ETHGW: " IPSTR "\r\n", IP2STR(&ip.gw));
}
}
return 0;
}
@ -119,14 +119,10 @@ static int eth_cmd_iperf(int argc, char **argv)
cfg.len_send_buf = iperf_args.length->ival[0];
}
/* acquiring for ip, could blocked here */
/* wait for ip, could blocked here */
xEventGroupWaitBits(eth_event_group, GOTIP_BIT, pdFALSE, pdTRUE, portMAX_DELAY);
cfg.source_ip4 = ip.ip.addr;
if (cfg.source_ip4 == 0) {
return 0;
}
cfg.source_ip4 = INADDR_ANY;
/* iperf -u */
if (iperf_args.udp->count == 0) {
@ -201,8 +197,6 @@ static void event_handler(void *arg, esp_event_base_t event_base,
xEventGroupClearBits(eth_event_group, GOTIP_BIT);
started = false;
} else if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
memcpy(&ip, &event->ip_info, sizeof(ip));
xEventGroupSetBits(eth_event_group, GOTIP_BIT);
}
}
@ -210,91 +204,38 @@ static void event_handler(void *arg, esp_event_base_t event_base,
void register_ethernet(void)
{
eth_event_group = xEventGroupCreate();
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
eth_netif = esp_netif_new(&cfg);
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
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
#if CONFIG_EXAMPLE_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
#endif
#elif CONFIG_ETH_USE_SPI_ETHERNET
gpio_install_isr_service(0);
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
ESP_ERROR_CHECK(example_eth_init(&s_eth_handles, &s_eth_port_cnt));
spi_device_interface_config_t spi_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(esp_netif_init());
s_eth_netifs = calloc(s_eth_port_cnt, sizeof(esp_netif_t *));
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
};
#if CONFIG_EXAMPLE_USE_KSZ8851SNL
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
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);
#elif CONFIG_EXAMPLE_USE_DM9051
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
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);
#elif CONFIG_EXAMPLE_USE_W5500
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
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);
#elif CONFIG_EXAMPLE_USE_ENC28J60
spi_devcfg.cs_ena_posttrans = enc28j60_cal_spi_cs_hold_time(CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ);
eth_enc28j60_config_t enc28j60_config = ETH_ENC28J60_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
enc28j60_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_enc28j60(&enc28j60_config, &mac_config);
phy_config.autonego_timeout_ms = 0; // ENC28J60 doesn't support auto-negotiation
phy_config.reset_gpio_num = -1; // ENC28J60 doesn't have a pin to reset internal PHY
esp_eth_phy_t *phy = esp_eth_phy_new_enc28j60(&phy_config);
#endif
#endif // CONFIG_ETH_USE_SPI_ETHERNET
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
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.
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
#if CONFIG_EXAMPLE_USE_ENC28J60 && CONFIG_EXAMPLE_ENC28J60_DUPLEX_FULL
eth_duplex_t duplex = ETH_DUPLEX_FULL;
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_DUPLEX_MODE, &duplex));
#endif
ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
for (int i = 0; i < s_eth_port_cnt; i++) {
itoa(i, num_str, 10);
strcat(strcpy(if_key_str, "ETH_"), 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 -= i*5;
s_eth_netifs[i] = esp_netif_new(&cfg_spi);
// attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(s_eth_netifs[i], esp_eth_new_netif_glue(s_eth_handles[i])));
}
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &event_handler, NULL));
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
for (int i = 0; i < s_eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_start(s_eth_handles[i]));
}
eth_control_args.control = arg_str1(NULL, NULL, "<info>", "Get info of Ethernet");
eth_control_args.end = arg_end(1);

View File

@ -7,11 +7,7 @@ examples/network/network_tests:
reason: target esp32c2 is not supported yet
examples/network/simple_sniffer:
disable:
- if: IDF_TARGET == "esp32c2"
temporary: true
reason: target esp32c2 is not supported yet
disable_test:
- if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3"]
- if: IDF_TARGET in ["esp32c3", "esp32c2", "esp32s2", "esp32s3"]
temporary: true
reason: not tested

View File

@ -2,5 +2,7 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/ethernet/basic/components/ethernet_init)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(bridge)

View File

@ -13,43 +13,12 @@
#include "esp_eth.h"
#include "esp_event.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "esp_mac.h"
#include "ethernet_init.h"
#include "sdkconfig.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif // CONFIG_ETH_USE_SPI_ETHERNET
static const char *TAG = "eth_bridge_example";
#if CONFIG_EXAMPLE_SPI_ETHERNETS_NUM
#define SPI_ETHERNETS_NUM CONFIG_EXAMPLE_SPI_ETHERNETS_NUM
#else
#define SPI_ETHERNETS_NUM 0
#endif
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#define INTERNAL_ETHERNETS_NUM 1
#else
#define INTERNAL_ETHERNETS_NUM 0
#endif
#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)
@ -94,144 +63,29 @@ static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
ESP_LOGI(TAG, "~~~~~~~~~~~");
}
#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
/** Internal EMAC initialization */
esp_eth_handle_t eth_init_internal(void)
{
esp_eth_handle_t eth_handle;
// 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;
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
#if CONFIG_EXAMPLE_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX
esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
#endif
esp_eth_config_t config = ETH_DEFAULT_CONFIG(mac, phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&config, &eth_handle));
return eth_handle;
}
#endif // CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
/** Ethernet SPI modules initialization */
esp_eth_handle_t eth_init_spi(spi_eth_module_config_t *spi_eth_module_config, uint8_t *mac_addr)
{
esp_eth_handle_t eth_handle;
// 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();
// Set module specific PHY config
phy_config.phy_addr = spi_eth_module_config->phy_addr;
phy_config.reset_gpio_num = spi_eth_module_config->phy_reset_gpio;
// Configure SPI interface and Ethernet driver for specific SPI module
esp_eth_mac_t *mac;
esp_eth_phy_t *phy;
spi_device_interface_config_t spi_devcfg = {
.mode = 0,
.clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.queue_size = 20,
.spics_io_num = spi_eth_module_config->spi_cs_gpio
};
#if CONFIG_EXAMPLE_USE_KSZ8851SNL
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
ksz8851snl_config.int_gpio_num = spi_eth_module_config->int_gpio;
mac = esp_eth_mac_new_ksz8851snl(&ksz8851snl_config, &mac_config);
phy = esp_eth_phy_new_ksz8851snl(&phy_config);
#elif CONFIG_EXAMPLE_USE_DM9051
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
dm9051_config.int_gpio_num = spi_eth_module_config->int_gpio;
mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config);
phy = esp_eth_phy_new_dm9051(&phy_config);
#elif CONFIG_EXAMPLE_USE_W5500
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg);
w5500_config.int_gpio_num = spi_eth_module_config->int_gpio;
mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
phy = esp_eth_phy_new_w5500(&phy_config);
#endif //CONFIG_EXAMPLE_USE_W5500
esp_eth_config_t eth_config_spi = ETH_DEFAULT_CONFIG(mac, phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&eth_config_spi, &eth_handle));
// The SPI Ethernet module might not have a burned factory MAC address, we cat to set it manually.
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, mac_addr));
return eth_handle;
}
#endif // CONFIG_EXAMPLE_USE_SPI_ETHERNET
void app_main(void)
{
// number of Ethernet ports to be used in the bridge
uint8_t port_cnt = 0;
// the same MAC address will be used for all Ethernet ports since the bridge acts as one device
// Initialize Ethernet driver
uint8_t eth_port_cnt = 0;
esp_eth_handle_t *eth_handles;
ESP_ERROR_CHECK(example_eth_init(&eth_handles, &eth_port_cnt));
// The same MAC address will be used for all Ethernet ports since the bridge acts as one device
uint8_t common_mac_addr[ETH_ADDR_LEN];
// If internal Ethernet is not supported by ESP32x SoC, Locally Administered OUI address might be returned.
// Note that Locally Administered OUI range should be used only when testing on a LAN under your control!
ESP_ERROR_CHECK(esp_read_mac(common_mac_addr, ESP_MAC_ETH));
for (int i = 0; i < eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handles[i], ETH_CMD_S_MAC_ADDR, common_mac_addr));
}
esp_eth_handle_t eth_handles[SPI_ETHERNETS_NUM + INTERNAL_ETHERNETS_NUM] = { NULL };
esp_netif_t *eth_netifs[SPI_ETHERNETS_NUM + INTERNAL_ETHERNETS_NUM] = { NULL };
// Initialize TCP/IP network interface (should be called only once in application)
// Initialize TCP/IP network interface
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
eth_handles[port_cnt++] = eth_init_internal();
// use burned ESP32 MAC address as commom address for all Ethernet interfaces
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handles[0], ETH_CMD_G_MAC_ADDR, common_mac_addr));
#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET
// if ESP32 internal Ethernet is not used, use manually configured MAC address
// 02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control.
memcpy(common_mac_addr, (uint8_t[]) {0x02, 0x00, 0x00, 0x12, 0x34, 0x56}, ETH_ADDR_LEN);
#endif //CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET
#if CONFIG_EXAMPLE_USE_SPI_ETHERNET
// Install GPIO ISR handler to be able to service SPI Eth modlues interrupts
gpio_install_isr_service(0);
// Init SPI bus
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -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
for (int i = 0; i < CONFIG_EXAMPLE_SPI_ETHERNETS_NUM; i++) {
eth_handles[port_cnt++] = eth_init_spi(&spi_eth_module_config[i], common_mac_addr);
}
#endif // CONFIG_ETH_USE_SPI_ETHERNET
// Create instances of esp-netif for Ethernet ports
esp_netif_t **eth_netifs = calloc(eth_port_cnt, sizeof(esp_netif_t *));
esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
esp_netif_config_t netif_cfg = {
.base = &esp_netif_config,
@ -240,18 +94,18 @@ void app_main(void)
char if_key_str[10];
char if_desc_str[10];
char num_str[3];
for (int i = 0; i < port_cnt; i++) {
for (int i = 0; i < eth_port_cnt; i++) {
itoa(i, num_str, 10);
strcat(strcpy(if_key_str, "ETH_"), 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 = 50 - i;
esp_netif_config.flags = 0; // ESP-NETIF flags need to be zero when port's to be bridged
esp_netif_config.flags = 0; // esp-netif flags need to be zero when port's to be bridged
eth_netifs[i] = esp_netif_new(&netif_cfg);
// attach Ethernet driver to TCP/IP stack
// Attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(esp_netif_attach(eth_netifs[i], esp_eth_new_netif_glue(eth_handles[i])));
}
@ -265,7 +119,7 @@ void app_main(void)
bridgeif_config_t bridgeif_config = {
.max_fdb_dyn_entries = 10, // maximum number of address entries in dynamic forwarding database
.max_fdb_sta_entries = 2, // maximum number of address entries in static forwarding database
.max_ports = port_cnt // maximum number of ports the bridge can consist of
.max_ports = eth_port_cnt // maximum number of ports the bridge can consist of
};
esp_netif_br_config.bridge_info = &bridgeif_config;
// Set MAC address of bridge interface the same as the Ethernet interface
@ -275,7 +129,7 @@ void app_main(void)
// Create new esp netif bridge glue instance
esp_netif_br_glue_handle_t netif_br_glue = esp_netif_br_glue_new();
// Add Ethernet port interfaces to that esp netif bridge glue instance
for (int i = 0; i < port_cnt; i++) {
for (int i = 0; i < eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_netif_br_glue_add_port(netif_br_glue, eth_netifs[i]));
}
// Attach esp netif bridge glue instance with added ports to bridge netif
@ -285,7 +139,7 @@ void app_main(void)
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));
for (int i = 0; i < port_cnt; i++) {
for (int i = 0; i < eth_port_cnt; i++) {
// Since the MAC forwarding is performed in lwIP bridge, we need to pass all addresses through the Ethernet MACs
bool promiscuous = true;
esp_eth_ioctl(eth_handles[i], ETH_CMD_S_PROMISCUOUS, &promiscuous);

View File

@ -2,5 +2,7 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/ethernet/basic/components/ethernet_init)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(simple_sniffer)

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
# Simple Sniffer Example
@ -26,7 +26,7 @@ See common pin assignments for Ethernet from [ethernet examples folder](../../et
### Configure the project
Open the project configuration menu (`idf.py menuconfig`). Then go into `Example Configuration` menu.
Open the project configuration menu (`idf.py menuconfig`). Then go into `Example Configuration` in top menu.
- Check `Store command history in flash` if you want to save command history into flash (recommend).
- Select where to save the pcap file in `Select destination to store pcap file` menu item.
@ -38,10 +38,8 @@ Open the project configuration menu (`idf.py menuconfig`). Then go into `Example
- Set the length of sniffer work queue in `Length of sniffer work queue` menu item.
- Set the stack size of the sniffer task in `Stack size of sniffer task` menu item.
- Set the priority of the sniffer task in `Length of sniffer work queue` menu item.
- Select Ethernet Type
- `No Ethernet` means your board does not have Ethernet.
- `Internal EMAC` means ESP32 EMAC is used in conjunction with with selected PHY.
- `DM9051 Module`, `W5500 Module` or `KSZ8851SNL Module` means that SPI-Ethernet module is used with its own EMAC and PHY.
To configure Ethernet device(s), go to `Example Ethernet Configuration` in top menu.
- For more information related to Ethernet configurations see common configuration of Ethernet from [ethernet examples folder](../../ethernet/README.md#common-configurations).
### Build and Flash

View File

@ -87,188 +87,4 @@ menu "Example Configuration"
help
Priority of sniffer task.
config SNIFFER_USE_SPI_ETHERNET
bool
choice SNIFFER_ETHERNET_TYPE
prompt "Ethernet Type"
default SNIFFER_NO_ETHERNET
help
Select which kind of Ethernet will be used in the example.
config SNIFFER_NO_ETHERNET
bool "No Ethernet"
help
No Ethernet.
config SNIFFER_USE_INTERNAL_ETHERNET
depends on IDF_TARGET_ESP32
select ETH_USE_ESP32_EMAC
bool "Internal EMAC"
help
Select internal Ethernet MAC controller.
config SNIFFER_USE_DM9051
bool "DM9051 Module"
select SNIFFER_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_DM9051
help
Select external SPI-Ethernet module (DM9051).
config SNIFFER_USE_W5500
bool "W5500 Module"
select SNIFFER_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_W5500
help
Select external SPI-Ethernet module (W5500).
config SNIFFER_USE_KSZ8851SNL
bool "KSZ8851SNL Module"
select SNIFFER_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_KSZ8851SNL
help
Select external SPI-Ethernet module (KSZ8851SNL).
endchoice # SNIFFER_ETHERNET_TYPE
if SNIFFER_USE_INTERNAL_ETHERNET
choice SNIFFER_ETH_PHY_MODEL
prompt "Ethernet PHY Device"
default SNIFFER_ETH_PHY_IP101
help
Select the Ethernet PHY device to use in the example.
config SNIFFER_ETH_PHY_IP101
bool "IP101"
help
IP101 is a single port 10/100 MII/RMII/TP/Fiber Fast Ethernet Transceiver.
Goto http://www.icplus.com.tw/pp-IP101G.html for more information about it.
config SNIFFER_ETH_PHY_RTL8201
bool "RTL8201/SR8201"
help
RTL8201F/SR8201F is a single port 10/100Mb Ethernet Transceiver with auto MDIX.
Goto http://www.corechip-sz.com/productsview.asp?id=22 for more information about it.
config SNIFFER_ETH_PHY_LAN87XX
bool "LAN87xx"
help
Below chips are supported:
LAN8710A is a small footprint MII/RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
LAN8720A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX Support.
LAN8740A/LAN8741A is a small footprint MII/RMII 10/100 Energy Efficient Ethernet Transceiver
with HP Auto-MDIX and flexPWR® Technology.
LAN8742A is a small footprint RMII 10/100 Ethernet Transceiver with HP Auto-MDIX and
flexPWR® Technology.
Goto https://www.microchip.com for more information about them.
config SNIFFER_ETH_PHY_DP83848
bool "DP83848"
help
DP83848 is a single port 10/100Mb/s Ethernet Physical Layer Transceiver.
Goto http://www.ti.com/product/DP83848J for more information about it.
config SNIFFER_ETH_PHY_KSZ80XX
bool "KSZ80xx"
help
With the KSZ80xx series, Microchip offers single-chip 10BASE-T/100BASE-TX
Ethernet Physical Layer Tranceivers (PHY).
The following chips are supported: KSZ8001, KSZ8021, KSZ8031, KSZ8041,
KSZ8051, KSZ8061, KSZ8081, KSZ8091
Goto https://www.microchip.com for more information about them.
endchoice # SNIFFER_ETH_PHY_MODEL
config SNIFFER_ETH_MDC_GPIO
int "SMI MDC GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 23
help
Set the GPIO number used by SMI MDC.
config SNIFFER_ETH_MDIO_GPIO
int "SMI MDIO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18
help
Set the GPIO number used by SMI MDIO.
endif # SNIFFER_USE_INTERNAL_ETHERNET
if SNIFFER_USE_SPI_ETHERNET
config SNIFFER_ETH_SPI_HOST
int "SPI Host Number"
range 0 2
default 1
help
Set the SPI host used to communicate with the SPI Ethernet Controller.
config SNIFFER_ETH_SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 14 if IDF_TARGET_ESP32
default 12 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 6 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI SCLK.
config SNIFFER_ETH_SPI_MOSI_GPIO
int "SPI MOSI GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 13 if IDF_TARGET_ESP32
default 11 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 7 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI MOSI.
config SNIFFER_ETH_SPI_MISO_GPIO
int "SPI MISO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 12 if IDF_TARGET_ESP32
default 13 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 2 if IDF_TARGET_ESP32C3
help
Set the GPIO number used by SPI MISO.
config SNIFFER_ETH_SPI_CS_GPIO
int "SPI CS GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 15 if IDF_TARGET_ESP32
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
help
Set the GPIO number used by SPI CS.
config SNIFFER_ETH_SPI_CLOCK_MHZ
int "SPI clock speed (MHz)"
range 5 80
default 12 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
default 36 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
Set the clock speed (MHz) of SPI interface.
config SNIFFER_ETH_SPI_INT_GPIO
int "Interrupt GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3
help
Set the GPIO number used by the SPI Ethernet module interrupt line.
endif # SNIFFER_USE_SPI_ETHERNET
if !SNIFFER_NO_ETHERNET
config SNIFFER_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
range -1 ENV_GPIO_OUT_RANGE_MAX
default 5
help
Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset.
config SNIFFER_ETH_PHY_ADDR
int "PHY Address"
range 0 31
default 1
help
Set PHY address according your board schematic.
endif # !SNIFFER_NO_ETHERNET
endmenu

View File

@ -373,11 +373,11 @@ static int do_sniffer_cmd(int argc, char **argv)
snf_rt.interf = SNIFFER_INTF_ETH;
snf_rt.interf_num = eth_intf_num;
} else {
ESP_LOGE(SNIFFER_TAG, "unsupported interface %s", sniffer_args.interface->sval[0]);
ESP_LOGE(SNIFFER_TAG, "interface %s not found", sniffer_args.interface->sval[0]);
return 1;
}
} else {
ESP_LOGE(SNIFFER_TAG, "unsupported interface %s", sniffer_args.interface->sval[0]);
ESP_LOGE(SNIFFER_TAG, "interface %s not found", sniffer_args.interface->sval[0]);
return 1;
}
} else {

View File

@ -16,6 +16,7 @@
#include "esp_event.h"
#include "esp_vfs_fat.h"
#include "esp_wifi.h"
#include "ethernet_init.h"
#include "esp_err.h"
#include "esp_log.h"
#if CONFIG_SNIFFER_PCAP_DESTINATION_SD
@ -27,9 +28,6 @@
#include "sdmmc_cmd.h"
#include "cmd_sniffer.h"
#include "cmd_pcap.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif // CONFIG_ETH_USE_SPI_ETHERNET
#if CONFIG_SNIFFER_STORE_HISTORY
#define HISTORY_MOUNT_POINT "/data"
@ -91,7 +89,6 @@ static void initialize_wifi(void)
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL));
}
#ifndef CONFIG_SNIFFER_NO_ETHERNET
/** 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)
@ -127,80 +124,23 @@ static void eth_event_handler(void *arg, esp_event_base_t event_base,
static void initialize_eth(void)
{
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
// Initialize Ethernet driver
uint8_t eth_port_cnt = 0;
esp_eth_handle_t *eth_handles;
ESP_ERROR_CHECK(example_eth_init(&eth_handles, &eth_port_cnt));
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_SNIFFER_ETH_PHY_ADDR;
phy_config.reset_gpio_num = CONFIG_SNIFFER_ETH_PHY_RST_GPIO;
#if CONFIG_SNIFFER_USE_INTERNAL_ETHERNET
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
esp32_emac_config.smi_mdc_gpio_num = CONFIG_SNIFFER_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_SNIFFER_ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
#if CONFIG_SNIFFER_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_SNIFFER_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_SNIFFER_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_SNIFFER_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_SNIFFER_ETH_PHY_KSZ80XX
esp_eth_phy_t *phy = esp_eth_phy_new_ksz80xx(&phy_config);
#endif
#elif CONFIG_ETH_USE_SPI_ETHERNET
gpio_install_isr_service(0);
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_SNIFFER_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_SNIFFER_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_SNIFFER_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_SNIFFER_ETH_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
spi_device_interface_config_t spi_devcfg = {
.mode = 0,
.clock_speed_hz = CONFIG_SNIFFER_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_SNIFFER_ETH_SPI_CS_GPIO,
.queue_size = 20
};
#if CONFIG_SNIFFER_USE_KSZ8851SNL
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(CONFIG_SNIFFER_ETH_SPI_HOST, &spi_devcfg);
ksz8851snl_config.int_gpio_num = CONFIG_SNIFFER_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);
#elif CONFIG_SNIFFER_USE_DM9051
eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_SNIFFER_ETH_SPI_HOST, &spi_devcfg);
dm9051_config.int_gpio_num = CONFIG_SNIFFER_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);
#elif CONFIG_SNIFFER_USE_W5500
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_SNIFFER_ETH_SPI_HOST, &spi_devcfg);
w5500_config.int_gpio_num = CONFIG_SNIFFER_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_SNIFFER_USE_INTERNAL_ETHERNET
/* The SPI Ethernet module might doesn't 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
/* start Ethernet driver state machine */
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
if (eth_port_cnt > 0) {
// Register user defined event handers
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
/* Register Ethernet interface to could be used by sniffer */
ESP_ERROR_CHECK(sniffer_reg_eth_intf(eth_handle));
for (uint32_t i = 0; i < eth_port_cnt; i++) {
/* start Ethernet driver state machine */
ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
/* Register Ethernet interface to could be used by sniffer */
ESP_ERROR_CHECK(sniffer_reg_eth_intf(eth_handles[i]));
}
}
}
#endif // CONFIG_SNIFFER_NO_ETHERNET
#if CONFIG_SNIFFER_PCAP_DESTINATION_SD
static struct {
@ -341,10 +281,8 @@ void app_main(void)
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* Initialize WiFi */
initialize_wifi();
#ifndef CONFIG_SNIFFER_NO_ETHERNET
/* Initialize Ethernet */
initialize_eth();
#endif
/*--- Initialize Console ---*/
esp_console_repl_t *repl = NULL;

View File

@ -19,3 +19,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# FatFS
CONFIG_FATFS_LFN_HEAP=y
CONFIG_FATFS_MAX_LFN=31
# Network Interfaces
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=n
CONFIG_EXAMPLE_USE_SPI_ETHERNET=n