mirror of
https://github.com/esphome/esphome.git
synced 2026-05-10 14:09:14 +08:00
[ethernet] Add W6100 and W6300 support for RP2040 (#15543)
This commit is contained in:
@@ -123,6 +123,8 @@ ETHERNET_TYPES = {
|
||||
"DM9051": EthernetType.ETHERNET_TYPE_DM9051,
|
||||
"LAN8670": EthernetType.ETHERNET_TYPE_LAN8670,
|
||||
"ENC28J60": EthernetType.ETHERNET_TYPE_ENC28J60,
|
||||
"W6100": EthernetType.ETHERNET_TYPE_W6100,
|
||||
"W6300": EthernetType.ETHERNET_TYPE_W6300,
|
||||
}
|
||||
|
||||
# PHY types that need compile-time defines for conditional compilation
|
||||
@@ -140,6 +142,8 @@ _PHY_TYPE_TO_DEFINE = {
|
||||
"DM9051": "USE_ETHERNET_DM9051",
|
||||
"LAN8670": "USE_ETHERNET_LAN8670",
|
||||
"ENC28J60": "USE_ETHERNET_ENC28J60",
|
||||
"W6100": "USE_ETHERNET_W6100",
|
||||
"W6300": "USE_ETHERNET_W6300",
|
||||
}
|
||||
|
||||
|
||||
@@ -170,12 +174,14 @@ _ALWAYS_EXTERNAL_IDF_COMPONENTS = {"LAN8670", "ENC28J60"}
|
||||
|
||||
# ESP32-only SPI ethernet types (W5100 is RP2040-only, no ESP-IDF driver)
|
||||
SPI_ETHERNET_TYPES = {"W5500", "DM9051", "ENC28J60"}
|
||||
# RP2040-supported SPI ethernet types
|
||||
RP2040_SPI_ETHERNET_TYPES = {"W5100", "W5500", "ENC28J60"}
|
||||
# RP2040-supported ethernet types (SPI and PIO QSPI)
|
||||
RP2040_ETHERNET_TYPES = {"W5100", "W5500", "W6100", "W6300", "ENC28J60"}
|
||||
_RP2040_SPI_LIBRARIES = {
|
||||
"W5100": "lwIP_w5100",
|
||||
"W5500": "lwIP_w5500",
|
||||
"ENC28J60": "lwIP_enc28j60",
|
||||
"W6100": "lwIP_w6100",
|
||||
"W6300": "lwIP_w6300",
|
||||
}
|
||||
SPI_ETHERNET_DEFAULT_POLLING_INTERVAL = TimePeriodMilliseconds(milliseconds=10)
|
||||
|
||||
@@ -328,9 +334,9 @@ def _validate(config):
|
||||
f"{config[CONF_TYPE]} PHY requires RMII interface and is only supported "
|
||||
f"on ESP32 classic and ESP32-P4, not {variant}"
|
||||
)
|
||||
elif CORE.is_rp2040 and config[CONF_TYPE] not in RP2040_SPI_ETHERNET_TYPES:
|
||||
elif CORE.is_rp2040 and config[CONF_TYPE] not in RP2040_ETHERNET_TYPES:
|
||||
raise cv.Invalid(
|
||||
f"Only {', '.join(sorted(RP2040_SPI_ETHERNET_TYPES))} are supported on RP2040, "
|
||||
f"Only {', '.join(sorted(RP2040_ETHERNET_TYPES))} are supported on RP2040, "
|
||||
f"not {config[CONF_TYPE]}"
|
||||
)
|
||||
return config
|
||||
@@ -427,6 +433,8 @@ CONFIG_SCHEMA = cv.All(
|
||||
"OPENETH": cv.All(BASE_SCHEMA, cv.only_on([Platform.ESP32])),
|
||||
"DM9051": SPI_SCHEMA,
|
||||
"ENC28J60": SPI_SCHEMA,
|
||||
"W6100": cv.All(SPI_SCHEMA, cv.only_on([Platform.RP2040])),
|
||||
"W6300": cv.All(SPI_SCHEMA, cv.only_on([Platform.RP2040])),
|
||||
"LAN8670": RMII_SCHEMA,
|
||||
},
|
||||
upper=True,
|
||||
|
||||
@@ -30,6 +30,20 @@ extern "C" eth_esp32_emac_config_t eth_esp32_emac_default_config(void);
|
||||
#include <W5500lwIP.h>
|
||||
#elif defined(USE_ETHERNET_W5100)
|
||||
#include <W5100lwIP.h>
|
||||
#elif defined(USE_ETHERNET_W6100)
|
||||
#include <W6100lwIP.h>
|
||||
#elif defined(USE_ETHERNET_W6300)
|
||||
#include <W6300lwIP.h>
|
||||
// W6300 uses PIO QSPI, not Arduino SPI. The upstream Wiznet6300 class
|
||||
// incorrectly returns needsSPI()=true, causing LwipIntfDev::begin() to
|
||||
// call SPI.begin() which claims GPIOs that PIO QSPI needs.
|
||||
// This wrapper hides needsSPI() with a version returning false.
|
||||
class Wiznet6300NoSPI : public Wiznet6300 {
|
||||
public:
|
||||
using Wiznet6300::Wiznet6300;
|
||||
constexpr bool needsSPI() const { return false; }
|
||||
};
|
||||
using Wiznet6300lwIPFixed = LwipIntfDev<Wiznet6300NoSPI>;
|
||||
#elif defined(USE_ETHERNET_ENC28J60)
|
||||
#include <ENC28J60lwIP.h>
|
||||
#else
|
||||
@@ -70,6 +84,8 @@ enum EthernetType : uint8_t {
|
||||
ETHERNET_TYPE_DM9051,
|
||||
ETHERNET_TYPE_LAN8670,
|
||||
ETHERNET_TYPE_ENC28J60,
|
||||
ETHERNET_TYPE_W6100,
|
||||
ETHERNET_TYPE_W6300,
|
||||
};
|
||||
|
||||
struct ManualIP {
|
||||
@@ -232,6 +248,8 @@ class EthernetComponent final : public Component {
|
||||
static constexpr uint32_t LINK_CHECK_INTERVAL = 500; // ms between link/IP polls
|
||||
#if defined(USE_ETHERNET_W5100)
|
||||
static constexpr uint32_t RESET_DELAY_MS = 150; // W5100S PLL lock time
|
||||
#elif defined(USE_ETHERNET_W6300)
|
||||
static constexpr uint32_t RESET_DELAY_MS = 100; // W6300 needs 100ms after hardware reset
|
||||
#else
|
||||
static constexpr uint32_t RESET_DELAY_MS = 10;
|
||||
#endif
|
||||
@@ -239,6 +257,10 @@ class EthernetComponent final : public Component {
|
||||
Wiznet5500lwIP *eth_{nullptr};
|
||||
#elif defined(USE_ETHERNET_W5100)
|
||||
Wiznet5100lwIP *eth_{nullptr};
|
||||
#elif defined(USE_ETHERNET_W6100)
|
||||
Wiznet6100lwIP *eth_{nullptr};
|
||||
#elif defined(USE_ETHERNET_W6300)
|
||||
Wiznet6300lwIPFixed *eth_{nullptr};
|
||||
#elif defined(USE_ETHERNET_ENC28J60)
|
||||
ENC28J60lwIP *eth_{nullptr};
|
||||
#else
|
||||
|
||||
@@ -18,9 +18,14 @@ static const char *const TAG = "ethernet";
|
||||
|
||||
void EthernetComponent::setup() {
|
||||
// Configure SPI pins
|
||||
#if !defined(USE_ETHERNET_W6300)
|
||||
SPI.setRX(this->miso_pin_);
|
||||
SPI.setTX(this->mosi_pin_);
|
||||
SPI.setSCK(this->clk_pin_);
|
||||
#endif
|
||||
// W6300 uses PIO QSPI with hardcoded pins, not Arduino SPI.
|
||||
// SPI pin config is skipped; Wiznet6300lwIPFixed (needsSPI()=false)
|
||||
// prevents LwipIntfDev::begin() from calling SPI.begin().
|
||||
|
||||
// Toggle reset pin if configured
|
||||
if (this->reset_pin_ >= 0) {
|
||||
@@ -40,6 +45,10 @@ void EthernetComponent::setup() {
|
||||
this->eth_ = new Wiznet5500lwIP(this->cs_pin_, SPI, this->interrupt_pin_); // NOLINT
|
||||
#elif defined(USE_ETHERNET_W5100)
|
||||
this->eth_ = new Wiznet5100lwIP(this->cs_pin_, SPI, this->interrupt_pin_); // NOLINT
|
||||
#elif defined(USE_ETHERNET_W6100)
|
||||
this->eth_ = new Wiznet6100lwIP(this->cs_pin_, SPI, this->interrupt_pin_); // NOLINT
|
||||
#elif defined(USE_ETHERNET_W6300)
|
||||
this->eth_ = new Wiznet6300lwIPFixed(this->cs_pin_, SPI, this->interrupt_pin_); // NOLINT
|
||||
#elif defined(USE_ETHERNET_ENC28J60)
|
||||
this->eth_ = new ENC28J60lwIP(this->cs_pin_, SPI, this->interrupt_pin_); // NOLINT
|
||||
#endif
|
||||
@@ -183,9 +192,23 @@ void EthernetComponent::dump_config() {
|
||||
type_str = "W5500";
|
||||
#elif defined(USE_ETHERNET_W5100)
|
||||
type_str = "W5100";
|
||||
#elif defined(USE_ETHERNET_W6100)
|
||||
type_str = "W6100";
|
||||
#elif defined(USE_ETHERNET_W6300)
|
||||
type_str = "W6300";
|
||||
#elif defined(USE_ETHERNET_ENC28J60)
|
||||
type_str = "ENC28J60";
|
||||
#endif
|
||||
#if defined(USE_ETHERNET_W6300)
|
||||
// W6300 uses PIO QSPI with hardcoded pins — SPI pin fields are not used
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Ethernet:\n"
|
||||
" Type: %s (PIO QSPI)\n"
|
||||
" Connected: %s\n"
|
||||
" IRQ Pin: %d\n"
|
||||
" Reset Pin: %d",
|
||||
type_str, YESNO(this->is_connected()), this->interrupt_pin_, this->reset_pin_);
|
||||
#else
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Ethernet:\n"
|
||||
" Type: %s\n"
|
||||
@@ -198,6 +221,7 @@ void EthernetComponent::dump_config() {
|
||||
" Reset Pin: %d",
|
||||
type_str, YESNO(this->is_connected()), this->clk_pin_, this->miso_pin_, this->mosi_pin_, this->cs_pin_,
|
||||
this->interrupt_pin_, this->reset_pin_);
|
||||
#endif
|
||||
this->dump_connect_params_();
|
||||
}
|
||||
|
||||
|
||||
@@ -300,6 +300,8 @@
|
||||
#define USE_ETHERNET_OPENETH
|
||||
#define USE_ETHERNET_W5100
|
||||
#define USE_ETHERNET_W5500
|
||||
#define USE_ETHERNET_W6100
|
||||
#define USE_ETHERNET_W6300
|
||||
#define USE_ETHERNET_DM9051
|
||||
#define CONFIG_ETH_SPI_ETHERNET_W5500 1
|
||||
#define CONFIG_ETH_SPI_ETHERNET_DM9051 1
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
ethernet:
|
||||
type: W6100
|
||||
clk_pin: 18
|
||||
mosi_pin: 19
|
||||
miso_pin: 16
|
||||
cs_pin: 17
|
||||
interrupt_pin: 21
|
||||
reset_pin: 20
|
||||
manual_ip:
|
||||
static_ip: 192.168.178.56
|
||||
gateway: 192.168.178.1
|
||||
subnet: 255.255.255.0
|
||||
domain: .local
|
||||
mac_address: "02:AA:BB:CC:DD:01"
|
||||
on_connect:
|
||||
- logger.log: "Ethernet connected!"
|
||||
on_disconnect:
|
||||
- logger.log: "Ethernet disconnected!"
|
||||
@@ -0,0 +1,18 @@
|
||||
ethernet:
|
||||
type: W6300
|
||||
clk_pin: 18
|
||||
mosi_pin: 19
|
||||
miso_pin: 16
|
||||
cs_pin: 17
|
||||
interrupt_pin: 21
|
||||
reset_pin: 20
|
||||
manual_ip:
|
||||
static_ip: 192.168.178.56
|
||||
gateway: 192.168.178.1
|
||||
subnet: 255.255.255.0
|
||||
domain: .local
|
||||
mac_address: "02:AA:BB:CC:DD:01"
|
||||
on_connect:
|
||||
- logger.log: "Ethernet connected!"
|
||||
on_disconnect:
|
||||
- logger.log: "Ethernet disconnected!"
|
||||
@@ -0,0 +1 @@
|
||||
<<: !include common-w6100-rp2040.yaml
|
||||
@@ -0,0 +1 @@
|
||||
<<: !include common-w6300-rp2040.yaml
|
||||
Reference in New Issue
Block a user