check Eth, and show warnings

This commit is contained in:
proddy
2026-09-14 12:43:34 +02:00
parent 13a29ecc00
commit ec73a134b5
3 changed files with 55 additions and 15 deletions
+44 -9
View File
@@ -88,6 +88,11 @@ void Network::begin() {
pinMode(eth_power_, OUTPUT);
digitalWrite(eth_power_, LOW);
}
// report it here rather than in startEthernet(), which is never reached because initialPhase() has already skipped Ethernet
if (phy_type_ != PHY_type::PHY_TYPE_NONE && ethClockConflictsPsram()) {
LOG_ERROR("Ethernet clock mode %d (GPIO16/17) conflicts with PSRAM - disabling Ethernet", eth_clock_mode_);
}
#endif
// avoid duplicate registration, so register the lambdas only once across the lifetime of this Network instance
@@ -225,15 +230,22 @@ void Network::reconnect() {
begin();
}
// the RMII clock output on GPIO16/17 shares its pins with PSRAM, so Ethernet can't be used at all on
// a board that has both. Ethernet is skipped for the whole boot when this is the case
bool Network::ethClockConflictsPsram() const {
#if CONFIG_IDF_TARGET_ESP32 && !defined(EMSESP_STANDALONE)
return ESP.getPsramSize() && ((eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO16_OUT || (eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO17_OUT);
#else
return false;
#endif
}
// pick the first phase that has the hardware/config to even be attempted on this device.
// boards without an Ethernet PHY skip straight to WIFI; without a configured SSID, straight to AP
// (unless AP provision mode is Never — then stay on WIFI and keep waiting)
NetPhase Network::initialPhase() const {
#if CONFIG_IDF_TARGET_ESP32
bool eth_clock_conflicts_psram =
ESP.getPsramSize() && ((eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO16_OUT || (eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO17_OUT);
if (phy_type_ != PHY_type::PHY_TYPE_NONE && !eth_clock_conflicts_psram) {
if (phy_type_ != PHY_type::PHY_TYPE_NONE && !ethClockConflictsPsram()) {
return NetPhase::ETHERNET;
}
#endif
@@ -605,11 +617,6 @@ void Network::startEthernet() {
return;
}
if (ESP.getPsramSize() && ((eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO16_OUT || (eth_clock_mode_t)eth_clock_mode_ == ETH_CLOCK_GPIO17_OUT)) {
LOG_ERROR("Ethernet clock mode %d (GPIO16/17) conflicts with PSRAM - disabling Ethernet", eth_clock_mode_);
return;
}
/*
// The Tasmota SDK is built with CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=2, so the Ethernet MAC is derived as
// a locally-administered address from base+1 instead of the universal base+3 that Arduino Core 2 used.
@@ -656,9 +663,11 @@ void Network::startEthernet() {
ETH.setFullDuplex(false);
}
// start the Eth module
if (ETH.begin(type, eth_phy_addr_, 23, 18, eth_power_, (eth_clock_mode_t)eth_clock_mode_)) {
// LOG_DEBUG("Ethernet module found - initialising");
ethernet_started_ = true;
ethernet_init_failed_ = false;
ethernet_connect_pending_ = true;
// check whether DHCP already announced us under lwIP's default hostname, before we correct it
@@ -687,12 +696,38 @@ void Network::startEthernet() {
ETH.config(localIP_, gatewayIP_, subnetMask_, dnsIP1_, dnsIP2_);
}
} else {
ethernet_init_failed_ = true;
LOG_ERROR("Failed to start Ethernet");
}
#endif
#endif
}
// Ethernet state as a printable string, for the console and the API
// returns nullptr when this board has no Ethernet PHY configured, so callers can omit Ethernet completely
const char * Network::ethernet_status() const {
#if CONFIG_IDF_TARGET_ESP32 && !defined(EMSESP_STANDALONE)
if (phy_type_ == PHY_type::PHY_TYPE_NONE) {
return nullptr;
}
if (ethClockConflictsPsram()) {
return "disabled - clock mode GPIO16/17 conflicts with PSRAM";
}
if (ethernet_connected()) {
return "connected";
}
if (ethernet_init_failed_) {
return "failed to initialize - no PHY found, check the board profile";
}
if (!ethernet_started_) {
return "not started";
}
return ethernet_connect_pending_ ? "connecting" : "no connection";
#else
return nullptr;
#endif
}
// check if the network is connected and set network_ip_ / network_iface_ / has_ipv6_
// Iterates over every esp-netif that exists, prioritizing Ethernet > WiFi > AP
void Network::findNetworks() {
+6 -3
View File
@@ -132,9 +132,10 @@ class Network {
return reconnect_count_;
}
std::string getLocalIP() const;
std::string getMacAddress() const;
uint8_t getStationNum() const;
std::string getLocalIP() const;
std::string getMacAddress() const;
uint8_t getStationNum() const;
const char * ethernet_status() const;
void reconnect();
@@ -192,6 +193,7 @@ class Network {
const char * disconnectReason(uint8_t code);
void stopAP();
NetPhase initialPhase() const;
bool ethClockConflictsPsram() const;
#if defined(__clang__)
#pragma clang diagnostic push
@@ -216,6 +218,7 @@ class Network {
bool wifi_events_registered_ = false; // ensure WiFi.onEvent() handlers are registered only once across begin()/reconnect() cycles
bool eth_hostname_handler_registered_ = false; // for the ETHERNET_EVENT_START hostname handler
bool ethernet_started_ = false; // ETH.begin() succeeded; the driver runs for the lifetime of the boot
bool ethernet_init_failed_ = false; // ETH.begin() failed, so the driver was never installed
bool wifi_ever_connected_ = false; // set true once we've successfully obtained an IP
bool ethernet_ever_connected_ = false; // set true once we've successfully obtained an IP
bool wifi_radio_off_ = false; // STA powered down because Ethernet is carrying the traffic
+5 -3
View File
@@ -1284,10 +1284,12 @@ void System::show_system(uuid::console::Shell & shell) {
break;
}
// show Ethernet if connected
// show the Ethernet state, and the details when it's actually up
const char * ethernet_status = EMSESP::network_.ethernet_status();
if (ethernet_status != nullptr) {
shell.printfln(" Ethernet Status: %s", ethernet_status);
}
if (EMSESP::network_.ethernet_connected()) {
shell.println();
shell.printfln(" Ethernet Status: connected");
shell.printfln(" Ethernet MAC address: %s", ETH.macAddress().c_str());
shell.printfln(" Hostname: %s", ETH.getHostname());
shell.printfln(" IPv4 address: %s/%s", uuid::printable_to_string(ETH.localIP()).c_str(), uuid::printable_to_string(ETH.subnetMask()).c_str());