From bacad9901145808c9bf4bce3e017bd3d4903a1ae Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Wed, 29 Jan 2025 23:37:54 +0100 Subject: [PATCH 01/24] [I2C] Add support for multiple I2C interfaces --- src/_P017_PN532.ino | 2 +- src/_P139_AXP2101.ino | 2 +- src/_P166_GP8403.ino | 2 +- src/src/Commands/GPIO.cpp | 16 ++ src/src/Commands/i2c.cpp | 37 +-- src/src/CustomBuild/define_plugin_sets.h | 17 ++ src/src/DataStructs/DeviceStruct.h | 2 + src/src/DataStructs/SettingsStruct.h | 33 ++- src/src/DataStructs_templ/SettingsStruct.cpp | 169 ++++++++++++- src/src/Globals/Plugins.cpp | 32 ++- src/src/Globals/Plugins.h | 3 +- src/src/Helpers/DeepSleep.cpp | 2 +- src/src/Helpers/ESPEasy_checks.cpp | 2 +- src/src/Helpers/ESPEasy_time.cpp | 20 +- src/src/Helpers/Hardware_I2C.cpp | 221 +++++++++++------ src/src/Helpers/Hardware_I2C.h | 33 +-- src/src/Helpers/Hardware_device_info.cpp | 57 +++-- src/src/Helpers/Hardware_device_info.h | 5 + src/src/Helpers/I2C_access.cpp | 51 +++- src/src/Helpers/I2C_access.h | 11 + src/src/Helpers/PeriodicalActions.cpp | 3 + src/src/Helpers/StringGenerator_GPIO.cpp | 11 +- src/src/WebServer/AdvancedConfigPage.cpp | 52 +++- src/src/WebServer/DevicesPage.cpp | 58 ++++- src/src/WebServer/HardwarePage.cpp | 235 +++++++++++++------ src/src/WebServer/HardwarePage.h | 11 +- src/src/WebServer/I2C_Scanner.cpp | 157 ++++++++----- src/src/WebServer/I2C_Scanner.h | 49 ++-- src/src/WebServer/JSON.cpp | 14 +- 29 files changed, 984 insertions(+), 323 deletions(-) diff --git a/src/_P017_PN532.ino b/src/_P017_PN532.ino index 4dd48b96ea..85ebe2424c 100644 --- a/src/_P017_PN532.ino +++ b/src/_P017_PN532.ino @@ -242,7 +242,7 @@ bool P017_handle_timer_in(struct EventStruct *event) # endif // ifdef P017_DEBUG_LOGIC_ANALYZER_PIN // TODO: Clock stretching issue https://github.com/esp8266/Arduino/issues/1541 - if (Settings.isI2CEnabled() + if (Settings.isI2CEnabled(get3BitFromUL(Settings.I2C_Flags[event->TaskIndex], I2C_FLAGS_BUS_NUMBER)) && ((DIRECT_pinRead(Settings.Pin_i2c_sda) == 0) || (DIRECT_pinRead(Settings.Pin_i2c_scl) == 0))) { addLog(LOG_LEVEL_ERROR, F("PN532: BUS error")); diff --git a/src/_P139_AXP2101.ino b/src/_P139_AXP2101.ino index b817e7c09a..36efbdab32 100644 --- a/src/_P139_AXP2101.ino +++ b/src/_P139_AXP2101.ino @@ -257,7 +257,7 @@ boolean Plugin_139(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_INIT: { - if (Settings.isI2CEnabled()) { + if (Settings.isI2CEnabled(get3BitFromUL(Settings.I2C_Flags[event->TaskIndex], I2C_FLAGS_BUS_NUMBER))) { // FIXME P139_data_struct *P139_init = static_cast(getPluginTaskData(event->TaskIndex)); if (nullptr != P139_init) { diff --git a/src/_P166_GP8403.ino b/src/_P166_GP8403.ino index e00eae4cd6..b543deeb48 100644 --- a/src/_P166_GP8403.ino +++ b/src/_P166_GP8403.ino @@ -214,7 +214,7 @@ boolean Plugin_166(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_INIT: { - if (Settings.isI2CEnabled()) { + if (Settings.isI2CEnabled(get3BitFromUL(Settings.I2C_Flags[event->TaskIndex], I2C_FLAGS_BUS_NUMBER))) { initPluginTaskData(event->TaskIndex, new (std::nothrow) P166_data_struct(P166_I2C_ADDRESS, static_cast(P166_MAX_VOLTAGE))); diff --git a/src/src/Commands/GPIO.cpp b/src/src/Commands/GPIO.cpp index dd9e68e7a3..c0d3c7ce63 100644 --- a/src/src/Commands/GPIO.cpp +++ b/src/src/Commands/GPIO.cpp @@ -18,6 +18,12 @@ #include "../Helpers/PortStatus.h" #include "../Helpers/Numerical.h" +#if FEATURE_I2C_MULTIPLE +#include "../Globals/Settings.h" +#include "../Helpers/Hardware_device_info.h" +#include "../Helpers/I2C_access.h" +#endif // if FEATURE_I2C_MULTIPLE + #if FEATURE_GPIO_USE_ESP8266_WAVEFORM # include #endif @@ -1216,6 +1222,11 @@ bool getGPIOPinStateValues(String& str) { #if FEATURE_PINSTATE_EXTENDED pluginID = PLUGIN_MCP; #endif // if FEATURE_PINSTATE_EXTENDED + #if FEATURE_I2C_MULTIPLE + if (getI2CBusCount() >= 2) { + I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP)); + } + #endif // if FEATURE_I2C_MULTIPLE str = GPIO_MCP_Read(par1); #ifndef BUILD_NO_DEBUG logPrefix = F("MCP"); @@ -1229,6 +1240,11 @@ bool getGPIOPinStateValues(String& str) { #if FEATURE_PINSTATE_EXTENDED pluginID = PLUGIN_PCF; #endif // if FEATURE_PINSTATE_EXTENDED + #if FEATURE_I2C_MULTIPLE + if (getI2CBusCount() >= 2) { + I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP)); + } + #endif // if FEATURE_I2C_MULTIPLE str = GPIO_PCF_Read(par1); #ifndef BUILD_NO_DEBUG logPrefix = F("PCF"); diff --git a/src/src/Commands/i2c.cpp b/src/src/Commands/i2c.cpp index c025a3290e..551bc9fe3b 100644 --- a/src/src/Commands/i2c.cpp +++ b/src/src/Commands/i2c.cpp @@ -37,27 +37,34 @@ void i2c_scanI2Cbus(bool dbg, int8_t channel) { const __FlashStringHelper* Command_i2c_Scanner(struct EventStruct *event, const char *Line) { - if (Settings.isI2CEnabled()) { - const bool dbg = equals(parseString(Line, 2), F("1")); - I2CSelect_Max100kHz_ClockSpeed(); // Scan bus using low speed + const bool dbg = equals(parseString(Line, 2), F("1")); + #if !FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = 0; + #else // if !FEATURE_I2C_MULTIPLE + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) + #endif // if !FEATURE_I2C_MULTIPLE + { + if (Settings.isI2CEnabled(i2cBus)) { + I2CSelect_Max100kHz_ClockSpeed(i2cBus); // Scan bus using low speed - i2c_scanI2Cbus(dbg, -1); // Base I2C bus + i2c_scanI2Cbus(dbg, -1); // Base I2C bus - #if FEATURE_I2CMULTIPLEXER + #if FEATURE_I2CMULTIPLEXER - if (isI2CMultiplexerEnabled()) { - uint8_t mux_max = I2CMultiplexerMaxChannels(); + if (isI2CMultiplexerEnabled(i2cBus)) { + uint8_t mux_max = I2CMultiplexerMaxChannels(i2cBus); - for (int8_t channel = 0; channel < mux_max; ++channel) { - I2CMultiplexerSelect(channel); - i2c_scanI2Cbus(dbg, channel); // Multiplexer I2C bus + for (int8_t channel = 0; channel < mux_max; ++channel) { + I2CMultiplexerSelect(i2cBus, channel); + i2c_scanI2Cbus(dbg, channel); // Multiplexer I2C bus + } + I2CMultiplexerOff(0); } - I2CMultiplexerOff(); + #endif // if FEATURE_I2CMULTIPLEXER + } else { + serialPrintln(F("I2C : Not enabled.")); } - #endif // if FEATURE_I2CMULTIPLEXER - I2CSelectHighClockSpeed(); // By default the bus is in standard speed - } else { - serialPrintln(F("I2C : Not enabled.")); } + I2CSelectHighClockSpeed(0); // By default the bus is in standard speed return return_see_serial(event); } diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 0f695283d5..f4e6528391 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -3646,6 +3646,23 @@ To create/register a plugin, you have to : #define FEATURE_ALTERNATIVE_CDN_URL 1 */ +#ifndef FEATURE_I2C_MULTIPLE + #ifdef ESP8266 + #define FEATURE_I2C_MULTIPLE 0 // NOT SUPPORTED + #endif + #ifdef ESP32 + #define FEATURE_I2C_MULTIPLE 1 + #endif +#endif +#if FEATURE_I2C_MULTIPLE + #ifndef FEATURE_I2C_INTERFACE_3 + #define FEATURE_I2C_INTERFACE_3 0 // Not enabled by default + #endif +#endif +#if defined(ESP8266) && FEATURE_I2C_MULTIPLE + #undef FEATURE_I2C_MULTIPLE + #define FEATURE_I2C_MULTIPLE 0 // NOT SUPPORTED +#endif #ifndef FEATURE_THINGSPEAK_EVENT #ifdef LIMIT_BUILD_SIZE diff --git a/src/src/DataStructs/DeviceStruct.h b/src/src/DataStructs/DeviceStruct.h index 7b3b81c74e..4c770f390d 100644 --- a/src/src/DataStructs/DeviceStruct.h +++ b/src/src/DataStructs/DeviceStruct.h @@ -38,6 +38,7 @@ #define I2C_FLAGS_SLOW_SPEED 0 // Force slow speed when this flag is set #define I2C_FLAGS_MUX_MULTICHANNEL 1 // Allow multiple multiplexer channels when set +#define I2C_FLAGS_BUS_NUMBER 2 // 3 bits. The I2C bus number to use (ESP32 only), 3 bits allow for future expansion @@ -110,6 +111,7 @@ struct __attribute__((__packed__)) DeviceStruct bool I2CMax100kHz : 1; // When enabled, the device is only able to handle 100 kHz bus-clock speed, shows warning and enables "Force Slow I2C speed" by default bool HasFormatUserVar : 1; // Optimization to only call this when PLUGIN_FORMAT_USERVAR is implemented + bool I2CNoBusSelection : 1; // Dis-allow I2C Bus selection in device configuration }; diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index 8cd707dff2..95c8e8ce0b 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -315,7 +315,19 @@ class SettingsStruct_tmpl bool isI2C_pin(int8_t pin) const; // Return true if I2C settings are correct - bool isI2CEnabled() const; + bool isI2CEnabled(uint8_t i2cBus) const; + + int8_t getI2CSdaPin(uint8_t i2cBus) const; + int8_t getI2CSclPin(uint8_t i2cBus) const; + uint32_t getI2CClockSpeed(uint8_t i2cBus) const; + uint32_t getI2CClockSpeedSlow(uint8_t i2cBus) const; + uint32_t getI2CClockStretch(uint8_t i2cBus) const; + + #if FEATURE_I2CMULTIPLEXER + int8_t getI2CMultiplexerType(uint8_t i2cBus) const; + int8_t getI2CMultiplexerAddr(uint8_t i2cBus) const; + int8_t getI2CMultiplexerResetPin(uint8_t i2cBus) const; + #endif // if FEATURE_I2CMULTIPLEXER // Return true when pin is one of the fixed Ethernet pins and Ethernet is enabled bool isEthernetPin(int8_t pin) const; @@ -400,7 +412,24 @@ class SettingsStruct_tmpl uint8_t Notification[NOTIFICATION_MAX] = {0}; //notifications, point to a NPLUGIN id // FIXME TD-er: Must change to pluginID_t, but then also another check must be added since changing the pluginID_t will also render settings incompatible uint8_t TaskDeviceNumber[N_TASKS] = {0}; // The "plugin number" set at as task (e.g. 4 for P004_dallas) - unsigned int OLD_TaskDeviceID[N_TASKS] = {0}; //UNUSED: this can be reused + int8_t Pin_i2c2_sda = -1; // DEFAULT_PIN_I2C2_SDA; // From here, storage borrowed from OLD_TaskDeviceID array + int8_t Pin_i2c2_scl = -1; // DEFAULT_PIN_I2C2_SCL; + int8_t Pin_i2c3_sda = -1; // DEFAULT_PIN_I2C3_SDA; + int8_t Pin_i2c3_scl = -1; // DEFAULT_PIN_I2C3_SCL; + uint32_t I2C2_clockSpeed = 400000; + uint32_t I2C2_clockSpeed_Slow = 100000; + uint32_t I2C3_clockSpeed = 400000; + uint32_t I2C3_clockSpeed_Slow = 100000; + int8_t I2C2_Multiplexer_Type = I2C_MULTIPLEXER_NONE; + int8_t I2C2_Multiplexer_Addr = -1; + int8_t I2C2_Multiplexer_ResetPin = -1; + int8_t I2C3_Multiplexer_Type = I2C_MULTIPLEXER_NONE; + int8_t I2C3_Multiplexer_Addr = -1; + int8_t I2C3_Multiplexer_ResetPin = -1; + uint16_t I2C_peripheral_bus = 0; + unsigned long Wire2ClockStretchLimit = 0; + unsigned long Wire3ClockStretchLimit = 0; + unsigned int OLD_TaskDeviceID[N_TASKS - 9] = {0}; //UNUSED: this can be reused // FIXME TD-er: When used on ESP8266, this conversion union may not work // It might work as it is 32-bit in size. diff --git a/src/src/DataStructs_templ/SettingsStruct.cpp b/src/src/DataStructs_templ/SettingsStruct.cpp index 8c2732e1f5..6e20e8422a 100644 --- a/src/src/DataStructs_templ/SettingsStruct.cpp +++ b/src/src/DataStructs_templ/SettingsStruct.cpp @@ -17,6 +17,9 @@ #include "../Helpers/Misc.h" #include "../Helpers/StringParser.h" +#if FEATURE_I2C_MULTIPLE +#include "../Helpers/Hardware_device_info.h" +#endif #if ESP_IDF_VERSION_MAJOR >= 5 #include @@ -963,16 +966,170 @@ bool SettingsStruct_tmpl::isSPI_valid() const { template bool SettingsStruct_tmpl::isI2C_pin(int8_t pin) const { if (pin < 0) { return false; } - return Pin_i2c_sda == pin || Pin_i2c_scl == pin; + return Pin_i2c_sda == pin || Pin_i2c_scl == pin + #if FEATURE_I2C_MULTIPLE + || ((getI2CBusCount() >= 2) && (Pin_i2c2_sda == pin || Pin_i2c2_scl == pin)) + #if FEATURE_I2C_INTERFACE_3 + || ((getI2CBusCount() >= 3) && (Pin_i2c3_sda == pin || Pin_i2c3_scl == pin)) + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + ; +} + +template +bool SettingsStruct_tmpl::isI2CEnabled(uint8_t i2cBus) const { + if (0 == i2cBus) { + return (Pin_i2c_sda != -1) && + (Pin_i2c_scl != -1) && + (I2C_clockSpeed > 0) && + (I2C_clockSpeed_Slow > 0); + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return (Pin_i2c2_sda != -1) && + (Pin_i2c2_scl != -1) && + (I2C2_clockSpeed > 0) && + (I2C2_clockSpeed_Slow > 0); + #if FEATURE_I2C_INTERFACE_3 + } else { + return (Pin_i2c3_sda != -1) && + (Pin_i2c3_scl != -1) && + (I2C3_clockSpeed > 0) && + (I2C3_clockSpeed_Slow > 0); + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return false; +} + +template +int8_t SettingsStruct_tmpl::getI2CSdaPin(uint8_t i2cBus) const { + if (0 == i2cBus) { + return Pin_i2c_sda; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return Pin_i2c2_sda; + #if FEATURE_I2C_INTERFACE_3 + } else { + return Pin_i2c3_sda; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return -1; +} + +template +int8_t SettingsStruct_tmpl::getI2CSclPin(uint8_t i2cBus) const { + if (0 == i2cBus) { + return Pin_i2c_scl; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return Pin_i2c2_scl; + #if FEATURE_I2C_INTERFACE_3 + } else { + return Pin_i2c3_scl; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return -1; +} + +template +uint32_t SettingsStruct_tmpl::getI2CClockSpeed(uint8_t i2cBus) const { + if (0 == i2cBus) { + return I2C_clockSpeed; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return I2C2_clockSpeed; + #if FEATURE_I2C_INTERFACE_3 + } else { + return I2C3_clockSpeed; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return 0u; } template -bool SettingsStruct_tmpl::isI2CEnabled() const { - return (Pin_i2c_sda != -1) && - (Pin_i2c_scl != -1) && - (I2C_clockSpeed > 0) && - (I2C_clockSpeed_Slow > 0); +uint32_t SettingsStruct_tmpl::getI2CClockSpeedSlow(uint8_t i2cBus) const { + if (0 == i2cBus) { + return I2C_clockSpeed_Slow; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return I2C2_clockSpeed_Slow; + #if FEATURE_I2C_INTERFACE_3 + } else { + return I2C3_clockSpeed_Slow; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return 0u; +} + +template +uint32_t SettingsStruct_tmpl::getI2CClockStretch(uint8_t i2cBus) const { + if (0 == i2cBus) { + return WireClockStretchLimit; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return Wire2ClockStretchLimit; + #if FEATURE_I2C_INTERFACE_3 + } else { + return Wire3ClockStretchLimit; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return 0u; +} + +#if FEATURE_I2CMULTIPLEXER +template +int8_t SettingsStruct_tmpl::getI2CMultiplexerType(uint8_t i2cBus) const { + if (0 == i2cBus) { + return I2C_Multiplexer_Type; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return I2C2_Multiplexer_Type; + #if FEATURE_I2C_INTERFACE_3 + } else { + return I2C3_Multiplexer_Type; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return -1; +} + +template +int8_t SettingsStruct_tmpl::getI2CMultiplexerAddr(uint8_t i2cBus) const { + if (0 == i2cBus) { + return I2C_Multiplexer_Addr; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return I2C2_Multiplexer_Addr; + #if FEATURE_I2C_INTERFACE_3 + } else { + return I2C3_Multiplexer_Addr; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return -1; +} + +template +int8_t SettingsStruct_tmpl::getI2CMultiplexerResetPin(uint8_t i2cBus) const { + if (0 == i2cBus) { + return I2C_Multiplexer_ResetPin; + #if FEATURE_I2C_MULTIPLE + } else if (1 == i2cBus) { + return I2C2_Multiplexer_ResetPin; + #if FEATURE_I2C_INTERFACE_3 + } else { + return I2C3_Multiplexer_ResetPin; + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + } + return -1; } +#endif // if FEATURE_I2CMULTIPLEXER template bool SettingsStruct_tmpl::isEthernetPin(int8_t pin) const { diff --git a/src/src/Globals/Plugins.cpp b/src/src/Globals/Plugins.cpp index 632d2ef3fe..64c60ea7d1 100644 --- a/src/src/Globals/Plugins.cpp +++ b/src/src/Globals/Plugins.cpp @@ -90,8 +90,13 @@ pluginID_t getPluginID_from_TaskIndex(taskIndex_t taskIndex) { } #if FEATURE_PLUGIN_PRIORITY -bool isPluginI2CPowerManager_from_TaskIndex(taskIndex_t taskIndex) { +bool isPluginI2CPowerManager_from_TaskIndex(taskIndex_t taskIndex, uint8_t i2cBus) { if (validTaskIndex(taskIndex)) { + #if FEATURE_I2C_MULTIPLE + if (get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER) != i2cBus) { + return false; + } + #endif // if FEATURE_I2C_MULTIPLE deviceIndex_t deviceIndex = getDeviceIndex_from_TaskIndex(taskIndex); if (validDeviceIndex(deviceIndex)) { @@ -212,6 +217,19 @@ bool prepare_I2C_by_taskIndex(taskIndex_t taskIndex, deviceIndex_t DeviceIndex) if (I2C_state != I2C_bus_state::OK) { return false; // Bus state is not OK, so do not consider task runnable } + + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE + + if (bitRead(Settings.I2C_Flags[taskIndex], I2C_FLAGS_SLOW_SPEED)) { + I2CSelectLowClockSpeed(i2cBus); // Set to slow, also switch the bus + } else { + I2CSelectHighClockSpeed(i2cBus); // Set to normal, also switch the bus + } + #if FEATURE_I2CMULTIPLEXER I2CMultiplexerSelectByTaskIndex(taskIndex); @@ -219,9 +237,6 @@ bool prepare_I2C_by_taskIndex(taskIndex_t taskIndex, deviceIndex_t DeviceIndex) // frequency is set before anything else is sent. #endif // if FEATURE_I2CMULTIPLEXER - if (bitRead(Settings.I2C_Flags[taskIndex], I2C_FLAGS_SLOW_SPEED)) { - I2CSelectLowClockSpeed(); // Set to slow - } return true; } @@ -233,11 +248,16 @@ void post_I2C_by_taskIndex(taskIndex_t taskIndex, deviceIndex_t DeviceIndex) { if (Device[DeviceIndex].Type != DEVICE_TYPE_I2C) { return; } + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + #else + const uint8_t i2cBus = 0; + #endif // ifdef ESP32 #if FEATURE_I2CMULTIPLEXER - I2CMultiplexerOff(); + I2CMultiplexerOff(i2cBus); #endif // if FEATURE_I2CMULTIPLEXER - I2CSelectHighClockSpeed(); // Reset + I2CSelectHighClockSpeed(i2cBus); // Reset, stay on current bus } // Add an event to the event queue. diff --git a/src/src/Globals/Plugins.h b/src/src/Globals/Plugins.h index 67c775d240..89015f245a 100644 --- a/src/src/Globals/Plugins.h +++ b/src/src/Globals/Plugins.h @@ -73,7 +73,8 @@ deviceIndex_t getDeviceIndex_from_TaskIndex(taskIndex_t taskIndex); pluginID_t getPluginID_from_TaskIndex(taskIndex_t taskIndex); #if FEATURE_PLUGIN_PRIORITY -bool isPluginI2CPowerManager_from_TaskIndex(taskIndex_t taskIndex); +bool isPluginI2CPowerManager_from_TaskIndex(taskIndex_t taskIndex, + uint8_t i2cBus); #endif // if FEATURE_PLUGIN_PRIORITY /********************************************************************************************\ diff --git a/src/src/Helpers/DeepSleep.cpp b/src/src/Helpers/DeepSleep.cpp index 0eb11bd9ac..f9248937e5 100644 --- a/src/src/Helpers/DeepSleep.cpp +++ b/src/src/Helpers/DeepSleep.cpp @@ -33,7 +33,7 @@ int getDeepSleepMax() #endif // ifdef ESP8266 #ifdef ESP32 int dsmax = 281474976; // / 3600 (hour) / 24 (day) / 365 (year) = ~8 years. (max. 48 bits in microseconds) - #endif // ifdef ESp32 + #endif // ifdef ESP32 #if defined(CORE_POST_2_5_0) dsmax = INT_MAX; diff --git a/src/src/Helpers/ESPEasy_checks.cpp b/src/src/Helpers/ESPEasy_checks.cpp index 7cb0789f07..451af7efe8 100644 --- a/src/src/Helpers/ESPEasy_checks.cpp +++ b/src/src/Helpers/ESPEasy_checks.cpp @@ -178,7 +178,7 @@ void run_compiletime_checks() { static_assert(198u == offsetof(SettingsStruct, TaskDeviceNumber), "NOTIFICATION_MAX has changed?"); // All settings related to N_TASKS - static_assert((200 + TASKS_MAX) == offsetof(SettingsStruct, OLD_TaskDeviceID), ""); // 32-bit alignment, so offset of 2 bytes. + static_assert((236 + TASKS_MAX) == offsetof(SettingsStruct, OLD_TaskDeviceID), ""); // 32-bit alignment, so offset of 2 bytes. static_assert((200 + (67 * TASKS_MAX)) == offsetof(SettingsStruct, ControllerEnabled), ""); // Used to compute true offset. diff --git a/src/src/Helpers/ESPEasy_time.cpp b/src/src/Helpers/ESPEasy_time.cpp index 3a26c249d0..6577104736 100644 --- a/src/src/Helpers/ESPEasy_time.cpp +++ b/src/src/Helpers/ESPEasy_time.cpp @@ -919,13 +919,18 @@ struct tm ESPEasy_time::getSunSet(int secOffset) const { bool ESPEasy_time::ExtRTC_get(uint32_t& unixtime) { unixtime = 0; + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE switch (Settings.ExtTimeSource()) { case ExtTimeSource_e::None: return false; case ExtTimeSource_e::DS1307: { - I2CSelect_Max100kHz_ClockSpeed(); // Only supports upto 100 kHz + I2CSelect_Max100kHz_ClockSpeed(i2cBus); // Only supports upto 100 kHz RTC_DS1307 rtc; if (!rtc.begin()) { @@ -942,6 +947,7 @@ bool ESPEasy_time::ExtRTC_get(uint32_t& unixtime) } case ExtTimeSource_e::DS3231: { + I2CSelectHighClockSpeed(i2cBus); RTC_DS3231 rtc; if (!rtc.begin()) { @@ -959,6 +965,7 @@ bool ESPEasy_time::ExtRTC_get(uint32_t& unixtime) case ExtTimeSource_e::PCF8523: { + I2CSelectHighClockSpeed(i2cBus); RTC_PCF8523 rtc; if (!rtc.begin()) { @@ -975,6 +982,7 @@ bool ESPEasy_time::ExtRTC_get(uint32_t& unixtime) } case ExtTimeSource_e::PCF8563: { + I2CSelectHighClockSpeed(i2cBus); RTC_PCF8563 rtc; if (!rtc.begin()) { @@ -1012,13 +1020,18 @@ bool ESPEasy_time::ExtRTC_set(uint32_t unixtime) return true; } bool timeAdjusted = false; + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE switch (Settings.ExtTimeSource()) { case ExtTimeSource_e::None: return false; case ExtTimeSource_e::DS1307: { - I2CSelect_Max100kHz_ClockSpeed(); // Only supports upto 100 kHz + I2CSelect_Max100kHz_ClockSpeed(i2cBus); // Only supports upto 100 kHz RTC_DS1307 rtc; if (rtc.begin()) { @@ -1029,6 +1042,7 @@ bool ESPEasy_time::ExtRTC_set(uint32_t unixtime) } case ExtTimeSource_e::DS3231: { + I2CSelectHighClockSpeed(i2cBus); RTC_DS3231 rtc; if (rtc.begin()) { @@ -1040,6 +1054,7 @@ bool ESPEasy_time::ExtRTC_set(uint32_t unixtime) case ExtTimeSource_e::PCF8523: { + I2CSelectHighClockSpeed(i2cBus); RTC_PCF8523 rtc; if (rtc.begin()) { @@ -1051,6 +1066,7 @@ bool ESPEasy_time::ExtRTC_set(uint32_t unixtime) } case ExtTimeSource_e::PCF8563: { + I2CSelectHighClockSpeed(i2cBus); RTC_PCF8563 rtc; if (rtc.begin()) { diff --git a/src/src/Helpers/Hardware_I2C.cpp b/src/src/Helpers/Hardware_I2C.cpp index 463d001101..080e5f2913 100644 --- a/src/src/Helpers/Hardware_I2C.cpp +++ b/src/src/Helpers/Hardware_I2C.cpp @@ -5,6 +5,7 @@ #include "../Helpers/Hardware_defines.h" #include "../Helpers/Hardware_GPIO.h" #include "../Helpers/I2C_access.h" +#include "../Helpers/StringConverter.h" #include @@ -12,33 +13,39 @@ void initI2C() { // configure hardware pins according to eeprom settings. - if (!Settings.isI2CEnabled()) + if (!Settings.isI2CEnabled(0) + #if FEATURE_I2C_MULTIPLE + && !Settings.isI2CEnabled(1) + # if FEATURE_I2C_INTERFACE_3 + && !Settings.isI2CEnabled(2) + # endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + ) { return; } - addLog(LOG_LEVEL_INFO, F("INIT : I2C")); - I2CSelectHighClockSpeed(); // Set normal clock speed + #if !FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = 0; + #else // if !FEATURE_I2C_MULTIPLE - if (Settings.WireClockStretchLimit) + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) + #endif // if !FEATURE_I2C_MULTIPLE { - if (loglevelActiveFor(LOG_LEVEL_INFO)) { - String log = F("INIT : I2C custom clockstretchlimit:"); - log += Settings.WireClockStretchLimit; - addLogMove(LOG_LEVEL_INFO, log); + if (Settings.isI2CEnabled(i2cBus)) { + addLog(LOG_LEVEL_INFO, concat(F("INIT : I2C interface "), i2cBus + 1)); + I2CSelectHighClockSpeed(i2cBus); // Set normal clock speed, on I2C Interface 1 (index 0) } - #if defined(ESP8266) - Wire.setClockStretchLimit(Settings.WireClockStretchLimit); - #endif // if defined(ESP8266) - #ifdef ESP32 - Wire.setTimeOut(Settings.WireClockStretchLimit); - #endif } #if FEATURE_I2CMULTIPLEXER - if (validGpio(Settings.I2C_Multiplexer_ResetPin)) { // Initialize Reset pin to High if configured - pinMode(Settings.I2C_Multiplexer_ResetPin, OUTPUT); - digitalWrite(Settings.I2C_Multiplexer_ResetPin, HIGH); + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) { + const int8_t Multiplexer_ResetPin = Settings.getI2CMultiplexerResetPin(i2cBus); + + if (validGpio(Multiplexer_ResetPin)) { // Initialize Reset pin to High if configured + pinMode(Multiplexer_ResetPin, OUTPUT); + digitalWrite(Multiplexer_ResetPin, HIGH); + } } #endif // if FEATURE_I2CMULTIPLEXER @@ -46,11 +53,16 @@ void initI2C() { if (Settings.WDI2CAddress != 0) { delay(500); + + #if FEATURE_I2C_MULTIPLE + I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT)); + #endif // if FEATURE_I2C_MULTIPLE + if (I2C_write8_reg(Settings.WDI2CAddress, 0x83, // command to set pointer - 17)) // pointer value to status uint8_t - { - bool is_ok = false; + 17)) // pointer value to status uint8_t + { + bool is_ok = false; const uint8_t status = I2C_read8(Settings.WDI2CAddress, &is_ok); if (is_ok) @@ -63,54 +75,72 @@ void initI2C() { } } } + I2CSelectHighClockSpeed(0); // Select first interface by default } -void I2CSelectHighClockSpeed() { - I2CSelectClockSpeed(Settings.I2C_clockSpeed); +void I2CSelectHighClockSpeed(uint8_t i2cBus) { + const uint32_t clockSpeed = Settings.getI2CClockSpeed(i2cBus); + + I2CSelectClockSpeed(i2cBus, clockSpeed); } -void I2CSelectLowClockSpeed() { - I2CSelectClockSpeed(Settings.I2C_clockSpeed_Slow); +void I2CSelectLowClockSpeed(uint8_t i2cBus) { + const uint32_t clockSpeed = Settings.getI2CClockSpeedSlow(i2cBus); + + I2CSelectClockSpeed(i2cBus, clockSpeed); } -void I2CSelect_Max100kHz_ClockSpeed() { - if (Settings.I2C_clockSpeed <= 100000) { - I2CSelectHighClockSpeed(); - } else if (Settings.I2C_clockSpeed_Slow <= 100000) { - I2CSelectLowClockSpeed(); +void I2CSelect_Max100kHz_ClockSpeed(uint8_t i2cBus) { + const uint32_t clockSpeed = Settings.getI2CClockSpeed(i2cBus); + const uint32_t clockSpeed_Slow = Settings.getI2CClockSpeedSlow(i2cBus); + + if (clockSpeed <= 100000) { + I2CSelectHighClockSpeed(i2cBus); + } else if (clockSpeed_Slow <= 100000) { + I2CSelectLowClockSpeed(i2cBus); } else { - I2CSelectClockSpeed(100000); + I2CSelectClockSpeed(i2cBus, 100000); } } -void I2CSelectClockSpeed(uint32_t clockFreq) { - I2CBegin(Settings.Pin_i2c_sda, Settings.Pin_i2c_scl, clockFreq); +void I2CSelectClockSpeed(uint8_t i2cBus, uint32_t clockFreq) { + const int8_t i2c_sda = Settings.getI2CSdaPin(i2cBus); + const int8_t i2c_scl = Settings.getI2CSclPin(i2cBus); + const uint32_t ClockStretchLimit = Settings.getI2CClockStretch(i2cBus); + + I2CBegin(i2c_sda, i2c_scl, clockFreq, ClockStretchLimit); } -void I2CForceResetBus_swap_pins(uint8_t address) { +void I2CForceResetBus_swap_pins(uint8_t i2cBus, uint8_t address) { #if FEATURE_CLEAR_I2C_STUCK + if (!Settings.EnableClearHangingI2Cbus()) { return; } -#endif +#endif // if FEATURE_CLEAR_I2C_STUCK // As a final work-around, we temporary swap SDA and SCL, perform a scan and return pin order. - I2CBegin(Settings.Pin_i2c_scl, Settings.Pin_i2c_sda, 100000); + const int8_t i2c_sda = Settings.getI2CSdaPin(i2cBus); + const int8_t i2c_scl = Settings.getI2CSclPin(i2cBus); + const uint32_t ClockStretchLimit = Settings.getI2CClockStretch(i2cBus); + + I2CBegin(i2c_scl, i2c_sda, 100000, ClockStretchLimit); I2C_wakeup(address); delay(1); // Now we switch back to the correct pins - I2CSelectClockSpeed(100000); + I2CSelectClockSpeed(i2cBus, 100000); } -void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq) { +void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq, uint32_t clockStretch) { #ifdef ESP32 uint32_t lastI2CClockSpeed = Wire.getClock(); #else // ifdef ESP32 static uint32_t lastI2CClockSpeed = 0; #endif // ifdef ESP32 - static int8_t last_sda = -1; - static int8_t last_scl = -1; + static int8_t last_sda = -1; + static int8_t last_scl = -1; + static uint32_t last_stretch = 0; - if ((clockFreq == lastI2CClockSpeed) && (sda == last_sda) && (scl == last_scl)) { + if ((clockFreq == lastI2CClockSpeed) && (sda == last_sda) && (scl == last_scl) && (clockStretch == last_stretch)) { // No need to change the clock speed. return; } @@ -120,41 +150,65 @@ void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq) { Wire.end(); } #endif // ifdef ESP32 + + #ifndef BUILD_NO_DEBUG + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { + addLog(LOG_LEVEL_DEBUG, strformat(F("I2C : SDA: %d, SCL: %d, Clock: %d (%d) (Stretch: %d)"), + sda, scl, clockFreq, lastI2CClockSpeed, clockStretch)); + } + #endif // ifndef BUILD_NO_DEBUG + + if ((sda != last_sda) || (scl != last_scl) || (clockFreq != lastI2CClockSpeed)) { + #ifdef ESP32 + Wire.begin(sda, scl, clockFreq); // Will only set the clock when not yet initialized. + Wire.setClock(clockFreq); + #else // ifdef ESP32 + Wire.begin(sda, scl); + Wire.setClock(clockFreq); + #endif // ifdef ESP32 + } lastI2CClockSpeed = clockFreq; last_scl = scl; last_sda = sda; - #ifdef ESP32 - Wire.begin(sda, scl, clockFreq); // Will only set the clock when not yet initialized. - Wire.setClock(clockFreq); - #else // ifdef ESP32 - Wire.begin(sda, scl); - Wire.setClock(clockFreq); - #endif // ifdef ESP32 + + if (clockStretch != last_stretch) { + #if defined(ESP8266) + Wire.setClockStretchLimit(clockStretch); + #endif // if defined(ESP8266) + #ifdef ESP32 + Wire.setTimeOut(clockStretch); + #endif // ifdef ESP32 + last_stretch = clockStretch; + } } #if FEATURE_I2CMULTIPLEXER // Check if the I2C Multiplexer is enabled -bool isI2CMultiplexerEnabled() { - return Settings.I2C_Multiplexer_Type != I2C_MULTIPLEXER_NONE - && Settings.I2C_Multiplexer_Addr != -1; +bool isI2CMultiplexerEnabled(uint8_t i2cBus) { + return Settings.getI2CMultiplexerType(i2cBus) != I2C_MULTIPLEXER_NONE + && Settings.getI2CMultiplexerAddr(i2cBus) != -1; } // Reset the I2C Multiplexer, if a pin is assigned for that. Pulled to low to force a reset. -void I2CMultiplexerReset() { - if (Settings.I2C_Multiplexer_ResetPin != -1) { - digitalWrite(Settings.I2C_Multiplexer_ResetPin, LOW); +void I2CMultiplexerReset(uint8_t i2cBus) { + const uint8_t Multiplexer_ResetPin = Settings.getI2CMultiplexerResetPin(i2cBus); + + if (Multiplexer_ResetPin != -1) { + digitalWrite(Multiplexer_ResetPin, LOW); delay(1); // minimum requirement of low for a proper reset seems to be about 6 nsec, so 1 msec should be more than sufficient - digitalWrite(Settings.I2C_Multiplexer_ResetPin, HIGH); + digitalWrite(Multiplexer_ResetPin, HIGH); } } // Shift the bit in the right position when selecting a single channel -uint8_t I2CMultiplexerShiftBit(uint8_t i) { - uint8_t toWrite = 0; +uint8_t I2CMultiplexerShiftBit(uint8_t i2cBus, uint8_t i) { + uint8_t toWrite = 0; + const int8_t Multiplexer_Type = Settings.getI2CMultiplexerType(i2cBus); - switch (Settings.I2C_Multiplexer_Type) { + switch (Multiplexer_Type) { case I2C_MULTIPLEXER_TCA9543A: // TCA9543/6/8 addressing case I2C_MULTIPLEXER_TCA9546A: case I2C_MULTIPLEXER_TCA9548A: @@ -181,48 +235,55 @@ void I2CMultiplexerSelectByTaskIndex(taskIndex_t taskIndex) { uint8_t toWrite = 0; + # if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + # else // if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = 0; + # endif // if FEATURE_I2C_MULTIPLE + if (!bitRead(Settings.I2C_Flags[taskIndex], I2C_FLAGS_MUX_MULTICHANNEL)) { uint8_t i = Settings.I2C_Multiplexer_Channel[taskIndex]; if (i > 7) { return; } - toWrite = I2CMultiplexerShiftBit(i); + toWrite = I2CMultiplexerShiftBit(i2cBus, i); } else { toWrite = Settings.I2C_Multiplexer_Channel[taskIndex]; // Bitpattern is already correctly stored } - SetI2CMultiplexer(toWrite); + SetI2CMultiplexer(i2cBus, toWrite); } -void I2CMultiplexerSelect(uint8_t i) { +void I2CMultiplexerSelect(uint8_t i2cBus, uint8_t i) { if (i > 7) { return; } - uint8_t toWrite = I2CMultiplexerShiftBit(i); + uint8_t toWrite = I2CMultiplexerShiftBit(i2cBus, i); - SetI2CMultiplexer(toWrite); + SetI2CMultiplexer(i2cBus, toWrite); } -void I2CMultiplexerOff() { - SetI2CMultiplexer(0); // no channel selected +void I2CMultiplexerOff(uint8_t i2cBus) { + SetI2CMultiplexer(i2cBus, 0); // no channel selected } -void SetI2CMultiplexer(uint8_t toWrite) { - if (isI2CMultiplexerEnabled()) { - // FIXME TD-er: Must check to see if we can cache the value so only change it when needed. +void SetI2CMultiplexer(uint8_t i2cBus, uint8_t toWrite) { + if (isI2CMultiplexerEnabled(i2cBus)) { + const int8_t Multiplexer_Addr = Settings.getI2CMultiplexerAddr(i2cBus); - I2C_write8(Settings.I2C_Multiplexer_Addr, toWrite); + I2C_write8(Multiplexer_Addr, toWrite); // FIXME TD-er: We must check if the chip needs some time to set the output. (delay?) } } -uint8_t I2CMultiplexerMaxChannels() { - uint channels = 0; +uint8_t I2CMultiplexerMaxChannels(uint8_t i2cBus) { + uint channels = 0; + int8_t Multiplexer_Type = Settings.getI2CMultiplexerType(i2cBus); - switch (Settings.I2C_Multiplexer_Type) { - case I2C_MULTIPLEXER_TCA9548A: channels = 8; break; // TCA9548A has 8 channels - case I2C_MULTIPLEXER_TCA9546A: channels = 4; break; // TCA9546A has 4 channels - case I2C_MULTIPLEXER_PCA9540: channels = 2; break; // PCA9540 has 2 channels - case I2C_MULTIPLEXER_TCA9543A: channels = 2; break; // TCA9543A has 2 channels + switch (Multiplexer_Type) { + case I2C_MULTIPLEXER_TCA9548A: channels = 8; break; // TCA9548A has 8 channels + case I2C_MULTIPLEXER_TCA9546A: channels = 4; break; // TCA9546A has 4 channels + case I2C_MULTIPLEXER_PCA9540: // PCA9540 has 2 channels + case I2C_MULTIPLEXER_TCA9543A: channels = 2; break; // TCA9543A has 2 channels } return channels; } @@ -232,9 +293,15 @@ uint8_t I2CMultiplexerMaxChannels() { bool I2CMultiplexerPortSelectedForTask(taskIndex_t taskIndex) { if (!validTaskIndex(taskIndex)) { return false; } - if (!isI2CMultiplexerEnabled()) { return false; } + # if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + # else // if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = 0; + # endif // if FEATURE_I2C_MULTIPLE + + if (!isI2CMultiplexerEnabled(i2cBus)) { return false; } return (!bitRead(Settings.I2C_Flags[taskIndex], I2C_FLAGS_MUX_MULTICHANNEL) && Settings.I2C_Multiplexer_Channel[taskIndex] != -1) || (bitRead(Settings.I2C_Flags[taskIndex], I2C_FLAGS_MUX_MULTICHANNEL) && Settings.I2C_Multiplexer_Channel[taskIndex] != 0); } -#endif // if FEATURE_I2CMULTIPLEXER \ No newline at end of file +#endif // if FEATURE_I2CMULTIPLEXER diff --git a/src/src/Helpers/Hardware_I2C.h b/src/src/Helpers/Hardware_I2C.h index a4535af01b..22b3d3947b 100644 --- a/src/src/Helpers/Hardware_I2C.h +++ b/src/src/Helpers/Hardware_I2C.h @@ -7,32 +7,35 @@ void initI2C(); -void I2CSelectHighClockSpeed(); -void I2CSelectLowClockSpeed(); -void I2CSelect_Max100kHz_ClockSpeed(); -void I2CSelectClockSpeed(uint32_t clockFreq); -void I2CForceResetBus_swap_pins(uint8_t address); +void I2CSelectHighClockSpeed(uint8_t i2cBus); +void I2CSelectLowClockSpeed(uint8_t i2cBus); +void I2CSelect_Max100kHz_ClockSpeed(uint8_t i2cBus); +void I2CSelectClockSpeed(uint8_t i2cBus, + uint32_t clockFreq); +void I2CForceResetBus_swap_pins(uint8_t i2cBus, + uint8_t address); void I2CBegin(int8_t sda, int8_t scl, - uint32_t clockFreq); + uint32_t clockFreq, + uint32_t clockStretch); #if FEATURE_I2CMULTIPLEXER -bool isI2CMultiplexerEnabled(); +bool isI2CMultiplexerEnabled(uint8_t i2cBus); void I2CMultiplexerSelectByTaskIndex(taskIndex_t taskIndex); -void I2CMultiplexerSelect(uint8_t i); +void I2CMultiplexerSelect(uint8_t i2cBus, + uint8_t i); -void I2CMultiplexerOff(); +void I2CMultiplexerOff(uint8_t i2cBus); -void SetI2CMultiplexer(uint8_t toWrite); +void SetI2CMultiplexer(uint8_t i2cBus, + uint8_t toWrite); -uint8_t I2CMultiplexerMaxChannels(); +uint8_t I2CMultiplexerMaxChannels(uint8_t i2cBus); -void I2CMultiplexerReset(); +void I2CMultiplexerReset(uint8_t i2cBus); bool I2CMultiplexerPortSelectedForTask(taskIndex_t taskIndex); #endif // if FEATURE_I2CMULTIPLEXER - - -#endif \ No newline at end of file +#endif // ifndef HELPERS_HARDWARE_I2C_H diff --git a/src/src/Helpers/Hardware_device_info.cpp b/src/src/Helpers/Hardware_device_info.cpp index 76ba7d2f33..932d5660df 100644 --- a/src/src/Helpers/Hardware_device_info.cpp +++ b/src/src/Helpers/Hardware_device_info.cpp @@ -36,7 +36,7 @@ # endif // if ESP_IDF_VERSION_MAJOR == 4 -#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 +# if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 # if ESP_IDF_VERSION_MAJOR < 5 # define HAS_HALL_EFFECT_SENSOR 1 # else // if ESP_IDF_VERSION_MAJOR < 5 @@ -44,14 +44,15 @@ // Support for Hall Effect sensor was removed in ESP_IDF 5.x # define HAS_HALL_EFFECT_SENSOR 0 # endif // if ESP_IDF_VERSION_MAJOR < 5 -# else +# else // if CONFIG_IDF_TARGET_ESP32 # define HAS_HALL_EFFECT_SENSOR 0 -# endif +# endif // if CONFIG_IDF_TARGET_ESP32 # if ESP_IDF_VERSION_MAJOR >= 5 # include # include +# include # include # include @@ -164,10 +165,11 @@ esp32_chip_features getChipFeatures() { res.embeddedPSRAM = chip_info.features & CHIP_FEATURE_EMB_PSRAM; if (!res.embeddedFlash) { - const int32_t flash_cap = getEmbeddedFlashSize(); - if (flash_cap > 0) { - res.embeddedFlash = true; - } + const int32_t flash_cap = getEmbeddedFlashSize(); + + if (flash_cap > 0) { + res.embeddedFlash = true; + } } loaded = true; @@ -361,8 +363,8 @@ uint8_t getChipCores() { bool isESP8285() { return false; } -#endif +#endif // ifdef ESP32 String getChipRevision() { @@ -398,6 +400,26 @@ uint32_t getFreeSketchSpace() { return res; } +/********************************************************************************************\ + I2C support + \*********************************************************************************************/ +const uint8_t getI2CBusCount() { + #if !FEATURE_I2C_MULTIPLE + return 1u; + #else // if !FEATURE_I2C_MULTIPLE + + // Assume/expect IDF 5.x + # if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED + # if FEATURE_I2C_INTERFACE_3 + return 3u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) + # else // if FEATURE_I2C_INTERFACE_3 + return 2u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) + # endif // if FEATURE_I2C_INTERFACE_3 + # endif // if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED + #endif // if !FEATURE_I2C_MULTIPLE + return 0u; // Unexpected exit... +} + /********************************************************************************************\ PSRAM support \*********************************************************************************************/ @@ -447,13 +469,13 @@ bool CanUsePSRAM() { esp_chip_info_t chip_info; esp_chip_info(&chip_info); - if ((CHIP_ESP32 == chip_info.model) && -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) - (chip_info.revision < 300) -#else - (chip_info.revision < 3) -#endif - ) { + if ((CHIP_ESP32 == chip_info.model) && +# if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + (chip_info.revision < 300) +# else // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + (chip_info.revision < 3) +# endif // if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + ) { return false; } # if ESP_IDF_VERSION_MAJOR < 4 @@ -472,7 +494,6 @@ bool CanUsePSRAM() { # ifdef ESP32 const __FlashStringHelper* getChipModel() { - // https://www.espressif.com/en/products/socs // https://github.com/arendst/Tasmota/blob/1e6b78a957be538cf494f0e2dc49060d1cb0fe8b/tasmota/support_esp.ino#L579 @@ -515,6 +536,7 @@ const __FlashStringHelper* getChipModel() */ esp_chip_info_t chip_info; + esp_chip_info(&chip_info); uint32_t chip_model = chip_info.model; @@ -536,7 +558,8 @@ const __FlashStringHelper* getChipModel() return getChipModel(chip_model, chip_revision, pkg_version, single_core); } -#endif + +# endif // ifdef ESP32 #endif // ESP32 diff --git a/src/src/Helpers/Hardware_device_info.h b/src/src/Helpers/Hardware_device_info.h index b0340f9407..9f289a7803 100644 --- a/src/src/Helpers/Hardware_device_info.h +++ b/src/src/Helpers/Hardware_device_info.h @@ -95,6 +95,11 @@ uint32_t getSketchSize(); uint32_t getFreeSketchSpace(); +/********************************************************************************************\ + I2C support + \*********************************************************************************************/ +const uint8_t getI2CBusCount(); + /********************************************************************************************\ PSRAM support \*********************************************************************************************/ diff --git a/src/src/Helpers/I2C_access.cpp b/src/src/Helpers/I2C_access.cpp index 89d4be9fac..57ce0019b4 100644 --- a/src/src/Helpers/I2C_access.cpp +++ b/src/src/Helpers/I2C_access.cpp @@ -6,6 +6,10 @@ #include "../Helpers/ESPEasy_time_calc.h" #include "../Helpers/StringConverter.h" +#if FEATURE_I2C_MULTIPLE +# include "../WebServer/Markup_Forms.h" +#endif // if FEATURE_I2C_MULTIPLE + enum class I2C_clear_bus_state { Start, Wait_SCL_become_high, // Wait for 2.5 seconds for SCL to become high after enabling pull-up resistors @@ -292,7 +296,6 @@ uint16_t I2C_read16(uint8_t i2caddr, bool *is_ok) { return value; } - // **************************************************************************/ // Reads an 8 bit value from a register over I2C // **************************************************************************/ @@ -420,3 +423,49 @@ bool I2C_deviceCheck(uint8_t i2caddr, #endif // if FEATURE_I2C_DEVICE_CHECK #undef END_TRANSMISSION_FLAG + +#if FEATURE_I2C_MULTIPLE +void I2CInterfaceSelector(String label, + String id, + uint8_t choice) { + const uint8_t i2cMaxBusCount = (getI2CBusCount() >= 2 + ? ((Settings.isI2CEnabled(1) ? 1 : 0) + # if FEATURE_I2C_INTERFACE_3 + + (Settings.isI2CEnabled(2) ? 1 : 0) + # endif // if FEATURE_I2C_INTERFACE_3 + ) + : 0) + (Settings.isI2CEnabled(0) ? 1 : 0); + + if (i2cMaxBusCount > 1) { + static uint8_t i2cBusCount = 0; + static String i2cBusList[3]; + static int i2cBusNumbers[3]; + + if (i2cBusList[0].isEmpty() || (i2cBusCount != i2cMaxBusCount)) { + i2cBusCount = 0; + i2cBusList[i2cBusCount] = '1'; + i2cBusNumbers[i2cBusCount] = 0; + ++i2cBusCount; + + if ((getI2CBusCount() >= 2) && Settings.isI2CEnabled(1)) { + i2cBusList[i2cBusCount] = '2'; + i2cBusNumbers[i2cBusCount] = 1; + ++i2cBusCount; + } + # if FEATURE_I2C_INTERFACE_3 + + if ((getI2CBusCount() >= 3) && Settings.isI2CEnabled(2)) { + i2cBusList[i2cBusCount] = '3'; + i2cBusNumbers[i2cBusCount] = 2; + ++i2cBusCount; + } + # endif // if FEATURE_I2C_INTERFACE_3 + } + FormSelectorOptions selector(i2cBusCount, + i2cBusList, i2cBusNumbers); + selector.default_index = 0; + selector.addFormSelector(label, id, choice); + } +} + +#endif // if FEATURE_I2C_MULTIPLE diff --git a/src/src/Helpers/I2C_access.h b/src/src/Helpers/I2C_access.h index bc7ea5a42e..a43df258b2 100644 --- a/src/src/Helpers/I2C_access.h +++ b/src/src/Helpers/I2C_access.h @@ -149,4 +149,15 @@ bool I2C_deviceCheck(uint8_t i2caddr, uint8_t function = 0); #endif // if FEATURE_I2C_DEVICE_CHECK +#if FEATURE_I2C_MULTIPLE +#define I2C_PERIPHERAL_BUS_CLOCK 0 // bit-offset for I2C bus used for the RTC clock device +#define I2C_PERIPHERAL_BUS_WDT 3 // bit-offset for I2C bus used for the watchdog timer +#define I2C_PERIPHERAL_BUS_PCFMCP 6 // bit-offset for I2C bus used for PCF & MCP direct access +// #define I2C_PERIPHERAL_BUS_??? 9 // bit-offset for I2C bus used for the ??? + +void I2CInterfaceSelector(String label, + String id, + uint8_t choice); +#endif // if FEATURE_I2C_MULTIPLE + #endif // HELPERS_I2C_ACCESS_H diff --git a/src/src/Helpers/PeriodicalActions.cpp b/src/src/Helpers/PeriodicalActions.cpp index 4d444567d8..e6f94a89f8 100644 --- a/src/src/Helpers/PeriodicalActions.cpp +++ b/src/src/Helpers/PeriodicalActions.cpp @@ -172,6 +172,9 @@ void runOncePerSecond() // I2C Watchdog feed if (Settings.WDI2CAddress != 0) { + #if FEATURE_I2C_MULTIPLE + I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT)); // Select bus + #endif // if FEATURE_I2C_MULTIPLE I2C_write8(Settings.WDI2CAddress, 0xA5); } diff --git a/src/src/Helpers/StringGenerator_GPIO.cpp b/src/src/Helpers/StringGenerator_GPIO.cpp index e33823d1a5..21f93d9d42 100644 --- a/src/src/Helpers/StringGenerator_GPIO.cpp +++ b/src/src/Helpers/StringGenerator_GPIO.cpp @@ -258,7 +258,16 @@ const __FlashStringHelper* getConflictingUse(int gpio, PinSelectPurpose purpose) } if (includeI2C && Settings.isI2C_pin(gpio)) { - return (Settings.Pin_i2c_sda == gpio) ? F("I2C SDA") : F("I2C SCL"); + return ((Settings.Pin_i2c_sda == gpio) + #if FEATURE_I2C_MULTIPLE + || (Settings.Pin_i2c2_sda == gpio) + #if FEATURE_I2C_INTERFACE_3 + || (Settings.Pin_i2c3_sda == gpio) + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + ) + ? F("I2C SDA") : + F("I2C SCL"); } if (includeSPI && Settings.isSPI_pin(gpio)) { diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 5a46b09fd9..cdc3c903d8 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -20,6 +20,10 @@ #include "../Helpers/Hardware_defines.h" #include "../Helpers/StringConverter.h" +#if FEATURE_I2C_MULTIPLE +#include "../Helpers/I2C_access.h" +#endif + void setLogLevelFor(uint8_t destination, LabelType::Enum label) { setLogLevelFor(destination, getFormItemInt(getInternalLabel(label))); } @@ -82,12 +86,28 @@ void handle_advanced() { Settings.ExtTimeSource( static_cast(getFormItemInt(F("exttimesource"))) ); + #if FEATURE_I2C_MULTIPLE + if (getI2CBusCount() >= 2) { + set3BitToUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK, getFormItemInt(F("pi2cbusrtc"))); + set3BitToUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT, getFormItemInt(F("pi2cbuswdt"))); + } + #endif // if FEATURE_I2C_MULTIPLE Settings.DST = isFormItemChecked(F("dst")); Settings.WDI2CAddress = getFormItemInt(F("wdi2caddress")); #if FEATURE_SSDP Settings.UseSSDP = isFormItemChecked(F("usessdp")); #endif // if FEATURE_SSDP - Settings.WireClockStretchLimit = getFormItemInt(F("wireclockstretchlimit")); + Settings.WireClockStretchLimit = getFormItemInt(F("wirestretch")); + #if FEATURE_I2C_MULTIPLE + if (getI2CBusCount() >= 2) { + Settings.Wire2ClockStretchLimit = getFormItemInt(F("wire2stretch")); + } + #if FEATURE_I2C_INTERFACE_3 + if (getI2CBusCount() >= 3) { + Settings.Wire3ClockStretchLimit = getFormItemInt(F("wire3stretch")); + } + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE Settings.UseRules = isFormItemChecked(F("userules")); Settings.ConnectionFailuresThreshold = getFormItemInt(LabelType::CONNECTION_FAIL_THRESH); Settings.ArduinoOTAEnable = isFormItemChecked(F("arduinootaenable")); @@ -215,6 +235,14 @@ void handle_advanced() { if (Settings.ExtTimeSource() != ExtTimeSource_e::None) { addFormNote(concat(getLabel(LabelType::EXT_RTC_UTC_TIME), F(": ")) + getValue(LabelType::EXT_RTC_UTC_TIME)); } + #if FEATURE_I2C_MULTIPLE + { + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK); + I2CInterfaceSelector(F("Ext. Time Source I2C Interface"), + F("pi2cbusrtc"), + i2cBus); + } + #endif // if FEATURE_I2C_MULTIPLE #endif addFormSubHeader(F("DST Settings")); @@ -293,14 +321,34 @@ void handle_advanced() { addFormNumericBox(F("WD I2C Address"), F("wdi2caddress"), Settings.WDI2CAddress, 0, 127); addHtml(F(" (decimal)")); + #if FEATURE_I2C_MULTIPLE + { + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT); + I2CInterfaceSelector(F("WD I2C Interface"), + F("pi2cbuswdt"), + i2cBus); + } + #endif // if FEATURE_I2C_MULTIPLE - addFormNumericBox(F("I2C ClockStretchLimit"), F("wireclockstretchlimit"), Settings.WireClockStretchLimit); // TODO define limits + addFormNumericBox(F("I2C ClockStretchLimit"), F("wirestretch"), Settings.WireClockStretchLimit); // TODO define limits #ifdef ESP8266 addUnit(F("usec")); #endif #ifdef ESP32 addUnit(F("1/80 usec")); #endif + #if FEATURE_I2C_MULTIPLE + if (getI2CBusCount() >= 2) { + addFormNumericBox(concat(F("I2C ClockStretchLimit"), F(" Interface 2")), F("wire2stretch"), Settings.Wire2ClockStretchLimit); // TODO define limits + addUnit(F("1/80 usec")); + } + #if FEATURE_I2C_INTERFACE_3 + if (getI2CBusCount() >= 3) { + addFormNumericBox(concat(F("I2C ClockStretchLimit"), F(" Interface 3")), F("wire3stretch"), Settings.Wire3ClockStretchLimit); // TODO define limits + addUnit(F("1/80 usec")); + } + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE #if FEATURE_ARDUINO_OTA addFormCheckBox(F("Enable Arduino OTA"), F("arduinootaenable"), Settings.ArduinoOTAEnable); #endif // if FEATURE_ARDUINO_OTA diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index 7dcc202e43..3264232de8 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -31,6 +31,9 @@ # include "../Helpers/StringConverter.h" # include "../Helpers/StringGenerator_GPIO.h" +#if FEATURE_I2C_MULTIPLE +# include "../Helpers/Hardware_device_info.h" +#endif # include "../../_Plugin_Helper.h" @@ -273,18 +276,32 @@ void handle_devices_CopySubmittedSettings(taskIndex_t taskIndex, pluginID_t task if (device.Type == DEVICE_TYPE_I2C) { uint8_t flags = 0; + uint8_t i2cBus = 0; bitWrite(flags, I2C_FLAGS_SLOW_SPEED, isFormItemChecked(F("taskdeviceflags0"))); + #if FEATURE_I2C_MULTIPLE + if ((getI2CBusCount() >= 2) && (Settings.isI2CEnabled(1) + #if FEATURE_I2C_INTERFACE_3 + || Settings.isI2CEnabled(2) + #endif + ) + && !Device[DeviceIndex].I2CNoBusSelection + ) { + i2cBus = getFormItemInt(F("pi2cbus")); + set3BitToUL(flags, I2C_FLAGS_BUS_NUMBER, i2cBus); + } + #endif // if FEATURE_I2C_MULTIPLE + # if FEATURE_I2CMULTIPLEXER - if (isI2CMultiplexerEnabled()) { + if (isI2CMultiplexerEnabled(i2cBus)) { int multipleMuxPortsOption = getFormItemInt(F("taskdeviceflags1"), 0); bitWrite(flags, I2C_FLAGS_MUX_MULTICHANNEL, multipleMuxPortsOption == 1); if (multipleMuxPortsOption == 1) { uint8_t selectedPorts = 0; - for (int x = 0; x < I2CMultiplexerMaxChannels(); ++x) { + for (int x = 0; x < I2CMultiplexerMaxChannels(i2cBus); ++x) { bitWrite(selectedPorts, x, isFormItemChecked(concat(F("taskdeviceflag1ch"), x))); } Settings.I2C_Multiplexer_Channel[taskIndex] = selectedPorts; @@ -819,19 +836,24 @@ void format_I2C_port_description(taskIndex_t x) } # endif // if FEATURE_I2C_GET_ADDRESS # if FEATURE_I2CMULTIPLEXER + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[x], I2C_FLAGS_BUS_NUMBER); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE - if (isI2CMultiplexerEnabled() && I2CMultiplexerPortSelectedForTask(x)) { + if (isI2CMultiplexerEnabled(i2cBus) && I2CMultiplexerPortSelectedForTask(x)) { String mux; if (bitRead(Settings.I2C_Flags[x], I2C_FLAGS_MUX_MULTICHANNEL)) { // Multi-channel mux = F("
Multiplexer channel(s)"); uint8_t b = 0; // For adding lineBreaks - for (uint8_t c = 0; c < I2CMultiplexerMaxChannels(); c++) { + for (uint8_t c = 0; c < I2CMultiplexerMaxChannels(i2cBus); ++c) { if (bitRead(Settings.I2C_Multiplexer_Channel[x], c)) { mux += b == 0 ? F("
") : F(", "); b++; - mux += String(c); + mux += c; } } } else { // Single channel @@ -1209,7 +1231,14 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex addFormSubHeader(F("I2C options")); - if (!Settings.isI2CEnabled()) { + if (!Settings.isI2CEnabled(0) + #if FEATURE_I2C_MULTIPLE + && (getI2CBusCount() >= 2 && !Settings.isI2CEnabled(1)) + #if FEATURE_I2C_INTERFACE_3 + && (getI2CBusCount() >= 3 && !Settings.isI2CEnabled(2)) + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + ) { addFormNote(F("I2C Interface is not configured yet (Hardware page).")); } @@ -1221,11 +1250,20 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex if (Device[DeviceIndex].I2CMax100kHz) { addFormNote(F("This device is specified for max. 100 kHz operation!")); } - + uint8_t i2cBus = 0; + + #if FEATURE_I2C_MULTIPLE + if (!Device[DeviceIndex].I2CNoBusSelection) { // If the device doesn't disallow bus selection + i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + I2CInterfaceSelector(F("I2C Interface"), + F("pi2cbus"), + i2cBus); + } + #endif // if FEATURE_I2C_MULTIPLE # if FEATURE_I2CMULTIPLEXER // Show selector for an I2C multiplexer port if a multiplexer is configured - if (isI2CMultiplexerEnabled()) { + if (isI2CMultiplexerEnabled(i2cBus)) { bool multipleMuxPorts = bitRead(Settings.I2C_Flags[taskIndex], I2C_FLAGS_MUX_MULTICHANNEL); { const __FlashStringHelper *i2c_mux_channels[] = { @@ -1258,7 +1296,7 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex html_table_header(F("Channel"), 100); html_table_header(F("Enable"), 80); - for (int x = 0; x < I2CMultiplexerMaxChannels(); x++) { + for (int x = 0; x < I2CMultiplexerMaxChannels(i2cBus); x++) { if (x % 2 == 0) { html_TR(); } // Start a new row for every 2 channels html_TD(); addHtml(concat(F("Channel "), x)); @@ -1268,7 +1306,7 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex html_end_table(); } else { int taskDeviceI2CMuxPort = Settings.I2C_Multiplexer_Channel[taskIndex]; - const uint32_t mux_max = I2CMultiplexerMaxChannels(); + const uint32_t mux_max = I2CMultiplexerMaxChannels(i2cBus); String i2c_mux_portoptions[mux_max + 1]; int i2c_mux_portchoices[mux_max + 1]; i2c_mux_portoptions[0] = F("(Not connected via multiplexer)"); diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 093774d096..9dd457679d 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -20,6 +20,11 @@ #include "../Helpers/StringConverter.h" #include "../Helpers/StringGenerator_GPIO.h" +#if FEATURE_I2C_MULTIPLE +#include "../Helpers/I2C_access.h" +#include "../Helpers/Hardware_device_info.h" +#endif // if FEATURE_I2C_MULTIPLE + // ******************************************************************************** // Web Interface hardware page // ******************************************************************************** @@ -39,23 +44,68 @@ void handle_hardware() { Settings.Pin_status_led_Inversed = isFormItemChecked(F("pledi")); Settings.Pin_Reset = getFormItemInt(F("pres")); #if FEATURE_PLUGIN_PRIORITY - if (!isI2CPriorityTaskActive()) + if (!isI2CPriorityTaskActive(0)) #endif //if FEATURE_PLUGIN_PRIORITY { - Settings.Pin_i2c_sda = getFormItemInt(F("psda")); - Settings.Pin_i2c_scl = getFormItemInt(F("pscl")); + Settings.Pin_i2c_sda = getFormItemInt(F("psda0")); + Settings.Pin_i2c_scl = getFormItemInt(F("pscl0")); } - Settings.I2C_clockSpeed = getFormItemInt(F("pi2csp"), DEFAULT_I2C_CLOCK_SPEED); - Settings.I2C_clockSpeed_Slow = getFormItemInt(F("pi2cspslow"), DEFAULT_I2C_CLOCK_SPEED_SLOW); + Settings.I2C_clockSpeed = getFormItemInt(F("pi2csp0"), DEFAULT_I2C_CLOCK_SPEED); + Settings.I2C_clockSpeed_Slow = getFormItemInt(F("pi2cspslow0"), DEFAULT_I2C_CLOCK_SPEED_SLOW); #if FEATURE_I2CMULTIPLEXER - Settings.I2C_Multiplexer_Type = getFormItemInt(F("pi2cmuxtype")); + Settings.I2C_Multiplexer_Type = getFormItemInt(F("pi2cmuxtype0")); if (Settings.I2C_Multiplexer_Type != I2C_MULTIPLEXER_NONE) { - Settings.I2C_Multiplexer_Addr = getFormItemInt(F("pi2cmuxaddr")); + Settings.I2C_Multiplexer_Addr = getFormItemInt(F("pi2cmuxaddr0")); } else { Settings.I2C_Multiplexer_Addr = -1; } - Settings.I2C_Multiplexer_ResetPin = getFormItemInt(F("pi2cmuxreset")); + Settings.I2C_Multiplexer_ResetPin = getFormItemInt(F("pi2cmuxreset0")); #endif // if FEATURE_I2CMULTIPLEXER + #if FEATURE_I2C_MULTIPLE // No loop used here, to avoid adding setters to the SettingsStruct template code + if (getI2CBusCount() >= 2) { + #if FEATURE_PLUGIN_PRIORITY + if (!isI2CPriorityTaskActive(1)) + #endif //if FEATURE_PLUGIN_PRIORITY + { + Settings.Pin_i2c2_sda = getFormItemInt(F("psda1")); + Settings.Pin_i2c2_scl = getFormItemInt(F("pscl1")); + } + Settings.I2C2_clockSpeed = getFormItemInt(F("pi2csp1"), DEFAULT_I2C_CLOCK_SPEED); + Settings.I2C2_clockSpeed_Slow = getFormItemInt(F("pi2cspslow1"), DEFAULT_I2C_CLOCK_SPEED_SLOW); + #if FEATURE_I2CMULTIPLEXER + Settings.I2C2_Multiplexer_Type = getFormItemInt(F("pi2cmuxtype1")); + if (Settings.I2C2_Multiplexer_Type != I2C_MULTIPLEXER_NONE) { + Settings.I2C2_Multiplexer_Addr = getFormItemInt(F("pi2cmuxaddr1")); + } else { + Settings.I2C2_Multiplexer_Addr = -1; + } + Settings.I2C2_Multiplexer_ResetPin = getFormItemInt(F("pi2cmuxreset1")); + #endif // if FEATURE_I2CMULTIPLEXER + } + #if FEATURE_I2C_INTERFACE_3 + if (getI2CBusCount() >= 3) { + #if FEATURE_PLUGIN_PRIORITY + if (!isI2CPriorityTaskActive(2)) + #endif //if FEATURE_PLUGIN_PRIORITY + { + Settings.Pin_i2c3_sda = getFormItemInt(F("psda2")); + Settings.Pin_i2c3_scl = getFormItemInt(F("pscl2")); + } + Settings.I2C3_clockSpeed = getFormItemInt(F("pi2csp2"), DEFAULT_I2C_CLOCK_SPEED); + Settings.I2C3_clockSpeed_Slow = getFormItemInt(F("pi2cspslow2"), DEFAULT_I2C_CLOCK_SPEED_SLOW); + #if FEATURE_I2CMULTIPLEXER + Settings.I2C3_Multiplexer_Type = getFormItemInt(F("pi2cmuxtype2")); + if (Settings.I2C3_Multiplexer_Type != I2C_MULTIPLEXER_NONE) { + Settings.I2C3_Multiplexer_Addr = getFormItemInt(F("pi2cmuxaddr2")); + } else { + Settings.I2C3_Multiplexer_Addr = -1; + } + Settings.I2C3_Multiplexer_ResetPin = getFormItemInt(F("pi2cmuxreset2")); + #endif // if FEATURE_I2CMULTIPLEXER + } + #endif // if FEATURE_I2C_INTERFACE_3 + set3BitToUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP, getFormItemInt(F("pi2cbuspcf"))); + #endif // if FEATURE_I2C_MULTIPLE #ifdef ESP32 Settings.InitSPI = getFormItemInt(F("initspi"), static_cast(SPI_Options_e::None)); if (Settings.InitSPI == static_cast(SPI_Options_e::UserDefined)) { // User-define SPI GPIO pins @@ -116,76 +166,99 @@ void handle_hardware() { addFormPinSelect(PinSelectPurpose::Generic_input, formatGpioName_input(F("Switch")), F("pres"), Settings.Pin_Reset); addFormNote(F("Press about 10s for factory reset")); - addFormSubHeader(F("I2C Interface")); - #if FEATURE_PLUGIN_PRIORITY - if (isI2CPriorityTaskActive()) { - int pinnr = -1; - bool input, output, warning = false; - addFormNote(F("I2C GPIO pins can't be changed when an I2C Priority task is configured.")); - addRowLabel(formatGpioName_bidirectional(F("SDA"))); - getGpioInfo(Settings.Pin_i2c_sda, pinnr, input, output, warning); - addHtml(createGPIO_label(Settings.Pin_i2c_sda, pinnr, true, true, false)); - addRowLabel(formatGpioName_output(F("SCL"))); - getGpioInfo(Settings.Pin_i2c_scl, pinnr, input, output, warning); - addHtml(createGPIO_label(Settings.Pin_i2c_scl, pinnr, true, true, false)); - } else - #endif // if FEATURE_PLUGIN_PRIORITY - { - addFormPinSelectI2C(formatGpioName_bidirectional(F("SDA")), F("psda"), Settings.Pin_i2c_sda); - addFormPinSelectI2C(formatGpioName_output(F("SCL")), F("pscl"), Settings.Pin_i2c_scl); - } - addFormNumericBox(F("Clock Speed"), F("pi2csp"), Settings.I2C_clockSpeed, 100, 3400000); - addUnit(F("Hz")); - addFormNote(F("Use 100 kHz for old I2C devices, 400 kHz is max for most.")); - addFormNumericBox(F("Slow device Clock Speed"), F("pi2cspslow"), Settings.I2C_clockSpeed_Slow, 100, 3400000); - addUnit(F("Hz")); #if FEATURE_I2CMULTIPLEXER - addFormSubHeader(F("I2C Multiplexer")); - // Select the type of multiplexer to use - { - const __FlashStringHelper *i2c_muxtype_options[] = { - F("- None -"), - F("TCA9548a - 8 channel"), - F("TCA9546a - 4 channel"), - F("TCA9543a - 2 channel"), - F("PCA9540 - 2 channel (experimental)") - }; - const int i2c_muxtype_choices[] = { - -1, - I2C_MULTIPLEXER_TCA9548A, - I2C_MULTIPLEXER_TCA9546A, - I2C_MULTIPLEXER_TCA9543A, - I2C_MULTIPLEXER_PCA9540 - }; - const FormSelectorOptions selector(NR_ELEMENTS(i2c_muxtype_choices), - i2c_muxtype_options, i2c_muxtype_choices); - selector.addFormSelector(F("I2C Multiplexer type"), F("pi2cmuxtype"), Settings.I2C_Multiplexer_Type); + const __FlashStringHelper *i2c_muxtype_options[] = { + F("- None -"), + F("TCA9548a - 8 channel"), + F("TCA9546a - 4 channel"), + F("TCA9543a - 2 channel"), + F("PCA9540 - 2 channel (experimental)") + }; + const int i2c_muxtype_choices[] = { + I2C_MULTIPLEXER_NONE, + I2C_MULTIPLEXER_TCA9548A, + I2C_MULTIPLEXER_TCA9546A, + I2C_MULTIPLEXER_TCA9543A, + I2C_MULTIPLEXER_PCA9540 + }; + const FormSelectorOptions muxSelector(NR_ELEMENTS(i2c_muxtype_choices), + i2c_muxtype_options, i2c_muxtype_choices); + +// Select the I2C address for a port multiplexer + + String i2c_mux_options[9]; + int i2c_mux_choices[9]; + uint8_t mux_opt = 0; + i2c_mux_options[mux_opt] = F("- None -"); + i2c_mux_choices[mux_opt] = I2C_MULTIPLEXER_NONE; + mux_opt++; + for (int8_t x = 0; x < 8; x++) { + i2c_mux_options[mux_opt] = formatToHex_decimal(0x70 + x); + if (x == 0) { // PCA9540 has a fixed address 0f 0x70 + i2c_mux_options[mux_opt] += F(" [TCA9543a/6a/8a, PCA9540]"); + } else if (x < 4) { + i2c_mux_options[mux_opt] += F(" [TCA9543a/6a/8a]"); + } else { + i2c_mux_options[mux_opt] += F(" [TCA9546a/8a]"); + } + i2c_mux_choices[mux_opt] = 0x70 + x; + mux_opt++; } - // Select the I2C address for a port multiplexer + const FormSelectorOptions addrSelector(mux_opt, i2c_mux_options, i2c_mux_choices); + #endif // if FEATURE_I2CMULTIPLEXER + + uint8_t i2cBus = 0; + #if FEATURE_I2C_MULTIPLE + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) + #endif // if FEATURE_I2C_MULTIPLE { - String i2c_mux_options[9]; - int i2c_mux_choices[9]; - uint8_t mux_opt = 0; - i2c_mux_options[mux_opt] = F("- None -"); - i2c_mux_choices[mux_opt] = I2C_MULTIPLEXER_NONE; - for (int8_t x = 0; x < 8; x++) { - mux_opt++; - i2c_mux_options[mux_opt] = formatToHex_decimal(0x70 + x); - if (x == 0) { // PCA9540 has a fixed address 0f 0x70 - i2c_mux_options[mux_opt] += F(" [TCA9543a/6a/8a, PCA9540]"); - } else if (x < 4) { - i2c_mux_options[mux_opt] += F(" [TCA9543a/6a/8a]"); - } else { - i2c_mux_options[mux_opt] += F(" [TCA9546a/8a]"); - } - i2c_mux_choices[mux_opt] = 0x70 + x; + #if !FEATURE_I2C_MULTIPLE + addFormSubHeader(F("I2C Interface")); + #else // if !FEATURE_I2C_MULTIPLE + addFormSubHeader(strformat(F("I2C Interface %u"), i2cBus + 1)); + #endif // if !FEATURE_I2C_MULTIPLE + #if FEATURE_PLUGIN_PRIORITY + if (isI2CPriorityTaskActive(i2cBus)) { + I2CShowSdaSclReadonly(Settings.getI2CSdaPin(i2cBus), Settings.getI2CSclPin(i2cBus), i2cBus); + } else + #endif // if FEATURE_PLUGIN_PRIORITY + { + addFormPinSelectI2C(formatGpioName_bidirectional(F("SDA")), strformat(F("psda%u"), i2cBus), Settings.getI2CSdaPin(i2cBus)); + addFormPinSelectI2C(formatGpioName_output(F("SCL")), strformat(F("pscl%u"), i2cBus), Settings.getI2CSclPin(i2cBus)); + } + addFormNumericBox(F("Clock Speed"), strformat(F("pi2csp%u"), i2cBus), Settings.getI2CClockSpeed(i2cBus), 100, 3400000); + addUnit(F("Hz")); + addFormNote(F("Use 100 kHz for old I2C devices, 400 kHz is max for most.")); + addFormNumericBox(F("Slow device Clock Speed"), strformat(F("pi2cspslow%u"), i2cBus), Settings.getI2CClockSpeedSlow(i2cBus), 100, 3400000); + addUnit(F("Hz")); + #if FEATURE_I2CMULTIPLEXER + #if !FEATURE_I2C_MULTIPLE + addFormSubHeader(F("I2C Multiplexer")); + #else // if !FEATURE_I2C_MULTIPLE + addFormSubHeader(strformat(F("I2C Multiplexer %u"), i2cBus + 1)); + #endif // if FEATURE_I2C_MULTIPLE + // Select the type of multiplexer to use + { + muxSelector.addFormSelector(F("I2C Multiplexer type"), strformat(F("pi2cmuxtype%u"), i2cBus), Settings.getI2CMultiplexerType(i2cBus)); + addrSelector.addFormSelector(F("I2C Multiplexer address"), strformat(F("pi2cmuxaddr%u"), i2cBus), Settings.getI2CMultiplexerAddr(i2cBus)); + // addFormPinSelect(PinSelectPurpose::Generic_output, formatGpioName_output_optional(F("Reset")), strformat(F("pi2cmuxreset%u"), i2cBus), Settings.getI2CMultiplexerResetPin(i2cBus)); + const String id = strformat(F("pi2cmuxreset%u"), i2cBus); + addRowLabel_tr_id(formatGpioName_output_optional(F("Reset")), id); + addPinSelect(PinSelectPurpose::Generic_output, id, Settings.getI2CMultiplexerResetPin(i2cBus)); + addFormNote(F("Will be pulled low to force a reset. Reset is not available on PCA9540.")); } - const FormSelectorOptions selector(mux_opt + 1, i2c_mux_options, i2c_mux_choices); - selector.addFormSelector(F("I2C Multiplexer address"), F("pi2cmuxaddr"), Settings.I2C_Multiplexer_Addr); + #endif // if FEATURE_I2CMULTIPLEXER } - addFormPinSelect(PinSelectPurpose::Generic_output, formatGpioName_output_optional(F("Reset")), F("pi2cmuxreset"), Settings.I2C_Multiplexer_ResetPin); - addFormNote(F("Will be pulled low to force a reset. Reset is not available on PCA9540.")); - #endif // if FEATURE_I2CMULTIPLEXER + #if FEATURE_I2C_MULTIPLE + if (getI2CBusCount() >= 2) { + addFormSubHeader(F("PCF & MCP Direct I/O")); + const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP); + I2CInterfaceSelector(F("I2C Interface"), + F("pi2cbuspcf"), + i2cBus); + + } + #endif // if FEATURE_I2C_MULTIPLE // SPI Init addFormSubHeader(F("SPI Interface")); @@ -388,13 +461,25 @@ void handle_hardware() { } #if FEATURE_PLUGIN_PRIORITY -bool isI2CPriorityTaskActive() { +bool isI2CPriorityTaskActive(uint8_t i2cBus) { bool hasI2CPriorityTask = false; for (taskIndex_t taskIndex = 0; taskIndex < TASKS_MAX && !hasI2CPriorityTask; taskIndex++) { - hasI2CPriorityTask |= isPluginI2CPowerManager_from_TaskIndex(taskIndex); + hasI2CPriorityTask |= isPluginI2CPowerManager_from_TaskIndex(taskIndex, i2cBus); } return hasI2CPriorityTask; } + +void I2CShowSdaSclReadonly(int8_t i2c_sda, int8_t i2c_scl, uint8_t i2cBus) { + int pinnr = -1; + bool input, output, warning = false; + addFormNote(strformat(F("I2C (%d) GPIO pins can't be changed when an I2C Priority task is configured."), i2cBus + 1)); + addRowLabel(formatGpioName_bidirectional(F("SDA"))); + getGpioInfo(i2c_sda, pinnr, input, output, warning); + addHtml(createGPIO_label(i2c_sda, pinnr, true, true, false)); + addRowLabel(formatGpioName_output(F("SCL"))); + getGpioInfo(i2c_scl, pinnr, input, output, warning); + addHtml(createGPIO_label(i2c_scl, pinnr, true, true, false)); +} #endif // if FEATURE_PLUGIN_PRIORITY #endif // ifdef WEBSERVER_HARDWARE diff --git a/src/src/WebServer/HardwarePage.h b/src/src/WebServer/HardwarePage.h index eac8cf9e93..fa42a9554b 100644 --- a/src/src/WebServer/HardwarePage.h +++ b/src/src/WebServer/HardwarePage.h @@ -10,9 +10,12 @@ // ******************************************************************************** void handle_hardware(); -#if FEATURE_PLUGIN_PRIORITY -bool isI2CPriorityTaskActive(); -#endif // if FEATURE_PLUGIN_PRIORITY +# if FEATURE_PLUGIN_PRIORITY +bool isI2CPriorityTaskActive(uint8_t i2cBus); +void I2CShowSdaSclReadonly(int8_t i2c_sda, + int8_t i2c_scl, + uint8_t i2cBus); +# endif // if FEATURE_PLUGIN_PRIORITY #endif // ifdef WEBSERVER_HARDWARE -#endif \ No newline at end of file +#endif // ifndef WEBSERVER_WEBSERVER_HARDWAREPAGE_H diff --git a/src/src/WebServer/I2C_Scanner.cpp b/src/src/WebServer/I2C_Scanner.cpp index a01a40c6ce..d6b6655bfd 100644 --- a/src/src/WebServer/I2C_Scanner.cpp +++ b/src/src/WebServer/I2C_Scanner.cpp @@ -23,6 +23,7 @@ // ******************************************************************************** int scanI2CbusForDevices_json( // Utility function for scanning the I2C bus for valid devices, with JSON output + uint8_t i2cBus, int8_t muxAddr , int8_t channel , int nDevices @@ -117,30 +118,52 @@ void handle_i2cscanner_json() { json_open(true); int nDevices = 0; + #ifdef ESP8266 + #endif + #if !FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = 0; + #else + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) + #endif + { + if (Settings.isI2CEnabled(i2cBus)) + { + I2CSelect_Max100kHz_ClockSpeed(i2cBus); // Always scan in low speed to also find old/slow devices + #if FEATURE_I2CMULTIPLEXER + int8_t Multiplexer_Addr = Settings.I2C_Multiplexer_Addr; // TODO Move to SettingsStruct + #if FEATURE_I2C_MULTIPLE + if (i2cBus == 1) { + Multiplexer_Addr = Settings.I2C2_Multiplexer_Addr; + } + #if FEATURE_I2C_INTERFACE_3 + else if (i2cBus == 2) { + Multiplexer_Addr = Settings.I2C3_Multiplexer_Addr; + } + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + i2c_addresses_t mainBusDevices; + mainBusDevices.resize(128); + for (int i = 0; i < 128; i++) { + mainBusDevices[i] = false; + } + nDevices = scanI2CbusForDevices_json(i2cBus, Multiplexer_Addr, -1, nDevices, mainBusDevices); // Channel -1 = standard I2C bus + #else // if FEATURE_I2CMULTIPLEXER + nDevices = scanI2CbusForDevices_json(0, -1, -1, nDevices); // Standard scan + #endif // if FEATURE_I2CMULTIPLEXER - I2CSelect_Max100kHz_ClockSpeed(); // Always scan in low speed to also find old/slow devices - #if FEATURE_I2CMULTIPLEXER - i2c_addresses_t mainBusDevices; - mainBusDevices.resize(128); - for (int i = 0; i < 128; i++) { - mainBusDevices[i] = false; - } - nDevices = scanI2CbusForDevices_json(Settings.I2C_Multiplexer_Addr, -1, nDevices, mainBusDevices); // Channel -1 = standard I2C bus - #else // if FEATURE_I2CMULTIPLEXER - nDevices = scanI2CbusForDevices_json(-1, -1, nDevices); // Standard scan - #endif // if FEATURE_I2CMULTIPLEXER - - #if FEATURE_I2CMULTIPLEXER - if (isI2CMultiplexerEnabled()) { - uint8_t mux_max = I2CMultiplexerMaxChannels(); - for (int8_t channel = 0; channel < mux_max; channel++) { - I2CMultiplexerSelect(channel); - nDevices += scanI2CbusForDevices_json(Settings.I2C_Multiplexer_Addr, channel, nDevices, mainBusDevices); // Specific channels + #if FEATURE_I2CMULTIPLEXER + if (isI2CMultiplexerEnabled(i2cBus)) { + uint8_t mux_max = I2CMultiplexerMaxChannels(i2cBus); + for (int8_t channel = 0; channel < mux_max; channel++) { + I2CMultiplexerSelect(i2cBus, channel); + nDevices += scanI2CbusForDevices_json(i2cBus, Multiplexer_Addr, channel, nDevices, mainBusDevices); // Specific channels + } + I2CMultiplexerOff(i2cBus); + } + #endif // if FEATURE_I2CMULTIPLEXER } - I2CMultiplexerOff(); } - #endif // if FEATURE_I2CMULTIPLEXER - I2CSelectHighClockSpeed(); // Reset bus to standard speed + I2CSelectHighClockSpeed(0); // Reset bus to standard speed json_close(true); TXBuffer.endStream(); @@ -383,6 +406,7 @@ String getKnownI2Cdevice(uint8_t address) { } int scanI2CbusForDevices( // Utility function for scanning the I2C bus for valid devices, with HTML table output + uint8_t i2cBus, int8_t muxAddr , int8_t channel , int nDevices @@ -447,7 +471,7 @@ int scanI2CbusForDevices( // Utility function for scanning the I2C bus for valid html_TR_TD(); addHtml(F("SDA low at address ")); addHtml(formatToHex(address, 2)); - I2CForceResetBus_swap_pins(address); + I2CForceResetBus_swap_pins(i2cBus, address); addHtml(F(" Reset bus attempted")); break; } @@ -459,7 +483,6 @@ int scanI2CbusForDevices( // Utility function for scanning the I2C bus for valid return nDevices; } -// FIXME TD-er: Query all included plugins for their supported addresses (return name of plugin) void handle_i2cscanner() { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("handle_i2cscanner")); @@ -470,49 +493,71 @@ void handle_i2cscanner() { TXBuffer.startStream(); sendHeadandTail_stdtemplate(_HEAD); - html_table_class_multirow(); - #if FEATURE_I2CMULTIPLEXER - if (isI2CMultiplexerEnabled()) { - html_table_header(F("I2C bus")); - } - #endif // if FEATURE_I2CMULTIPLEXER - html_table_header(F("I2C Addresses in use")); - html_table_header(F("Supported devices")); - - if (Settings.isI2CEnabled()) { - int nDevices = 0; - I2CSelect_Max100kHz_ClockSpeed(); // Scan bus using low speed + int nDevices = 0; + #if !FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = 0; + #else // if !FEATURE_I2C_MULTIPLE + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) + #endif // if !FEATURE_I2C_MULTIPLE + if (Settings.isI2CEnabled(i2cBus)) + { + html_table_class_multirow(); + #if FEATURE_I2C_MULTIPLE + html_table_header(strformat(F("I2C interface %d"), i2cBus + 1)); + html_TR(); + #endif // if FEATURE_I2C_MULTIPLE #if FEATURE_I2CMULTIPLEXER - i2c_addresses_t mainBusDevices; - mainBusDevices.resize(128); - for (int i = 0; i < 128; i++) { - mainBusDevices[i] = false; + if (isI2CMultiplexerEnabled(i2cBus)) { + html_table_header(F("I2C multiplexer channel")); } - nDevices = scanI2CbusForDevices(Settings.I2C_Multiplexer_Addr, -1, nDevices, mainBusDevices); // Channel -1 = standard I2C bus - #else // if FEATURE_I2CMULTIPLEXER - nDevices = scanI2CbusForDevices(-1, -1, nDevices); // Standard scan #endif // if FEATURE_I2CMULTIPLEXER + html_table_header(F("I2C Addresses found")); + html_table_header(F("Supported devices")); - #if FEATURE_I2CMULTIPLEXER - if (isI2CMultiplexerEnabled()) { - uint8_t mux_max = I2CMultiplexerMaxChannels(); - for (int8_t channel = 0; channel < mux_max; channel++) { - I2CMultiplexerSelect(channel); - nDevices += scanI2CbusForDevices(Settings.I2C_Multiplexer_Addr, channel, nDevices, mainBusDevices); + if (Settings.isI2CEnabled(i2cBus)) { + I2CSelect_Max100kHz_ClockSpeed(i2cBus); // Scan bus using low speed + #if FEATURE_I2CMULTIPLEXER + i2c_addresses_t mainBusDevices; + mainBusDevices.resize(128); + for (int i = 0; i < 128; i++) { + mainBusDevices[i] = false; + } + int8_t Multiplexer_Addr = Settings.I2C_Multiplexer_Addr; + #if FEATURE_I2C_MULTIPLE + if (i2cBus == 1) { + Multiplexer_Addr = Settings.I2C2_Multiplexer_Addr; + } + #if FEATURE_I2C_INTERFACE_3 + else if (i2cBus == 2) { + Multiplexer_Addr = Settings.I2C3_Multiplexer_Addr; + } + #endif // if FEATURE_I2C_INTERFACE_3 + #endif // if FEATURE_I2C_MULTIPLE + nDevices = scanI2CbusForDevices(i2cBus, Multiplexer_Addr, -1, nDevices, mainBusDevices); // Channel -1 = standard I2C bus + #else // if FEATURE_I2CMULTIPLEXER + nDevices = scanI2CbusForDevices(i2cBus, -1, -1, nDevices); // Standard scan + #endif // if FEATURE_I2CMULTIPLEXER + + #if FEATURE_I2CMULTIPLEXER + if (isI2CMultiplexerEnabled(i2cBus)) { + uint8_t mux_max = I2CMultiplexerMaxChannels(i2cBus); + for (int8_t channel = 0; channel < mux_max; channel++) { + I2CMultiplexerSelect(i2cBus, channel); + nDevices += scanI2CbusForDevices(i2cBus, Multiplexer_Addr, channel, nDevices, mainBusDevices); + } + I2CMultiplexerOff(i2cBus); } - I2CMultiplexerOff(); + #endif // if FEATURE_I2CMULTIPLEXER + } else { + addHtml(strformat(F("I2C pins not configured for interface %d
"), i2cBus + 1)); } - #endif // if FEATURE_I2CMULTIPLEXER - I2CSelectHighClockSpeed(); // By default the bus is in standard speed + html_end_table(); + I2CSelectHighClockSpeed(0); // By default the bus is in standard speed if (nDevices == 0) { - addHtml(F("No I2C devices found")); + addHtml(F("No I2C devices found
")); } - } else { - addHtml(F("I2C pins not configured")); } - - html_end_table(); sendHeadandTail_stdtemplate(_TAIL); TXBuffer.endStream(); } diff --git a/src/src/WebServer/I2C_Scanner.h b/src/src/WebServer/I2C_Scanner.h index e609de5b12..5ac953d512 100644 --- a/src/src/WebServer/I2C_Scanner.h +++ b/src/src/WebServer/I2C_Scanner.h @@ -4,49 +4,50 @@ #include "../WebServer/common.h" - #ifdef WEBSERVER_I2C_SCANNER -#if FEATURE_I2CMULTIPLEXER -#include +# if FEATURE_I2CMULTIPLEXER +# include typedef std::vector i2c_addresses_t; -#endif // if FEATURE_I2CMULTIPLEXER +# endif // if FEATURE_I2CMULTIPLEXER -#ifdef WEBSERVER_NEW_UI +# ifdef WEBSERVER_NEW_UI // ******************************************************************************** // Web Interface I2C scanner // ******************************************************************************** int scanI2CbusForDevices_json( // Utility function for scanning the I2C bus for valid devices, with JSON output - int8_t muxAddr - , int8_t channel - , int nDevices - #if FEATURE_I2CMULTIPLEXER - , i2c_addresses_t &excludeDevices - #endif // if FEATURE_I2CMULTIPLEXER -); + uint8_t i2cBus, + int8_t muxAddr, + int8_t channel, + int nDevices + # if FEATURE_I2CMULTIPLEXER + , + i2c_addresses_t& excludeDevices + # endif // if FEATURE_I2CMULTIPLEXER + ); void handle_i2cscanner_json(); -#endif // WEBSERVER_NEW_UI +# endif // WEBSERVER_NEW_UI String getKnownI2Cdevice(uint8_t address); -int scanI2CbusForDevices( // Utility function for scanning the I2C bus for valid devices, with HTML table output - int8_t muxAddr - , int8_t channel - , int nDevices - #if FEATURE_I2CMULTIPLEXER - , i2c_addresses_t &excludeDevices - #endif // if FEATURE_I2CMULTIPLEXER -); +int scanI2CbusForDevices( // Utility function for scanning the I2C bus for valid devices, with HTML table output + uint8_t i2cBus, + int8_t muxAddr, + int8_t channel, + int nDevices + # if FEATURE_I2CMULTIPLEXER + , + i2c_addresses_t& excludeDevices + # endif // if FEATURE_I2CMULTIPLEXER + ); // FIXME TD-er: Query all included plugins for their supported addresses (return name of plugin) void handle_i2cscanner(); #endif // WEBSERVER_I2C_SCANNER - - -#endif \ No newline at end of file +#endif // ifndef WEBSERVER_WEBSERVER_I2C_SCANNER_H diff --git a/src/src/WebServer/JSON.cpp b/src/src/WebServer/JSON.cpp index e1df8668b6..5d03538d9f 100644 --- a/src/src/WebServer/JSON.cpp +++ b/src/src/WebServer/JSON.cpp @@ -516,12 +516,19 @@ void handle_json() } #if FEATURE_I2CMULTIPLEXER - if (Device[DeviceIndex].Type == DEVICE_TYPE_I2C && isI2CMultiplexerEnabled()) { + uint8_t i2cBus = 0; + #if FEATURE_I2C_MULTIPLE + i2cBus = get3BitFromUL(Settings.I2C_Flags[TaskIndex], I2C_FLAGS_BUS_NUMBER); + #endif + if (Device[DeviceIndex].Type == DEVICE_TYPE_I2C && isI2CMultiplexerEnabled(i2cBus)) { + #if FEATURE_I2C_MULTIPLE + stream_next_json_object_value(F("I2C_Interface"), static_cast(i2cBus + 1)); + #endif int8_t channel = Settings.I2C_Multiplexer_Channel[TaskIndex]; if (bitRead(Settings.I2C_Flags[TaskIndex], I2C_FLAGS_MUX_MULTICHANNEL)) { addHtml(F("\"I2CBus\" : [")); uint8_t b = 0; - for (uint8_t c = 0; c < I2CMultiplexerMaxChannels(); c++) { + for (uint8_t c = 0; c < I2CMultiplexerMaxChannels(i2cBus); ++c) { if (bitRead(channel, c)) { if (b > 0) { stream_comma_newline(); } b++; @@ -535,8 +542,7 @@ void handle_json() if (channel == -1){ stream_next_json_object_value(F("I2Cbus"), F("Standard I2C bus")); } else { - String i2cChannel = F("Multiplexer channel "); - i2cChannel += String(channel); + String i2cChannel = concat(F("Multiplexer channel "), channel); stream_next_json_object_value(F("I2Cbus"), i2cChannel); } } From c30cfee9df66b21998b6f6e250bb6c2725d366b2 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 30 Jan 2025 22:56:27 +0100 Subject: [PATCH 02/24] [I2C] Re-order I2C variables for better alignment, add (Custom) defaults --- src/Custom-sample.h | 4 ++++ src/src/CustomBuild/ESPEasyDefaults.h | 16 ++++++++++++++++ src/src/DataStructs/SettingsStruct.h | 18 +++++++++--------- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/Custom-sample.h b/src/Custom-sample.h index b27dbc43f0..9ac9a70763 100644 --- a/src/Custom-sample.h +++ b/src/Custom-sample.h @@ -113,12 +113,16 @@ #endif #ifdef ESP32 #define DEFAULT_PIN_I2C_SDA -1 // Undefined +#define DEFAULT_PIN_I2C2_SDA -1 // Undefined +#define DEFAULT_PIN_I2C3_SDA -1 // Undefined #endif #ifdef ESP8266 #define DEFAULT_PIN_I2C_SCL 5 #endif #ifdef ESP32 #define DEFAULT_PIN_I2C_SCL -1 // Undefined +#define DEFAULT_PIN_I2C3_SCL -1 // Undefined +#define DEFAULT_PIN_I2C3_SCL -1 // Undefined #endif #define DEFAULT_I2C_CLOCK_SPEED 400000 // Use 100 kHz if working with old I2C chips #define FEATURE_I2C_DEVICE_SCAN 1 diff --git a/src/src/CustomBuild/ESPEasyDefaults.h b/src/src/CustomBuild/ESPEasyDefaults.h index 389011813b..12cb7ec6d4 100644 --- a/src/src/CustomBuild/ESPEasyDefaults.h +++ b/src/src/CustomBuild/ESPEasyDefaults.h @@ -220,6 +220,14 @@ #define DEFAULT_PIN_I2C_SDA -1 // Undefined #endif #endif +#ifdef ESP32 +#ifndef DEFAULT_PIN_I2C2_SDA +#define DEFAULT_PIN_I2C2_SDA -1 // Undefined +#endif +#ifndef DEFAULT_PIN_I2C3_SDA +#define DEFAULT_PIN_I2C3_SDA -1 // Undefined +#endif +#endif #ifndef DEFAULT_PIN_I2C_SCL #ifdef ESP8266 #define DEFAULT_PIN_I2C_SCL 5 @@ -228,6 +236,14 @@ #define DEFAULT_PIN_I2C_SCL -1 // Undefined #endif #endif +#ifdef ESP32 +#ifndef DEFAULT_PIN_I2C2_SCL +#define DEFAULT_PIN_I2C2_SCL -1 // Undefined +#endif +#ifndef DEFAULT_PIN_I2C3_SCL +#define DEFAULT_PIN_I2C3_SCL -1 // Undefined +#endif +#endif #ifndef DEFAULT_I2C_CLOCK_SPEED #define DEFAULT_I2C_CLOCK_SPEED 400000 // Use 100 kHz if working with old I2C chips #endif diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index 95c8e8ce0b..033b5cb3a9 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -412,21 +412,21 @@ class SettingsStruct_tmpl uint8_t Notification[NOTIFICATION_MAX] = {0}; //notifications, point to a NPLUGIN id // FIXME TD-er: Must change to pluginID_t, but then also another check must be added since changing the pluginID_t will also render settings incompatible uint8_t TaskDeviceNumber[N_TASKS] = {0}; // The "plugin number" set at as task (e.g. 4 for P004_dallas) - int8_t Pin_i2c2_sda = -1; // DEFAULT_PIN_I2C2_SDA; // From here, storage borrowed from OLD_TaskDeviceID array - int8_t Pin_i2c2_scl = -1; // DEFAULT_PIN_I2C2_SCL; - int8_t Pin_i2c3_sda = -1; // DEFAULT_PIN_I2C3_SDA; - int8_t Pin_i2c3_scl = -1; // DEFAULT_PIN_I2C3_SCL; - uint32_t I2C2_clockSpeed = 400000; - uint32_t I2C2_clockSpeed_Slow = 100000; - uint32_t I2C3_clockSpeed = 400000; - uint32_t I2C3_clockSpeed_Slow = 100000; + int8_t Pin_i2c2_sda = DEFAULT_PIN_I2C2_SDA; // From here, storage borrowed from OLD_TaskDeviceID array + int8_t Pin_i2c2_scl = DEFAULT_PIN_I2C2_SCL; + int8_t Pin_i2c3_sda = DEFAULT_PIN_I2C3_SDA; + int8_t Pin_i2c3_scl = DEFAULT_PIN_I2C3_SCL; + uint32_t I2C2_clockSpeed = DEFAULT_I2C_CLOCK_SPEED; + uint32_t I2C2_clockSpeed_Slow = DEFAULT_I2C_CLOCK_SPEED_SLOW; + uint32_t I2C3_clockSpeed = DEFAULT_I2C_CLOCK_SPEED; + uint32_t I2C3_clockSpeed_Slow = DEFAULT_I2C_CLOCK_SPEED_SLOW; + uint16_t I2C_peripheral_bus = 0; int8_t I2C2_Multiplexer_Type = I2C_MULTIPLEXER_NONE; int8_t I2C2_Multiplexer_Addr = -1; int8_t I2C2_Multiplexer_ResetPin = -1; int8_t I2C3_Multiplexer_Type = I2C_MULTIPLEXER_NONE; int8_t I2C3_Multiplexer_Addr = -1; int8_t I2C3_Multiplexer_ResetPin = -1; - uint16_t I2C_peripheral_bus = 0; unsigned long Wire2ClockStretchLimit = 0; unsigned long Wire3ClockStretchLimit = 0; unsigned int OLD_TaskDeviceID[N_TASKS - 9] = {0}; //UNUSED: this can be reused From f8cba3c93466399145ae549a932eef9b4c503374 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 30 Jan 2025 22:59:42 +0100 Subject: [PATCH 03/24] [I2C] Add conversion to adjust defaults if all zeroes --- src/src/Helpers/ESPEasy_Storage.cpp | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index fb6c949f68..021fd98259 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -474,6 +474,44 @@ bool BuildFixes() #endif // if FEATURE_MQTT } + if (Settings.Build <= 21156) { // 2025-03-31 + // PR #5235 Add 2nd and 3rd I2C Interface + if ((Settings.Pin_i2c2_sda == 0) && + (Settings.Pin_i2c2_scl == 0)) { + Settings.Pin_i2c2_sda = DEFAULT_PIN_I2C2_SDA; + Settings.Pin_i2c2_scl = DEFAULT_PIN_I2C2_SCL; + } + if ((Settings.Pin_i2c3_sda == 0) && + (Settings.Pin_i2c3_scl == 0)) { + Settings.Pin_i2c3_sda = DEFAULT_PIN_I2C3_SDA; + Settings.Pin_i2c3_scl = DEFAULT_PIN_I2C3_SCL; + } + if ((Settings.I2C2_clockSpeed == 0) && + (Settings.I2C2_clockSpeed_Slow == 0)) { + Settings.I2C2_clockSpeed = DEFAULT_I2C_CLOCK_SPEED; + Settings.I2C2_clockSpeed_Slow = DEFAULT_I2C_CLOCK_SPEED_SLOW; + } + if ((Settings.I2C3_clockSpeed == 0) && + (Settings.I2C3_clockSpeed_Slow == 0)) { + Settings.I2C3_clockSpeed = DEFAULT_I2C_CLOCK_SPEED; + Settings.I2C3_clockSpeed_Slow = DEFAULT_I2C_CLOCK_SPEED_SLOW; + } + if ((Settings.I2C2_Multiplexer_Type == 0) && + (Settings.I2C2_Multiplexer_Addr == 0) && + (Settings.I2C2_Multiplexer_ResetPin == 0)) { + Settings.I2C2_Multiplexer_Type = I2C_MULTIPLEXER_NONE; + Settings.I2C2_Multiplexer_Addr = -1; + Settings.I2C2_Multiplexer_ResetPin = -1; + } + if ((Settings.I2C3_Multiplexer_Type == 0) && + (Settings.I2C3_Multiplexer_Addr == 0) && + (Settings.I2C3_Multiplexer_ResetPin == 0)) { + Settings.I2C3_Multiplexer_Type = I2C_MULTIPLEXER_NONE; + Settings.I2C3_Multiplexer_Addr = -1; + Settings.I2C3_Multiplexer_ResetPin = -1; + } + } + // Starting 2022/08/18 // Use get_build_nr() value for settings transitions. // This value will also be shown when building using PlatformIO, when showing the Compile time defines From 114161a5632cc8cbece21042bf137fab7b7ab2e1 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Thu, 30 Jan 2025 23:01:18 +0100 Subject: [PATCH 04/24] [I2C] Add more getters to SettingsStruct to simplify code --- src/_P017_PN532.ino | 2 +- src/_P139_AXP2101.ino | 2 +- src/_P166_GP8403.ino | 2 +- src/src/Commands/GPIO.cpp | 4 +- src/src/DataStructs/DeviceStruct.h | 6 ++ src/src/DataStructs/SettingsStruct.h | 7 +++ src/src/DataStructs_templ/SettingsStruct.cpp | 61 ++++++++++---------- src/src/Globals/Plugins.cpp | 6 +- src/src/Helpers/ESPEasy_time.cpp | 4 +- src/src/Helpers/Hardware_I2C.cpp | 6 +- src/src/Helpers/Hardware_device_info.cpp | 6 +- src/src/Helpers/I2C_access.h | 5 -- src/src/Helpers/PeriodicalActions.cpp | 2 +- src/src/WebServer/AdvancedConfigPage.cpp | 4 +- src/src/WebServer/DevicesPage.cpp | 8 +-- src/src/WebServer/HardwarePage.cpp | 2 +- src/src/WebServer/JSON.cpp | 2 +- 17 files changed, 68 insertions(+), 61 deletions(-) diff --git a/src/_P017_PN532.ino b/src/_P017_PN532.ino index 85ebe2424c..8634fea1be 100644 --- a/src/_P017_PN532.ino +++ b/src/_P017_PN532.ino @@ -242,7 +242,7 @@ bool P017_handle_timer_in(struct EventStruct *event) # endif // ifdef P017_DEBUG_LOGIC_ANALYZER_PIN // TODO: Clock stretching issue https://github.com/esp8266/Arduino/issues/1541 - if (Settings.isI2CEnabled(get3BitFromUL(Settings.I2C_Flags[event->TaskIndex], I2C_FLAGS_BUS_NUMBER)) + if (Settings.isI2CEnabled(Settings.getI2CInterface(event->TaskIndex)) && ((DIRECT_pinRead(Settings.Pin_i2c_sda) == 0) || (DIRECT_pinRead(Settings.Pin_i2c_scl) == 0))) { addLog(LOG_LEVEL_ERROR, F("PN532: BUS error")); diff --git a/src/_P139_AXP2101.ino b/src/_P139_AXP2101.ino index 36efbdab32..3cdffcb75a 100644 --- a/src/_P139_AXP2101.ino +++ b/src/_P139_AXP2101.ino @@ -257,7 +257,7 @@ boolean Plugin_139(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_INIT: { - if (Settings.isI2CEnabled(get3BitFromUL(Settings.I2C_Flags[event->TaskIndex], I2C_FLAGS_BUS_NUMBER))) { // FIXME + if (Settings.isI2CEnabled(Settings.getI2CInterface(event->TaskIndex))) { // FIXME P139_data_struct *P139_init = static_cast(getPluginTaskData(event->TaskIndex)); if (nullptr != P139_init) { diff --git a/src/_P166_GP8403.ino b/src/_P166_GP8403.ino index b543deeb48..f8c3251c76 100644 --- a/src/_P166_GP8403.ino +++ b/src/_P166_GP8403.ino @@ -214,7 +214,7 @@ boolean Plugin_166(uint8_t function, struct EventStruct *event, String& string) case PLUGIN_INIT: { - if (Settings.isI2CEnabled(get3BitFromUL(Settings.I2C_Flags[event->TaskIndex], I2C_FLAGS_BUS_NUMBER))) { + if (Settings.isI2CEnabled(Settings.getI2CInterface(event->TaskIndex))) { initPluginTaskData(event->TaskIndex, new (std::nothrow) P166_data_struct(P166_I2C_ADDRESS, static_cast(P166_MAX_VOLTAGE))); diff --git a/src/src/Commands/GPIO.cpp b/src/src/Commands/GPIO.cpp index c0d3c7ce63..f5eaa398d2 100644 --- a/src/src/Commands/GPIO.cpp +++ b/src/src/Commands/GPIO.cpp @@ -1224,7 +1224,7 @@ bool getGPIOPinStateValues(String& str) { #endif // if FEATURE_PINSTATE_EXTENDED #if FEATURE_I2C_MULTIPLE if (getI2CBusCount() >= 2) { - I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP)); + I2CSelectHighClockSpeed(Settings.getI2CInterfacePCFMCP()); } #endif // if FEATURE_I2C_MULTIPLE str = GPIO_MCP_Read(par1); @@ -1242,7 +1242,7 @@ bool getGPIOPinStateValues(String& str) { #endif // if FEATURE_PINSTATE_EXTENDED #if FEATURE_I2C_MULTIPLE if (getI2CBusCount() >= 2) { - I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP)); + I2CSelectHighClockSpeed(Settings.getI2CInterfacePCFMCP()); } #endif // if FEATURE_I2C_MULTIPLE str = GPIO_PCF_Read(par1); diff --git a/src/src/DataStructs/DeviceStruct.h b/src/src/DataStructs/DeviceStruct.h index 4c770f390d..9527834c35 100644 --- a/src/src/DataStructs/DeviceStruct.h +++ b/src/src/DataStructs/DeviceStruct.h @@ -40,6 +40,12 @@ #define I2C_FLAGS_MUX_MULTICHANNEL 1 // Allow multiple multiplexer channels when set #define I2C_FLAGS_BUS_NUMBER 2 // 3 bits. The I2C bus number to use (ESP32 only), 3 bits allow for future expansion +#if FEATURE_I2C_MULTIPLE +#define I2C_PERIPHERAL_BUS_CLOCK 0 // bit-offset for I2C bus used for the RTC clock device +#define I2C_PERIPHERAL_BUS_WDT 3 // bit-offset for I2C bus used for the watchdog timer +#define I2C_PERIPHERAL_BUS_PCFMCP 6 // bit-offset for I2C bus used for PCF & MCP direct access +// #define I2C_PERIPHERAL_BUS_??? 9 // bit-offset for I2C bus used for the ??? +#endif // if FEATURE_I2C_MULTIPLE /*********************************************************************************************\ diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index 033b5cb3a9..bd58371e99 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -317,12 +317,19 @@ class SettingsStruct_tmpl // Return true if I2C settings are correct bool isI2CEnabled(uint8_t i2cBus) const; + uint8_t getI2CInterface(taskIndex_t TaskIndex) const; int8_t getI2CSdaPin(uint8_t i2cBus) const; int8_t getI2CSclPin(uint8_t i2cBus) const; uint32_t getI2CClockSpeed(uint8_t i2cBus) const; uint32_t getI2CClockSpeedSlow(uint8_t i2cBus) const; uint32_t getI2CClockStretch(uint8_t i2cBus) const; + #if FEATURE_I2C_MULTIPLE + uint8_t getI2CInterfaceRTC() const; + uint8_t getI2CInterfaceWDT() const; + uint8_t getI2CInterfacePCFMCP() const; + #endif // if FEATURE_I2C_MULTIPLE + #if FEATURE_I2CMULTIPLEXER int8_t getI2CMultiplexerType(uint8_t i2cBus) const; int8_t getI2CMultiplexerAddr(uint8_t i2cBus) const; diff --git a/src/src/DataStructs_templ/SettingsStruct.cpp b/src/src/DataStructs_templ/SettingsStruct.cpp index 6e20e8422a..62df71cae4 100644 --- a/src/src/DataStructs_templ/SettingsStruct.cpp +++ b/src/src/DataStructs_templ/SettingsStruct.cpp @@ -966,39 +966,25 @@ bool SettingsStruct_tmpl::isSPI_valid() const { template bool SettingsStruct_tmpl::isI2C_pin(int8_t pin) const { if (pin < 0) { return false; } - return Pin_i2c_sda == pin || Pin_i2c_scl == pin - #if FEATURE_I2C_MULTIPLE - || ((getI2CBusCount() >= 2) && (Pin_i2c2_sda == pin || Pin_i2c2_scl == pin)) - #if FEATURE_I2C_INTERFACE_3 - || ((getI2CBusCount() >= 3) && (Pin_i2c3_sda == pin || Pin_i2c3_scl == pin)) - #endif // if FEATURE_I2C_INTERFACE_3 - #endif // if FEATURE_I2C_MULTIPLE - ; + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) { + if ((getI2CSdaPin(i2cBus) == pin) || (getI2CSclPin(i2cBus) == pin)) { + return true; + } + } + return false; } template bool SettingsStruct_tmpl::isI2CEnabled(uint8_t i2cBus) const { - if (0 == i2cBus) { - return (Pin_i2c_sda != -1) && - (Pin_i2c_scl != -1) && - (I2C_clockSpeed > 0) && - (I2C_clockSpeed_Slow > 0); - #if FEATURE_I2C_MULTIPLE - } else if (1 == i2cBus) { - return (Pin_i2c2_sda != -1) && - (Pin_i2c2_scl != -1) && - (I2C2_clockSpeed > 0) && - (I2C2_clockSpeed_Slow > 0); - #if FEATURE_I2C_INTERFACE_3 - } else { - return (Pin_i2c3_sda != -1) && - (Pin_i2c3_scl != -1) && - (I2C3_clockSpeed > 0) && - (I2C3_clockSpeed_Slow > 0); - #endif // if FEATURE_I2C_INTERFACE_3 - #endif // if FEATURE_I2C_MULTIPLE - } - return false; + return (getI2CSdaPin(i2cBus) != -1) && + (getI2CSclPin(i2cBus) != -1) && + (getI2CClockSpeed(i2cBus) > 0) && + (getI2CClockSpeedSlow(i2cBus) > 0); +} + +template +uint8_t SettingsStruct_tmpl::getI2CInterface(taskIndex_t TaskIndex) const { + return get3BitFromUL(I2C_Flags[TaskIndex], I2C_FLAGS_BUS_NUMBER); } template @@ -1081,6 +1067,23 @@ uint32_t SettingsStruct_tmpl::getI2CClockStretch(uint8_t i2cBus) const return 0u; } +#if FEATURE_I2C_MULTIPLE +template +uint8_t SettingsStruct_tmpl::getI2CInterfaceRTC() const { + return get3BitFromUL(I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK); +} + +template +uint8_t SettingsStruct_tmpl::getI2CInterfaceWDT() const { + return get3BitFromUL(I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT); +} + +template +uint8_t SettingsStruct_tmpl::getI2CInterfacePCFMCP() const { + return get3BitFromUL(I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP); +} +#endif // if FEATURE_I2C_MULTIPLE + #if FEATURE_I2CMULTIPLEXER template int8_t SettingsStruct_tmpl::getI2CMultiplexerType(uint8_t i2cBus) const { diff --git a/src/src/Globals/Plugins.cpp b/src/src/Globals/Plugins.cpp index 64c60ea7d1..a0d78e6286 100644 --- a/src/src/Globals/Plugins.cpp +++ b/src/src/Globals/Plugins.cpp @@ -93,7 +93,7 @@ pluginID_t getPluginID_from_TaskIndex(taskIndex_t taskIndex) { bool isPluginI2CPowerManager_from_TaskIndex(taskIndex_t taskIndex, uint8_t i2cBus) { if (validTaskIndex(taskIndex)) { #if FEATURE_I2C_MULTIPLE - if (get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER) != i2cBus) { + if (Settings.getI2CInterface(taskIndex) != i2cBus) { return false; } #endif // if FEATURE_I2C_MULTIPLE @@ -219,7 +219,7 @@ bool prepare_I2C_by_taskIndex(taskIndex_t taskIndex, deviceIndex_t DeviceIndex) } #if FEATURE_I2C_MULTIPLE - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + const uint8_t i2cBus = Settings.getI2CInterface(taskIndex); #else const uint8_t i2cBus = 0; #endif // if FEATURE_I2C_MULTIPLE @@ -249,7 +249,7 @@ void post_I2C_by_taskIndex(taskIndex_t taskIndex, deviceIndex_t DeviceIndex) { return; } #if FEATURE_I2C_MULTIPLE - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + const uint8_t i2cBus = Settings.getI2CInterface(taskIndex); #else const uint8_t i2cBus = 0; #endif // ifdef ESP32 diff --git a/src/src/Helpers/ESPEasy_time.cpp b/src/src/Helpers/ESPEasy_time.cpp index 6577104736..84bb15a593 100644 --- a/src/src/Helpers/ESPEasy_time.cpp +++ b/src/src/Helpers/ESPEasy_time.cpp @@ -920,7 +920,7 @@ bool ESPEasy_time::ExtRTC_get(uint32_t& unixtime) { unixtime = 0; #if FEATURE_I2C_MULTIPLE - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK); + const uint8_t i2cBus = Settings.getI2CInterfaceRTC(); #else const uint8_t i2cBus = 0; #endif // if FEATURE_I2C_MULTIPLE @@ -1021,7 +1021,7 @@ bool ESPEasy_time::ExtRTC_set(uint32_t unixtime) } bool timeAdjusted = false; #if FEATURE_I2C_MULTIPLE - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK); + const uint8_t i2cBus = Settings.getI2CInterfaceRTC(); #else const uint8_t i2cBus = 0; #endif // if FEATURE_I2C_MULTIPLE diff --git a/src/src/Helpers/Hardware_I2C.cpp b/src/src/Helpers/Hardware_I2C.cpp index 080e5f2913..238ef9a6e4 100644 --- a/src/src/Helpers/Hardware_I2C.cpp +++ b/src/src/Helpers/Hardware_I2C.cpp @@ -55,7 +55,7 @@ void initI2C() { delay(500); #if FEATURE_I2C_MULTIPLE - I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT)); + I2CSelectHighClockSpeed(Settings.getI2CInterfaceWDT()); #endif // if FEATURE_I2C_MULTIPLE if (I2C_write8_reg(Settings.WDI2CAddress, @@ -236,7 +236,7 @@ void I2CMultiplexerSelectByTaskIndex(taskIndex_t taskIndex) { uint8_t toWrite = 0; # if FEATURE_I2C_MULTIPLE - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + const uint8_t i2cBus = Settings.getI2CInterface(taskIndex); # else // if FEATURE_I2C_MULTIPLE const uint8_t i2cBus = 0; # endif // if FEATURE_I2C_MULTIPLE @@ -294,7 +294,7 @@ bool I2CMultiplexerPortSelectedForTask(taskIndex_t taskIndex) { if (!validTaskIndex(taskIndex)) { return false; } # if FEATURE_I2C_MULTIPLE - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + const uint8_t i2cBus = Settings.getI2CInterface(taskIndex); # else // if FEATURE_I2C_MULTIPLE const uint8_t i2cBus = 0; # endif // if FEATURE_I2C_MULTIPLE diff --git a/src/src/Helpers/Hardware_device_info.cpp b/src/src/Helpers/Hardware_device_info.cpp index 932d5660df..2b74959c1f 100644 --- a/src/src/Helpers/Hardware_device_info.cpp +++ b/src/src/Helpers/Hardware_device_info.cpp @@ -52,7 +52,6 @@ # include # include -# include # include # include @@ -408,14 +407,15 @@ const uint8_t getI2CBusCount() { return 1u; #else // if !FEATURE_I2C_MULTIPLE + // Not querying the supported nr. of I2C busses in hardware, but using software multiplexing // Assume/expect IDF 5.x - # if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED + // # if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED # if FEATURE_I2C_INTERFACE_3 return 3u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) # else // if FEATURE_I2C_INTERFACE_3 return 2u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) # endif // if FEATURE_I2C_INTERFACE_3 - # endif // if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED + // # endif // if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED #endif // if !FEATURE_I2C_MULTIPLE return 0u; // Unexpected exit... } diff --git a/src/src/Helpers/I2C_access.h b/src/src/Helpers/I2C_access.h index a43df258b2..316fae7817 100644 --- a/src/src/Helpers/I2C_access.h +++ b/src/src/Helpers/I2C_access.h @@ -150,11 +150,6 @@ bool I2C_deviceCheck(uint8_t i2caddr, #endif // if FEATURE_I2C_DEVICE_CHECK #if FEATURE_I2C_MULTIPLE -#define I2C_PERIPHERAL_BUS_CLOCK 0 // bit-offset for I2C bus used for the RTC clock device -#define I2C_PERIPHERAL_BUS_WDT 3 // bit-offset for I2C bus used for the watchdog timer -#define I2C_PERIPHERAL_BUS_PCFMCP 6 // bit-offset for I2C bus used for PCF & MCP direct access -// #define I2C_PERIPHERAL_BUS_??? 9 // bit-offset for I2C bus used for the ??? - void I2CInterfaceSelector(String label, String id, uint8_t choice); diff --git a/src/src/Helpers/PeriodicalActions.cpp b/src/src/Helpers/PeriodicalActions.cpp index e6f94a89f8..9c285b7219 100644 --- a/src/src/Helpers/PeriodicalActions.cpp +++ b/src/src/Helpers/PeriodicalActions.cpp @@ -173,7 +173,7 @@ void runOncePerSecond() if (Settings.WDI2CAddress != 0) { #if FEATURE_I2C_MULTIPLE - I2CSelectHighClockSpeed(get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT)); // Select bus + I2CSelectHighClockSpeed(Settings.getI2CInterfaceWDT()); // Select bus #endif // if FEATURE_I2C_MULTIPLE I2C_write8(Settings.WDI2CAddress, 0xA5); } diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index cdc3c903d8..8f5167356b 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -237,7 +237,7 @@ void handle_advanced() { } #if FEATURE_I2C_MULTIPLE { - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_CLOCK); + const uint8_t i2cBus = Settings.getI2CInterfaceRTC(); I2CInterfaceSelector(F("Ext. Time Source I2C Interface"), F("pi2cbusrtc"), i2cBus); @@ -323,7 +323,7 @@ void handle_advanced() { addHtml(F(" (decimal)")); #if FEATURE_I2C_MULTIPLE { - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_WDT); + const uint8_t i2cBus = Settings.getI2CInterfaceWDT(); I2CInterfaceSelector(F("WD I2C Interface"), F("pi2cbuswdt"), i2cBus); diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index 3264232de8..86dbc3545a 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -31,10 +31,6 @@ # include "../Helpers/StringConverter.h" # include "../Helpers/StringGenerator_GPIO.h" -#if FEATURE_I2C_MULTIPLE -# include "../Helpers/Hardware_device_info.h" -#endif - # include "../../_Plugin_Helper.h" # include @@ -837,7 +833,7 @@ void format_I2C_port_description(taskIndex_t x) # endif // if FEATURE_I2C_GET_ADDRESS # if FEATURE_I2CMULTIPLEXER #if FEATURE_I2C_MULTIPLE - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_Flags[x], I2C_FLAGS_BUS_NUMBER); + const uint8_t i2cBus = Settings.getI2CInterface(x); #else const uint8_t i2cBus = 0; #endif // if FEATURE_I2C_MULTIPLE @@ -1254,7 +1250,7 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex #if FEATURE_I2C_MULTIPLE if (!Device[DeviceIndex].I2CNoBusSelection) { // If the device doesn't disallow bus selection - i2cBus = get3BitFromUL(Settings.I2C_Flags[taskIndex], I2C_FLAGS_BUS_NUMBER); + i2cBus = Settings.getI2CInterface(taskIndex); I2CInterfaceSelector(F("I2C Interface"), F("pi2cbus"), i2cBus); diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 9dd457679d..3d431a9d16 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -252,7 +252,7 @@ void handle_hardware() { #if FEATURE_I2C_MULTIPLE if (getI2CBusCount() >= 2) { addFormSubHeader(F("PCF & MCP Direct I/O")); - const uint8_t i2cBus = get3BitFromUL(Settings.I2C_peripheral_bus, I2C_PERIPHERAL_BUS_PCFMCP); + const uint8_t i2cBus = Settings.getI2CInterfacePCFMCP(); I2CInterfaceSelector(F("I2C Interface"), F("pi2cbuspcf"), i2cBus); diff --git a/src/src/WebServer/JSON.cpp b/src/src/WebServer/JSON.cpp index 5d03538d9f..8877fe477e 100644 --- a/src/src/WebServer/JSON.cpp +++ b/src/src/WebServer/JSON.cpp @@ -518,7 +518,7 @@ void handle_json() #if FEATURE_I2CMULTIPLEXER uint8_t i2cBus = 0; #if FEATURE_I2C_MULTIPLE - i2cBus = get3BitFromUL(Settings.I2C_Flags[TaskIndex], I2C_FLAGS_BUS_NUMBER); + i2cBus = Settings.getI2CInterface(TaskIndex); #endif if (Device[DeviceIndex].Type == DEVICE_TYPE_I2C && isI2CMultiplexerEnabled(i2cBus)) { #if FEATURE_I2C_MULTIPLE From 1eb141ced01993bbd6fe987ac61ea569ecb26717 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 31 Jan 2025 20:41:37 +0100 Subject: [PATCH 05/24] [I2C] Fix compilation for ESP8266 --- src/Custom-sample.h | 6 +++--- src/src/CustomBuild/ESPEasyDefaults.h | 4 ---- src/src/DataStructs_templ/SettingsStruct.cpp | 7 ++++++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Custom-sample.h b/src/Custom-sample.h index 9ac9a70763..f566815bcd 100644 --- a/src/Custom-sample.h +++ b/src/Custom-sample.h @@ -113,17 +113,17 @@ #endif #ifdef ESP32 #define DEFAULT_PIN_I2C_SDA -1 // Undefined -#define DEFAULT_PIN_I2C2_SDA -1 // Undefined -#define DEFAULT_PIN_I2C3_SDA -1 // Undefined #endif #ifdef ESP8266 #define DEFAULT_PIN_I2C_SCL 5 #endif #ifdef ESP32 #define DEFAULT_PIN_I2C_SCL -1 // Undefined +#endif +#define DEFAULT_PIN_I2C2_SDA -1 // Undefined +#define DEFAULT_PIN_I2C3_SDA -1 // Undefined #define DEFAULT_PIN_I2C3_SCL -1 // Undefined #define DEFAULT_PIN_I2C3_SCL -1 // Undefined -#endif #define DEFAULT_I2C_CLOCK_SPEED 400000 // Use 100 kHz if working with old I2C chips #define FEATURE_I2C_DEVICE_SCAN 1 diff --git a/src/src/CustomBuild/ESPEasyDefaults.h b/src/src/CustomBuild/ESPEasyDefaults.h index 12cb7ec6d4..5be4f2ae55 100644 --- a/src/src/CustomBuild/ESPEasyDefaults.h +++ b/src/src/CustomBuild/ESPEasyDefaults.h @@ -220,14 +220,12 @@ #define DEFAULT_PIN_I2C_SDA -1 // Undefined #endif #endif -#ifdef ESP32 #ifndef DEFAULT_PIN_I2C2_SDA #define DEFAULT_PIN_I2C2_SDA -1 // Undefined #endif #ifndef DEFAULT_PIN_I2C3_SDA #define DEFAULT_PIN_I2C3_SDA -1 // Undefined #endif -#endif #ifndef DEFAULT_PIN_I2C_SCL #ifdef ESP8266 #define DEFAULT_PIN_I2C_SCL 5 @@ -236,14 +234,12 @@ #define DEFAULT_PIN_I2C_SCL -1 // Undefined #endif #endif -#ifdef ESP32 #ifndef DEFAULT_PIN_I2C2_SCL #define DEFAULT_PIN_I2C2_SCL -1 // Undefined #endif #ifndef DEFAULT_PIN_I2C3_SCL #define DEFAULT_PIN_I2C3_SCL -1 // Undefined #endif -#endif #ifndef DEFAULT_I2C_CLOCK_SPEED #define DEFAULT_I2C_CLOCK_SPEED 400000 // Use 100 kHz if working with old I2C chips #endif diff --git a/src/src/DataStructs_templ/SettingsStruct.cpp b/src/src/DataStructs_templ/SettingsStruct.cpp index 62df71cae4..8e9aaa1d05 100644 --- a/src/src/DataStructs_templ/SettingsStruct.cpp +++ b/src/src/DataStructs_templ/SettingsStruct.cpp @@ -966,7 +966,12 @@ bool SettingsStruct_tmpl::isSPI_valid() const { template bool SettingsStruct_tmpl::isI2C_pin(int8_t pin) const { if (pin < 0) { return false; } - for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) { + #if !FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = 0; + #else // if !FEATURE_I2C_MULTIPLE + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) + #endif // if !FEATURE_I2C_MULTIPLE + { if ((getI2CSdaPin(i2cBus) == pin) || (getI2CSclPin(i2cBus) == pin)) { return true; } From 1cc8d7961ab4e7a4c74eebda5726c54c16917ba8 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 1 Feb 2025 22:50:24 +0100 Subject: [PATCH 06/24] [I2C] Code improvements and UI issues fixed --- src/_P017_PN532.ino | 9 +++++++-- src/_P036_FrameOLED.ino | 9 +++++++-- src/src/DataStructs_templ/SettingsStruct.cpp | 6 ++++++ src/src/Helpers/I2C_Plugin_Helper.cpp | 11 ++++++++--- src/src/PluginStructs/P109_data_struct.cpp | 9 +++++++-- src/src/WebServer/AdvancedConfigPage.cpp | 4 ++-- src/src/WebServer/DevicesPage.cpp | 15 +++++++++++++-- src/src/WebServer/HardwarePage.cpp | 9 ++++++++- 8 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/_P017_PN532.ino b/src/_P017_PN532.ino index 8634fea1be..63cdb4db1f 100644 --- a/src/_P017_PN532.ino +++ b/src/_P017_PN532.ino @@ -242,8 +242,13 @@ bool P017_handle_timer_in(struct EventStruct *event) # endif // ifdef P017_DEBUG_LOGIC_ANALYZER_PIN // TODO: Clock stretching issue https://github.com/esp8266/Arduino/issues/1541 - if (Settings.isI2CEnabled(Settings.getI2CInterface(event->TaskIndex)) - && ((DIRECT_pinRead(Settings.Pin_i2c_sda) == 0) || (DIRECT_pinRead(Settings.Pin_i2c_scl) == 0))) + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = Settings.getI2CInterface(event->TaskIndex); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE + if (Settings.isI2CEnabled(i2cBus) + && ((DIRECT_pinRead(Settings.getI2CSdaPin(i2cBus)) == 0) || (DIRECT_pinRead(Settings.getI2CSclPin(i2cBus)) == 0))) { addLog(LOG_LEVEL_ERROR, F("PN532: BUS error")); Plugin_017_Init(CONFIG_PIN3); diff --git a/src/_P036_FrameOLED.ino b/src/_P036_FrameOLED.ino index 6070a33377..2337ab862a 100644 --- a/src/_P036_FrameOLED.ino +++ b/src/_P036_FrameOLED.ino @@ -747,12 +747,17 @@ boolean Plugin_036(uint8_t function, struct EventStruct *event, String& string) P036_CheckHeap(F("_INIT: Before P036_data->init()")); # endif // P036_CHECK_HEAP + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = Settings.getI2CInterface(event->TaskIndex); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE if (!(P036_data->init(event->TaskIndex, get4BitFromUL(P036_FLAGS_0, P036_FLAG_SETTINGS_VERSION), // Bit23-20 Version CustomTaskSettings P036_CONTROLLER, // Type P036_ADR, // I2C address - Settings.Pin_i2c_sda, - Settings.Pin_i2c_scl, + Settings.getI2CSdaPin(i2cBus), + Settings.getI2CSclPin(i2cBus), static_cast(P036_RESOLUTION), // OLED index (P036_ROTATE == 2), // 1 = Normal, 2 = Rotated P036_CONTRAST, diff --git a/src/src/DataStructs_templ/SettingsStruct.cpp b/src/src/DataStructs_templ/SettingsStruct.cpp index 8e9aaa1d05..5106b7e005 100644 --- a/src/src/DataStructs_templ/SettingsStruct.cpp +++ b/src/src/DataStructs_templ/SettingsStruct.cpp @@ -578,6 +578,12 @@ void SettingsStruct_tmpl::clearMisc() { Pin_status_led_Inversed = DEFAULT_PIN_STATUS_LED_INVERSED; Pin_sd_cs = -1; #ifdef ESP32 + #if FEATURE_I2C_MULTIPLE + Pin_i2c2_sda = DEFAULT_PIN_I2C2_SDA; + Pin_i2c2_scl = DEFAULT_PIN_I2C2_SCL; + Pin_i2c3_sda = DEFAULT_PIN_I2C3_SDA; + Pin_i2c3_scl = DEFAULT_PIN_I2C3_SCL; + #endif // Ethernet related settings are never used on ESP8266 ETH_Phy_Addr = DEFAULT_ETH_PHY_ADDR; ETH_Pin_mdc_cs = DEFAULT_ETH_PIN_MDC; diff --git a/src/src/Helpers/I2C_Plugin_Helper.cpp b/src/src/Helpers/I2C_Plugin_Helper.cpp index 86b2393743..2f92f3b571 100644 --- a/src/src/Helpers/I2C_Plugin_Helper.cpp +++ b/src/src/Helpers/I2C_Plugin_Helper.cpp @@ -9,14 +9,19 @@ **********************************************************************/ bool checkI2CConfigValid_toHtml(taskIndex_t taskIndex, bool outputToHtml) { - if ((Settings.Pin_i2c_sda == -1) || (Settings.Pin_i2c_scl == -1)) { + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = Settings.getI2CInterface(taskIndex); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE + if ((Settings.getI2CSdaPin(i2cBus) == -1) || (Settings.getI2CSclPin(i2cBus) == -1)) { if (outputToHtml) { addHtml(F("Incomplete I2C configuration.")); } return false; } #if FEATURE_I2CMULTIPLEXER - if ((Settings.I2C_Multiplexer_Type != I2C_MULTIPLEXER_NONE) && - (Settings.I2C_Multiplexer_Addr == -1)) { // Multiplexer selected, but no port configured + if ((Settings.getI2CMultiplexerType(i2cBus) != I2C_MULTIPLEXER_NONE) && + (Settings.getI2CMultiplexerAddr(i2cBus) == -1)) { // Multiplexer selected, but no port configured if (outputToHtml) { addHtml(F("Incomplete I2C Multiplexer configuration.")); } return false; } diff --git a/src/src/PluginStructs/P109_data_struct.cpp b/src/src/PluginStructs/P109_data_struct.cpp index b43220bad6..fc4a398c75 100644 --- a/src/src/PluginStructs/P109_data_struct.cpp +++ b/src/src/PluginStructs/P109_data_struct.cpp @@ -87,10 +87,15 @@ bool P109_data_struct::plugin_init(struct EventStruct *event) { _relayInverted = P109_GET_RELAY_INVERT; _setpointTimeout = P109_CONFIG_SETPOINT_DELAY - P109_SETPOINT_OFFSET; + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = Settings.getI2CInterface(event->TaskIndex); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE if (P109_CONFIG_DISPLAYTYPE == 1) { - _display = new (std::nothrow) SSD1306Wire(P109_CONFIG_I2CADDRESS, Settings.Pin_i2c_sda, Settings.Pin_i2c_scl); + _display = new (std::nothrow) SSD1306Wire(P109_CONFIG_I2CADDRESS, Settings.getI2CSdaPin(i2cBus), Settings.getI2CSclPin(i2cBus)); } else { - _display = new (std::nothrow) SH1106Wire(P109_CONFIG_I2CADDRESS, Settings.Pin_i2c_sda, Settings.Pin_i2c_scl); + _display = new (std::nothrow) SH1106Wire(P109_CONFIG_I2CADDRESS, Settings.getI2CSdaPin(i2cBus), Settings.getI2CSclPin(i2cBus)); } if (nullptr == _display) { diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 8f5167356b..880a9a1abe 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -338,12 +338,12 @@ void handle_advanced() { addUnit(F("1/80 usec")); #endif #if FEATURE_I2C_MULTIPLE - if (getI2CBusCount() >= 2) { + if ((getI2CBusCount() >= 2) && Settings.isI2CEnabled(1)) { addFormNumericBox(concat(F("I2C ClockStretchLimit"), F(" Interface 2")), F("wire2stretch"), Settings.Wire2ClockStretchLimit); // TODO define limits addUnit(F("1/80 usec")); } #if FEATURE_I2C_INTERFACE_3 - if (getI2CBusCount() >= 3) { + if ((getI2CBusCount() >= 3) && Settings.isI2CEnabled(2)) { addFormNumericBox(concat(F("I2C ClockStretchLimit"), F(" Interface 3")), F("wire3stretch"), Settings.Wire3ClockStretchLimit); // TODO define limits addUnit(F("1/80 usec")); } diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index 86dbc3545a..ab92fc9eed 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -834,6 +834,12 @@ void format_I2C_port_description(taskIndex_t x) # if FEATURE_I2CMULTIPLEXER #if FEATURE_I2C_MULTIPLE const uint8_t i2cBus = Settings.getI2CInterface(x); + if (i2cBus > 0) { + html_BR(); + addHtml(F("I2C Interface")); + addHtml(' '); + addHtmlInt(i2cBus + 1); + } #else const uint8_t i2cBus = 0; #endif // if FEATURE_I2C_MULTIPLE @@ -876,10 +882,15 @@ void format_SPI_port_description(int8_t spi_gpios[3]) void format_I2C_pin_description(taskIndex_t x) { + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = Settings.getI2CInterface(x); + #else + const uint8_t i2cBus = 0; + #endif // if FEATURE_I2C_MULTIPLE if (checkI2CConfigValid_toHtml(x)) { - Label_Gpio_toHtml(F("SDA"), formatGpioLabel(Settings.Pin_i2c_sda, false)); + Label_Gpio_toHtml(F("SDA"), formatGpioLabel(Settings.getI2CSdaPin(i2cBus), false)); html_BR(); - Label_Gpio_toHtml(F("SCL"), formatGpioLabel(Settings.Pin_i2c_scl, false)); + Label_Gpio_toHtml(F("SCL"), formatGpioLabel(Settings.getI2CSclPin(i2cBus), false)); } } diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 3d431a9d16..a496e2ab3d 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -250,7 +250,14 @@ void handle_hardware() { #endif // if FEATURE_I2CMULTIPLEXER } #if FEATURE_I2C_MULTIPLE - if (getI2CBusCount() >= 2) { + const uint8_t i2cMaxBusCount = (getI2CBusCount() >= 2 + ? ((Settings.isI2CEnabled(1) ? 1 : 0) + # if FEATURE_I2C_INTERFACE_3 + + (Settings.isI2CEnabled(2) ? 1 : 0) + # endif // if FEATURE_I2C_INTERFACE_3 + ) + : 0) + (Settings.isI2CEnabled(0) ? 1 : 0); + if (i2cMaxBusCount > 1) { addFormSubHeader(F("PCF & MCP Direct I/O")); const uint8_t i2cBus = Settings.getI2CInterfacePCFMCP(); I2CInterfaceSelector(F("I2C Interface"), From a8bea04542612ef49520b99862a1505ec5c5da48 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sat, 1 Feb 2025 23:03:05 +0100 Subject: [PATCH 07/24] [I2C] Code improvements and UI issues fixed --- src/src/WebServer/DevicesPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index ab92fc9eed..33c8ebae1c 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -834,7 +834,7 @@ void format_I2C_port_description(taskIndex_t x) # if FEATURE_I2CMULTIPLEXER #if FEATURE_I2C_MULTIPLE const uint8_t i2cBus = Settings.getI2CInterface(x); - if (i2cBus > 0) { + if ((i2cBus > 0) || Settings.isI2CEnabled(1) || Settings.isI2CEnabled(2)) { html_BR(); addHtml(F("I2C Interface")); addHtml(' '); From 406ee0277a8d5881663dff7c5a9faee4c7be996b Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 2 Feb 2025 20:38:24 +0100 Subject: [PATCH 08/24] [I2C] Make I2C Interface selector reload page when needed (multiplexer enabled) --- src/src/Helpers/I2C_access.cpp | 21 ++++++++++++++++++++- src/src/Helpers/I2C_access.h | 3 ++- src/src/WebServer/AdvancedConfigPage.cpp | 6 ++++-- src/src/WebServer/DevicesPage.cpp | 3 ++- src/src/WebServer/HardwarePage.cpp | 3 ++- 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/src/Helpers/I2C_access.cpp b/src/src/Helpers/I2C_access.cpp index 57ce0019b4..08228a3b68 100644 --- a/src/src/Helpers/I2C_access.cpp +++ b/src/src/Helpers/I2C_access.cpp @@ -4,6 +4,7 @@ #include "../Globals/I2Cdev.h" #include "../Globals/Settings.h" #include "../Helpers/ESPEasy_time_calc.h" +#include "../Helpers/Hardware_I2C.h" #include "../Helpers/StringConverter.h" #if FEATURE_I2C_MULTIPLE @@ -427,7 +428,8 @@ bool I2C_deviceCheck(uint8_t i2caddr, #if FEATURE_I2C_MULTIPLE void I2CInterfaceSelector(String label, String id, - uint8_t choice) { + uint8_t choice, + bool reloadWhenNeeded) { const uint8_t i2cMaxBusCount = (getI2CBusCount() >= 2 ? ((Settings.isI2CEnabled(1) ? 1 : 0) # if FEATURE_I2C_INTERFACE_3 @@ -464,6 +466,23 @@ void I2CInterfaceSelector(String label, FormSelectorOptions selector(i2cBusCount, i2cBusList, i2cBusNumbers); selector.default_index = 0; + bool reloadOnChange = false; + + # if FEATURE_I2CMULTIPLEXER + + if (reloadWhenNeeded) { + // Only use reloadOnChange if current I2C Interface has multiplexer availability different than the other I2C Interface(s) + bool hasMultiplexer = false; + + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) { + if (i2cBus != choice) { + hasMultiplexer |= (Settings.isI2CEnabled(i2cBus) && isI2CMultiplexerEnabled(i2cBus)); + } + } + reloadOnChange = (hasMultiplexer != isI2CMultiplexerEnabled(choice)); + } + # endif // if FEATURE_I2CMULTIPLEXER + selector.reloadonchange = reloadOnChange; selector.addFormSelector(label, id, choice); } } diff --git a/src/src/Helpers/I2C_access.h b/src/src/Helpers/I2C_access.h index 316fae7817..7c3d970516 100644 --- a/src/src/Helpers/I2C_access.h +++ b/src/src/Helpers/I2C_access.h @@ -152,7 +152,8 @@ bool I2C_deviceCheck(uint8_t i2caddr, #if FEATURE_I2C_MULTIPLE void I2CInterfaceSelector(String label, String id, - uint8_t choice); + uint8_t choice, + bool reloadWhenNeeded); #endif // if FEATURE_I2C_MULTIPLE #endif // HELPERS_I2C_ACCESS_H diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 880a9a1abe..46d5667b22 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -240,7 +240,8 @@ void handle_advanced() { const uint8_t i2cBus = Settings.getI2CInterfaceRTC(); I2CInterfaceSelector(F("Ext. Time Source I2C Interface"), F("pi2cbusrtc"), - i2cBus); + i2cBus, + false); } #endif // if FEATURE_I2C_MULTIPLE #endif @@ -326,7 +327,8 @@ void handle_advanced() { const uint8_t i2cBus = Settings.getI2CInterfaceWDT(); I2CInterfaceSelector(F("WD I2C Interface"), F("pi2cbuswdt"), - i2cBus); + i2cBus, + false); } #endif // if FEATURE_I2C_MULTIPLE diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index 33c8ebae1c..eda51112e7 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -1264,7 +1264,8 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex i2cBus = Settings.getI2CInterface(taskIndex); I2CInterfaceSelector(F("I2C Interface"), F("pi2cbus"), - i2cBus); + i2cBus, + true); } #endif // if FEATURE_I2C_MULTIPLE # if FEATURE_I2CMULTIPLEXER diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index a496e2ab3d..11c25d8504 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -262,7 +262,8 @@ void handle_hardware() { const uint8_t i2cBus = Settings.getI2CInterfacePCFMCP(); I2CInterfaceSelector(F("I2C Interface"), F("pi2cbuspcf"), - i2cBus); + i2cBus, + false); } #endif // if FEATURE_I2C_MULTIPLE From c67cf01eb24bdeebcc4843f25e834b7974bb852d Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 2 Feb 2025 22:10:37 +0100 Subject: [PATCH 09/24] [I2C] I2C Scan layout improvements --- src/src/WebServer/I2C_Scanner.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/src/WebServer/I2C_Scanner.cpp b/src/src/WebServer/I2C_Scanner.cpp index d6b6655bfd..e1c2ffc12f 100644 --- a/src/src/WebServer/I2C_Scanner.cpp +++ b/src/src/WebServer/I2C_Scanner.cpp @@ -499,7 +499,6 @@ void handle_i2cscanner() { #else // if !FEATURE_I2C_MULTIPLE for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) #endif // if !FEATURE_I2C_MULTIPLE - if (Settings.isI2CEnabled(i2cBus)) { html_table_class_multirow(); #if FEATURE_I2C_MULTIPLE @@ -548,15 +547,18 @@ void handle_i2cscanner() { I2CMultiplexerOff(i2cBus); } #endif // if FEATURE_I2CMULTIPLEXER + if (nDevices == 0) { + html_TR_TD(); + addHtml(F("No I2C devices found")); + } + nDevices = 0; // Reset for next interface } else { - addHtml(strformat(F("I2C pins not configured for interface %d
"), i2cBus + 1)); + html_TR_TD(); + addHtml(strformat(F("I2C pins not configured for interface %d"), i2cBus + 1)); } html_end_table(); I2CSelectHighClockSpeed(0); // By default the bus is in standard speed - if (nDevices == 0) { - addHtml(F("No I2C devices found
")); - } } sendHeadandTail_stdtemplate(_TAIL); TXBuffer.endStream(); From ec8a927cfca70df57bd352e7144fbb6165cc7e0c Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Sun, 2 Feb 2025 22:11:21 +0100 Subject: [PATCH 10/24] [I2C] Update documentation --- .../Hardware/Device_I2CInterfaceSelection.png | Bin 0 -> 13209 bytes .../Device_I2CInterfaceSelection3.png | Bin 0 -> 18500 bytes .../Device_I2CInterfaceSelectionReload.png | Bin 0 -> 13585 bytes docs/source/Hardware/Hardware.rst | 57 +++++++++++++++++- .../Hardware/Hardware_I2CInterface2.png | Bin 0 -> 11015 bytes .../Hardware/Hardware_I2CMultiplexer2.png | Bin 0 -> 11267 bytes .../Hardware/Hardware_PCFMCP_I2CSelector.png | Bin 0 -> 3051 bytes docs/source/Tools/Tools.rst | 28 +++++++++ .../Tools_I2Cscan_multipleInterfaces.png | Bin 0 -> 65422 bytes .../Tools/images/Tools_RTC_I2CSelector.png | Bin 0 -> 4209 bytes .../Tools/images/Tools_WD_I2CSelector.png | Bin 0 -> 3998 bytes 11 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 docs/source/Hardware/Device_I2CInterfaceSelection.png create mode 100644 docs/source/Hardware/Device_I2CInterfaceSelection3.png create mode 100644 docs/source/Hardware/Device_I2CInterfaceSelectionReload.png create mode 100644 docs/source/Hardware/Hardware_I2CInterface2.png create mode 100644 docs/source/Hardware/Hardware_I2CMultiplexer2.png create mode 100644 docs/source/Hardware/Hardware_PCFMCP_I2CSelector.png create mode 100644 docs/source/Tools/images/Tools_I2Cscan_multipleInterfaces.png create mode 100644 docs/source/Tools/images/Tools_RTC_I2CSelector.png create mode 100644 docs/source/Tools/images/Tools_WD_I2CSelector.png diff --git a/docs/source/Hardware/Device_I2CInterfaceSelection.png b/docs/source/Hardware/Device_I2CInterfaceSelection.png new file mode 100644 index 0000000000000000000000000000000000000000..538b8210ba8d79793be3ad9edd94b22ccbd73cc9 GIT binary patch literal 13209 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 A#{d8T literal 0 HcmV?d00001 diff --git a/docs/source/Hardware/Device_I2CInterfaceSelection3.png b/docs/source/Hardware/Device_I2CInterfaceSelection3.png new file mode 100644 index 0000000000000000000000000000000000000000..8ec7c9908f8b05f0f177cbfdc44e888fb54db588 GIT binary patch literal 18500 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 Kde*v!GX4kG5FSnd literal 0 HcmV?d00001 diff --git a/docs/source/Hardware/Device_I2CInterfaceSelectionReload.png b/docs/source/Hardware/Device_I2CInterfaceSelectionReload.png new file mode 100644 index 0000000000000000000000000000000000000000..690a725e4241331243db6a6d79cabb9cd92a84ce GIT binary patch literal 13585 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 VF7Es07E>S7xoL3YgO>fXe*-tBtT6xp literal 0 HcmV?d00001 diff --git a/docs/source/Hardware/Hardware_I2CMultiplexer2.png b/docs/source/Hardware/Hardware_I2CMultiplexer2.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c6128fcd015f2a81557eb482a6c2d448dc06c2 GIT binary patch literal 11267 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

T0${MyhIQ;dN9dAfb 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

bVa>dVC+`mY+ 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

VILhs%x4WCWiqHF3ZYC=& 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 literal 0 HcmV?d00001 diff --git a/docs/source/Hardware/Device_I2CInterfaceSelection.png b/docs/source/Hardware/Device_I2CInterfaceSelection.png deleted file mode 100644 index 538b8210ba8d79793be3ad9edd94b22ccbd73cc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13209 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 A#{d8T diff --git a/docs/source/Hardware/Device_I2CInterfaceSelection3.png b/docs/source/Hardware/Device_I2CInterfaceSelection3.png deleted file mode 100644 index 8ec7c9908f8b05f0f177cbfdc44e888fb54db588..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18500 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 Kde*v!GX4kG5FSnd diff --git a/docs/source/Hardware/Device_I2CInterfaceSelectionReload.png b/docs/source/Hardware/Device_I2CInterfaceSelectionReload.png deleted file mode 100644 index 690a725e4241331243db6a6d79cabb9cd92a84ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13585 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 some pins have to be configured, and initialized during boot, for the SDA and SCL connections. This can be any unused pair of pins on the ESP board. -The pins can be configured here, and will have default values initially (ESP8266: SDA: GPIO-4 (D2), SCL: GPIO-5 (D3), ESP32: SDA: GPIO-22, SCL: GPIO-23). When I2C is not used, these can be set to `- None -`, so the pins are available for other purposes. +The pins can be configured here, and will have default values initially (ESP8266: SDA: GPIO-4 (D2), SCL: GPIO-5 (D3), ESP32: No defaults). When I2C is not used, these can be set to `- None -`, so the pins are available for other purposes. -When having an I2C Priority task configured, the I2C GPIO pins can no longer be changed, as that could disable the hardware, thus blocking the device. The configured GPIO pins will be display-only. +When having an I2C Priority task configured, the I2C GPIO pins (for that bus, when multiple buses are available) can no longer be changed, as that could disable the hardware, thus blocking the device. The configured GPIO pins will be display-only. -The default bus clock speed can also be set here. If only devices supporting 100 kHz are connected (Old/Slow devices), then the value can be set to 100 kHz, by default 400 kHz is configured, that is supported by newer devices, though there are many devices supporting higher frequencies. ESP8266 is able to achieve ca. 400 kHz, while ESP32 allows much higher speeds. +The default bus clock speed can also be set here. If only devices supporting 100 kHz are connected (Old/Slow devices), then the value can be set to 100 kHz, by default 400 kHz is configured, that is supported by newer devices, though there are many devices supporting higher frequencies. ESP8266 is able to achieve ca. 400 kHz, while ESP32 allows higher speeds. -ESPEasy has a separate setting for Slow I2C devices, and per I2C device this slow clock speed can be selected in the Device edit page. This value is by default set to 100 kHz, but can be set lower or higher if desired. +ESPEasy has a separate setting for Slow I2C devices, and per I2C device this slow clock speed can be selected in the Device configuration page. This value is by default set to 100 kHz, but can be set lower or higher if desired. -.. image:: Hardware_I2CInterface.png +.. image:: Hardware_I2CBus.png *Device specific Force Slow I2C speed selection:* @@ -59,33 +59,33 @@ A device flag has been added for specific devices to have **Force Slow I2C speed Added: 2025-02-02 -Multiple I2C Busses can be configured on ESP32 builds. This aids in connecting all on-board sensors and devices when multiple GPIO pin-pairs are used for I2C devices. By default, 2 I2C Busses are made available, but via compile-time options, a 3rd I2C Bus can be enabled, if required. +Multiple I2C Buses can be configured on ESP32 builds. This aids in connecting all on-board sensors and devices when multiple GPIO pin-pairs are used for I2C devices. By default, 2 I2C Buses are made available, but via compile-time options, a 3rd I2C Bus can be enabled, if required. -.. image:: Hardware_I2CInterface2.png +.. image:: Hardware_I2CBus2.png The available options are the same as for the first I2C Bus. If a second (or third) I2C Bus are not needed, then leave the GPIO settings on ``- None -``, and the interface won't be initialized, and not shown in the configuration options. -NB: The second (or third) I2C Bus should not be configured for the same GPIO pins as any other I2C Bus. +NB: The second (or third) I2C Bus should of course not be configured for the same GPIO pins as any other I2C Bus. NB2: Some boards require that in the Serial Console Settings (Tools/Advanced), the ``Fall-back to Serial 0`` option is disabled, to free the GPIO pins for I2C use. -When multiple I2C Busses are configured (so, ``SDA`` and ``SCL`` GPIO-pins configured), each task configured with an I2C device will show a selection for the I2C Bus to use. As expected, the first I2C Bus is selected by default, and another interface can be selected as required. +When multiple I2C Buses are configured (so, ``SDA`` and ``SCL`` GPIO-pins configured), each task configured with an I2C device will show a selection for the I2C Bus to use. As expected, the first I2C Bus is selected by default, and another interface can be selected as required. *Device specific I2C Bus selection:* -.. image:: Device_I2CInterfaceSelection.png +.. image:: Device_I2CBusSelection.png -NB: If a multiplexer is configured for 1 of the I2C Busses (but *not* for all interfaces), the I2C Bus selector will save & reload the page to show/hide the multiplexer options, below. +NB: If a multiplexer is configured for 1 of the I2C Buses (but *not* for all interfaces), the I2C Bus selector will save & reload the page to show/hide the multiplexer options, below. -.. image:: Device_I2CInterfaceSelectionReload.png +.. image:: Device_I2CBusSelectionReload.png This screenshot shows the reload icon, to indicate that changing the selection will reload the page. -.. image:: Device_I2CInterfaceSelection3.png +.. image:: Device_I2CBusSelection3.png -And an example for when 3 I2C Busses are available (compile-time option!) and configured. +And an example for when 3 I2C Buses are available (compile-time option!) and configured. --------------- I2C Multiplexer @@ -138,11 +138,11 @@ All these chips/boards can be found at Adafruit, Aliexpress, Banggood, EBay, etc Added: 2025-02-02 -With the introduction of multiple I2C Busses, it is also plausible to configure an I2C Multiplexer on the second (or third, when included in the build) I2C Bus. +With the introduction of multiple I2C Buses, it is also plausible to configure an I2C Multiplexer on the second (or third, when included in the build) I2C Bus. .. image:: Hardware_I2CMultiplexer2.png -This allows the same configuration options as shown above for the first I2C Bus, as all I2C Busses are completely independent from each other. +This allows the same configuration options as shown above for the first I2C Bus, as all I2C Buses are completely independent from each other. Device configuration ^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ Added: 2025-02-02 For interacting with the PCF8574 or MCP23017 GPIO Extenders no Device Task is required, so no I2C Bus configuration is available. -When multiple I2C Busses are configured (ESP32 only), we need some configuration to overcome that situation, to avoid having to connect these I/O extenders on the first I2C Bus. +When multiple I2C Buses are configured (ESP32 only), we need some configuration to overcome that situation, to avoid having to connect these I/O extenders on the first I2C Bus. .. image:: Hardware_PCFMCP_I2CSelector.png diff --git a/docs/source/Hardware/Hardware_I2CBus.png b/docs/source/Hardware/Hardware_I2CBus.png new file mode 100644 index 0000000000000000000000000000000000000000..2450fd22dbcc0dd639f172d513dc6d2d4a238829 GIT binary patch literal 11258 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 literal 0 HcmV?d00001 diff --git a/docs/source/Hardware/Hardware_I2CInterface.png b/docs/source/Hardware/Hardware_I2CInterface.png deleted file mode 100644 index 4329653d12b08ffd464f03f36c5af51b2a2a996d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10598 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 diff --git a/docs/source/Hardware/Hardware_I2CInterface2.png b/docs/source/Hardware/Hardware_I2CInterface2.png deleted file mode 100644 index fcb8c93eff956f5c4038c1024c9f4e91808ade5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11015 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 VF7Es07E>S7xoL3YgO>fXe*-tBtT6xp diff --git a/docs/source/Hardware/Hardware_PCFMCP_I2CSelector.png b/docs/source/Hardware/Hardware_PCFMCP_I2CSelector.png index 3a63c6d5482674a631d4f2271d1a987a19a69d7c..1db3ad5648cf7310199256622ee4f6ab4120e9dc 100644 GIT binary patch delta 2664 zcmZvcc|4SB8^=c{k|m}y4Mm!$JS5E6vQCykvdkp=dWJ!=9K_h4PR5v~aAeJrW>l6e zjj^vSoT)HgS+WbEgCP+a)H}}ky#Kw|fA{CPKiBj7{jU4^E=fFx|0yA4DJTGeKo*^| zMAA+x@_D3LN`gq#1y$4qlqyOCp@cx8bWmzKNOe&mW53YgKmx*&;QO0b6vE+pkasXq zR0v~>RYMtT1|c;sAk{Px7Z7H_!M*_m#J{%-Ws{X55Fx^46T@qf?wkTE>v40*OFPm| zk2B3F>Ayql^An`J)7%Xa`M)GSpFI+Az{Da8RC44$sBI)l$mWz)wJACf$5zg*Kiqiy zlJj-SGGB{8M5*x<^SUyZmTn|acm_7=~~86|4E`!~PI zZ=U76s@e`P2*!tkpToLbdnXwdi1Vz$CIdh_rJ-A=4Cx<%Js zMPTp-EniAjR@Qpef+pDmz3+OUk*Wq^zvRoW`LqI`G8<8Ce8Z^)?cWV3G7{Tqs@ zVm#Bu#7?Y;@#9Zg@lyeorD+3UmV-GTdZRZ_Nf-Zo({vcoTmUs@s6-10cY4OojacK;=Xtiu!Wnlj}WzP{2!R_%S|*;{8*RbyuuL#o&&rw;x4iAB9R zuf99%3Szm4@pf2ftPLRWfxa*m-d9U8Mn!99fq z^8TyRwFKOE`i`-WZX@C31d-hMB3`ulcHIHCWc(NYWWTIx-Bbnk1>GUxXPOq7ITp#O zRW8yKYdY^XGj9BP-nefsU+3KFs2$g%?5%(TZ-OZtPulPfrC&G^xCB~Q#j9zxs(2iy zzTB)vs=sX9_Oj(p*O&lLtMUxGB+B$r*2~3LN%TlG&c#McqKGHxV&X4ke8ncKeMuuh{st+T>Gv0<02_8JXVv@T-o7 z{|9v)2VOwqlm~+UY;ng=W;*Afju?rjPFA*zEwaDzw+^J|32TEwG(kxEmyHeYwzwUi zl$4b2Vw*y7s8(64gqy2t&ccFkRPzBbBPhglp|=n{zp*i}ySv@5r>B>boh@O~k?g;U zArgu6pFVZy85q19gI^THKqQapru)g^CLcqg^%$wU-Aaq%REVnLW(c$3a)y?VNk`z? z=4M^Ah$xaI3qtNu&rVnKKeFq=4RP(D^d7?BK_}(ve!NtGI~piz~VPJDwrtwPJ(S zgiU6ZN4x2)Af`aW2pONz5SRsW3)@XlQx8Yvz${eHDL!L>%f% z4bqrQcNK$%bIPZ8wpPa+YtSxv<^fr6Lr8S?J6cJcHX#RlZAO`U+tLtdV$E!#g&Jib zmaLmJM-cr`bjrq3uUd2xH}IF!>#dUnfGeG<@oI|~+=85!>u^``LSB&~*eDqtT8o2sW5Xt0ZGChA-^G2j5>PRBSnrE3E$DxIX3nwP&Jxp$r@tb$Vwtkf6B z4&4eF_5&(4iX;_{ar#gDjMI)|ItVqteP5YqUc}v0K3c&uca@ft+(Bjhh?I`f8;uvL zQ)z!93Mo=^1N>Lz{JTEsQn@-P)NAa(PsxY#(3_G}JRBR__*5M>7fo@T=j9#^%Jo?Q zi?AfTeo?WR>!l5Y->g9I+?&ADwwKFsFP|6~sK7D<6PfoRs{H+lc-g1++@Y`*n{ZR) z8sPk6O?x7unKj-;#@FgmolK-HjBv%Oux1sq-#fDx6JGAU%a(<5>lF);aP0DIIREkb zwatv*m9&*1jt>-!k+EC<3Cjf0X1HY=GXA>*w~;g1Aij}cy)ssjE`<4cvB_-yj@f6* z#T*jd8U^EnkUc3_B?s`#?tCr7>F7I3Lp6zhWFHo&K%lMRcq91tl~cQJy%gL3Q6fEQ z=59>>PHIcnZ zKF@2)%F5jn6K*%XOijk&!NI{jTdPxZ9N~RF$*u4123T8L)1}m8XX+wjV*`Ht*gGHW z;mPZmbBo0?Tc7L7Ui>*4C6Y`Td(+>t0;KBLQ96B~N{-dCv)ciiHFJr7tDvdmE{}+3|0HFW? delta 2796 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 diff --git a/docs/source/Tools/Tools.rst b/docs/source/Tools/Tools.rst index e69ef2aff6..d21f0a10e3 100644 --- a/docs/source/Tools/Tools.rst +++ b/docs/source/Tools/Tools.rst @@ -275,7 +275,7 @@ N.B. these modules all use I2C, so they need to be connected to the configured I Added: 2025-02-02 -When multiple I2C Busses are configured (ESP32 only), we need to configure on which I2C Bus the RTC chip is connected: +When multiple I2C Buses are configured (ESP32 only), we need to configure on which I2C Bus the RTC chip is connected: .. image:: images/Tools_RTC_I2CSelector.png @@ -420,7 +420,7 @@ What can be read/set/changed must still be documented. Added: 2025-02-02 -When multiple I2C Busses are configured (ESP32 only), we need to configure on which I2C Bus the Watchdog chip is connected: +When multiple I2C Buses are configured (ESP32 only), we need to configure on which I2C Bus the Watchdog chip is connected: .. image:: images/Tools_WD_I2CSelector.png @@ -954,7 +954,7 @@ Interfaces I2C Scan ======== -To verify if any connected I2C devices are properly detected by the ESP, the I2C Scan is available. This will scan the I2C bus, and, when configured, the additional busses provided via an I2C multiplexer, for available devices. +To verify if any connected I2C devices are properly detected by the ESP, the I2C Scan is available. This will scan the I2C bus, and, when configured, the additional buses/channels provided via an I2C multiplexer, for available devices. The scan is performed if the I2C ``SDA`` and ``SCL`` GPIO pins are configured on the Hardware page, and will use the configured ``Slow device Clock Speed`` setting (default: 100 kHz) during the scan, as that should be supported by any I2C device available. @@ -970,11 +970,11 @@ Example scan using an I2C multiplexer, showing multiple devices across multiple Added: 2025-02-02 -When having multiple I2C Busses configured, for each configured interface an I2C Scan is performed, including the multiplexer if that's configured. +When having multiple I2C Buses configured, for each configured interface an I2C Scan is performed, including the multiplexer if that's configured. An example: (No actual multiplexer connected...) -.. image:: images/Tools_I2Cscan_multipleInterfaces.png +.. image:: images/Tools_I2Cscan_multipleBuses.png | diff --git a/docs/source/Tools/images/Tools_I2Cscan_multipleBuses.png b/docs/source/Tools/images/Tools_I2Cscan_multipleBuses.png new file mode 100644 index 0000000000000000000000000000000000000000..43bf831eca6c5e46ad2234f7a491c0b47d681492 GIT binary patch literal 70446 zcmd432UHW^_b(a+L69OMh;&dvrCA_!B2pBk3J6GVQbUzah)7q8N|hD_q(i8oCsHI7 z0hN+KC;|dP2na|hA@G8Ji@$r8vtPHJo-D9 zEW*S^X*7GHX8c6e-rLs8$>WKWyBomP(aRld&q#m$hS;?mVmGeckm48Rzj0IUhNPU7 zG$XyruhaaR_72vz0sKZzZg%c|jPwS#?XAK3H^r_?-sBhKzvJ%i;A+qR`_eNOE*k&< zKR`oO*}&goB}*%Qq6zWX`x=b`i}b1P0tek1|Mw9t0Ji{o*@(FXeDmCSZjPczc|#t* zl5_TCUBT@Gpqg4_()qT!r#@>jFIDxDo(ZB1!eQb^oc-FQXM2#x{{G=17OwTr@y(Nz zVfnp%eS8}D_eJmf`CX6y)&4X?8B6{5MbcrFbblYa(O9$oeLTU?F7)?t!+D)U^7J7@ zS(UO8pa+|LM+Xx#L)W7BelD>JQZ~*g&of7t*Q#K{qobpZU;XOUiZ5J?@++E+?iW!+ z<^QFVdD9^WZvrDMr(bNN4zJ3`fk3E6FbJ~etC0cUZwmIqpCB=OBFVKq`BWfwx=QDd zXXYunJ~;M8mE|~u6hQZoYjAOn*3*>ZqEi_ur+x5rR?8%p9=UMUb*x-b&>`E!lK}TC_=1Y9#mHIO&YRi;6EdIP>@2Ndw(Cka0Q+c^BuTJ=0 zxZInqU2UDX=REl!l4P`^WFM-pxbL+k=z68>GbP;}`DI5gV){x7YrWNsHy<*qw+UkdA~BU1bnT`@PwkYOfcN8I$= z_1k@tR5Td>wHt9lkSO*`+utjl%s9=$!XomAG+0=w1piN-w59t+0)+||7WbKo%I>pfc99#}w~ywfFh$&gf;MVh z8b^JQF1jAImUYX}QSS7F{WT-c3ky&#TBQhn{Tj+V3|ctS{pRvV z?#5e-^BJZRKZ1}xwahd1u+-x5Eim$37*4;i*;f&^w$^}gdDk*}dYzr}=wOieTtX*& z%`Gd)M+R{;Ik)|AGAWz9QrR*kW~#vybr;|*IGK@>f%?Ee^E{{f3(%udO_JGyllF3J zgw|S+M;|}a`dtcPNao2_ne~d*9?Y9AaQ|FgdYrB7n%-PYUawl`wx~7hto2@H53S_b z&<&@Yq!SN5JiWkN0;I}*qJQYUyVbYq-O+XIIVc6~D?8;Un`3`E%0HhnY|~-*R=4wf zVo;OP1e4V^G*iausymc{V;+js!sCPatyN;}CobNO^PEiaaNwyjLxLG)Rxku4eyeXJ z!~%({yn-7%<6&=)MXB#8#~zO7n4%TW7bFx1m)tKKG9Jj^-JAIMNE)TEH*R-;JcWP0 zX@H2}@=xD8+^g6Qjjn&?d1f|9cM`v1jMwL=#jYEM@L6<84$-HsjfHFyR*bvj&=Whk zqW2S$52oh_4^8XSy76vZcbria-W~A%?Yu@x>iy_UlQH`s+WDsINhNEta z42m}Rr`Z6$)gCkG1L9JkJT;{5Q6Im>%&kaE%l^nqvP1kL<00h<6k`(d!?A}}$oErq zH9XVIe8IrN%-zQoY@PVH`G6JP=yqDKPlj$?5xawn3F;8);XI>eoA#=OY38|!;y1

et$TU;hgJ7ap~_XIusM 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

Lhvbpq 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 literal 0 HcmV?d00001 diff --git a/docs/source/Tools/images/Tools_I2Cscan_multipleInterfaces.png b/docs/source/Tools/images/Tools_I2Cscan_multipleInterfaces.png deleted file mode 100644 index 727263df8a469736bff8f716780864031c44f387..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65422 zcmce;2Urv9*Do3bRBV9QX^Kh}5mc%qA}FE+P(V6}hzKN915%PGMT!b4QlttZO?nAE zp^AWlN=ZV5C;jY`aoKRB+{?tyWoj!Q%pqi@oNeyka zQ`@&#oO5-Co1auxJ$3S+@hdw zdwrVcT`uRyU&?#ec#|?Mus)0R&F4_&>^jwdZIp9_f4kYK3PBgMbuYd-2aU)18KDb{gB=$ z7M{7vozHjbH01VAQ#2Y&Y`tyil<73PvgMGGANau9Vp?^-Q~vxM*MF4svX-Z@MCu=~ zuVGrq8Js!xiz6+-q($a!Mb%&5Yj@s|udI62;M?Fh(RtunZEqx$9Gg4+NZaAVF@eLd zb4{MVXL1+ME_dJRgt>QktL{~i1i`Cl6pGZ_8(!ooa0I_CZ4CNuxqA}|fBUjQ(~G}2 z+;wpM32;I+u227n_`AVO<5WC6;;D3OMWH>7-4{k=}FyJ|*U_)C3#01fSERNn!OEzjM2V;mm*SU>l26x1_FkCmVZiw)1=`j7kY-3eSXt_lbqIIE;)at^rljI6U5aQ4Rew?^wurRxY_YN=!s z$Xfa>6tbVZhGN$=H7`<@m(oVBm1vZ(mzF=2>|N0%YmY?z1RTOu8e5(GxmB`oz@ag# zpBeatQ*+hPGy1O3ez`+f>DmRualn)GHETe4%h7P?9mijK>nEPj0r@Tg8NT-QKia; zX8&)G0mBygpp0tc1M;r-EmXh03op9WlHfIiHo>8YNcCBXmn$wou-XY^GQaIc-)Q`E z-<{(jJ~%vl;uTHBldjsUyFvgM5hoAm!BDmH08d-`B0< z6t`hCuo+c9(mxO=uI|bqZYV9@#=&2NL@zjr-=WsYwJ)nCnj&Hl+PyZXoU-hQ)Tv}c zr?mIvKxYTv%pQynzp43}6PXScSx^J`A1YiFk|F7d+!DS=2ir5>PD;6D^KDs|9{oG+Y{Ah+hLmY)XEuQrKSa|VmPBR#M`_fA5 ztE18>1ijwA3O_%@i_1a2%|jLRNN8#Rcdw)W=)s(%bxxHp)r!SGfIibb68rYV$sozL z-BrQwLRQw&d8FogufzDPcjtY33!Xf<7t-(5qD3MT0en58fjcZoCFuCvgI80SX)-erqAmdo(& zf2xFUrcf)h#Fs4g%Z%9rZuE_U*S#04?GBNe9%;vipx1UZg&~Ou%b+X|XCtlh!nH}W zZJ%#-fLeE)=yW>8Y)x$2Xs47T@me@7jN$(+(Xp(S+jBozS*IkQc|SV&DZoe0)zNw6 zb&JNVSdLG5CbIeVTvw}g_fRKx569BwT(^DJSDq6wzIcs+Rp^g$K|yK92I4Y~nVrIze~NOH{zY>Sokr0@Top-T75kbL@M-(Gv^?LQSy#`GYfYT!1=WJgnhMC_oH@(`I;hmxZod@#JJGULjsw)LU-dNSB=l zP)mDnhCf`rH6OEShsVpDnJQ%s{_vfm1o^maFSq%X-zIL{mza;iOg!!-ZaSnpdDoI) z;fV{qCnmXO{EEA(RWi7Cb0aGHuIRez3wtuncdK7CAbfw)`uL^iY|C>a-7}(K)Nga|=An6)Twyicux}GGn&uYVY2jx00tl5w@cO z+gL%RzruYlz{w*k= z&Fjohqlm+g%Z4mxBsLu%SD5XqNXO5e+-JI?mo5=MB9}0T>hZnQwXbMmg?suNUax}$ zI1(UWS+CpG#Qsf(U#sVyGw1;S4sM}m){o1Se#f_XfaNmd2q5eLfv@v6UA*R8-afv4^SL)ZA%6Mw05 zSl5OVOUwh5)H;QKX3)$xAfT4D>%G_|RV@d(j^M@Bz7(o$TCQnv0{nElquh|k6$zPR zd~H150r`S+YI$Faq~z~ZW=hvIKBP@#7FPEM73=j=zApJ)qRl1OFI_22v(s>~nX0ub z{RG4Lvx0PoJ;}&9q>bPe^2?s^>=$Lw(x|k*)@tiqD6!e_bdfLp_PL-Ul@PZGQ)#$G zTi$@Sjbc)wX&9k0SqLj6Xln|m8~+R`6xg$PCjLSVvhO2}cT`}M#y3HA*Nl4d+doLL*;hqRpcgM>|iXGu3Y1^j|FvIa+td@7K^N~HX>azm$YS4<Xx5?7(B)oV?GwkqFEKjq@Gp zq__3QHf#&b$ecmwG`tr)rSw>PxQvx(yZ;uk-N|LiZi*V~zV?Av0c)SqF8ng9TkCB{ zRyM076)-&}S9k~|w>6)7#4K_{sqnA$=vl$HMzu#a>(3f=nHlfw6oAQO-99Fkuo@HV zdgH3eAaha;)cYi1pN(*pwBeb0lLUo|AGoy~dSEMP~wMQhg~WH0P>(y2itw?1U_+Y^L7o%Q)|q zU)KLxH;ijqeE&h2{sWykc&lINW7N0IvWnNJ$0$P@x%gG-ke|+|cj7k(nneD@PJHgx zXAEX6`*fUn=2rjNN{Kqff6QuBMCZz-0wMDY;OS=xaWQAkR&pvP_c|wJ8qf@SmBda3 z-itZ2tMYA^G+ys|{Ap*>_npPAY!}r8Y^k<#SBmM`0le?(qGq+y2u`zK)#KSrzYDhi zYbZe-Q`Ub$+Iz(<Q$f`eP%->BYu5g>Ii4AMK$uxHobMSJ2L|-T=s`2fmB>!e< z4kmU4?Gq=PwDjDbq+|>69`N7{Zz!z%;MSqFfWJ+|^?ZF?KKor^H+j2%;PJ#B~P4jh1`Q;Cv6! z9&_bRH?!&}h!3pY6c@&f-dP_oEQElkT;2NMCX0HSqsmQsvI5JntL+Im|3tOMZMlAK zd#Y@X+ObddSdu3!*d~+7f|Gb2YknCPahv03*+P5OV*=jwKF`|v3Acwsr8)_vjmiCH z@{>%X$NH<0B$HABPVkKlN7`ifO2DdnK;y-1}j&B%J=bdpp1XFVkgS|4RrQ&Jj5#YjNgk;E^9pa&8 zc}8)d_EhEu*&NTVoh5;__>{4?HMkLUg^7=ZTO>3Gxpk0|qXP5GI@%sEwx|KnDDjWi z_cA(BQ2@O;tHufLgkJa@F;!)aOL-}nQ1SS7eTqQ|wPAu3-Q$r>f|`~NHk1Ts7@abz z5unzexUqdB7|pB0BXr5qP%gb9ZNfs#_rBsArOhWcRZH~WFE4z^K3z3CfC4Xn$7-%o zhM``2o&3)?$8Us+wNge8Q4#(46yEy=Ph*->gcioZ;-EXzvRJIzyB>{@jOH>UoNqO< z>S*-`VZr{t9i%cU>@==W?zzXa&`Svib?#S-Wg~W;gnH2gI!r!x2sEeU#s>e0d7NUs z+d%Bi9*>=Yu~b*NtPjB%F|a_WR=sX_1BC)p@h@z|frpt@8I9LlGbtd%aW2B6FGH8H zD>vF@);&wa7ry5^&05Ic{-UqfXc%o4Q9G*wapQ#|MCseZ3>)9V(&q5ihi9)kn_%bZ zsf*c(!pb3i(_>f$o#z;o!mgTNR}}X}K#se4=55*pyKN$g%Bx6%JdoSwj$%Qi&q92g0!Xnl1)G0L4pn9j}*zldV0+$ zlE?q>dl!tsQW5Tp^8APP@vCZWs@5 zTG0+>kkw@d4 z%6h!y>x_3Jq5E`}E6H`i(*Lf4*%Op&A6uHy@7B|d}}gd zhd;5Xj~c&KgEY}9M55SFiBOiN{eK1#OLy0ru9ZEEMEFzsyx){oJzj4ATngi8)s|gO zLN43uC;AQFgDQvd*{mld)ZeT|EST=LlzlklI{&C=z);+oaL2Y*qc>JA8%CVTl5raG z3{gq3|DYF+T-w&wGM?MFba!xsqRDYxt6Z8-(;rWbxZVj^UE_M zR`^iG5M_#`^T4zpUi%D454}10pQJI@^G4f~*=C<}`%JDfh1@GjY|$a;7pLAF>_C;g zyOwW%yeGNqR`iUzv)nnG+h*JMZZQTO4c~xVrF`6WEEY*ByFtt^vG^#P`MJl$Sk$Y| z9|P87B5>DcwK9zEcR?mkpRRTG&0sBEvll~?zEOvzT(9R~bd6C+f@f#>peK>?`2uRK zt1m-Nd+&f<5e)f(*l+An>rPfQwjAULJ0-7ZTXfOLRfw^82dAh39uKpI-zCBESA9A{ z$;v5Sl_;IBS3iZ%wsX@O>t9Qm2%x!^*;K?$2M)OPN_$%*UzW;;cfIx9(~4w(?RWiS zuca4hMh|ZP^p+c@dTQv6%E|>lOErz_jVT*NIc5{`L)4C}1e@5Do)wT6Pjp4Kz44_E zwaG5A_iDsx{Y%V}k=cTvJ?2s2}O3GY1sQ zh8T#HzVqBA%<}}ivQ893*A6XuydJ)&-N3tCovj=9Qu=sr1xKA05ub)V@9WL086`cahvf=_;=Z^OxHMYVtiNvm0HV$*mE~rS zuV~sq*WNRfH{)+BrB5sy8dhMIozn~f_aX*aRkSypLccXPNw*SdozQfwM4iMxLDoT7 zm-tZb;Z|0}C8)e?k{X5yEpU<3TcXxT1-v+FUmA8)%f0vAxkGMuR}-~0VRm_PCs)Pz zkds3;vN0oEA6Q1fBJ~hN&R+**kMnqyWSH&ni8qxRZ6;=hkg7snptL)Z8Fb>iiO1lr zTRHU=B<1A{9X-Q+ujA|@ch`8nLWJr}AF!J0lA2d4^S;tQZN0_|^nNc})|#P1M8R z?vnmd?DgGeYUaiw?<0EZOdl+EKUINbeJO}B=~Mf(z_GP(Hg{DMgPMp(Bq&FcqFy{g zd#$!C^DVQgJF-nHkm`C_Ga6+OT_=J8NQdEY#G9e~jZR@83JP5sx!9$MlHEM@*^WMv(6v6lJXpmJj004fb1 zTL=Cg)O3zuAt0EL^SB7#1dBTT1j=!U@Ao1XrM)_NJJrnf&Dm^JoMM-Qh?CRNh2Ty^ zT?WUUTLT{mS&Dz>MpGt{bIysxH{@BQ?S{W8b!d$Hf^***B;ob|icx#uA7>7qnAYrj z+5FWHFqM`>>rEO%eCGU1du0O6PZqRp1GRWMr{B?C&dpXgs_31iMx@*>7Axq_;({M` zKTf~xD$qM5;BJGLa=Ku4Z7b2MwWHA5s#MHaqW>imT#R3$Tg!5@*05P|i0y~LsT0Xv z2sN71Ry8#Xo5$rw$4w_*@;jUF9rC<2>UNEFv}Gs0QDMStbcX;`tP+NhsFW1ru|FCh z!wiReX>QG4JjbX3E3M=}JR*;Jg6!y^Bi4zKXUpDaKY9bs)7(fT6R2i19PDIG)*YC8 zhRhSvwHGr@$t9%PRf$Y=I!{}n)>GQ;F7{V1v1NC;h6ksCKZM`fDatkXde7(}2;{hF zB3DU9E_vbR6=?bpSI^Y15)xKm^cllzSi8Yl1W(O4&)bklsLvK6#;LXiLL&wiDmuP> z)bE%e!G=-6TjSb?sE6ig?&p;Hoj)Z7%=&hgyQ2z6EG1k_IT0&MZr!9$CcMC5ze>hj zX{>em<=4Y1&R&S4N z&x;ugt{It;7;M&&Z45M|izK)~M8|AKj%vF}Qe4hK&+4@0O_t2w)YB>YHqnE zTcmre5XqZAFnC_)62gYm%=|*6zBxevALqQQxvifT&F?&5+=Y-Yt)H|V$QorM3IL^K zKZ@d7@Eo_?PRJVYu6*54#O0`)cZmp|>D89z;{Fa5F?SSZ``zcteM`YCfm>YV47 z_y=t$TJ%dHDRB;6Gfej9x?x353#Y}-2M2z6Im>LIS*ZZo+}8sqOxEjH>peD*eG0&! z<+)XQ{TPnt>KZLg1sZVoJpU+d`S_+nM6k_?+=u%e4tvgU-5@84K}O&T@F9*1Lm z&4Wu4&%d`oh2mD+sN4ifui}(&NaaBQ!>~@`{bLt<94Y+!#V;zCRmnXA=J^KA%83AY zQpyKZ*);nOEQiLeSvKsNB5dn=9FqfSgVrrv#maAf6$V*k`Pw>e(!ub93iN?un^oJY z(r(t*o09ty(dVnsog{pM>*l|CaLR^Yz?CXEad2%(aB|;!FWIik zo!-vupYFGG@)qGBkl;U63Xsq9GasLRGm$}Nz)d1@@}sod@=8`~9!=M*vhE+eXj{8A zpyD9UcMs^^=70P&P&Ax!&wDGTH|c%&1-Z$7xF79RwqdVlJ-rtLpAC8+ z9_roxl>3Ef{U?tS0O?lqr=C8=UO}6zxuHDddA{?ni+62y09JDHsH*N_|CPXe5a`Trf&mr( zUn|D`mvzrSwgO-|fT|Se<5boFB|m>)V4!ONkET_kO`RYYdU=ce6kKnniS$4ly=Hj= zKhQ9INil@E1nJyz)SOuQC=!iBz3&m4X#lP(#)3c_ehc_zx5RiT7?~L+{en^K{CsQh zFmnk$Rc;ii>sel%=+w9OwX+*r1!gCqGP!If`?%9mf%dAz? z)49H;Cq8&XO+{bO+smh`H(sDtuHsHksX<>_oT>TVmUr~0V*9Jfl);d~^|D04KWm+x zAPbwUeW_WpJ!^L55tlEYtrj>7KIRbx^<|0q*W0{&9+u}WzT4n@wxx~9mejoK#*yYA z(9u7}f4u0P$5oJnvf=qX19~;(g&0^K7QJ8ngDX3~Vm!YZFteBI_WU0CE)p0RF@0e{H-klMbYDAiu8X-3(AmdDxwhvzcTTxn2Q@w!3R zh5>HiKjrplLipkA?TDo9Q?AlD)Z?tH&-ku|$Gvo4zr^bggMC>TaU4J|IfdKt%hWc1 z!JKpZc?@BaL%**x!~DebF;~WbBoN3qR9j6d4d}3*|$%N zb{5)ZSE>A<=YNo!NsnrE@Tp3Ox_r4H7gZOcEGL}Z&@L-|yXK>Ff^hSA*+(dF^;z-X z@^2AE3Lcl^_WG;^a$D!+cU>}-do5CM5_X9%>Ds3AR|u!BBw3Ll08!Qd6z2Zh8V~;y zT?bg(^8NM~ zdTqsz{c|}qxMKdW4E8F3f7qwcrT9h~yXr$V<*h8X7E`-aYW!$yOcP~qRe#Wg3o5b+QbC-AaYLYOkdTHheF1n6L@`t67ulx`coo+r^& zJh8h9wIyiLNA4J&y|@}k63$nFEaGM5Q^{}QpC)M!_Efmk)2%nBi>N*UT1YB$YS&f6 zQ{(QNOshrvqAjaR!?QaNPac+GbORl$!=Bk6&q(zo4GlYF-W=&ttw97PL*5fx+{V;H z`iI-!blC@KCGRI48ovlYLdH95!qYop2NR^)j}NP&X;hZ&mjkDuXxD`Bg9aU2*M$K* z&rDU_rVFh8kr*1J@b*NFUm&L~ZyG^2S~#hH_^o5K^?FN81-4ArSX!wGnkDhh_w&43 zV6GoK?`;w-I|=|$9u-HP>#PjFZ&LE5Z3_S6z4z_XscbysdjboZcVb^}4}C({pyND% zNogw2a2}Y49h}^FK_Rqfqv>>6U~9`m;PHPwW}ANY>@;k@}b!p}1n8gZn%rP{( z`%z<(YBDivUz&31L`9Gjw<|n)Vja`67XyJQZZw?p3~cK;{KIgQZ*+7sfU4+tr(7V~ zkRP?h^?}={k{!($8DvRO|K(eSCc7uzi1uyp!CBRigwq?MifX0?;bF>r2slD1J8@J$+;?`FqE~uJtx# zEzlX3xo|=6@yX2(awZ)n`$*9c0^*GC^Y}Cj8CF#6QtJfZYC5dfSy1QaGtSGYjEJnCWN!*RS@qFM)K%@CnnRW= zo0^J`X-w_p_#^x#W08ktZmnxa;;FU4(iJPS9$dt0^ym@s>hDffRj&I0lUlG{C+4E~ z=jFPHQ}w7-zuYgowjJdrTwvi2YD{O{Se%ST#G>h?I8?M|-hW#I^?zo||KqN$|JGla zrgax1s`4!X$uBC}^%Jtj5(Zkj0OY9?nJO!h1x5l5;``}rAXNgkdzbYAMrs0C)US^| z+W{z_=%&P9p#cPBiR-Q6mw!RrKrN>M1fqe2#V`L00@ZC?pK|!6U!7PG2oI#%qP}K- zAsm5JSw!8rmW<-rl%_h7A2M-kiYi4A2(BLfkaiMtlP);cI^Z`at(Q&k`a=)!XxqoiNht zebXNALCD2|r|=~GEZu!0S$T`|g^PPT@jtF|Ev#L$K;}-$_V@+F(7fetTKu}#`X$(P zNe0+$Pg|7pulzb$j<6+ySrPOGWK9d`f{@Rh;)U_uLR<65dz51c$Y5I z!CCTgC44syvFE`tnS+(iCTqbq$XaIT$BEj@?DFoiv`7dw1b|e|;B(p>D4;~qG=pFqFTK!8){y!V?f6Ywd zxeqmDWWbnZZglj-#jN<~=vn|%3YhaW2k;?J!P26l-T=H7p!+lPFc9~VU>TXQtAHc# z(0e^^Xdq$84mB`ndi|F}Ajd~*#x1h|1m@*+U$!X`D=q3PF}(x;LXy@InmZJc5Sek! z&y>S52!4wpSMLD%Z4O!qZoq9c z(qbfCVKINy!+%PJ<}Up#_{=2NvUxwb7GqMpbQEfdgatm)C<^3Nd|*Y~oiZmxTFGhw zFP;(rCV%rKFEwutoL;KHV}srzwI%K7yn$)r#23#|a;fFwJ?!p?)Pu)%X>2$t zT5g|{pldaxm7jLN*?jt6L(cI;7@S*Q_m|dw^he8wKMguu8<$jWG}G68|Lgq5vHuKX zD1Peb9K>gYVm8Dv&3B9UFGHXk0o-TVlk({daZ_1F+)e4_{8o2HGVQ0zn776g%Z#cm zX?>Q7=(4dT(Av|!_E(q4Xz~areC@p}I-S6Na`}sNB_F4(B*6nV!8DhgeHb#T-ze$r zturA#8rokQ4N_nf(=jSLr+lh9YGehx&zE)SLK8sSbPZVSyjw97)EtS z=*$UMb?WAeO1+Q^Kp};PRkX{S;!Tk^Fr#~XTwMur;Rf>K?2EN=+$}layqRW$q1VB} zKPNxjL{!l+$cjd*JqQt+RpX}j>`6cAyMdo6F6Q_^<2;`JYPODq=kfVTq#^NxA*tqV zX4ZS|4M&B2Xr4Are_;*G?Z@cdz>$e40-egLFkT&{1QIv4O>s*sqYfUaqV!z9Yy_;@E_~?I1&@~IbfyGG(qxC6sEnKwbZ3TVu;=G3wUBXjDMiK6n24->x;hM zt&I+Gy7aD$_JKspn8C&sQO{|9vq@?&L4FGSvNeQro}M|aiRCuLFlxT`XXl~P#m3)` zHV93m836*t%nO6>1=G0BpXc!Oq3-f5>z}RIwy2|CHr3on_Pfxtl8FOz`n0cTt1*8{ za3?dpsl=7j$ngyg71L$b?+=MvD9!Ef!sL~01}_CavJy($MZz?5%|ANzMK8EjtgMM~ ztT8b&@|4Z7Bbv2XXaA-wV4jVO5_KpDy1%m4%9C8Pr2jQS8ECTC7x^o^*M9oi{Aa?$ zS92M6W{MYE^Y8XY>KV4>`AHHh8W*dW2D zbr3}>FFZyzIRIm^pj~2#lgZs7^ABiGp!Mev@2}xEmLR|5JDM(exIjQD)$rYk4#WBp zep-o3kLEA4d7NQ-s|RsabUA#{7H4kB5G_K-FkJC9Wv{r^!vncU5|6ZYdYIuk+2K)1 zb-Y0xAg$H6h7O`I5Jp+=;tb7=1E7FMG@ zYy0WAwoinBLgcbJ?q5V5%JT^&$QbVKaS z-YB5tEvilo5cY0c8D96crNWr`hpt6sx;NfHMwxr*z5zeqaPqiF2w^Ckajyidhf8Fd z>d9rzkhK}Z-;W-cP44>EF58%)JC9@vjiNAFn6lB}fMa2SN0H!6*D;N2Zx@TQV&=3a zIT&2+>$SPK9q#5t%E;jL0@AWj>0M_pT_piQY)K+IrT0hrnXnC>V=zh z09AcW6`SQGRy57H-61=3G;pKE(_PD8$Y~0n2X5i6%?~zZ49?~CEFS1`{V?;Cm+{E9 z{u}RPBQry3F5XMB!xE5RDeX(Ip5HQGe_Mfk?v`3h&TOa(H56l_JpV*dLmqL`Z$73n zmJ!`!MOV|v1FBXT%l*}7(pq4o+4)Y6hiNDVUZqV~v=@&?65z4w#IXSlzgoB%+Ah9X zVHG@T4l?w*e%E}OGf%RWwr6nb%jzHk-0;ycI$u$I+E`73D8iJ$c+EM15dKLW!A}PG zBkhvs@+#yy@S5Ra`B=aB;hDLSbi_3m8AGdQu#^UQ2 z?p(vpbQ!EwNB!hUeP!1`A=eU-nbaySSGlNaNK&6Sc0c5ylIbyjX7MmDpD{zMMM}c(*dXBJhqU^U+ZZMha$51|6`qq8XZ+HSgM6~j?X;P?j=!<$I<1$oG<(qx60qaOyiq_beA3O}etdA*vsZx^tHzvuh1e-r4Q9ng!< zM1!+3Gczwi)?Dz~Tn>H0s0k^^(?xO%s6T_Xdw5Lh^u({a`;x|*7V`MWyW`{+BZaX3 z{`{V?TS@Q{Dqqt^Hmc6lc+HNAvwP1CDJiQ#atEee28sMl{(lpq*Sgb>@b%{Qn_!eK z+`FHDIbW|m53%?Z{)z;5Q1PxEkOB_{8W9BWQCR7@_}5OO{L&ouW`&ENktK6)5V##a z!hg>o?9tJ?Ps0Pmj}!4$uMdl8r^Qvm38x?|S2;OsIvU(1_AKayk_*uO^WsB7zKB

T0${MyhIQ;dN9dAfb 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

bVa>dVC+`mY+ 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

uU?> zt+U55(C9~((;YKs=YHko;1QaJHl_@MwFKxMDYEI|YL|z5OcqyJ$s7AMBalPb zF6{Zm8;^v-nDMfw5J`%5WklIRQl|Ubh{Z7b`B*7=xtENHUMxJE8c|4B-4VC|? znhJ+~k5YLkjR?&>XJf(YBbLr7#!V{LItmlvO5_D@?@rnJ%R@%^& z0k~c=5%Nh+{FThci5fxgbq&dPX2u2@n!Qow1)BJo zi6;3IKORFFEjHPs5+MZtbjSB=QD$RO1Q+zqq0#xdN@nHX{+fXTSXeRCnSSsIqudMB zgMW@wMQTSk6^_I>5M`6gH(qDIB+^b2;`}m~#@eo%69IZ1I1j3yfp*SHR#=Ddq<17@ zINZORb$rTb1iMeg%}ZB!Q}tH7DLu2C7+5#W^?lf>4`t`4+O^InWAx;!7&qRtgzpkX z{)x zD1kn~mo>t9(vdMtd#Ls>YYdLy#*aBOxyExDsrP0{#`;bt; z(SL>4Du=S|U#YSatipNc2;m&-2?*qz9G zodiXJS802}gq%qQ)aVO?+67A*e%HT<-!4PF%2`N@(sy)FaI#XGy!or=0NSmI9x>f)j#brLAkA%H+Ej}0j`4(4L z^q=kve#TNp#p2n?IBQ9>h=_>6fe#hC`31;>OvG?}7VGxpvml^f^uiraU+{F0^auJk qU}yq`24G$ZA_e(VDd2{{u>84O`E)_^=ke8f{?rU%4JR4>5%V7nPIFNJ literal 4209 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 PB+#`ow?h!%*Ao8&MQ+bo diff --git a/docs/source/Tools/images/Tools_WD_I2CSelector.png b/docs/source/Tools/images/Tools_WD_I2CSelector.png index 95a804c5ef45a3fe393111a9d4b799a61bdb374e..f5090f43935486b46e3de370fdd3743370964a46 100644 GIT binary patch literal 3830 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 literal 3998 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 diff --git a/src/src/Helpers/Hardware_I2C.cpp b/src/src/Helpers/Hardware_I2C.cpp index b345d626e1..58dc7304f4 100644 --- a/src/src/Helpers/Hardware_I2C.cpp +++ b/src/src/Helpers/Hardware_I2C.cpp @@ -32,7 +32,11 @@ void initI2C() { #endif // if !FEATURE_I2C_MULTIPLE { if (Settings.isI2CEnabled(i2cBus)) { - addLog(LOG_LEVEL_INFO, concat(F("INIT : I2C interface "), i2cBus + 1)); + #if !FEATURE_I2C_MULTIPLE + addLog(LOG_LEVEL_INFO, F("INIT : I2C Bus")); + #else // if !FEATURE_I2C_MULTIPLE + addLog(LOG_LEVEL_INFO, concat(F("INIT : I2C Bus "), i2cBus + 1)); + #endif // if !FEATURE_I2C_MULTIPLE I2CSelectHighClockSpeed(i2cBus); // Set normal clock speed, on I2C Bus 1 (index 0) } } diff --git a/src/src/WebServer/I2C_Scanner.cpp b/src/src/WebServer/I2C_Scanner.cpp index e1c2ffc12f..a56e5a618c 100644 --- a/src/src/WebServer/I2C_Scanner.cpp +++ b/src/src/WebServer/I2C_Scanner.cpp @@ -502,7 +502,7 @@ void handle_i2cscanner() { { html_table_class_multirow(); #if FEATURE_I2C_MULTIPLE - html_table_header(strformat(F("I2C interface %d"), i2cBus + 1)); + html_table_header(strformat(F("I2C Bus %d"), i2cBus + 1)); html_TR(); #endif // if FEATURE_I2C_MULTIPLE #if FEATURE_I2CMULTIPLEXER @@ -554,7 +554,7 @@ void handle_i2cscanner() { nDevices = 0; // Reset for next interface } else { html_TR_TD(); - addHtml(strformat(F("I2C pins not configured for interface %d"), i2cBus + 1)); + addHtml(strformat(F("I2C pins not configured for bus %d"), i2cBus + 1)); } html_end_table(); I2CSelectHighClockSpeed(0); // By default the bus is in standard speed

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 PB+#`ow?h!%*Ao8&MQ+bo literal 0 HcmV?d00001 diff --git a/docs/source/Tools/images/Tools_WD_I2CSelector.png b/docs/source/Tools/images/Tools_WD_I2CSelector.png new file mode 100644 index 0000000000000000000000000000000000000000..95a804c5ef45a3fe393111a9d4b799a61bdb374e GIT binary patch literal 3998 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 literal 0 HcmV?d00001 From 26c9fa8a5d6338fcac3c5b3adcd42b8ccbbe44ae Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 10 Feb 2025 23:28:40 +0100 Subject: [PATCH 11/24] [Libs] Avoid using Wire.begin() --- .../examples/SodaqOne-TTN-Mapper-ascii/Sodaq_UBlox_GPS.cpp | 2 +- .../examples/SodaqOne-TTN-Mapper-binary/Sodaq_UBlox_GPS.cpp | 2 +- .../src/SparkFun_ADXL345.cpp | 6 +++--- lib/esp8266-oled-ssd1306/SH1106Wire.cpp | 2 +- lib/esp8266-oled-ssd1306/SSD1306Wire.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-ascii/Sodaq_UBlox_GPS.cpp b/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-ascii/Sodaq_UBlox_GPS.cpp index da0073802e..c455977f34 100644 --- a/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-ascii/Sodaq_UBlox_GPS.cpp +++ b/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-ascii/Sodaq_UBlox_GPS.cpp @@ -82,7 +82,7 @@ void Sodaq_UBlox_GPS::resetValues() void Sodaq_UBlox_GPS::init(int8_t enable_pin) { _enablePin = enable_pin; - Wire.begin(); + // Wire.begin(); ESPEasy has already taken care of this digitalWrite(_enablePin, GPS_ENABLE_OFF); pinMode(_enablePin, OUTPUT); } diff --git a/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-binary/Sodaq_UBlox_GPS.cpp b/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-binary/Sodaq_UBlox_GPS.cpp index da0073802e..c455977f34 100644 --- a/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-binary/Sodaq_UBlox_GPS.cpp +++ b/lib/RN2483-Arduino-Library/examples/SodaqOne-TTN-Mapper-binary/Sodaq_UBlox_GPS.cpp @@ -82,7 +82,7 @@ void Sodaq_UBlox_GPS::resetValues() void Sodaq_UBlox_GPS::init(int8_t enable_pin) { _enablePin = enable_pin; - Wire.begin(); + // Wire.begin(); ESPEasy has already taken care of this digitalWrite(_enablePin, GPS_ENABLE_OFF); pinMode(_enablePin, OUTPUT); } diff --git a/lib/SparkFun_ADXL345_Arduino_Library/src/SparkFun_ADXL345.cpp b/lib/SparkFun_ADXL345_Arduino_Library/src/SparkFun_ADXL345.cpp index 36e14a92bf..cdf22b23aa 100644 --- a/lib/SparkFun_ADXL345_Arduino_Library/src/SparkFun_ADXL345.cpp +++ b/lib/SparkFun_ADXL345_Arduino_Library/src/SparkFun_ADXL345.cpp @@ -55,9 +55,9 @@ ADXL345::ADXL345(int CS) { } void ADXL345::powerOn() { - if (I2C) { - Wire.begin(); // If in I2C Mode Only - } + // if (I2C) { + // Wire.begin(); // If in I2C Mode Only ESPEasy has already taken care of this + // } // ADXL345 TURN ON writeTo(ADXL345_POWER_CTL, 0); // Wakeup diff --git a/lib/esp8266-oled-ssd1306/SH1106Wire.cpp b/lib/esp8266-oled-ssd1306/SH1106Wire.cpp index a24398685b..ce4c9e127c 100644 --- a/lib/esp8266-oled-ssd1306/SH1106Wire.cpp +++ b/lib/esp8266-oled-ssd1306/SH1106Wire.cpp @@ -8,7 +8,7 @@ _scl(scl) {} bool SH1106Wire::connect() { - Wire.begin(this->_sda, this->_scl); + // Wire.begin(this->_sda, this->_scl); // ESPEasy already has Wire initialized properly return true; } diff --git a/lib/esp8266-oled-ssd1306/SSD1306Wire.cpp b/lib/esp8266-oled-ssd1306/SSD1306Wire.cpp index 59b7e7c331..b8991754a6 100644 --- a/lib/esp8266-oled-ssd1306/SSD1306Wire.cpp +++ b/lib/esp8266-oled-ssd1306/SSD1306Wire.cpp @@ -8,7 +8,7 @@ } bool SSD1306Wire::connect() { - Wire.begin(this->_sda, this->_scl); + // Wire.begin(this->_sda, this->_scl); // ESPEasy already has Wire initialized properly return true; } From c32bf94b79e7ff3310115edef1cf22e4c7c9c740 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 10 Feb 2025 23:30:09 +0100 Subject: [PATCH 12/24] [Device] Initialization and alignment improvements on struct --- src/src/DataStructs/DeviceStruct.cpp | 4 ++-- src/src/DataStructs/DeviceStruct.h | 22 ++++++++++++++++++++-- src/src/Helpers/ESPEasy_checks.cpp | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/src/DataStructs/DeviceStruct.cpp b/src/src/DataStructs/DeviceStruct.cpp index 96eafb470c..7f08bed50f 100644 --- a/src/src/DataStructs/DeviceStruct.cpp +++ b/src/src/DataStructs/DeviceStruct.cpp @@ -13,8 +13,8 @@ DeviceStruct::DeviceStruct() : TimerOption(false), TimerOptional(false), DecimalsOnly(false), DuplicateDetection(false), ExitTaskBeforeSave(true), ErrorStateValues(false), PluginStats(false), PluginLogsPeaks(false), PowerManager(false), - TaskLogsOwnPeaks(false), I2CNoDeviceCheck(false), - I2CMax100kHz(false), HasFormatUserVar(false) + TaskLogsOwnPeaks(false), + I2CMax100kHz(false), HasFormatUserVar(false), I2CNoDeviceCheck(false) {} bool DeviceStruct::connectedToGPIOpins() const { diff --git a/src/src/DataStructs/DeviceStruct.h b/src/src/DataStructs/DeviceStruct.h index 9527834c35..8af0b8138a 100644 --- a/src/src/DataStructs/DeviceStruct.h +++ b/src/src/DataStructs/DeviceStruct.h @@ -52,7 +52,7 @@ * DeviceStruct * Description of a plugin \*********************************************************************************************/ -struct __attribute__((__packed__)) DeviceStruct +struct DeviceStruct { DeviceStruct(); @@ -95,7 +95,9 @@ struct __attribute__((__packed__)) DeviceStruct uint8_t Pin1Direction : GPIO_DIRECTION_NR_BITS; uint8_t Pin2Direction : GPIO_DIRECTION_NR_BITS; uint8_t Pin3Direction : GPIO_DIRECTION_NR_BITS; - + + union { + struct { bool PullUpOption : 1; // Allow to set internal pull-up resistors. bool InverseLogicOption : 1; // Allow to invert the boolean state (e.g. a switch) bool FormulaOption : 1; // Allow to enter a formula to convert values during read. (not possible with Custom enabled) @@ -118,6 +120,22 @@ struct __attribute__((__packed__)) DeviceStruct bool HasFormatUserVar : 1; // Optimization to only call this when PLUGIN_FORMAT_USERVAR is implemented bool I2CNoBusSelection : 1; // Dis-allow I2C Bus selection in device configuration + + bool Dummy21 : 1; // Dummy added to force alignment, can be re-used + bool Dummy22 : 1; // Dummy added to force alignment, can be re-used + bool Dummy23 : 1; // Dummy added to force alignment, can be re-used + bool Dummy24 : 1; // Dummy added to force alignment, can be re-used + bool Dummy25 : 1; // Dummy added to force alignment, can be re-used + bool Dummy26 : 1; // Dummy added to force alignment, can be re-used + bool Dummy27 : 1; // Dummy added to force alignment, can be re-used + bool Dummy28 : 1; // Dummy added to force alignment, can be re-used + bool Dummy29 : 1; // Dummy added to force alignment, can be re-used + bool Dummy30 : 1; // Dummy added to force alignment, can be re-used + bool Dummy31 : 1; // Dummy added to force alignment, can be re-used + bool Dummy32 : 1; // Dummy added to force alignment, can be re-used + }; + uint32_t _all{}; + }; }; diff --git a/src/src/Helpers/ESPEasy_checks.cpp b/src/src/Helpers/ESPEasy_checks.cpp index 451af7efe8..bf6a9e582b 100644 --- a/src/src/Helpers/ESPEasy_checks.cpp +++ b/src/src/Helpers/ESPEasy_checks.cpp @@ -108,7 +108,7 @@ void run_compiletime_checks() { const unsigned int LogStructSize = ((13u + 20 * LOG_STRUCT_MESSAGE_LINES) + 3) & ~3; #endif check_size(); // Is not stored - check_size(); // Is not stored + check_size(); // Is not stored #if FEATURE_MQTT_TLS check_size(); #else From 79ebde9c179b56469e7fd7aeb67229a7d8a92f04 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Mon, 10 Feb 2025 23:31:14 +0100 Subject: [PATCH 13/24] [I2C] GPIO (de)coupling improvements --- src/src/Helpers/Hardware_I2C.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/src/Helpers/Hardware_I2C.cpp b/src/src/Helpers/Hardware_I2C.cpp index 238ef9a6e4..9c12c543e0 100644 --- a/src/src/Helpers/Hardware_I2C.cpp +++ b/src/src/Helpers/Hardware_I2C.cpp @@ -136,6 +136,7 @@ void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq, uint32_t clockStretch) #else // ifdef ESP32 static uint32_t lastI2CClockSpeed = 0; #endif // ifdef ESP32 + // static uint8_t cntr = 200; static int8_t last_sda = -1; static int8_t last_scl = -1; static uint32_t last_stretch = 0; @@ -146,8 +147,17 @@ void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq, uint32_t clockStretch) } #ifdef ESP32 - if ((sda != last_sda) || (scl != last_scl)) { - Wire.end(); + if (((sda != last_sda) || (scl != last_scl)) && (last_sda != -1) && (last_scl != -1)) { + if (!Wire.end()) { + addLog(LOG_LEVEL_ERROR, strformat(F("I2C : Wire.end() failed on SDA: %d SCL: %d"), last_sda, last_scl)); + } + gpio_reset_pin((gpio_num_t)last_sda); + gpio_reset_pin((gpio_num_t)last_scl); + // if (cntr) { + // addLog(LOG_LEVEL_ERROR, strformat(F("I2C : Wire.end() called on SDA: %d SCL: %d"), last_sda, last_scl)); + // --cntr; + // } + delay(0); // Release some cycles } #endif // ifdef ESP32 @@ -161,7 +171,8 @@ void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq, uint32_t clockStretch) if ((sda != last_sda) || (scl != last_scl) || (clockFreq != lastI2CClockSpeed)) { #ifdef ESP32 - Wire.begin(sda, scl, clockFreq); // Will only set the clock when not yet initialized. + Wire.setPins(sda, scl); + Wire.begin(); Wire.setClock(clockFreq); #else // ifdef ESP32 Wire.begin(sda, scl); From 8ae4e8286c21c500f527c49e30c97e20a124c43c Mon Sep 17 00:00:00 2001 From: TD-er Date: Tue, 11 Feb 2025 01:39:57 +0100 Subject: [PATCH 14/24] [DeviceStruct] Properly initialize DeviceStruct class --- src/src/DataStructs/DeviceStruct.cpp | 56 +++++++++++++---- src/src/DataStructs/DeviceStruct.h | 89 +++++++++++++++------------- src/src/Helpers/_Plugin_init.cpp | 1 + 3 files changed, 96 insertions(+), 50 deletions(-) diff --git a/src/src/DataStructs/DeviceStruct.cpp b/src/src/DataStructs/DeviceStruct.cpp index 7f08bed50f..ff9ed59fe5 100644 --- a/src/src/DataStructs/DeviceStruct.cpp +++ b/src/src/DataStructs/DeviceStruct.cpp @@ -1,21 +1,57 @@ #include "../DataStructs/DeviceStruct.h" - +//constexpr size_t size = sizeof(DeviceStruct); DeviceStruct::DeviceStruct() : + _all(0u), +// PullUpOption (false), +// InverseLogicOption (false), +// FormulaOption (false), +// Custom (false), +// SendDataOption (false), +// GlobalSyncOption (false), +// TimerOption (false), +// TimerOptional (false), +// DecimalsOnly (false), +// DuplicateDetection (false), +// ExitTaskBeforeSave (true), +// ErrorStateValues (false), +// PluginStats (false), +// PluginLogsPeaks (false), +// PowerManager (false), +// TaskLogsOwnPeaks (false), +// I2CNoDeviceCheck (false), +// I2CMax100kHz (false), +// HasFormatUserVar (false), +// I2CNoBusSelection (false), + Number(0), Type(0), VType(Sensor_VType::SENSOR_TYPE_NONE), Ports(0), ValueCount(0), OutputDataType(Output_Data_type_t::Default), Pin1Direction(static_cast(gpio_direction::gpio_direction_MAX)), Pin2Direction(static_cast(gpio_direction::gpio_direction_MAX)), - Pin3Direction(static_cast(gpio_direction::gpio_direction_MAX)), - PullUpOption(false), InverseLogicOption(false), FormulaOption(false), - Custom(false), SendDataOption(false), GlobalSyncOption(false), - TimerOption(false), TimerOptional(false), DecimalsOnly(false), - DuplicateDetection(false), ExitTaskBeforeSave(true), ErrorStateValues(false), - PluginStats(false), PluginLogsPeaks(false), PowerManager(false), - TaskLogsOwnPeaks(false), - I2CMax100kHz(false), HasFormatUserVar(false), I2CNoDeviceCheck(false) -{} + Pin3Direction(static_cast(gpio_direction::gpio_direction_MAX)) +{ + // Only initialize union members in the constructor body + // TODO: Rename this so it can be default initialized to 'false' + ExitTaskBeforeSave = true; +} + +void DeviceStruct::clear() { + _all = 0; + + ExitTaskBeforeSave = true; + + Number= 0; + Type = 0; + VType = Sensor_VType::SENSOR_TYPE_NONE; + Ports = 0; + ValueCount = 0; + OutputDataType = Output_Data_type_t::Default; + Pin1Direction = static_cast(gpio_direction::gpio_direction_MAX); + Pin2Direction = static_cast(gpio_direction::gpio_direction_MAX); + Pin3Direction = static_cast(gpio_direction::gpio_direction_MAX); + +} bool DeviceStruct::connectedToGPIOpins() const { switch(Type) { diff --git a/src/src/DataStructs/DeviceStruct.h b/src/src/DataStructs/DeviceStruct.h index 8af0b8138a..86b0f2b9a2 100644 --- a/src/src/DataStructs/DeviceStruct.h +++ b/src/src/DataStructs/DeviceStruct.h @@ -56,6 +56,8 @@ struct DeviceStruct { DeviceStruct(); + void clear(); + bool connectedToGPIOpins() const; bool usesTaskDevicePin(int pin) const; @@ -85,6 +87,47 @@ struct DeviceStruct PinSelectPurpose pinDirectionToPurpose(gpio_direction direction) const; PinSelectPurpose getPinSelectPurpose(int pin) const; + union { + uint32_t _all; + + struct { + uint32_t PullUpOption : 1; // Allow to set internal pull-up resistors. + uint32_t InverseLogicOption : 1; // Allow to invert the boolean state (e.g. a switch) + uint32_t FormulaOption : 1; // Allow to enter a formula to convert values during read. (not possible with Custom enabled) + uint32_t Custom : 1; + uint32_t SendDataOption : 1; // Allow to send data to a controller. + uint32_t GlobalSyncOption : 1; // No longer used. Was used for ESPeasy values sync between nodes + uint32_t TimerOption : 1; // Allow to set the "Interval" timer for the plugin. + uint32_t TimerOptional : 1; // When taskdevice timer is not set and not optional, use default "Interval" delay (Settings.Delay) + uint32_t DecimalsOnly : 1; // Allow to set the number of decimals (otherwise treated a 0 decimals) + uint32_t DuplicateDetection : 1; // Some (typically receiving) plugins may receive the same data on multiple nodes. Such a plugin must help detect message duplicates. + uint32_t ExitTaskBeforeSave : 1; // Optimization in memory usage, Do not exit when task data is needed during save. + uint32_t ErrorStateValues : 1; // Support Error State Values, can be called to retrieve surrogate values when PLUGIN_READ returns false + uint32_t PluginStats : 1; // Support for PluginStats to record last N task values, show charts etc. + uint32_t PluginLogsPeaks : 1; // When PluginStats is enabled, a call to PLUGIN_READ will also check for peaks. With this enabled, the plugin must call to check for peaks itself. + uint32_t PowerManager : 1; // Is a Power management controller (Power manager), that can be selected to be intialized *before* the SPI interface is started. + // (F.e.: M5Stack Core/Core2 needs to power the TFT before SPI can be started) + uint32_t TaskLogsOwnPeaks : 1; // When PluginStats is enabled, a call to PLUGIN_READ will also check for peaks. With this enabled, the plugin must call to check for peaks itself. + uint32_t I2CNoDeviceCheck : 1; // When enabled, NO I2C check will be done on the I2C address returned from PLUGIN_I2C_GET_ADDRESS function call + uint32_t I2CMax100kHz : 1; // When enabled, the device is only able to handle 100 kHz bus-clock speed, shows warning and enables "Force Slow I2C speed" by default + + uint32_t HasFormatUserVar : 1; // Optimization to only call this when PLUGIN_FORMAT_USERVAR is implemented + uint32_t I2CNoBusSelection : 1; // Dis-allow I2C Bus selection in device configuration + + uint32_t Dummy21 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy22 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy23 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy24 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy25 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy26 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy27 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy28 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy29 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy30 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy31 : 1; // Dummy added to force alignment, can be re-used + uint32_t Dummy32 : 1; // Dummy added to force alignment, can be re-used + }; + }; uint8_t Number; // Plugin ID number. (PLUGIN_ID_xxx) uint8_t Type; // How the device is connected. e.g. DEVICE_TYPE_SINGLE => connected through 1 datapin @@ -92,50 +135,16 @@ struct DeviceStruct uint8_t Ports; // Port to use when device has multiple I/O pins (N.B. not used much) uint8_t ValueCount; // The number of output values of a plugin. The value should match the number of keys PLUGIN_VALUENAME1_xxx Output_Data_type_t OutputDataType; // Subset of selectable output data types (Default = no selection) - uint8_t Pin1Direction : GPIO_DIRECTION_NR_BITS; - uint8_t Pin2Direction : GPIO_DIRECTION_NR_BITS; - uint8_t Pin3Direction : GPIO_DIRECTION_NR_BITS; - union { + uint8_t PinDirection_allBits; struct { - bool PullUpOption : 1; // Allow to set internal pull-up resistors. - bool InverseLogicOption : 1; // Allow to invert the boolean state (e.g. a switch) - bool FormulaOption : 1; // Allow to enter a formula to convert values during read. (not possible with Custom enabled) - bool Custom : 1; - bool SendDataOption : 1; // Allow to send data to a controller. - bool GlobalSyncOption : 1; // No longer used. Was used for ESPeasy values sync between nodes - bool TimerOption : 1; // Allow to set the "Interval" timer for the plugin. - bool TimerOptional : 1; // When taskdevice timer is not set and not optional, use default "Interval" delay (Settings.Delay) - bool DecimalsOnly : 1; // Allow to set the number of decimals (otherwise treated a 0 decimals) - bool DuplicateDetection : 1; // Some (typically receiving) plugins may receive the same data on multiple nodes. Such a plugin must help detect message duplicates. - bool ExitTaskBeforeSave : 1; // Optimization in memory usage, Do not exit when task data is needed during save. - bool ErrorStateValues : 1; // Support Error State Values, can be called to retrieve surrogate values when PLUGIN_READ returns false - bool PluginStats : 1; // Support for PluginStats to record last N task values, show charts etc. - bool PluginLogsPeaks : 1; // When PluginStats is enabled, a call to PLUGIN_READ will also check for peaks. With this enabled, the plugin must call to check for peaks itself. - bool PowerManager : 1; // Is a Power management controller (Power manager), that can be selected to be intialized *before* the SPI interface is started. - // (F.e.: M5Stack Core/Core2 needs to power the TFT before SPI can be started) - bool TaskLogsOwnPeaks : 1; // When PluginStats is enabled, a call to PLUGIN_READ will also check for peaks. With this enabled, the plugin must call to check for peaks itself. - bool I2CNoDeviceCheck : 1; // When enabled, NO I2C check will be done on the I2C address returned from PLUGIN_I2C_GET_ADDRESS function call - bool I2CMax100kHz : 1; // When enabled, the device is only able to handle 100 kHz bus-clock speed, shows warning and enables "Force Slow I2C speed" by default - - bool HasFormatUserVar : 1; // Optimization to only call this when PLUGIN_FORMAT_USERVAR is implemented - bool I2CNoBusSelection : 1; // Dis-allow I2C Bus selection in device configuration - - bool Dummy21 : 1; // Dummy added to force alignment, can be re-used - bool Dummy22 : 1; // Dummy added to force alignment, can be re-used - bool Dummy23 : 1; // Dummy added to force alignment, can be re-used - bool Dummy24 : 1; // Dummy added to force alignment, can be re-used - bool Dummy25 : 1; // Dummy added to force alignment, can be re-used - bool Dummy26 : 1; // Dummy added to force alignment, can be re-used - bool Dummy27 : 1; // Dummy added to force alignment, can be re-used - bool Dummy28 : 1; // Dummy added to force alignment, can be re-used - bool Dummy29 : 1; // Dummy added to force alignment, can be re-used - bool Dummy30 : 1; // Dummy added to force alignment, can be re-used - bool Dummy31 : 1; // Dummy added to force alignment, can be re-used - bool Dummy32 : 1; // Dummy added to force alignment, can be re-used + uint8_t Pin1Direction : GPIO_DIRECTION_NR_BITS; + uint8_t Pin2Direction : GPIO_DIRECTION_NR_BITS; + uint8_t Pin3Direction : GPIO_DIRECTION_NR_BITS; + uint8_t PinDirection_unused : GPIO_DIRECTION_NR_BITS; }; - uint32_t _all{}; }; + uint8_t Unused{}; // Padding to 12 bytes struct size }; diff --git a/src/src/Helpers/_Plugin_init.cpp b/src/src/Helpers/_Plugin_init.cpp index 84007adad9..56f5bd3688 100644 --- a/src/src/Helpers/_Plugin_init.cpp +++ b/src/src/Helpers/_Plugin_init.cpp @@ -2225,6 +2225,7 @@ void PluginSetup() for (deviceIndex_t deviceIndex; deviceIndex < DeviceIndex_to_Plugin_id_size; ++deviceIndex) { + Device.getDeviceStructForEdit(deviceIndex).clear(); const pluginID_t pluginID = getPluginID_from_DeviceIndex(deviceIndex); if (validPluginID(pluginID)) { From ebf5025c72e52b8e1e0b3f4bfb14fd0e2e7cb3c8 Mon Sep 17 00:00:00 2001 From: TD-er Date: Tue, 11 Feb 2025 15:10:17 +0100 Subject: [PATCH 15/24] [I2C] Fix build failure on ESP8266 --- src/src/Helpers/_Plugin_init.cpp | 4 ++++ src/src/WebServer/DevicesPage.cpp | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/src/Helpers/_Plugin_init.cpp b/src/src/Helpers/_Plugin_init.cpp index 56f5bd3688..9365b8d794 100644 --- a/src/src/Helpers/_Plugin_init.cpp +++ b/src/src/Helpers/_Plugin_init.cpp @@ -2225,7 +2225,11 @@ void PluginSetup() for (deviceIndex_t deviceIndex; deviceIndex < DeviceIndex_to_Plugin_id_size; ++deviceIndex) { + #ifdef ESP32 Device.getDeviceStructForEdit(deviceIndex).clear(); + #elif defined(ESP8266) + Device[deviceIndex].clear(); + #endif const pluginID_t pluginID = getPluginID_from_DeviceIndex(deviceIndex); if (validPluginID(pluginID)) { diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index eda51112e7..db573d2d8f 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -272,10 +272,12 @@ void handle_devices_CopySubmittedSettings(taskIndex_t taskIndex, pluginID_t task if (device.Type == DEVICE_TYPE_I2C) { uint8_t flags = 0; - uint8_t i2cBus = 0; bitWrite(flags, I2C_FLAGS_SLOW_SPEED, isFormItemChecked(F("taskdeviceflags0"))); +#if FEATURE_I2C_MULTIPLE || FEATURE_I2CMULTIPLEXER + uint8_t i2cBus = 0; +#endif - #if FEATURE_I2C_MULTIPLE +#if FEATURE_I2C_MULTIPLE if ((getI2CBusCount() >= 2) && (Settings.isI2CEnabled(1) #if FEATURE_I2C_INTERFACE_3 || Settings.isI2CEnabled(2) @@ -286,7 +288,7 @@ void handle_devices_CopySubmittedSettings(taskIndex_t taskIndex, pluginID_t task i2cBus = getFormItemInt(F("pi2cbus")); set3BitToUL(flags, I2C_FLAGS_BUS_NUMBER, i2cBus); } - #endif // if FEATURE_I2C_MULTIPLE +#endif // if FEATURE_I2C_MULTIPLE # if FEATURE_I2CMULTIPLEXER @@ -1257,7 +1259,9 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex if (Device[DeviceIndex].I2CMax100kHz) { addFormNote(F("This device is specified for max. 100 kHz operation!")); } +#if FEATURE_I2C_MULTIPLE || FEATURE_I2CMULTIPLEXER uint8_t i2cBus = 0; +#endif #if FEATURE_I2C_MULTIPLE if (!Device[DeviceIndex].I2CNoBusSelection) { // If the device doesn't disallow bus selection From 273f41723099f6b30db621d5f6a934e1ac99aaed Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 11 Feb 2025 22:44:00 +0100 Subject: [PATCH 16/24] [I2C] Clean up unneeded logging --- src/src/Helpers/Hardware_I2C.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/src/Helpers/Hardware_I2C.cpp b/src/src/Helpers/Hardware_I2C.cpp index 9c12c543e0..1151d185ef 100644 --- a/src/src/Helpers/Hardware_I2C.cpp +++ b/src/src/Helpers/Hardware_I2C.cpp @@ -136,7 +136,6 @@ void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq, uint32_t clockStretch) #else // ifdef ESP32 static uint32_t lastI2CClockSpeed = 0; #endif // ifdef ESP32 - // static uint8_t cntr = 200; static int8_t last_sda = -1; static int8_t last_scl = -1; static uint32_t last_stretch = 0; @@ -151,21 +150,17 @@ void I2CBegin(int8_t sda, int8_t scl, uint32_t clockFreq, uint32_t clockStretch) if (!Wire.end()) { addLog(LOG_LEVEL_ERROR, strformat(F("I2C : Wire.end() failed on SDA: %d SCL: %d"), last_sda, last_scl)); } - gpio_reset_pin((gpio_num_t)last_sda); + gpio_reset_pin((gpio_num_t)last_sda); // Force-release pins to allow GPIO-multiplexing the Wire object gpio_reset_pin((gpio_num_t)last_scl); - // if (cntr) { - // addLog(LOG_LEVEL_ERROR, strformat(F("I2C : Wire.end() called on SDA: %d SCL: %d"), last_sda, last_scl)); - // --cntr; - // } - delay(0); // Release some cycles + delay(0); // Release some cycles } #endif // ifdef ESP32 #ifndef BUILD_NO_DEBUG - if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { - addLog(LOG_LEVEL_DEBUG, strformat(F("I2C : SDA: %d, SCL: %d, Clock: %d (%d) (Stretch: %d)"), - sda, scl, clockFreq, lastI2CClockSpeed, clockStretch)); + if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) { + addLog(LOG_LEVEL_DEBUG_DEV, strformat(F("I2C : SDA: %d, SCL: %d, Clock: %d (%d) (Stretch: %d)"), + sda, scl, clockFreq, lastI2CClockSpeed, clockStretch)); } #endif // ifndef BUILD_NO_DEBUG From ab734377739e8d87d10eefb40f8a82a88c07108f Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 11 Feb 2025 22:45:43 +0100 Subject: [PATCH 17/24] [FormSelector] Use INT_MAX as default to avoid -1 -none- value being shown as default --- src/src/DataTypes/FormSelectorOptions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/src/DataTypes/FormSelectorOptions.h b/src/src/DataTypes/FormSelectorOptions.h index c09791fe45..e5b01a24ad 100644 --- a/src/src/DataTypes/FormSelectorOptions.h +++ b/src/src/DataTypes/FormSelectorOptions.h @@ -71,7 +71,7 @@ class FormSelectorOptions { String onChangeCall; // Allow to add "(default)" to some option. - int default_index = -1; + int default_index = INT_MAX; protected: From 007eb4cff2534ddfa0a26c477abafc826d1d9254 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 11 Feb 2025 22:46:14 +0100 Subject: [PATCH 18/24] [I2C] Update screenshot without (default) --- .../Hardware/Hardware_I2CMultiplexer2.png | Bin 11267 -> 10548 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/source/Hardware/Hardware_I2CMultiplexer2.png b/docs/source/Hardware/Hardware_I2CMultiplexer2.png index b5c6128fcd015f2a81557eb482a6c2d448dc06c2..93505af9937a17e9bf111b2b088ffc09ac0fb6cd 100644 GIT binary patch literal 10548 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 Date: Tue, 11 Feb 2025 22:47:29 +0100 Subject: [PATCH 19/24] [GPIO Selector] Show Wifi Status LED and Reset Pin when configured --- src/src/Helpers/StringGenerator_GPIO.cpp | 16 +++++++++++++++ src/src/Helpers/StringGenerator_GPIO.h | 3 ++- src/src/WebServer/HardwarePage.cpp | 4 ++-- src/src/WebServer/Markup.cpp | 26 ++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/src/Helpers/StringGenerator_GPIO.cpp b/src/src/Helpers/StringGenerator_GPIO.cpp index 21f93d9d42..d50c470fba 100644 --- a/src/src/Helpers/StringGenerator_GPIO.cpp +++ b/src/src/Helpers/StringGenerator_GPIO.cpp @@ -226,6 +226,8 @@ const __FlashStringHelper* getConflictingUse(int gpio, PinSelectPurpose purpose) #if FEATURE_ETHERNET bool includeEthernet = true; #endif // if FEATURE_ETHERNET + bool includeStatusLed = true; + bool includeResetPin = true; switch (purpose) { case PinSelectPurpose::I2C: @@ -255,6 +257,12 @@ const __FlashStringHelper* getConflictingUse(int gpio, PinSelectPurpose purpose) includeSDCard = false; break; #endif + case PinSelectPurpose::Status_led: + includeStatusLed = false; + break; + case PinSelectPurpose::Reset_pin: + includeResetPin = false; + break; } if (includeI2C && Settings.isI2C_pin(gpio)) { @@ -274,6 +282,14 @@ const __FlashStringHelper* getConflictingUse(int gpio, PinSelectPurpose purpose) return F("SPI"); } + if (includeStatusLed && (Settings.Pin_status_led == gpio) && (-1 != gpio)) { + return F("Wifi Status LED"); + } + + if (includeResetPin && (Settings.Pin_Reset == gpio) && (-1 != gpio)) { + return F("Reset Pin"); + } + if (includeSerial) { #if FEATURE_DEFINE_SERIAL_CONSOLE_PORT if (Settings.UseSerial && diff --git a/src/src/Helpers/StringGenerator_GPIO.h b/src/src/Helpers/StringGenerator_GPIO.h index 80ab040ecc..90d09c4fb0 100644 --- a/src/src/Helpers/StringGenerator_GPIO.h +++ b/src/src/Helpers/StringGenerator_GPIO.h @@ -32,7 +32,8 @@ enum class PinSelectPurpose : uint8_t { #if FEATURE_SD SD_Card, #endif - + Status_led, + Reset_pin, }; diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 11c25d8504..79afa14ec5 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -158,12 +158,12 @@ void handle_hardware() { addFormHeader(F("Hardware Settings"), F("ESPEasy#Hardware_page"), F("Hardware/Hardware.html")); addFormSubHeader(F("Wifi Status LED")); - addFormPinSelect(PinSelectPurpose::Generic_output, formatGpioName_output(F("LED")), F("pled"), Settings.Pin_status_led); + addFormPinSelect(PinSelectPurpose::Status_led, formatGpioName_output(F("LED")), F("pled"), Settings.Pin_status_led); addFormCheckBox(F("Inversed LED"), F("pledi"), Settings.Pin_status_led_Inversed); addFormNote(F("Use ’GPIO-2 (D4)’ with ’Inversed’ checked for onboard LED")); addFormSubHeader(F("Reset Pin")); - addFormPinSelect(PinSelectPurpose::Generic_input, formatGpioName_input(F("Switch")), F("pres"), Settings.Pin_Reset); + addFormPinSelect(PinSelectPurpose::Reset_pin, formatGpioName_input(F("Switch")), F("pres"), Settings.Pin_Reset); addFormNote(F("Press about 10s for factory reset")); #if FEATURE_I2CMULTIPLEXER diff --git a/src/src/WebServer/Markup.cpp b/src/src/WebServer/Markup.cpp index ff9dc6c7ce..cf7cce7243 100644 --- a/src/src/WebServer/Markup.cpp +++ b/src/src/WebServer/Markup.cpp @@ -116,6 +116,8 @@ void addPinSelector_Item(PinSelectPurpose purpose, const String& gpio_label, int #if FEATURE_SD bool includeSDCard = true; #endif // if FEATURE_SD + // bool includeStatusLed = true; // Added as place-holders, see below + // bool includeResetPin = true; switch (purpose) { case PinSelectPurpose::SPI: @@ -185,6 +187,21 @@ void addPinSelector_Item(PinSelectPurpose purpose, const String& gpio_label, int } break; #endif + + case PinSelectPurpose::Status_led: + // includeStatusLed = false; // Placeholder, see below + if (!output) { + return; + } + break; + + case PinSelectPurpose::Reset_pin: + // includeResetPin = false; // Placeholder, see below + if (!input) { + return; + } + break; + } if (includeI2C && Settings.isI2C_pin(gpio)) { @@ -199,6 +216,15 @@ void addPinSelector_Item(PinSelectPurpose purpose, const String& gpio_label, int disabled = true; } + // Not blocking these GPIO pins, as they may already be in dual-purpose use, just a place-holder + // if (includeStatusLed && (Settings.Pin_status_led == gpio)) { + // disabled = true; + // } + + // if (includeResetPin && (Settings.Pin_Reset == gpio)) { + // disabled = true; + // } + #if FEATURE_ETHERNET if (Settings.isEthernetPin(gpio) || (includeEthernet && Settings.isEthernetPinOptional(gpio))) { From 8611b79426cfebe66bc6b7b6b118ae57474fb9c2 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Tue, 11 Feb 2025 23:21:06 +0100 Subject: [PATCH 20/24] [I2C] Switch to correct bus for PCF/MCP GPIO monitoring --- src/src/Globals/Plugins.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/src/Globals/Plugins.cpp b/src/src/Globals/Plugins.cpp index a0d78e6286..ead60d0509 100644 --- a/src/src/Globals/Plugins.cpp +++ b/src/src/Globals/Plugins.cpp @@ -540,6 +540,10 @@ bool PluginCall(uint8_t Function, struct EventStruct *event, String& str) if (validDeviceIndex(DeviceIndex)) { START_TIMER; + #if FEATURE_I2C_MULTIPLE + const uint8_t i2cBus = Settings.getI2CInterfacePCFMCP(); + I2CSelectHighClockSpeed(i2cBus); // Switch to desired bus, no need to switch back, net I2C plugin call will switch to desired bus + #endif // if FEATURE_I2C_MULTIPLE PluginCall(DeviceIndex, Function, &TempEvent, str); STOP_TIMER_TASK(DeviceIndex, Function); } From c78a087287e4c8a4113e5ef3fcad0ac211302671 Mon Sep 17 00:00:00 2001 From: TD-er Date: Wed, 12 Feb 2025 14:54:02 +0100 Subject: [PATCH 21/24] [I2C] Show conflicting I2C bus when using multiple I2C busses --- src/src/Helpers/Hardware_device_info.cpp | 20 ----------- src/src/Helpers/Hardware_device_info.h | 18 +++++++++- src/src/Helpers/StringGenerator_GPIO.cpp | 45 ++++++++++++++++++------ src/src/Helpers/StringGenerator_GPIO.h | 8 +++++ src/src/WebServer/HardwarePage.cpp | 4 +-- src/src/WebServer/Markup.cpp | 3 +- src/src/WebServer/Markup_Forms.cpp | 7 ++-- src/src/WebServer/Markup_Forms.h | 1 + 8 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/src/Helpers/Hardware_device_info.cpp b/src/src/Helpers/Hardware_device_info.cpp index 2b74959c1f..ce69b6eb13 100644 --- a/src/src/Helpers/Hardware_device_info.cpp +++ b/src/src/Helpers/Hardware_device_info.cpp @@ -399,26 +399,6 @@ uint32_t getFreeSketchSpace() { return res; } -/********************************************************************************************\ - I2C support - \*********************************************************************************************/ -const uint8_t getI2CBusCount() { - #if !FEATURE_I2C_MULTIPLE - return 1u; - #else // if !FEATURE_I2C_MULTIPLE - - // Not querying the supported nr. of I2C busses in hardware, but using software multiplexing - // Assume/expect IDF 5.x - // # if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED - # if FEATURE_I2C_INTERFACE_3 - return 3u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) - # else // if FEATURE_I2C_INTERFACE_3 - return 2u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) - # endif // if FEATURE_I2C_INTERFACE_3 - // # endif // if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED - #endif // if !FEATURE_I2C_MULTIPLE - return 0u; // Unexpected exit... -} /********************************************************************************************\ PSRAM support diff --git a/src/src/Helpers/Hardware_device_info.h b/src/src/Helpers/Hardware_device_info.h index 9f289a7803..8b86100172 100644 --- a/src/src/Helpers/Hardware_device_info.h +++ b/src/src/Helpers/Hardware_device_info.h @@ -98,7 +98,23 @@ uint32_t getFreeSketchSpace(); /********************************************************************************************\ I2C support \*********************************************************************************************/ -const uint8_t getI2CBusCount(); +constexpr uint8_t getI2CBusCount() { +#if FEATURE_I2C_MULTIPLE + // Not querying the supported nr. of I2C busses in hardware, but using software multiplexing + // Assume/expect IDF 5.x + // # if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED + # if FEATURE_I2C_INTERFACE_3 + return 3u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) + # else // if FEATURE_I2C_INTERFACE_3 + return 2u; // SOC_I2C_NUM; // Let's go for all I2C busses, including LP_I2C (low power, where available) + # endif // if FEATURE_I2C_INTERFACE_3 + // #else + // return 0u; + // # endif // if defined(SOC_I2C_SUPPORTED) && SOC_I2C_SUPPORTED +#else + return 1u; +#endif +} /********************************************************************************************\ PSRAM support diff --git a/src/src/Helpers/StringGenerator_GPIO.cpp b/src/src/Helpers/StringGenerator_GPIO.cpp index d50c470fba..473da0a571 100644 --- a/src/src/Helpers/StringGenerator_GPIO.cpp +++ b/src/src/Helpers/StringGenerator_GPIO.cpp @@ -231,6 +231,12 @@ const __FlashStringHelper* getConflictingUse(int gpio, PinSelectPurpose purpose) switch (purpose) { case PinSelectPurpose::I2C: +#if FEATURE_I2C_MULTIPLE + case PinSelectPurpose::I2C_2: +#if FEATURE_I2C_INTERFACE_3 + case PinSelectPurpose::I2C_3: +#endif +#endif includeI2C = false; break; case PinSelectPurpose::SPI: @@ -266,16 +272,35 @@ const __FlashStringHelper* getConflictingUse(int gpio, PinSelectPurpose purpose) } if (includeI2C && Settings.isI2C_pin(gpio)) { - return ((Settings.Pin_i2c_sda == gpio) - #if FEATURE_I2C_MULTIPLE - || (Settings.Pin_i2c2_sda == gpio) - #if FEATURE_I2C_INTERFACE_3 - || (Settings.Pin_i2c3_sda == gpio) - #endif // if FEATURE_I2C_INTERFACE_3 - #endif // if FEATURE_I2C_MULTIPLE - ) - ? F("I2C SDA") : - F("I2C SCL"); + for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) + { + if (Settings.getI2CSdaPin(i2cBus) == gpio) { + #if FEATURE_I2C_MULTIPLE + switch (i2cBus) { + case 0: return F("I2C SDA (bus 1)"); + case 1: return F("I2C SDA (bus 2)"); + #if FEATURE_I2C_INTERFACE_3 + case 2: return F("I2C SDA (bus 3)"); + #endif + } + #else + return F("I2C SDA"); + #endif + } + if (Settings.getI2CSclPin(i2cBus) == gpio) { + #if FEATURE_I2C_MULTIPLE + switch (i2cBus) { + case 0: return F("I2C SCL (bus 1)"); + case 1: return F("I2C SCL (bus 2)"); + #if FEATURE_I2C_INTERFACE_3 + case 2: return F("I2C SCL (bus 3)"); + #endif + } + #else + return F("I2C SCL"); + #endif + } + } } if (includeSPI && Settings.isSPI_pin(gpio)) { diff --git a/src/src/Helpers/StringGenerator_GPIO.h b/src/src/Helpers/StringGenerator_GPIO.h index 90d09c4fb0..e81d41e09c 100644 --- a/src/src/Helpers/StringGenerator_GPIO.h +++ b/src/src/Helpers/StringGenerator_GPIO.h @@ -23,6 +23,12 @@ enum class PinSelectPurpose : uint8_t { Generic_output, Generic_bidir, I2C, + #if FEATURE_I2C_MULTIPLE + I2C_2, + #if FEATURE_I2C_INTERFACE_3 + I2C_3, + #endif + #endif SPI, SPI_MISO, Ethernet, @@ -37,6 +43,8 @@ enum class PinSelectPurpose : uint8_t { }; + + /*********************************************************************************************\ Device GPIO name functions to share flash strings \*********************************************************************************************/ diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 79afa14ec5..d2c491f75d 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -223,8 +223,8 @@ void handle_hardware() { } else #endif // if FEATURE_PLUGIN_PRIORITY { - addFormPinSelectI2C(formatGpioName_bidirectional(F("SDA")), strformat(F("psda%u"), i2cBus), Settings.getI2CSdaPin(i2cBus)); - addFormPinSelectI2C(formatGpioName_output(F("SCL")), strformat(F("pscl%u"), i2cBus), Settings.getI2CSclPin(i2cBus)); + addFormPinSelectI2C(formatGpioName_bidirectional(F("SDA")), strformat(F("psda%u"), i2cBus), i2cBus, Settings.getI2CSdaPin(i2cBus)); + addFormPinSelectI2C(formatGpioName_output(F("SCL")), strformat(F("pscl%u"), i2cBus), i2cBus, Settings.getI2CSclPin(i2cBus)); } addFormNumericBox(F("Clock Speed"), strformat(F("pi2csp%u"), i2cBus), Settings.getI2CClockSpeed(i2cBus), 100, 3400000); addUnit(F("Hz")); diff --git a/src/src/WebServer/Markup.cpp b/src/src/WebServer/Markup.cpp index cf7cce7243..5d40701947 100644 --- a/src/src/WebServer/Markup.cpp +++ b/src/src/WebServer/Markup.cpp @@ -154,9 +154,10 @@ void addPinSelector_Item(PinSelectPurpose purpose, const String& gpio_label, int } break; - case PinSelectPurpose::Generic_bidir: case PinSelectPurpose::I2C: includeI2C = false; + // fallthrough + case PinSelectPurpose::Generic_bidir: if (!output || !input) { // SDA is obviously bidirectional. diff --git a/src/src/WebServer/Markup_Forms.cpp b/src/src/WebServer/Markup_Forms.cpp index 98af3a2ceb..d89e0dda25 100644 --- a/src/src/WebServer/Markup_Forms.cpp +++ b/src/src/WebServer/Markup_Forms.cpp @@ -470,10 +470,13 @@ void addFormPinSelect(const String& label, const String & id, int choice) } */ -void addFormPinSelectI2C(const String& label, const String& id, int choice) +void addFormPinSelectI2C(const String& label, const String& id, uint8_t i2cBus, int choice) { addRowLabel_tr_id(label, id); - addPinSelect(PinSelectPurpose::I2C, id, choice); + const PinSelectPurpose purpose = static_cast( + static_cast(PinSelectPurpose::I2C) + i2cBus); + + addPinSelect(purpose, id, choice); } void addFormSelectorI2C(const String& id, diff --git a/src/src/WebServer/Markup_Forms.h b/src/src/WebServer/Markup_Forms.h index a467dc3200..b1202670cb 100644 --- a/src/src/WebServer/Markup_Forms.h +++ b/src/src/WebServer/Markup_Forms.h @@ -279,6 +279,7 @@ void addFormPinSelect(PinSelectPurpose purpose, const __FlashStringHelper * labe void addFormPinSelectI2C(const String& label, const String& id, + uint8_t i2cBus, int choice); void addFormSelectorI2C(const String& id, From 7812f631c098a688320743008e2c8b11b2d128e3 Mon Sep 17 00:00:00 2001 From: TD-er Date: Wed, 12 Feb 2025 18:22:15 +0100 Subject: [PATCH 22/24] [I2C] Fix saving 2nd I2C bus GPIOs --- src/src/WebServer/HardwarePage.cpp | 12 ++++++------ src/src/WebServer/Markup.cpp | 6 ++++++ src/src/WebServer/Markup_Forms.cpp | 17 +++++++++++++++++ src/src/WebServer/Markup_Forms.h | 6 ++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index d2c491f75d..53d0c5f3fe 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -47,8 +47,8 @@ void handle_hardware() { if (!isI2CPriorityTaskActive(0)) #endif //if FEATURE_PLUGIN_PRIORITY { - Settings.Pin_i2c_sda = getFormItemInt(F("psda0")); - Settings.Pin_i2c_scl = getFormItemInt(F("pscl0")); + update_whenset_FormItemInt(F("psda0"), Settings.Pin_i2c_sda); + update_whenset_FormItemInt(F("pscl0"), Settings.Pin_i2c_scl); } Settings.I2C_clockSpeed = getFormItemInt(F("pi2csp0"), DEFAULT_I2C_CLOCK_SPEED); Settings.I2C_clockSpeed_Slow = getFormItemInt(F("pi2cspslow0"), DEFAULT_I2C_CLOCK_SPEED_SLOW); @@ -67,8 +67,8 @@ void handle_hardware() { if (!isI2CPriorityTaskActive(1)) #endif //if FEATURE_PLUGIN_PRIORITY { - Settings.Pin_i2c2_sda = getFormItemInt(F("psda1")); - Settings.Pin_i2c2_scl = getFormItemInt(F("pscl1")); + update_whenset_FormItemInt(F("psda1"), Settings.Pin_i2c2_sda); + update_whenset_FormItemInt(F("pscl1"), Settings.Pin_i2c2_scl); } Settings.I2C2_clockSpeed = getFormItemInt(F("pi2csp1"), DEFAULT_I2C_CLOCK_SPEED); Settings.I2C2_clockSpeed_Slow = getFormItemInt(F("pi2cspslow1"), DEFAULT_I2C_CLOCK_SPEED_SLOW); @@ -88,8 +88,8 @@ void handle_hardware() { if (!isI2CPriorityTaskActive(2)) #endif //if FEATURE_PLUGIN_PRIORITY { - Settings.Pin_i2c3_sda = getFormItemInt(F("psda2")); - Settings.Pin_i2c3_scl = getFormItemInt(F("pscl2")); + update_whenset_FormItemInt(F("psda2"), Settings.Pin_i2c3_sda); + update_whenset_FormItemInt(F("pscl2"), Settings.Pin_i2c3_scl); } Settings.I2C3_clockSpeed = getFormItemInt(F("pi2csp2"), DEFAULT_I2C_CLOCK_SPEED); Settings.I2C3_clockSpeed_Slow = getFormItemInt(F("pi2cspslow2"), DEFAULT_I2C_CLOCK_SPEED_SLOW); diff --git a/src/src/WebServer/Markup.cpp b/src/src/WebServer/Markup.cpp index 5d40701947..93429bae7b 100644 --- a/src/src/WebServer/Markup.cpp +++ b/src/src/WebServer/Markup.cpp @@ -155,6 +155,12 @@ void addPinSelector_Item(PinSelectPurpose purpose, const String& gpio_label, int break; case PinSelectPurpose::I2C: +#if FEATURE_I2C_MULTIPLE + case PinSelectPurpose::I2C_2: +#if FEATURE_I2C_INTERFACE_3 + case PinSelectPurpose::I2C_3: +#endif +#endif includeI2C = false; // fallthrough case PinSelectPurpose::Generic_bidir: diff --git a/src/src/WebServer/Markup_Forms.cpp b/src/src/WebServer/Markup_Forms.cpp index d89e0dda25..ca9518637a 100644 --- a/src/src/WebServer/Markup_Forms.cpp +++ b/src/src/WebServer/Markup_Forms.cpp @@ -640,6 +640,23 @@ bool update_whenset_FormItemInt(const String& key, int& value) { return false; } +bool update_whenset_FormItemInt(const __FlashStringHelper * key, + int8_t& value) +{ + return update_whenset_FormItemInt(String(key), value); +} + + +bool update_whenset_FormItemInt(const String& key, int8_t& value) { + int tmpVal; + + if (getCheckWebserverArg_int(key, tmpVal)) { + value = tmpVal; + return true; + } + return false; +} + bool update_whenset_FormItemInt(const __FlashStringHelper * key, uint8_t& value) { diff --git a/src/src/WebServer/Markup_Forms.h b/src/src/WebServer/Markup_Forms.h index b1202670cb..00c4a89a4a 100644 --- a/src/src/WebServer/Markup_Forms.h +++ b/src/src/WebServer/Markup_Forms.h @@ -326,6 +326,12 @@ bool update_whenset_FormItemInt(const __FlashStringHelper * key, bool update_whenset_FormItemInt(const String& key, int & value); +bool update_whenset_FormItemInt(const __FlashStringHelper * key, + int8_t & value); + +bool update_whenset_FormItemInt(const String& key, + int8_t & value); + bool update_whenset_FormItemInt(const __FlashStringHelper * key, uint8_t & value); From c28c98932bab008bcc5df0a330716af5fa3e3733 Mon Sep 17 00:00:00 2001 From: TD-er Date: Wed, 12 Feb 2025 18:22:45 +0100 Subject: [PATCH 23/24] [I2C] Rename "I2C Interface" to "I2C Bus" --- docs/source/Hardware/Hardware.rst | 32 ++++++++++++------------ docs/source/Tools/Tools.rst | 10 ++++---- src/src/Helpers/ESPEasy_Storage.cpp | 2 +- src/src/Helpers/Hardware_I2C.cpp | 2 +- src/src/Helpers/I2C_access.cpp | 2 +- src/src/WebServer/AdvancedConfigPage.cpp | 4 +-- src/src/WebServer/DevicesPage.cpp | 6 ++--- src/src/WebServer/HardwarePage.cpp | 6 ++--- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/source/Hardware/Hardware.rst b/docs/source/Hardware/Hardware.rst index 2480651d2a..446ce8d99f 100644 --- a/docs/source/Hardware/Hardware.rst +++ b/docs/source/Hardware/Hardware.rst @@ -34,7 +34,7 @@ This feature can be useful in a development/laboratory environment, for when the ------------- -I2C Interface +I2C Bus ------------- When using devices that use the I2C bus (Inter-integrated circuit, also known as IIC, and mostly compatible with SM Bus) (`Wikipedia: I2C `_) some pins have to be configured, and initialized during boot, for the SDA and SCL connections. This can be any unused pair of pins on the ESP board. @@ -59,25 +59,25 @@ A device flag has been added for specific devices to have **Force Slow I2C speed Added: 2025-02-02 -Multiple I2C Interfaces can be configured on ESP32 builds. This aids in connecting all on-board sensors and devices when multiple GPIO pin-pairs are used for I2C devices. By default, 2 I2C Interfaces are made available, but via compile-time options, a 3rd I2C Interface can be enabled, if required. +Multiple I2C Busses can be configured on ESP32 builds. This aids in connecting all on-board sensors and devices when multiple GPIO pin-pairs are used for I2C devices. By default, 2 I2C Busses are made available, but via compile-time options, a 3rd I2C Bus can be enabled, if required. .. image:: Hardware_I2CInterface2.png -The available options are the same as for the first I2C Interface. +The available options are the same as for the first I2C Bus. -If a second (or third) I2C Interface are not needed, then leave the GPIO settings on ``- None -``, and the interface won't be initialized, and not shown in the configuration options. +If a second (or third) I2C Bus are not needed, then leave the GPIO settings on ``- None -``, and the interface won't be initialized, and not shown in the configuration options. -NB: The second (or third) I2C Interface should not be configured for the same GPIO pins as any other I2C Interface. +NB: The second (or third) I2C Bus should not be configured for the same GPIO pins as any other I2C Bus. NB2: Some boards require that in the Serial Console Settings (Tools/Advanced), the ``Fall-back to Serial 0`` option is disabled, to free the GPIO pins for I2C use. -When multiple I2C Interfaces are configured (so, ``SDA`` and ``SCL`` GPIO-pins configured), each task configured with an I2C device will show a selection for the I2C Interface to use. As expected, the first I2C Interface is selected by default, and another interface can be selected as required. +When multiple I2C Busses are configured (so, ``SDA`` and ``SCL`` GPIO-pins configured), each task configured with an I2C device will show a selection for the I2C Bus to use. As expected, the first I2C Bus is selected by default, and another interface can be selected as required. -*Device specific I2C Interface selection:* +*Device specific I2C Bus selection:* .. image:: Device_I2CInterfaceSelection.png -NB: If a multiplexer is configured for 1 of the I2C Interfaces (but *not* for all interfaces), the I2C Interface selector will save & reload the page to show/hide the multiplexer options, below. +NB: If a multiplexer is configured for 1 of the I2C Busses (but *not* for all interfaces), the I2C Bus selector will save & reload the page to show/hide the multiplexer options, below. .. image:: Device_I2CInterfaceSelectionReload.png @@ -85,7 +85,7 @@ This screenshot shows the reload icon, to indicate that changing the selection w .. image:: Device_I2CInterfaceSelection3.png -And an example for when 3 I2C Interfaces are available (compile-time option!) and configured. +And an example for when 3 I2C Busses are available (compile-time option!) and configured. --------------- I2C Multiplexer @@ -138,16 +138,16 @@ All these chips/boards can be found at Adafruit, Aliexpress, Banggood, EBay, etc Added: 2025-02-02 -With the introduction of multiple I2C Interfaces, it is also plausible to configure an I2C Multiplexer on the second (or third, when included in the build) I2C Interface. +With the introduction of multiple I2C Busses, it is also plausible to configure an I2C Multiplexer on the second (or third, when included in the build) I2C Bus. .. image:: Hardware_I2CMultiplexer2.png -This allows the same configuration options as shown above for the first I2C Interface, as all I2C Interfaces are completely independent from each other. +This allows the same configuration options as shown above for the first I2C Bus, as all I2C Busses are completely independent from each other. Device configuration ^^^^^^^^^^^^^^^^^^^^ -If an I2C multiplexer is configured for the selected I2C Interface, the Device edit page for I2C devices will show extra options to select the multiplexer channel the device is connected on. +If an I2C multiplexer is configured for the selected I2C Bus, the Device edit page for I2C devices will show extra options to select the multiplexer channel the device is connected on. There is the default option of Single channel, or, when a TCA9548a, TCA9546a or TCA9543a is configured, Multiple channels. @@ -180,15 +180,15 @@ PCF & MCP Direct I/O Added: 2025-02-02 -For interacting with the PCF8574 or MCP23017 GPIO Extenders no Device Task is required, so no I2C Interface configuration is available. +For interacting with the PCF8574 or MCP23017 GPIO Extenders no Device Task is required, so no I2C Bus configuration is available. -When multiple I2C Interfaces are configured (ESP32 only), we need some configuration to overcome that situation, to avoid having to connect these I/O extenders on the first I2C Interface. +When multiple I2C Busses are configured (ESP32 only), we need some configuration to overcome that situation, to avoid having to connect these I/O extenders on the first I2C Bus. .. image:: Hardware_PCFMCP_I2CSelector.png -When using multiple PCF and/or MCP GPIO extenders, they must all be connected to this I2C Interface, and any Device Tasks should also use the same I2C Interface. +When using multiple PCF and/or MCP GPIO extenders, they must all be connected to this I2C Bus, and any Device Tasks should also use the same I2C Bus. -NB: If only 1 I2C Interface is configured, this section isn't shown. +NB: If only 1 I2C Bus is configured, this section isn't shown. ------------- diff --git a/docs/source/Tools/Tools.rst b/docs/source/Tools/Tools.rst index 2fccbbbb0d..e69ef2aff6 100644 --- a/docs/source/Tools/Tools.rst +++ b/docs/source/Tools/Tools.rst @@ -275,11 +275,11 @@ N.B. these modules all use I2C, so they need to be connected to the configured I Added: 2025-02-02 -When multiple I2C Interfaces are configured (ESP32 only), we need to configure on which I2C Interface the RTC chip is connected: +When multiple I2C Busses are configured (ESP32 only), we need to configure on which I2C Bus the RTC chip is connected: .. image:: images/Tools_RTC_I2CSelector.png -NB: If only 1 I2C Interface is configured, this configuration option isn't shown. +NB: If only 1 I2C Bus is configured, this configuration option isn't shown. Procedure to configure a real time clock (RTC) chip: @@ -420,11 +420,11 @@ What can be read/set/changed must still be documented. Added: 2025-02-02 -When multiple I2C Interfaces are configured (ESP32 only), we need to configure on which I2C Interface the Watchdog chip is connected: +When multiple I2C Busses are configured (ESP32 only), we need to configure on which I2C Bus the Watchdog chip is connected: .. image:: images/Tools_WD_I2CSelector.png -NB: If only 1 I2C Interface is configured, this configuration option isn't shown. +NB: If only 1 I2C Bus is configured, this configuration option isn't shown. JSON bool output without quotes @@ -970,7 +970,7 @@ Example scan using an I2C multiplexer, showing multiple devices across multiple Added: 2025-02-02 -When having multiple I2C Interfaces configured, for each configured interface an I2C Scan is performed, including the multiplexer if that's configured. +When having multiple I2C Busses configured, for each configured interface an I2C Scan is performed, including the multiplexer if that's configured. An example: (No actual multiplexer connected...) diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index 413ae329d3..ad5c44f531 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -475,7 +475,7 @@ bool BuildFixes() } if (Settings.Build <= 21156) { // 2025-03-31 - // PR #5235 Add 2nd and 3rd I2C Interface + // PR #5235 Add 2nd and 3rd I2C Bus if ((Settings.Pin_i2c2_sda == 0) && (Settings.Pin_i2c2_scl == 0)) { Settings.Pin_i2c2_sda = DEFAULT_PIN_I2C2_SDA; diff --git a/src/src/Helpers/Hardware_I2C.cpp b/src/src/Helpers/Hardware_I2C.cpp index 1151d185ef..b345d626e1 100644 --- a/src/src/Helpers/Hardware_I2C.cpp +++ b/src/src/Helpers/Hardware_I2C.cpp @@ -33,7 +33,7 @@ void initI2C() { { if (Settings.isI2CEnabled(i2cBus)) { addLog(LOG_LEVEL_INFO, concat(F("INIT : I2C interface "), i2cBus + 1)); - I2CSelectHighClockSpeed(i2cBus); // Set normal clock speed, on I2C Interface 1 (index 0) + I2CSelectHighClockSpeed(i2cBus); // Set normal clock speed, on I2C Bus 1 (index 0) } } diff --git a/src/src/Helpers/I2C_access.cpp b/src/src/Helpers/I2C_access.cpp index 08228a3b68..cef2adcc65 100644 --- a/src/src/Helpers/I2C_access.cpp +++ b/src/src/Helpers/I2C_access.cpp @@ -471,7 +471,7 @@ void I2CInterfaceSelector(String label, # if FEATURE_I2CMULTIPLEXER if (reloadWhenNeeded) { - // Only use reloadOnChange if current I2C Interface has multiplexer availability different than the other I2C Interface(s) + // Only use reloadOnChange if current I2C Bus has multiplexer availability different than the other I2C Bus(s) bool hasMultiplexer = false; for (uint8_t i2cBus = 0; i2cBus < getI2CBusCount(); ++i2cBus) { diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 46d5667b22..4d6bef13c3 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -238,7 +238,7 @@ void handle_advanced() { #if FEATURE_I2C_MULTIPLE { const uint8_t i2cBus = Settings.getI2CInterfaceRTC(); - I2CInterfaceSelector(F("Ext. Time Source I2C Interface"), + I2CInterfaceSelector(F("Ext. Time Source I2C Bus"), F("pi2cbusrtc"), i2cBus, false); @@ -325,7 +325,7 @@ void handle_advanced() { #if FEATURE_I2C_MULTIPLE { const uint8_t i2cBus = Settings.getI2CInterfaceWDT(); - I2CInterfaceSelector(F("WD I2C Interface"), + I2CInterfaceSelector(F("WD I2C Bus"), F("pi2cbuswdt"), i2cBus, false); diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index db573d2d8f..eaa570b3ce 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -838,7 +838,7 @@ void format_I2C_port_description(taskIndex_t x) const uint8_t i2cBus = Settings.getI2CInterface(x); if ((i2cBus > 0) || Settings.isI2CEnabled(1) || Settings.isI2CEnabled(2)) { html_BR(); - addHtml(F("I2C Interface")); + addHtml(F("I2C Bus")); addHtml(' '); addHtmlInt(i2cBus + 1); } @@ -1248,7 +1248,7 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex #endif // if FEATURE_I2C_INTERFACE_3 #endif // if FEATURE_I2C_MULTIPLE ) { - addFormNote(F("I2C Interface is not configured yet (Hardware page).")); + addFormNote(F("I2C Bus is not configured yet (Hardware page).")); } String dummy; @@ -1266,7 +1266,7 @@ void devicePage_show_I2C_config(taskIndex_t taskIndex, deviceIndex_t DeviceIndex #if FEATURE_I2C_MULTIPLE if (!Device[DeviceIndex].I2CNoBusSelection) { // If the device doesn't disallow bus selection i2cBus = Settings.getI2CInterface(taskIndex); - I2CInterfaceSelector(F("I2C Interface"), + I2CInterfaceSelector(F("I2C Bus"), F("pi2cbus"), i2cBus, true); diff --git a/src/src/WebServer/HardwarePage.cpp b/src/src/WebServer/HardwarePage.cpp index 53d0c5f3fe..d201d99838 100644 --- a/src/src/WebServer/HardwarePage.cpp +++ b/src/src/WebServer/HardwarePage.cpp @@ -213,9 +213,9 @@ void handle_hardware() { #endif // if FEATURE_I2C_MULTIPLE { #if !FEATURE_I2C_MULTIPLE - addFormSubHeader(F("I2C Interface")); + addFormSubHeader(F("I2C Bus")); #else // if !FEATURE_I2C_MULTIPLE - addFormSubHeader(strformat(F("I2C Interface %u"), i2cBus + 1)); + addFormSubHeader(strformat(F("I2C Bus %u"), i2cBus + 1)); #endif // if !FEATURE_I2C_MULTIPLE #if FEATURE_PLUGIN_PRIORITY if (isI2CPriorityTaskActive(i2cBus)) { @@ -260,7 +260,7 @@ void handle_hardware() { if (i2cMaxBusCount > 1) { addFormSubHeader(F("PCF & MCP Direct I/O")); const uint8_t i2cBus = Settings.getI2CInterfacePCFMCP(); - I2CInterfaceSelector(F("I2C Interface"), + I2CInterfaceSelector(F("I2C Bus"), F("pi2cbuspcf"), i2cBus, false); From 876273e2ada26c388f03d876d6c2fe51147c6f95 Mon Sep 17 00:00:00 2001 From: Ton Huisman Date: Fri, 14 Feb 2025 22:16:16 +0100 Subject: [PATCH 24/24] [I2C] Docs: Use I2C Bus instead of I2C Interface --- .../Hardware/Device_I2CBusSelection.png | Bin 0 -> 12859 bytes .../Hardware/Device_I2CBusSelection3.png | Bin 0 -> 18074 bytes .../Hardware/Device_I2CBusSelectionReload.png | Bin 0 -> 13244 bytes .../Hardware/Device_I2CInterfaceSelection.png | Bin 13209 -> 0 bytes .../Device_I2CInterfaceSelection3.png | Bin 18500 -> 0 bytes .../Device_I2CInterfaceSelectionReload.png | Bin 13585 -> 0 bytes docs/source/Hardware/Hardware.rst | 34 +++++++++--------- docs/source/Hardware/Hardware_I2CBus.png | Bin 0 -> 11258 bytes docs/source/Hardware/Hardware_I2CBus2.png | Bin 0 -> 10832 bytes .../source/Hardware/Hardware_I2CInterface.png | Bin 10598 -> 0 bytes .../Hardware/Hardware_I2CInterface2.png | Bin 11015 -> 0 bytes .../Hardware/Hardware_PCFMCP_I2CSelector.png | Bin 3051 -> 2864 bytes docs/source/Tools/Tools.rst | 10 +++--- .../images/Tools_I2Cscan_multipleBuses.png | Bin 0 -> 70446 bytes .../Tools_I2Cscan_multipleInterfaces.png | Bin 65422 -> 0 bytes .../Tools/images/Tools_RTC_I2CSelector.png | Bin 4209 -> 4054 bytes .../Tools/images/Tools_WD_I2CSelector.png | Bin 3998 -> 3830 bytes src/src/Helpers/Hardware_I2C.cpp | 6 +++- src/src/WebServer/I2C_Scanner.cpp | 4 +-- 19 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 docs/source/Hardware/Device_I2CBusSelection.png create mode 100644 docs/source/Hardware/Device_I2CBusSelection3.png create mode 100644 docs/source/Hardware/Device_I2CBusSelectionReload.png delete mode 100644 docs/source/Hardware/Device_I2CInterfaceSelection.png delete mode 100644 docs/source/Hardware/Device_I2CInterfaceSelection3.png delete mode 100644 docs/source/Hardware/Device_I2CInterfaceSelectionReload.png create mode 100644 docs/source/Hardware/Hardware_I2CBus.png create mode 100644 docs/source/Hardware/Hardware_I2CBus2.png delete mode 100644 docs/source/Hardware/Hardware_I2CInterface.png delete mode 100644 docs/source/Hardware/Hardware_I2CInterface2.png create mode 100644 docs/source/Tools/images/Tools_I2Cscan_multipleBuses.png delete mode 100644 docs/source/Tools/images/Tools_I2Cscan_multipleInterfaces.png diff --git a/docs/source/Hardware/Device_I2CBusSelection.png b/docs/source/Hardware/Device_I2CBusSelection.png new file mode 100644 index 0000000000000000000000000000000000000000..bf281fe3c6d79c9c9498bc9f3ee686206076c125 GIT binary patch literal 12859 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 ePyEzH@&5;Z4&Q?OLRokK00001nue66sl7TM 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