Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e3752b5
[Serial Console] Fix outputting data to USBCDC port for ESP32S2
TD-er Jan 14, 2026
dbc5e87
[TimingStats] Tweak timing stats for console output
TD-er Jan 19, 2026
0d09e9a
[Domoticz] Fix Domoticz MQTT outputting svalue wrapped in quotes
TD-er Jan 19, 2026
7f997e9
[Build] Fix failing custom build (#5485)
TD-er Jan 26, 2026
62c45a7
Merge remote-tracking branch 'letscontrolit/mega' into bugfix/ESP32S2…
TD-er Jan 26, 2026
1a343c6
Merge remote-tracking branch 'chromoxdor/mega' into bugfix/ESP32S2_US…
TD-er Jan 28, 2026
5592b1f
[ESP-IDF] Update to latest 1901-1318-5.5 platform build
TD-er Jan 28, 2026
f40b915
[Build] Fix compile issues
TD-er Jan 29, 2026
9ffe8b6
Revert "[ESP-IDF] Update to latest 1901-1318-5.5 platform build"
TD-er Jan 29, 2026
d5b5721
[Sysinfo] Show free space on file system
TD-er Feb 9, 2026
42443c3
[ESP-IDF] Update to latest IDF/Arduino code to test if P4 builds work
TD-er Feb 9, 2026
3050243
[Build] Fix non-ESP32P4 builds with latest ESP-IDF/Arduino
TD-er Feb 9, 2026
4592722
[Build] Set BUILD_NO_DEBUG for Climate-A builds to make them fit again
TD-er Feb 9, 2026
80d4d25
Merge remote-tracking branch 'letscontrolit/mega' into bugfix/ESP32S2…
TD-er Feb 10, 2026
4f52461
Merge remote-tracking branch 'letscontrolit/mega' into bugfix/ESP32S2…
TD-er Feb 10, 2026
cc4e8e9
[SPI] Fix returning 'other' SPI bus for user defined SPI
TD-er Feb 10, 2026
6d07059
[Interfaces] Split SPI and I2C config into new Interfaces page
TD-er Feb 11, 2026
3a1515a
[WebUI] Add some icon to Interfaces tab + minor tweaks
TD-er Feb 11, 2026
7ba7226
[ESP-IDF] Update to latest ESP-IDF/Arduino SDK
TD-er Feb 11, 2026
59c3953
[Web UI] Change icon for Interfaces
TD-er Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion platformio_core_defs.ini
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ extra_scripts = ${esp82xx_common.extra_scripts}
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1311-2008-5.5_orig/framework-arduinoespressif32-release_v5.5_orig-276436da.tar.xz

platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc15
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/0401-1225-5.5/framework-arduinoespressif32-release_v5.5-ad03770f.tar.xz
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1002-1125-5.5_gcc151/framework-arduinoespressif32-release_v5.5_gcc151-7eede06a.tar.xz

custom_remove_include = true

Expand Down
5 changes: 5 additions & 0 deletions platformio_esp32c6_envs.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ build_unflags = ${esp32_base_idf5_5.build_unflags}
-fexceptions
board_build.filesystem = littlefs
lib_ignore = ${esp32_base_idf5_5.lib_ignore}
PPP
HeatpumpIR
IRremoteESP8266
board = esp32c6cdc


Expand Down Expand Up @@ -78,6 +81,7 @@ build_flags = ${esp32c6_common_LittleFS.build_flags}
-D ST7789_EXTRA_INIT=1
-D P116_EXTRA_ST7789=1
extra_scripts = ${esp32c6_common_LittleFS.extra_scripts}
lib_ignore = ${esp32_base_idf5_5.lib_ignore}


[env:max_ESP32c6_16M8M]
Expand All @@ -91,6 +95,7 @@ build_flags = ${esp32c6_common_LittleFS.build_flags}
-D ST7789_EXTRA_INIT=1
-D P116_EXTRA_ST7789=1
extra_scripts = ${esp32c6_common_LittleFS.extra_scripts}
lib_ignore = ${esp32_base_idf5_5.lib_ignore}



Expand Down
9 changes: 6 additions & 3 deletions src/ESPEasy/net/NWPluginStructs/NW004_data_struct_ETH_SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,15 @@ void NW004_data_struct_ETH_SPI::webform_load(EventStruct *event)
addFormNote(F("I²C-address of Ethernet PHY"));
}
{
if ((getSPIBusCount() > 1) && (Settings.isSPI_valid(0u) || Settings.isSPI_valid(1u))) {
if (Settings.getNrConfiguredSPI_buses()) {
const int key = NW004_KEY_SPI_BUS;
const uint8_t spiBus = _kvs->getValueAsInt(key);
KVS_StorageType::Enum storageType;
SPIInterfaceSelector(getLabelString(key, true, storageType),
getLabelString(key, false, storageType),
spiBus);
} else {
// TODO TD-er: Add error message as we need a SPI bus
}

const int gpio_keys[] = {
Expand Down Expand Up @@ -446,15 +448,16 @@ bool NW004_data_struct_ETH_SPI::ETHConnectRelaxed() {

// FIXME TD-er: Fallback for ETH01-EVO board
SPI_host = spi_host_device_t::SPI2_HOST;
Settings.InitSPI = static_cast<int>(SPI_Options_e::UserDefined);
Settings.InitSPI = static_cast<int>(SPI_Options_e::UserDefined_VSPI);
Settings.SPI_SCLK_pin = 7;
Settings.SPI_MISO_pin = 3;
Settings.SPI_MOSI_pin = 10;
# endif // ifdef ESP32C3
}

// else
{
if (SPI_host != spi_host_device_t::SPI_HOST_MAX) {
// TODO TD-er: Do we need to include the CLK, MISO, MOSI pins in the call or do we need to start the SPI bus first?
# if ETH_SPI_SUPPORTS_CUSTOM
success = iface->begin(
to_ESP_phy_type(phyType),
Expand Down
4 changes: 2 additions & 2 deletions src/src/Commands/InternalCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ bool checkNrArguments(const char *cmd, const String& Line, int nrArguments) {
log += F(" ExtraArg");
}
log += i;
log += '=';
log += ':';
log += parameter;
}
++i;
}
}
log += F(" lineLength=");
log += F(" lineLength:");
log += Line.length();
addLogMove(LOG_LEVEL_ERROR, log);
}
Expand Down
7 changes: 7 additions & 0 deletions src/src/CustomBuild/define_plugin_sets.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ To create/register a plugin, you have to :
#ifndef WEBSERVER_HARDWARE
#define WEBSERVER_HARDWARE
#endif
#ifndef WEBSERVER_INTERFACES
#define WEBSERVER_INTERFACES
#endif
#ifndef WEBSERVER_PINSTATES
#define WEBSERVER_PINSTATES
#endif
Expand Down Expand Up @@ -2179,6 +2182,10 @@ To create/register a plugin, you have to :
#define PLUGIN_DESCR "Climate A"
#endif

#ifndef BUILD_NO_DEBUG
#define BUILD_NO_DEBUG
#endif

// Features and plugins cherry picked from stable set
#ifndef FEATURE_SERVO
#define FEATURE_SERVO 1
Expand Down
3 changes: 3 additions & 0 deletions src/src/DataStructs/SettingsStruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ class SettingsStruct_tmpl
bool noCheck = false) const;

bool isSPI_enabled(uint8_t spi_bus) const;
uint8_t getNrConfiguredSPI_buses() const;
#ifdef ESP32
spi_host_device_t getSPI_host(uint8_t spi_bus = 0) const;
#endif
Expand All @@ -395,6 +396,8 @@ class SettingsStruct_tmpl

// Return true if I2C settings are correct
bool isI2CEnabled(uint8_t i2cBus) const;
uint8_t getNrConfiguredI2C_buses() const;


uint8_t getI2CInterface(taskIndex_t TaskIndex) const;
int8_t getI2CSdaPin(uint8_t i2cBus) const;
Expand Down
45 changes: 38 additions & 7 deletions src/src/DataStructs_templ/SettingsStruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,17 @@ bool SettingsStruct_tmpl<N_TASKS>::isSPI_enabled(uint8_t spi_bus) const {
return SPI_Options_e::None != SPI_selection;
}

template<uint32_t N_TASKS>
uint8_t SettingsStruct_tmpl<N_TASKS>::getNrConfiguredSPI_buses() const
{
uint8_t res{};
if (isSPI_valid(0u)) ++res;
#ifdef ESP32
if (getSPIBusCount() > 1 && isSPI_valid(1u)) ++res;
#endif
return res;
}

template<uint32_t N_TASKS>
bool SettingsStruct_tmpl<N_TASKS>::getSPI_pins(int8_t spi_gpios[3], uint8_t spi_bus, bool noCheck) const {
spi_gpios[0] = -1;
Expand Down Expand Up @@ -1020,7 +1031,10 @@ bool SettingsStruct_tmpl<N_TASKS>::getSPI_pins(int8_t spi_gpios[3], uint8_t spi_
break;
}
#endif
case SPI_Options_e::UserDefined:
case SPI_Options_e::UserDefined_VSPI:
#if SOC_SPI_PERIPH_NUM > 2
case SPI_Options_e::UserDefined_HSPI:
#endif
{
#ifdef ESP32
if (0 == spi_bus)
Expand Down Expand Up @@ -1059,6 +1073,7 @@ spi_host_device_t SettingsStruct_tmpl<N_TASKS>::getSPI_host(uint8_t spi_bus) con
const SPI_Options_e SPI_selection = static_cast<SPI_Options_e>(0 == spi_bus ? InitSPI : InitSPI1);
switch (SPI_selection) {
case SPI_Options_e::Vspi_Fspi:
case SPI_Options_e::UserDefined_VSPI:
{
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
return static_cast<spi_host_device_t>(FSPI_HOST);
Expand All @@ -1072,14 +1087,12 @@ spi_host_device_t SettingsStruct_tmpl<N_TASKS>::getSPI_host(uint8_t spi_bus) con
return static_cast<spi_host_device_t>(HSPI_HOST);
}
#endif
case SPI_Options_e::UserDefined:
#if SOC_SPI_PERIPH_NUM > 2
case SPI_Options_e::UserDefined_HSPI:
{
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
return static_cast<spi_host_device_t>(FSPI_HOST);
#else
return static_cast<spi_host_device_t>(VSPI_HOST);
#endif
return static_cast<spi_host_device_t>(HSPI_HOST);
}
#endif
case SPI_Options_e::None:
break;
}
Expand Down Expand Up @@ -1202,6 +1215,24 @@ bool SettingsStruct_tmpl<N_TASKS>::isI2CEnabled(uint8_t i2cBus) const {
(getI2CClockSpeedSlow(i2cBus) > 0);
}

template<uint32_t N_TASKS>
uint8_t SettingsStruct_tmpl<N_TASKS>::getNrConfiguredI2C_buses() const
{
#ifdef ESP32
uint8_t res{};
if (isI2CEnabled(0)) ++res;
if (getI2CBusCount() > 1) {
if (isI2CEnabled(1)) ++res;
#if FEATURE_I2C_INTERFACE_3
if (isI2CEnabled(2)) ++res;
#endif
}
return res;
#else
return isI2CEnabled(0) ? 1 : 0;
#endif
}

// stored in I2C_SPI_bus_Flags per Task
template<uint32_t N_TASKS>
uint8_t SettingsStruct_tmpl<N_TASKS>::getSPIBusForTask(taskIndex_t TaskIndex) const {
Expand Down
99 changes: 67 additions & 32 deletions src/src/DataTypes/SPI_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#ifdef ESP32

#include "../Helpers/Hardware_device_info.h"

// ESP32 VSPI:
// SCK = 18
// MISO = 19
Expand Down Expand Up @@ -35,28 +37,31 @@


# if CONFIG_IDF_TARGET_ESP32S3 // ESP32-S3
#define VSPI_FSPI_SHORT_STRING "FSPI"
#define VSPI_FSPI_SHORT_STRING "FSPI (" STRINGIFY(FSPI_HOST) ")"
# elif CONFIG_IDF_TARGET_ESP32S2 // ESP32-S2
#define VSPI_FSPI_SHORT_STRING "FSPI"
# elif CONFIG_IDF_TARGET_ESP32C2 // ESP32-C2
#define VSPI_FSPI_SHORT_STRING "FSPI"
# elif CONFIG_IDF_TARGET_ESP32C3 // ESP32-C3
#define VSPI_FSPI_SHORT_STRING "SPI"
# elif CONFIG_IDF_TARGET_ESP32C5 // ESP32-C5
#define VSPI_FSPI_SHORT_STRING "FSPI"
# elif CONFIG_IDF_TARGET_ESP32C6 // ESP32-C6
#define VSPI_FSPI_SHORT_STRING "FSPI"
# elif CONFIG_IDF_TARGET_ESP32C61 // ESP32-C61
#define VSPI_FSPI_SHORT_STRING "FSPI"
# elif CONFIG_IDF_TARGET_ESP32P4 // ESP32-P4
#define VSPI_FSPI_SHORT_STRING "FSPI"
#define VSPI_FSPI_SHORT_STRING "FSPI (" STRINGIFY(FSPI_HOST) ")"
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61 || CONFIG_IDF_TARGET_ESP32P4
# if SOC_SPI_PERIPH_NUM > 2
#define VSPI_FSPI_SHORT_STRING "FSPI (" STRINGIFY(VSPI_HOST) ")"
# else
#define VSPI_FSPI_SHORT_STRING "SPI" // STRINGIFY(VSPI_HOST)
# endif

# elif CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#define VSPI_FSPI_SHORT_STRING "VSPI"
#define VSPI_FSPI_SHORT_STRING "VSPI (" STRINGIFY(VSPI_HOST) ")"

# else // if CONFIG_IDF_TARGET_ESP32S2
# error Target CONFIG_IDF_TARGET is not supported
# endif // if CONFIG_IDF_TARGET_ESP32S2

#if SOC_SPI_PERIPH_NUM > 2
#ifdef ESP32_CLASSIC
#define HSPI_SHORT_STRING "HSPI (" STRINGIFY(HSPI_HOST) ")"
#else
#define HSPI_SHORT_STRING STRINGIFY(HSPI_HOST)
#endif
#endif


const __FlashStringHelper* getSPI_optionToString(SPI_Options_e option) {
switch (option) {
Expand All @@ -65,43 +70,73 @@ const __FlashStringHelper* getSPI_optionToString(SPI_Options_e option) {
case SPI_Options_e::Vspi_Fspi:
return F(
VSPI_FSPI_SHORT_STRING
": CLK=GPIO-" STRINGIFY(VSPI_FSPI_SCK)
", MISO=GPIO-" STRINGIFY(VSPI_FSPI_MISO)
", MOSI=GPIO-" STRINGIFY(VSPI_FSPI_MOSI) );
": CLK=" STRINGIFY(VSPI_FSPI_SCK)
", MISO=" STRINGIFY(VSPI_FSPI_MISO)
", MOSI=" STRINGIFY(VSPI_FSPI_MOSI) );
#ifdef ESP32_CLASSIC
case SPI_Options_e::Hspi:
return F(
"HSPI"
": CLK=GPIO-" STRINGIFY(HSPI_SCLK)
", MISO=GPIO-" STRINGIFY(HSPI_MISO)
", MOSI=GPIO-" STRINGIFY(HSPI_MOSI) );
HSPI_SHORT_STRING
": CLK=" STRINGIFY(HSPI_SCLK)
", MISO=" STRINGIFY(HSPI_MISO)
", MOSI=" STRINGIFY(HSPI_MOSI) );


#endif
case SPI_Options_e::UserDefined:
return F("User-defined: CLK, MISO, MOSI GPIO-pins");
case SPI_Options_e::UserDefined_VSPI:
return F("User-defined " VSPI_FSPI_SHORT_STRING);
#if SOC_SPI_PERIPH_NUM > 2
case SPI_Options_e::UserDefined_HSPI:
return F("User-defined " HSPI_SHORT_STRING);
#endif
}
return F("Unknown");
}

const __FlashStringHelper* get_vspi_fspi_str()
{
return F(VSPI_FSPI_SHORT_STRING);
}

const String getSPI_optionToShortString(SPI_Options_e option, uint8_t spi_bus) {
#ifdef ESP32
String res;
switch (option) {
case SPI_Options_e::None:
return F("Disabled");
case SPI_Options_e::Vspi_Fspi:
return F(VSPI_FSPI_SHORT_STRING);
res = F(VSPI_FSPI_SHORT_STRING);
break;
#ifdef ESP32_CLASSIC
case SPI_Options_e::Hspi:
return F("HSPI");
res = F("HSPI");
break;
#endif
case SPI_Options_e::UserDefined_VSPI:
res = F("User-defined " VSPI_FSPI_SHORT_STRING);
break;
#if SOC_SPI_PERIPH_NUM > 2
case SPI_Options_e::UserDefined_HSPI:
res = F("User-defined " HSPI_SHORT_STRING);
break;
#endif
case SPI_Options_e::UserDefined:
#ifdef ESP32
return concat(F("User-defined SPI Bus "), spi_bus);
#endif // ifdef ESP32
#ifdef ESP8266
}
if (!res.isEmpty()) {
if (getSPIBusCount() > 1) {
return concat(res + F(" bus "), spi_bus);
}
return res;
}
#else
switch (option) {
case SPI_Options_e::None:
return F("Disabled");
case SPI_Options_e::Vspi_Fspi:
return F(VSPI_FSPI_SHORT_STRING);
case SPI_Options_e::UserDefined_VSPI:
return F("User-defined SPI");
#endif // ifdef ESP8266
}
#endif
return F("Unknown");
}

Expand Down
8 changes: 6 additions & 2 deletions src/src/DataTypes/SPI_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// ESP32-S2/S3 : FSPI

// ESP32 classic:
// SPI_HOST = SPI1_HOST // Only usable on ESP32
// SPI_HOST = SPI1_HOST // Only usable on ESP32, when all functions doing SPI operations are in IRAM
// HSPI_HOST = SPI2_HOST
// VSPI_HOST = SPI3_HOST
//
Expand Down Expand Up @@ -73,12 +73,16 @@ enum class SPI_Options_e {
// For ESP32 classic, this is called VSPI
// For later versions it is called FSPI
// N.B. the ESP32-C3 does not seem to name these as there is no SPI3_HOST.
UserDefined = 9 // Leave some room for other, possible future, hardware-related options
UserDefined_VSPI = 9 // Leave some room for other, possible future, hardware-related options
#if SOC_SPI_PERIPH_NUM > 2
,UserDefined_HSPI = 10
#endif

};

#ifdef ESP32
const __FlashStringHelper* getSPI_optionToString(SPI_Options_e option);
const __FlashStringHelper* get_vspi_fspi_str();
const String getSPI_optionToShortString(SPI_Options_e option, uint8_t spi_bus = 0);
#endif // ifdef ESP32

Expand Down
Loading
Loading