From c1e514d8bf2cf376fcf866c0fe49963acba755f9 Mon Sep 17 00:00:00 2001 From: Michael Pape Date: Fri, 4 Sep 2026 13:20:49 +0200 Subject: [PATCH] add OLIMEXPOEW board profile, guard against PSRAM/eth clock GPIO conflict Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01GnozuURE2WF6AWJzxSu6fP --- interface/src/app/main/types.ts | 1 + src/core/console.cpp | 2 +- src/core/network.cpp | 9 ++++++++- src/core/system.cpp | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index 70d91b29d..93ce12f4f 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -307,6 +307,7 @@ export const BOARD_PROFILES = { LOLIN: 'Lolin D32', OLIMEX: 'Olimex ESP32-EVB', OLIMEXPOE: 'Olimex ESP32-POE', + OLIMEXPOEW: 'Olimex ESP32-POE-ISO WROVER (PSRAM)', C3MINI: 'Wemos C3 Mini', S2MINI: 'Wemos S2 Mini', S3MINI: 'Liligo S3' diff --git a/src/core/console.cpp b/src/core/console.cpp index 7a5e3de4e..d7ea0f118 100644 --- a/src/core/console.cpp +++ b/src/core/console.cpp @@ -305,7 +305,7 @@ static void setup_commands(std::shared_ptr const & commands) { std::string board_profile = Helpers::toUpper(arguments.front()); if (!EMSESP::system_.load_board_profile(data, board_profile)) { shell.println( - "Invalid board profile (S32, E32, E32V2, E32V2_2, MH-ET, NODEMCU, LOLIN, OLIMEX, OLIMEXPOE, C3MINI, S2MINI, S3MINI, S32S3, CUSTOM)"); + "Invalid board profile (S32, E32, E32V2, E32V2_2, MH-ET, NODEMCU, LOLIN, OLIMEX, OLIMEXPOE, OLIMEXPOEW, C3MINI, S2MINI, S3MINI, S32S3, CUSTOM)"); return; } diff --git a/src/core/network.cpp b/src/core/network.cpp index f99800eaa..0c8f6494b 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -229,7 +229,9 @@ void Network::reconnect() { // 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 (phy_type_ != PHY_type::PHY_TYPE_NONE) { + 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) { return NetPhase::ETHERNET; } if (!ssid_.isEmpty() || ap_provisionMode_ == AP_MODE_NEVER) { @@ -600,6 +602,11 @@ 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. diff --git a/src/core/system.cpp b/src/core/system.cpp index 252c1af83..050c62f34 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -2822,6 +2822,9 @@ bool System::load_board_profile(std::vector & data, const std::string & // https://github.com/OLIMEX/ESP32-POE/blob/master/HARDWARE/ESP32-PoE-hardware-revision-L1/ESP32-PoE_Rev_L1.pdf // uart0 = 1, 3; SD-card = 2, 14, 15; button = 34; valid_system_gpios_ = {4, 34, 36, 12, 13, 21, 22, 25, 26, 27, 32, 33, 39}; + } else if (board_profile == "OLIMEXPOEW") { + data = {0, 0, 36, 4, 34, PHY_type::PHY_TYPE_LAN8720, 12, 0, 1, 0}; // Olimex ESP32-POE-ISO WROVER (PSRAM) + valid_system_gpios_ = {4, 34, 36, 12, 13, 21, 22, 25, 26, 27, 32, 33, 39}; } else if (board_profile == "C3MINI") { #if defined(BOARD_C3_MINI_V1) data = {7, 1, 4, 5, 9, PHY_type::PHY_TYPE_NONE, 0, 0, 0, 0}; // Lolin C3 Mini V1