Sync with sample stuffing (#69)

* upgrade to IDF v5.1.1
* add new synchronization implementation, use sample stuffing / removal to keep up sync
* use big DMA buffer for I2S and improve sync
* Add DAC TAS5805M as custom board
* add wifi credential reset
  o press reset button (nRESET pin) 3 times
    but wait about 1s between button presses
    the button press counter is reset 5s after boot
* Add support for PT8211 DAC (#78)
* upgrade ethernet interface to IDF v5 (#84)
* port official example of ethernet for IDF v5.x
* Fix cmake if guard for ethernet

Signed-off-by: Karl Osterseher <karli_o@gmx.at>
Co-authored-by: DerPicknicker <64746593+DerPicknicker@users.noreply.github.com>
Co-authored-by: whc2001 <ianwang0122@outlook.com>
This commit is contained in:
CarlosDerSeher
2024-05-31 20:38:09 +02:00
committed by GitHub
Unverified
parent fd701a1ead
commit fae271186c
477 changed files with 34664 additions and 41052 deletions

View File

@@ -1,11 +1,3 @@
if(CONFIG_SNAPCLIENT_ENABLE_ETHERNET)
idf_component_register(SRCS "eth_interface.c"
INCLUDE_DIRS "include")
else()
idf_component_register()
endif()
INCLUDE_DIRS "include"
REQUIRES driver esp_eth esp_netif)

View File

@@ -1,51 +1,19 @@
menu "Snapclient Ethernet Configuration"
config SNAPCLIENT_ENABLE_ETHERNET
bool "enable Ethernet"
default n
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config SNAPCLIENT_USE_INTERNAL_ETHERNET
depends on SOC_EMAC_SUPPORTED
select ETH_USE_ESP32_EMAC
default y
bool "Internal EMAC"
help
Enable Ethernet interface
config SNAPCLIENT_USE_SPI_ETHERNET
bool
depends on SNAPCLIENT_ENABLE_ETHERNET
choice SNAPCLIENT_ETHERNET_TYPE
prompt "Ethernet Type"
default SNAPCLIENT_USE_INTERNAL_ETHERNET if IDF_TARGET_ESP32
default SNAPCLIENT_USE_W5500
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Select which kind of Ethernet will be used in the example.
config SNAPCLIENT_USE_INTERNAL_ETHERNET
depends on IDF_TARGET_ESP32
select ETH_USE_ESP32_EMAC
bool "Internal EMAC"
help
Select internal Ethernet MAC controller.
config SNAPCLIENT_USE_DM9051
bool "DM9051 Module"
select SNAPCLIENT_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_DM9051
help
Select external SPI-Ethernet module (DM9051).
config SNAPCLIENT_USE_W5500
bool "W5500 Module"
select SNAPCLIENT_USE_SPI_ETHERNET
select ETH_USE_SPI_ETHERNET
select ETH_SPI_ETHERNET_W5500
help
Select external SPI-Ethernet module (W5500).
endchoice # SNAPCLIENT_ETHERNET_TYPE
Use internal Ethernet MAC controller.
if SNAPCLIENT_USE_INTERNAL_ETHERNET
choice SNAPCLIENT_ETH_PHY_MODEL
prompt "Ethernet PHY Device"
default SNAPCLIENT_ETH_PHY_IP101
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Select the Ethernet PHY device to use in the example.
@@ -61,11 +29,18 @@ menu "Snapclient Ethernet Configuration"
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 SNAPCLIENT_ETH_PHY_LAN8720
bool "LAN8720"
config SNAPCLIENT_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.
Goto https://www.microchip.com/LAN8720A for more information about it.
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 SNAPCLIENT_ETH_PHY_DP83848
bool "DP83848"
@@ -73,98 +48,202 @@ menu "Snapclient Ethernet Configuration"
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 SNAPCLIENT_ETH_PHY_KSZ8041
bool "KSZ8041"
config SNAPCLIENT_ETH_PHY_KSZ80XX
bool "KSZ80xx"
help
The KSZ8041 is a single supply 10Base-T/100Base-TX Physical Layer Transceiver.
Goto https://www.microchip.com/wwwproducts/en/KSZ8041 for more information about it.
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 # SNAPCLIENT_ETH_PHY_MODEL
config SNAPCLIENT_ETH_MDC_GPIO
int "SMI MDC GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 23
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Set the GPIO number used by SMI MDC.
config SNAPCLIENT_ETH_MDIO_GPIO
int "SMI MDIO GPIO number"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Set the GPIO number used by SMI MDIO.
config SNAPCLIENT_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
range -1 ENV_GPIO_OUT_RANGE_MAX
default 17
help
Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset.
config SNAPCLIENT_ETH_PHY_ADDR
int "PHY Address"
range 0 31
default 0
help
Set PHY address according your board schematic.
endif # SNAPCLIENT_USE_INTERNAL_ETHERNET
config SNAPCLIENT_USE_SPI_ETHERNET
bool "SPI Ethernet"
default n
select ETH_USE_SPI_ETHERNET
help
Use external SPI-Ethernet module(s).
if SNAPCLIENT_USE_SPI_ETHERNET
config SNAPCLIENT_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 SNAPCLIENT_ETHERNET_TYPE_SPI
prompt "Ethernet SPI"
default SNAPCLIENT_USE_W5500
help
Select which kind of Ethernet will be used in the example.
config SNAPCLIENT_USE_DM9051
bool "DM9051 Module"
select ETH_SPI_ETHERNET_DM9051
help
Select external SPI-Ethernet module (DM9051).
config SNAPCLIENT_USE_KSZ8851SNL
bool "KSZ8851SNL Module"
select ETH_SPI_ETHERNET_KSZ8851SNL
help
Select external SPI-Ethernet module (KSZ8851SNL).
config SNAPCLIENT_USE_W5500
bool "W5500 Module"
select ETH_SPI_ETHERNET_W5500
help
Select external SPI-Ethernet module (W5500).
endchoice
config SNAPCLIENT_ETH_SPI_HOST
int "SPI Host Number"
range 0 2
default 1
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Set the SPI host used to communicate with the SPI Ethernet Controller.
config SNAPCLIENT_ETH_SPI_SCLK_GPIO
int "SPI SCLK GPIO number"
range 0 33
default 20
depends on SNAPCLIENT_ENABLE_ETHERNET
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 || IDF_TARGET_ESP32C2
default 4 if IDF_TARGET_ESP32H2
help
Set the GPIO number used by SPI SCLK.
config SNAPCLIENT_ETH_SPI_MOSI_GPIO
int "SPI MOSI GPIO number"
range 0 33
default 19
depends on SNAPCLIENT_ENABLE_ETHERNET
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 || IDF_TARGET_ESP32C2
default 5 if IDF_TARGET_ESP32H2
help
Set the GPIO number used by SPI MOSI.
config SNAPCLIENT_ETH_SPI_MISO_GPIO
int "SPI MISO GPIO number"
range 0 33
default 18
depends on SNAPCLIENT_ENABLE_ETHERNET
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 || IDF_TARGET_ESP32C2
default 0 if IDF_TARGET_ESP32H2
help
Set the GPIO number used by SPI MISO.
config SNAPCLIENT_ETH_SPI_CS_GPIO
int "SPI CS GPIO number"
range 0 33
default 21
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Set the GPIO number used by SPI CS.
config SNAPCLIENT_ETH_SPI_CLOCK_MHZ
int "SPI clock speed (MHz)"
range 5 80
default 36
depends on SNAPCLIENT_ENABLE_ETHERNET
default 12 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2
default 36 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
Set the clock speed (MHz) of SPI interface.
config SNAPCLIENT_ETH_SPI_INT_GPIO
int "Interrupt GPIO number"
default 4
depends on SNAPCLIENT_ENABLE_ETHERNET
config SNAPCLIENT_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 || IDF_TARGET_ESP32C2
default 1 if IDF_TARGET_ESP32H2
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 SNAPCLIENT_ETH_SPI_CS1_GPIO
depends on SNAPCLIENT_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
default 3 if IDF_TARGET_ESP32C2
default 11 if IDF_TARGET_ESP32H2
help
Set the GPIO number used by SPI CS1, i.e. Chip Select associated with the second SPI Eth module.
config SNAPCLIENT_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
default 4 if IDF_TARGET_ESP32C2
default 9 if IDF_TARGET_ESP32H2
help
Set the GPIO number used by the first SPI Ethernet module interrupt line.
config SNAPCLIENT_ETH_SPI_INT1_GPIO
depends on SNAPCLIENT_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 || IDF_TARGET_ESP32C2
default 10 if IDF_TARGET_ESP32H2
help
Set the GPIO number used by the second SPI Ethernet module interrupt line.
config SNAPCLIENT_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 SNAPCLIENT_ETH_SPI_PHY_RST1_GPIO
depends on SNAPCLIENT_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 SNAPCLIENT_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 SNAPCLIENT_ETH_SPI_PHY_ADDR1
depends on SNAPCLIENT_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 # SNAPCLIENT_USE_SPI_ETHERNET
config SNAPCLIENT_ETH_PHY_RST_GPIO
int "PHY Reset GPIO number"
default 17
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Set the GPIO number used to reset PHY chip.
Set to -1 to disable PHY chip hardware reset.
config SNAPCLIENT_ETH_PHY_ADDR
int "PHY Address"
range 0 31
default 0
depends on SNAPCLIENT_ENABLE_ETHERNET
help
Set PHY address according your board schematic.
endmenu

View File

@@ -1,27 +1,30 @@
/* Ethernet Basic Example
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "eth_interface.h"
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "driver/gpio.h"
#include "esp_check.h"
#include "esp_eth.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_mac.h"
#include "esp_netif.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#if CONFIG_ETH_USE_SPI_ETHERNET
#if CONFIG_SNAPCLIENT_USE_SPI_ETHERNET
#include "driver/spi_master.h"
#endif // CONFIG_ETH_USE_SPI_ETHERNET
#endif
static const char *TAG = "snapclient_eth_init";
static const char *TAG = "ETH";
/* The event group allows multiple bits for each event, but we only care about
* two events:
@@ -32,11 +35,324 @@ static const char *TAG = "ETH";
static EventGroupHandle_t s_eth_event_group;
#if CONFIG_SNAPCLIENT_SPI_ETHERNETS_NUM
#define SPI_ETHERNETS_NUM CONFIG_SNAPCLIENT_SPI_ETHERNETS_NUM
#else
#define SPI_ETHERNETS_NUM 0
#endif
#if CONFIG_SNAPCLIENT_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_SNAPCLIENT_ETH_SPI_CS##num##_GPIO; \
eth_module_config[num].int_gpio = \
CONFIG_SNAPCLIENT_ETH_SPI_INT##num##_GPIO; \
eth_module_config[num].phy_reset_gpio = \
CONFIG_SNAPCLIENT_ETH_SPI_PHY_RST##num##_GPIO; \
eth_module_config[num].phy_addr = CONFIG_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_ETH_PHY_ADDR;
phy_config.reset_gpio_num = CONFIG_SNAPCLIENT_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_SNAPCLIENT_ETH_MDC_GPIO;
esp32_emac_config.smi_mdio_gpio_num = CONFIG_SNAPCLIENT_ETH_MDIO_GPIO;
// Set clock mode and GPIO
#if CONFIG_ETH_RMII_CLK_INPUT
esp32_emac_config.clock_config.rmii.clock_mode = EMAC_CLK_EXT_IN;
#elif CONFIG_ETH_RMII_CLK_OUTPUT
esp32_emac_config.clock_config.rmii.clock_mode = EMAC_CLK_EXT_OUT;
#else
esp32_emac_config.clock_config.rmii.clock_mode = EMAC_CLK_DEFAULT;
#endif
esp32_emac_config.clock_config.rmii.clock_gpio = CONFIG_ETH_RMII_CLK_IN_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_SNAPCLIENT_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_SNAPCLIENT_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_SNAPCLIENT_ETH_PHY_LAN87XX
esp_eth_phy_t *phy = esp_eth_phy_new_lan87xx(&phy_config);
#elif CONFIG_SNAPCLIENT_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_SNAPCLIENT_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_SNAPCLIENT_USE_INTERNAL_ETHERNET
#if CONFIG_SNAPCLIENT_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_SNAPCLIENT_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_SNAPCLIENT_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_SNAPCLIENT_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_GOTO_ON_ERROR(spi_bus_initialize(CONFIG_SNAPCLIENT_ETH_SPI_HOST, &buscfg,
SPI_DMA_CH_AUTO),
err, TAG, "SPI host #%d init failed",
CONFIG_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_USE_KSZ8851SNL
eth_ksz8851snl_config_t ksz8851snl_config = ETH_KSZ8851SNL_DEFAULT_CONFIG(
CONFIG_SNAPCLIENT_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_SNAPCLIENT_USE_DM9051
eth_dm9051_config_t dm9051_config =
ETH_DM9051_DEFAULT_CONFIG(CONFIG_SNAPCLIENT_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_SNAPCLIENT_USE_W5500
eth_w5500_config_t w5500_config =
ETH_W5500_DEFAULT_CONFIG(CONFIG_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_USE_SPI_ETHERNET
/** Original init function in the example */
esp_err_t original_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_SNAPCLIENT_USE_INTERNAL_ETHERNET || \
CONFIG_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_USE_INTERNAL_ETHERNET
#if CONFIG_SNAPCLIENT_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_SNAPCLIENT_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");
uint8_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_SNAPCLIENT_SPI_ETHERNETS_NUM > 1
INIT_SPI_ETH_MODULE_CONFIG(spi_eth_module_config, 1);
uint8_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_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_USE_INTERNAL_ETHERNET ||
// CONFIG_SNAPCLIENT_USE_SPI_ETHERNET
*eth_handles_out = eth_handles;
*eth_cnt_out = eth_cnt;
return ret;
#if CONFIG_SNAPCLIENT_USE_INTERNAL_ETHERNET || \
CONFIG_SNAPCLIENT_USE_SPI_ETHERNET
err:
free(eth_handles);
return ret;
#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) {
uint8_t mac_addr[6] = {0};
/* we can get the Ethernet driver handle from event data */
/* we can get the ethernet driver handle from event data */
esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
switch (event_id) {
@@ -46,7 +362,6 @@ static void eth_event_handler(void *arg, esp_event_base_t event_base,
ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4],
mac_addr[5]);
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
@@ -79,106 +394,64 @@ static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
xEventGroupSetBits(s_eth_event_group, ETH_CONNECTED_BIT);
}
/** Init function that exposes to the main application */
void eth_init(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(original_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());
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));
// 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);
// Attach Ethernet driver to TCP/IP stack
ESP_ERROR_CHECK(
esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i])));
}
}
// 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));
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_SNAPCLIENT_ETH_PHY_ADDR;
phy_config.reset_gpio_num = CONFIG_SNAPCLIENT_ETH_PHY_RST_GPIO;
// phy_config.reset_timeout_ms = 500;
// mac_config.sw_reset_timeout_ms = 500;
#if CONFIG_SNAPCLIENT_USE_INTERNAL_ETHERNET
mac_config.smi_mdc_gpio_num = CONFIG_SNAPCLIENT_ETH_MDC_GPIO;
mac_config.smi_mdio_gpio_num = CONFIG_SNAPCLIENT_ETH_MDIO_GPIO;
esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
#if CONFIG_SNAPCLIENT_ETH_PHY_IP101
esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
#elif CONFIG_SNAPCLIENT_ETH_PHY_RTL8201
esp_eth_phy_t *phy = esp_eth_phy_new_rtl8201(&phy_config);
#elif CONFIG_SNAPCLIENT_ETH_PHY_LAN8720
esp_eth_phy_t *phy = esp_eth_phy_new_lan8720(&phy_config);
#elif CONFIG_SNAPCLIENT_ETH_PHY_DP83848
esp_eth_phy_t *phy = esp_eth_phy_new_dp83848(&phy_config);
#elif CONFIG_SNAPCLIENT_ETH_PHY_KSZ8041
esp_eth_phy_t *phy = esp_eth_phy_new_ksz8041(&phy_config);
#endif
#elif CONFIG_ETH_USE_SPI_ETHERNET
gpio_install_isr_service(0);
spi_device_handle_t spi_handle = NULL;
spi_bus_config_t buscfg = {
.miso_io_num = CONFIG_SNAPCLIENT_ETH_SPI_MISO_GPIO,
.mosi_io_num = CONFIG_SNAPCLIENT_ETH_SPI_MOSI_GPIO,
.sclk_io_num = CONFIG_SNAPCLIENT_ETH_SPI_SCLK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
};
ESP_ERROR_CHECK(
spi_bus_initialize(CONFIG_SNAPCLIENT_ETH_SPI_HOST, &buscfg, 1));
#if CONFIG_SNAPCLIENT_USE_DM9051
spi_device_interface_config_t devcfg = {
.command_bits = 1,
.address_bits = 7,
.mode = 0,
.clock_speed_hz = CONFIG_SNAPCLIENT_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_SNAPCLIENT_ETH_SPI_CS_GPIO,
.queue_size = 20};
ESP_ERROR_CHECK(
spi_bus_add_device(CONFIG_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_ETH_SPI_CLOCK_MHZ * 1000 * 1000,
.spics_io_num = CONFIG_SNAPCLIENT_ETH_SPI_CS_GPIO,
.queue_size = 20};
ESP_ERROR_CHECK(
spi_bus_add_device(CONFIG_SNAPCLIENT_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_SNAPCLIENT_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_SNAPCLIENT_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
/* attach Ethernet driver to TCP/IP stack */
ESP_ERROR_CHECK(
esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
/* start Ethernet driver state machine */
ESP_ERROR_CHECK(esp_eth_start(eth_handle));
// Start Ethernet driver state machine
for (int i = 0; i < eth_port_cnt; i++) {
ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
}
/* Waiting until either the connection is established (ETH_CONNECTED_BIT) or
* connection failed for the maximum number of re-tries (ETH_FAIL_BIT). The

View File

@@ -1,6 +1,13 @@
#ifndef _ETH_INTERFACE_H_
#define _ETH_INTERFACE_H_
#pragma once
#include "esp_eth_driver.h"
#ifdef __cplusplus
extern "C" {
#endif
void eth_init(void);
#endif /* _ETH_INTERFACE_H_ */
#ifdef __cplusplus
}
#endif