mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 06:58:11 +01:00
Support W5500 SPI-Ethernet polling mode if framework is supported (#7503)
This commit is contained in:
parent
df750d0d11
commit
302ba2874e
4 changed files with 77 additions and 3 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import logging
|
||||||
from esphome import pins
|
from esphome import pins
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant
|
from esphome.components.esp32 import add_idf_sdkconfig_option, get_esp32_variant
|
||||||
|
@ -23,6 +24,7 @@ from esphome.const import (
|
||||||
CONF_MISO_PIN,
|
CONF_MISO_PIN,
|
||||||
CONF_MOSI_PIN,
|
CONF_MOSI_PIN,
|
||||||
CONF_PAGE_ID,
|
CONF_PAGE_ID,
|
||||||
|
CONF_POLLING_INTERVAL,
|
||||||
CONF_RESET_PIN,
|
CONF_RESET_PIN,
|
||||||
CONF_SPI,
|
CONF_SPI,
|
||||||
CONF_STATIC_IP,
|
CONF_STATIC_IP,
|
||||||
|
@ -30,13 +32,16 @@ from esphome.const import (
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
CONF_USE_ADDRESS,
|
CONF_USE_ADDRESS,
|
||||||
CONF_VALUE,
|
CONF_VALUE,
|
||||||
|
KEY_CORE,
|
||||||
|
KEY_FRAMEWORK_VERSION,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, coroutine_with_priority
|
from esphome.core import CORE, TimePeriodMilliseconds, coroutine_with_priority
|
||||||
import esphome.final_validate as fv
|
import esphome.final_validate as fv
|
||||||
|
|
||||||
CONFLICTS_WITH = ["wifi"]
|
CONFLICTS_WITH = ["wifi"]
|
||||||
DEPENDENCIES = ["esp32"]
|
DEPENDENCIES = ["esp32"]
|
||||||
AUTO_LOAD = ["network"]
|
AUTO_LOAD = ["network"]
|
||||||
|
LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ethernet_ns = cg.esphome_ns.namespace("ethernet")
|
ethernet_ns = cg.esphome_ns.namespace("ethernet")
|
||||||
PHYRegister = ethernet_ns.struct("PHYRegister")
|
PHYRegister = ethernet_ns.struct("PHYRegister")
|
||||||
|
@ -63,6 +68,7 @@ ETHERNET_TYPES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
SPI_ETHERNET_TYPES = ["W5500"]
|
SPI_ETHERNET_TYPES = ["W5500"]
|
||||||
|
SPI_ETHERNET_DEFAULT_POLLING_INTERVAL = TimePeriodMilliseconds(milliseconds=10)
|
||||||
|
|
||||||
emac_rmii_clock_mode_t = cg.global_ns.enum("emac_rmii_clock_mode_t")
|
emac_rmii_clock_mode_t = cg.global_ns.enum("emac_rmii_clock_mode_t")
|
||||||
emac_rmii_clock_gpio_t = cg.global_ns.enum("emac_rmii_clock_gpio_t")
|
emac_rmii_clock_gpio_t = cg.global_ns.enum("emac_rmii_clock_gpio_t")
|
||||||
|
@ -100,6 +106,24 @@ EthernetComponent = ethernet_ns.class_("EthernetComponent", cg.Component)
|
||||||
ManualIP = ethernet_ns.struct("ManualIP")
|
ManualIP = ethernet_ns.struct("ManualIP")
|
||||||
|
|
||||||
|
|
||||||
|
def _is_framework_spi_polling_mode_supported():
|
||||||
|
# SPI Ethernet without IRQ feature is added in
|
||||||
|
# esp-idf >= (5.3+ ,5.2.1+, 5.1.4) and arduino-esp32 >= 3.0.0
|
||||||
|
framework_version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
|
||||||
|
if CORE.using_esp_idf:
|
||||||
|
if framework_version >= cv.Version(5, 3, 0):
|
||||||
|
return True
|
||||||
|
if cv.Version(5, 3, 0) > framework_version >= cv.Version(5, 2, 1):
|
||||||
|
return True
|
||||||
|
if cv.Version(5, 2, 0) > framework_version >= cv.Version(5, 1, 4):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
if CORE.using_arduino:
|
||||||
|
return framework_version >= cv.Version(3, 0, 0)
|
||||||
|
# fail safe: Unknown framework
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _validate(config):
|
def _validate(config):
|
||||||
if CONF_USE_ADDRESS not in config:
|
if CONF_USE_ADDRESS not in config:
|
||||||
if CONF_MANUAL_IP in config:
|
if CONF_MANUAL_IP in config:
|
||||||
|
@ -107,6 +131,27 @@ def _validate(config):
|
||||||
else:
|
else:
|
||||||
use_address = CORE.name + config[CONF_DOMAIN]
|
use_address = CORE.name + config[CONF_DOMAIN]
|
||||||
config[CONF_USE_ADDRESS] = use_address
|
config[CONF_USE_ADDRESS] = use_address
|
||||||
|
if config[CONF_TYPE] in SPI_ETHERNET_TYPES:
|
||||||
|
if _is_framework_spi_polling_mode_supported():
|
||||||
|
if CONF_POLLING_INTERVAL in config and CONF_INTERRUPT_PIN in config:
|
||||||
|
raise cv.Invalid(
|
||||||
|
f"Cannot specify more than one of {CONF_INTERRUPT_PIN}, {CONF_POLLING_INTERVAL}"
|
||||||
|
)
|
||||||
|
if CONF_POLLING_INTERVAL not in config and CONF_INTERRUPT_PIN not in config:
|
||||||
|
config[CONF_POLLING_INTERVAL] = SPI_ETHERNET_DEFAULT_POLLING_INTERVAL
|
||||||
|
else:
|
||||||
|
if CONF_POLLING_INTERVAL in config:
|
||||||
|
raise cv.Invalid(
|
||||||
|
"In this version of the framework "
|
||||||
|
f"({CORE.target_framework} {CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]}), "
|
||||||
|
f"'{CONF_POLLING_INTERVAL}' is not supported."
|
||||||
|
)
|
||||||
|
if CONF_INTERRUPT_PIN not in config:
|
||||||
|
raise cv.Invalid(
|
||||||
|
"In this version of the framework "
|
||||||
|
f"({CORE.target_framework} {CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]}), "
|
||||||
|
f"'{CONF_INTERRUPT_PIN}' is a required option for [ethernet]."
|
||||||
|
)
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,6 +202,11 @@ SPI_SCHEMA = BASE_SCHEMA.extend(
|
||||||
cv.Optional(CONF_CLOCK_SPEED, default="26.67MHz"): cv.All(
|
cv.Optional(CONF_CLOCK_SPEED, default="26.67MHz"): cv.All(
|
||||||
cv.frequency, cv.int_range(int(8e6), int(80e6))
|
cv.frequency, cv.int_range(int(8e6), int(80e6))
|
||||||
),
|
),
|
||||||
|
# Set default value (SPI_ETHERNET_DEFAULT_POLLING_INTERVAL) at _validate()
|
||||||
|
cv.Optional(CONF_POLLING_INTERVAL): cv.All(
|
||||||
|
cv.positive_time_period_milliseconds,
|
||||||
|
cv.Range(min=TimePeriodMilliseconds(milliseconds=1)),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -234,6 +284,10 @@ async def to_code(config):
|
||||||
cg.add(var.set_cs_pin(config[CONF_CS_PIN]))
|
cg.add(var.set_cs_pin(config[CONF_CS_PIN]))
|
||||||
if CONF_INTERRUPT_PIN in config:
|
if CONF_INTERRUPT_PIN in config:
|
||||||
cg.add(var.set_interrupt_pin(config[CONF_INTERRUPT_PIN]))
|
cg.add(var.set_interrupt_pin(config[CONF_INTERRUPT_PIN]))
|
||||||
|
else:
|
||||||
|
cg.add(var.set_polling_interval(config[CONF_POLLING_INTERVAL]))
|
||||||
|
if _is_framework_spi_polling_mode_supported():
|
||||||
|
cg.add_define("USE_ETHERNET_SPI_POLLING_SUPPORT")
|
||||||
if CONF_RESET_PIN in config:
|
if CONF_RESET_PIN in config:
|
||||||
cg.add(var.set_reset_pin(config[CONF_RESET_PIN]))
|
cg.add(var.set_reset_pin(config[CONF_RESET_PIN]))
|
||||||
cg.add(var.set_clock_speed(config[CONF_CLOCK_SPEED]))
|
cg.add(var.set_clock_speed(config[CONF_CLOCK_SPEED]))
|
||||||
|
|
|
@ -116,6 +116,9 @@ void EthernetComponent::setup() {
|
||||||
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
|
eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
|
||||||
#endif
|
#endif
|
||||||
w5500_config.int_gpio_num = this->interrupt_pin_;
|
w5500_config.int_gpio_num = this->interrupt_pin_;
|
||||||
|
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||||
|
w5500_config.poll_period_ms = this->polling_interval_;
|
||||||
|
#endif
|
||||||
phy_config.phy_addr = this->phy_addr_spi_;
|
phy_config.phy_addr = this->phy_addr_spi_;
|
||||||
phy_config.reset_gpio_num = this->reset_pin_;
|
phy_config.reset_gpio_num = this->reset_pin_;
|
||||||
|
|
||||||
|
@ -327,7 +330,14 @@ void EthernetComponent::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, " MISO Pin: %u", this->miso_pin_);
|
ESP_LOGCONFIG(TAG, " MISO Pin: %u", this->miso_pin_);
|
||||||
ESP_LOGCONFIG(TAG, " MOSI Pin: %u", this->mosi_pin_);
|
ESP_LOGCONFIG(TAG, " MOSI Pin: %u", this->mosi_pin_);
|
||||||
ESP_LOGCONFIG(TAG, " CS Pin: %u", this->cs_pin_);
|
ESP_LOGCONFIG(TAG, " CS Pin: %u", this->cs_pin_);
|
||||||
ESP_LOGCONFIG(TAG, " IRQ Pin: %u", this->interrupt_pin_);
|
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||||
|
if (this->polling_interval_ != 0) {
|
||||||
|
ESP_LOGCONFIG(TAG, " Polling Interval: %lu ms", this->polling_interval_);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
ESP_LOGCONFIG(TAG, " IRQ Pin: %d", this->interrupt_pin_);
|
||||||
|
}
|
||||||
ESP_LOGCONFIG(TAG, " Reset Pin: %d", this->reset_pin_);
|
ESP_LOGCONFIG(TAG, " Reset Pin: %d", this->reset_pin_);
|
||||||
ESP_LOGCONFIG(TAG, " Clock Speed: %d MHz", this->clock_speed_ / 1000000);
|
ESP_LOGCONFIG(TAG, " Clock Speed: %d MHz", this->clock_speed_ / 1000000);
|
||||||
#else
|
#else
|
||||||
|
@ -536,6 +546,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_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_reset_pin(uint8_t reset_pin) { this->reset_pin_ = reset_pin; }
|
||||||
void EthernetComponent::set_clock_speed(int clock_speed) { this->clock_speed_ = clock_speed; }
|
void EthernetComponent::set_clock_speed(int clock_speed) { this->clock_speed_ = clock_speed; }
|
||||||
|
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||||
|
void EthernetComponent::set_polling_interval(uint32_t polling_interval) { this->polling_interval_ = polling_interval; }
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
void EthernetComponent::set_phy_addr(uint8_t phy_addr) { this->phy_addr_ = phy_addr; }
|
void EthernetComponent::set_phy_addr(uint8_t phy_addr) { this->phy_addr_ = phy_addr; }
|
||||||
void EthernetComponent::set_power_pin(int power_pin) { this->power_pin_ = power_pin; }
|
void EthernetComponent::set_power_pin(int power_pin) { this->power_pin_ = power_pin; }
|
||||||
|
|
|
@ -67,6 +67,9 @@ class EthernetComponent : public Component {
|
||||||
void set_interrupt_pin(uint8_t interrupt_pin);
|
void set_interrupt_pin(uint8_t interrupt_pin);
|
||||||
void set_reset_pin(uint8_t reset_pin);
|
void set_reset_pin(uint8_t reset_pin);
|
||||||
void set_clock_speed(int clock_speed);
|
void set_clock_speed(int clock_speed);
|
||||||
|
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||||
|
void set_polling_interval(uint32_t polling_interval);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
void set_phy_addr(uint8_t phy_addr);
|
void set_phy_addr(uint8_t phy_addr);
|
||||||
void set_power_pin(int power_pin);
|
void set_power_pin(int power_pin);
|
||||||
|
@ -108,10 +111,13 @@ class EthernetComponent : public Component {
|
||||||
uint8_t miso_pin_;
|
uint8_t miso_pin_;
|
||||||
uint8_t mosi_pin_;
|
uint8_t mosi_pin_;
|
||||||
uint8_t cs_pin_;
|
uint8_t cs_pin_;
|
||||||
uint8_t interrupt_pin_;
|
int interrupt_pin_{-1};
|
||||||
int reset_pin_{-1};
|
int reset_pin_{-1};
|
||||||
int phy_addr_spi_{-1};
|
int phy_addr_spi_{-1};
|
||||||
int clock_speed_;
|
int clock_speed_;
|
||||||
|
#ifdef USE_ETHERNET_SPI_POLLING_SUPPORT
|
||||||
|
uint32_t polling_interval_{0};
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
uint8_t phy_addr_{0};
|
uint8_t phy_addr_{0};
|
||||||
int power_pin_{-1};
|
int power_pin_{-1};
|
||||||
|
|
|
@ -666,6 +666,7 @@ CONF_PMC_1_0 = "pmc_1_0"
|
||||||
CONF_PMC_10_0 = "pmc_10_0"
|
CONF_PMC_10_0 = "pmc_10_0"
|
||||||
CONF_PMC_2_5 = "pmc_2_5"
|
CONF_PMC_2_5 = "pmc_2_5"
|
||||||
CONF_PMC_4_0 = "pmc_4_0"
|
CONF_PMC_4_0 = "pmc_4_0"
|
||||||
|
CONF_POLLING_INTERVAL = "polling_interval"
|
||||||
CONF_PORT = "port"
|
CONF_PORT = "port"
|
||||||
CONF_POSITION = "position"
|
CONF_POSITION = "position"
|
||||||
CONF_POSITION_ACTION = "position_action"
|
CONF_POSITION_ACTION = "position_action"
|
||||||
|
|
Loading…
Reference in a new issue