mirror of
https://github.com/esphome/esphome.git
synced 2026-09-02 19:16:06 +00:00
enhance ethernet component for spi interface choice on esp-idf
This commit is contained in:
@@ -68,6 +68,8 @@ CONF_CLK_MODE = "clk_mode"
|
||||
CONF_POWER_PIN = "power_pin"
|
||||
CONF_PHY_REGISTERS = "phy_registers"
|
||||
|
||||
CONF_INTERFACE = "interface"
|
||||
|
||||
CONF_CLOCK_SPEED = "clock_speed"
|
||||
|
||||
EthernetType = ethernet_ns.enum("EthernetType")
|
||||
@@ -110,6 +112,12 @@ CLK_MODES_DEPRECATED = {
|
||||
"GPIO17_OUT": ("CLK_OUT", 17),
|
||||
}
|
||||
|
||||
SPI_INTERFACE_MAP = {
|
||||
"spi1": "SPI1_HOST",
|
||||
"spi2": "SPI2_HOST",
|
||||
"spi3": "SPI3_HOST",
|
||||
}
|
||||
|
||||
MANUAL_IP_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_STATIC_IP): cv.ipv4address,
|
||||
@@ -243,6 +251,10 @@ SPI_SCHEMA = BASE_SCHEMA.extend(
|
||||
cv.Optional(CONF_CLOCK_SPEED, default="26.67MHz"): cv.All(
|
||||
cv.frequency, cv.int_range(int(8e6), int(80e6))
|
||||
),
|
||||
cv.Optional(CONF_INTERFACE): cv.All(
|
||||
cv.only_with_framework("esp-idf"),
|
||||
cv.one_of(*SPI_INTERFACE_MAP.keys()),
|
||||
),
|
||||
# Set default value (SPI_ETHERNET_DEFAULT_POLLING_INTERVAL) at _validate()
|
||||
cv.Optional(CONF_POLLING_INTERVAL): cv.All(
|
||||
cv.positive_time_period_milliseconds,
|
||||
@@ -277,18 +289,21 @@ def _final_validate(config):
|
||||
if config[CONF_TYPE] not in SPI_ETHERNET_TYPES:
|
||||
return
|
||||
if spi_configs := fv.full_config.get().get(CONF_SPI):
|
||||
variant = get_esp32_variant()
|
||||
if variant in (VARIANT_ESP32C3, VARIANT_ESP32S2, VARIANT_ESP32S3):
|
||||
spi_host = "SPI2_HOST"
|
||||
if CORE.using_esp_idf and CONF_INTERFACE in config:
|
||||
spi_host = SPI_INTERFACE_MAP[config[CONF_INTERFACE]]
|
||||
else:
|
||||
spi_host = "SPI3_HOST"
|
||||
variant = get_esp32_variant()
|
||||
if variant in (VARIANT_ESP32C3, VARIANT_ESP32S2, VARIANT_ESP32S3):
|
||||
spi_host = "SPI2_HOST"
|
||||
else:
|
||||
spi_host = "SPI3_HOST"
|
||||
for spi_conf in spi_configs:
|
||||
if (index := spi_conf.get(CONF_INTERFACE_INDEX)) is not None:
|
||||
interface = get_spi_interface(index)
|
||||
if interface == spi_host:
|
||||
raise cv.Invalid(
|
||||
f"`spi` component is using interface '{interface}'. "
|
||||
f"To use {config[CONF_TYPE]}, you must change the `interface` on the `spi` component.",
|
||||
f"this and an `spi` component are both using interface '{interface}'. "
|
||||
f"To use {config[CONF_TYPE]}, you must change the `interface` on one of these."
|
||||
)
|
||||
|
||||
|
||||
@@ -336,8 +351,17 @@ async def to_code(config):
|
||||
cg.add(var.set_clock_speed(config[CONF_CLOCK_SPEED]))
|
||||
|
||||
cg.add_define("USE_ETHERNET_SPI")
|
||||
add_idf_sdkconfig_option("CONFIG_ETH_USE_SPI_ETHERNET", True)
|
||||
add_idf_sdkconfig_option(f"CONFIG_ETH_SPI_ETHERNET_{config[CONF_TYPE]}", True)
|
||||
if CORE.using_esp_idf:
|
||||
if CONF_INTERFACE in config:
|
||||
cg.add(
|
||||
var.set_interface(
|
||||
cg.RawExpression(SPI_INTERFACE_MAP[config[CONF_INTERFACE]])
|
||||
)
|
||||
)
|
||||
add_idf_sdkconfig_option("CONFIG_ETH_USE_SPI_ETHERNET", True)
|
||||
add_idf_sdkconfig_option(
|
||||
f"CONFIG_ETH_SPI_ETHERNET_{config[CONF_TYPE]}", True
|
||||
)
|
||||
elif config[CONF_TYPE] == "OPENETH":
|
||||
cg.add_define("USE_ETHERNET_OPENETH")
|
||||
add_idf_sdkconfig_option("CONFIG_ETH_USE_OPENETH", True)
|
||||
|
||||
@@ -87,11 +87,20 @@ void EthernetComponent::setup() {
|
||||
.intr_flags = 0,
|
||||
};
|
||||
|
||||
spi_host_device_t host;
|
||||
#ifdef USE_ESP_IDF
|
||||
if (this->interface_ != SPI_HOST_MAX) {
|
||||
host = this->interface_;
|
||||
} else {
|
||||
#endif
|
||||
#if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || \
|
||||
defined(USE_ESP32_VARIANT_ESP32C6)
|
||||
auto host = SPI2_HOST;
|
||||
host = SPI2_HOST;
|
||||
#else
|
||||
auto host = SPI3_HOST;
|
||||
host = SPI3_HOST;
|
||||
#endif
|
||||
#if USE_ESP_IDF
|
||||
}
|
||||
#endif
|
||||
|
||||
err = spi_bus_initialize(host, &buscfg, SPI_DMA_CH_AUTO);
|
||||
@@ -390,6 +399,15 @@ void EthernetComponent::dump_config() {
|
||||
" MOSI Pin: %u\n"
|
||||
" CS Pin: %u",
|
||||
this->clk_pin_, this->miso_pin_, this->mosi_pin_, this->cs_pin_);
|
||||
#ifdef USE_ESP_IDF
|
||||
{
|
||||
constexpr std::array<char const *const, SPI_HOST_MAX> values{"spi1", "spi2", "spi3"};
|
||||
char const *const value{this->interface_ < values.size() ? values[this->interface_] : nullptr};
|
||||
if (value) {
|
||||
ESP_LOGCONFIG(TAG, " Interface: %s", value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||
if (this->polling_interval_ != 0) {
|
||||
ESP_LOGCONFIG(TAG, " Polling Interval: %lu ms", this->polling_interval_);
|
||||
@@ -674,6 +692,9 @@ void EthernetComponent::set_cs_pin(uint8_t cs_pin) { this->cs_pin_ = cs_pin; }
|
||||
void EthernetComponent::set_interrupt_pin(uint8_t interrupt_pin) { this->interrupt_pin_ = interrupt_pin; }
|
||||
void EthernetComponent::set_reset_pin(uint8_t reset_pin) { this->reset_pin_ = reset_pin; }
|
||||
void EthernetComponent::set_clock_speed(int clock_speed) { this->clock_speed_ = clock_speed; }
|
||||
#ifdef USE_ESP_IDF
|
||||
void EthernetComponent::set_interface(SPIInterface interface) { this->interface_ = interface; }
|
||||
#endif
|
||||
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||
void EthernetComponent::set_polling_interval(uint32_t polling_interval) { this->polling_interval_ = polling_interval; }
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,14 @@
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/components/network/ip_address.h"
|
||||
|
||||
#ifdef USE_ESP_IDF
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
using SPIInterface = spi_host_device_t;
|
||||
|
||||
#endif // USE_ESP_IDF
|
||||
|
||||
#ifdef USE_ESP32
|
||||
|
||||
#include "esp_eth.h"
|
||||
@@ -70,6 +78,9 @@ class EthernetComponent : public Component {
|
||||
void set_interrupt_pin(uint8_t interrupt_pin);
|
||||
void set_reset_pin(uint8_t reset_pin);
|
||||
void set_clock_speed(int clock_speed);
|
||||
#ifdef USE_ESP_IDF
|
||||
void set_interface(SPIInterface interface);
|
||||
#endif
|
||||
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||
void set_polling_interval(uint32_t polling_interval);
|
||||
#endif
|
||||
@@ -124,6 +135,9 @@ class EthernetComponent : public Component {
|
||||
int reset_pin_{-1};
|
||||
int phy_addr_spi_{-1};
|
||||
int clock_speed_;
|
||||
#ifdef USE_ESP_IDF
|
||||
SPIInterface interface_{SPI_HOST_MAX}; // Default to invalid, will be set based on ESP32 variant
|
||||
#endif
|
||||
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||
uint32_t polling_interval_{0};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user