Add ESP8266 experimental support for second I2C bus

This commit is contained in:
Theo Arends 2024-09-19 14:47:18 +02:00
parent a9f0623769
commit 9238ee73d6
14 changed files with 156 additions and 84 deletions

View File

@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Support for I2C M5Unit (Mini)Scales using HX711 driver - Support for I2C M5Unit (Mini)Scales using HX711 driver
- Berry virtual Energy driver (#22134) - Berry virtual Energy driver (#22134)
- Support for RX8010 RTC as used in IOTTIMER (#21376) - Support for RX8010 RTC as used in IOTTIMER (#21376)
- ESP8266 experimental support for second I2C bus
### Breaking Changed ### Breaking Changed

View File

@ -131,6 +131,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Support nexus protocol and calculation of separation limit to rc-switch library [#21886](https://github.com/arendst/Tasmota/issues/21886) - Support nexus protocol and calculation of separation limit to rc-switch library [#21886](https://github.com/arendst/Tasmota/issues/21886)
- KNX additional KnxTx functions and define KNX_USE_DPT9 [#22071](https://github.com/arendst/Tasmota/issues/22071) - KNX additional KnxTx functions and define KNX_USE_DPT9 [#22071](https://github.com/arendst/Tasmota/issues/22071)
- SML multi TRX line [#22056](https://github.com/arendst/Tasmota/issues/22056) - SML multi TRX line [#22056](https://github.com/arendst/Tasmota/issues/22056)
- ESP8266 experimental support for second I2C bus
- Zigbee Koenkk firmware 20240710 for Sonoff Zigbee ZBPro [#22076](https://github.com/arendst/Tasmota/issues/22076) - Zigbee Koenkk firmware 20240710 for Sonoff Zigbee ZBPro [#22076](https://github.com/arendst/Tasmota/issues/22076)
- Berry Zigbee improvements to prepare Matter [#22083](https://github.com/arendst/Tasmota/issues/22083) - Berry Zigbee improvements to prepare Matter [#22083](https://github.com/arendst/Tasmota/issues/22083)
- Berry virtual Energy driver [#22134](https://github.com/arendst/Tasmota/issues/22134) - Berry virtual Energy driver [#22134](https://github.com/arendst/Tasmota/issues/22134)

View File

@ -94,7 +94,6 @@ const uint16_t VL53LXX_MAX_SENSORS = 8; // Max number of VL53L0X sensors
const uint8_t MAX_SR04 = 3; // Max number of SR04 ultrasonic sensors const uint8_t MAX_SR04 = 3; // Max number of SR04 ultrasonic sensors
#ifdef ESP32 #ifdef ESP32
const uint8_t MAX_I2C = 2; // Max number of I2C controllers (ESP32 = 2)
const uint8_t MAX_SPI = 2; // Max number of Hardware SPI controllers (ESP32 = 2) const uint8_t MAX_SPI = 2; // Max number of Hardware SPI controllers (ESP32 = 2)
const uint8_t MAX_I2S = 2; // Max number of Hardware I2S controllers (ESP32 = 2) const uint8_t MAX_I2S = 2; // Max number of Hardware I2S controllers (ESP32 = 2)
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
@ -109,7 +108,6 @@ const uint8_t MAX_I2S = 2; // Max number of Hardware I2S contro
const uint8_t MAX_RMT = 0; // Max number or RMT channels (0 if unknown) const uint8_t MAX_RMT = 0; // Max number or RMT channels (0 if unknown)
#endif #endif
#else #else
const uint8_t MAX_I2C = 0; // Max number of I2C controllers (ESP8266 = 0, no choice)
const uint8_t MAX_SPI = 0; // Max number of Hardware SPI controllers (ESP8266 = 0, no choice) const uint8_t MAX_SPI = 0; // Max number of Hardware SPI controllers (ESP8266 = 0, no choice)
const uint8_t MAX_I2S = 0; // Max number of Hardware I2S controllers (ESP8266 = 0, no choice) const uint8_t MAX_I2S = 0; // Max number of Hardware I2S controllers (ESP8266 = 0, no choice)
const uint8_t MAX_RMT = 0; // No RMT channel on ESP8266 const uint8_t MAX_RMT = 0; // No RMT channel on ESP8266

View File

@ -499,6 +499,11 @@ const char kSensorNamesFixed[] PROGMEM =
D_SENSOR_USER; D_SENSOR_USER;
// Max number of GPIOs // Max number of GPIOs
#define MAX_I2C 0 // Display no index if one bus
#ifdef USE_I2C_BUS2
#undef MAX_I2C
#define MAX_I2C 2
#endif
#define MAX_MAX31855S 6 #define MAX_MAX31855S 6
#define MAX_MAX31865S 6 #define MAX_MAX31865S 6
#define MAX_MCP23XXX 6 #define MAX_MCP23XXX 6

View File

@ -603,6 +603,7 @@
#define I2CDRIVERS_64_95 0xFFFFFFFF // Enable I2CDriver64 to I2CDriver95 #define I2CDRIVERS_64_95 0xFFFFFFFF // Enable I2CDriver64 to I2CDriver95
#ifdef USE_I2C #ifdef USE_I2C
// #define USE_I2C_BUS2 // Add experimental support for second I2C bus on ESP8266 (+0k6k code)
// #define USE_SHT // [I2cDriver8] Enable SHT1X sensor (+1k4 code) // #define USE_SHT // [I2cDriver8] Enable SHT1X sensor (+1k4 code)
// #define USE_HTU // [I2cDriver9] Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code) // #define USE_HTU // [I2cDriver9] Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code)
// #define USE_BMP // [I2cDriver10] Enable BMP085/BMP180/BMP280/BME280 sensors (I2C addresses 0x76 and 0x77) (+4k4 code) // #define USE_BMP // [I2cDriver10] Enable BMP085/BMP180/BMP280/BME280 sensors (I2C addresses 0x76 and 0x77) (+4k4 code)

View File

@ -313,8 +313,8 @@ struct TasmotaGlobal_t {
bool blinkstate; // LED state bool blinkstate; // LED state
bool pwm_present; // Any PWM channel configured with SetOption15 0 bool pwm_present; // Any PWM channel configured with SetOption15 0
bool i2c_enabled; // I2C configured bool i2c_enabled; // I2C configured
bool i2c_enabled_2; // I2C configured, second controller, Wire1
#ifdef ESP32 #ifdef ESP32
bool i2c_enabled_2; // I2C configured, second controller on ESP32, Wire1
bool ota_factory; // Select safeboot binary bool ota_factory; // Select safeboot binary
#endif #endif
bool ntp_force_sync; // Force NTP sync bool ntp_force_sync; // Force NTP sync

View File

@ -11,49 +11,88 @@
* Basic I2C routines supporting two busses * Basic I2C routines supporting two busses
\*********************************************************************************************/ \*********************************************************************************************/
#ifdef ESP8266
#ifdef USE_I2C_BUS2
#define USE_I2C_BUS2_ESP8266
#endif // USE_I2C_BUS2_ESP8266
#endif // ESP8266
#ifdef ESP32
#define USE_I2C_BUS2
#endif
const uint8_t I2C_RETRY_COUNTER = 3; const uint8_t I2C_RETRY_COUNTER = 3;
#ifdef ESP8266
uint32_t i2c_active[1][4] = { 0 };
#else
uint32_t i2c_active[2][4] = { 0 };
#endif
uint32_t i2c_buffer = 0;
struct I2Ct { struct I2Ct {
uint32_t buffer;
uint32_t frequency[2]; uint32_t frequency[2];
#ifdef USE_I2C_BUS2
uint32_t active[2][4];
#else
uint32_t active[1][4];
#endif // No USE_I2C_BUS2
#ifdef USE_I2C_BUS2_ESP8266
int8_t sda[2]; int8_t sda[2];
int8_t scl[2]; int8_t scl[2];
int8_t active_bus; int8_t active_bus = -1;
#endif // USE_I2C_BUS2_ESP8266
} I2C; } I2C;
#ifdef USE_I2C_BUS2_ESP8266
TwoWire Wire1 = Wire; // Not really backward compatible with ESP32
void I2cSetBus(uint32_t bus = 0);
void I2cSetBus(uint32_t bus) {
if (I2C.active_bus != bus) {
I2C.active_bus = bus;
Wire.begin(I2C.sda[bus], I2C.scl[bus]);
Wire.setClock(I2C.frequency[bus]);
}
}
#endif // USE_I2C_BUS2_ESP8266
bool I2cBegin(int sda, int scl, uint32_t bus = 0, uint32_t frequency = 100000); bool I2cBegin(int sda, int scl, uint32_t bus = 0, uint32_t frequency = 100000);
bool I2cBegin(int sda, int scl, uint32_t bus, uint32_t frequency) { bool I2cBegin(int sda, int scl, uint32_t bus, uint32_t frequency) {
I2C.frequency[bus] = frequency; I2C.frequency[bus] = frequency;
bool result = true; bool result = true;
#ifdef ESP8266 #ifdef ESP8266
#ifdef USE_I2C_BUS2_ESP8266
I2C.sda[bus] = sda;
I2C.scl[bus] = scl;
I2cSetBus();
#else
if (bus > 0) { return false; }
Wire.begin(sda, scl); Wire.begin(sda, scl);
Wire.setClock(frequency); Wire.setClock(frequency);
#endif #endif // USE_I2C_BUS2_ESP8266
#endif // ESP8266
#ifdef ESP32 #ifdef ESP32
static bool reinit = false;
TwoWire& myWire = (0 == bus) ? Wire : Wire1; TwoWire& myWire = (0 == bus) ? Wire : Wire1;
static bool reinit = false;
if (reinit) { myWire.end(); } if (reinit) { myWire.end(); }
result = myWire.begin(sda, scl, frequency); result = myWire.begin(sda, scl, frequency);
reinit = result; reinit = result;
#endif #endif // ESP32
// AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Bus%d %d"), bus +1, result); // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Bus%d %d"), bus +1, result);
return result; return result;
} }
TwoWire& I2cGetWire(uint8_t bus = 0) { TwoWire& I2cGetWire(uint8_t bus = 0) {
if ((0 == bus) && TasmotaGlobal.i2c_enabled) { if ((0 == bus) && TasmotaGlobal.i2c_enabled) {
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus(bus);
#endif
return Wire; return Wire;
#ifdef ESP32 }
} else if ((1 == bus) && TasmotaGlobal.i2c_enabled_2) { #ifdef USE_I2C_BUS2
else if ((1 == bus) && TasmotaGlobal.i2c_enabled_2) {
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus(bus);
#endif
return Wire1; return Wire1;
#endif // ESP32 }
} else { #endif // USE_I2C_BUS2
else {
// AddLog(LOG_LEVEL_ERROR, PSTR("I2C: bus%d not initialized"), bus +1); // AddLog(LOG_LEVEL_ERROR, PSTR("I2C: bus%d not initialized"), bus +1);
return *(TwoWire*)nullptr; return *(TwoWire*)nullptr;
} }
@ -82,7 +121,7 @@ bool I2cSetClock(uint32_t frequency, uint32_t bus) {
\*-------------------------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------------------------*/
bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0, bool sendStop = false) { bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0, bool sendStop = false) {
i2c_buffer = 0; I2C.buffer = 0;
TwoWire& myWire = I2cGetWire(bus); TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return false; } // No valid I2c bus if (&myWire == nullptr) { return false; } // No valid I2c bus
@ -96,7 +135,7 @@ bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0, bool
myWire.requestFrom((int)addr, (int)size); // send data n-bytes read myWire.requestFrom((int)addr, (int)size); // send data n-bytes read
if (myWire.available() == size) { if (myWire.available() == size) {
for (uint32_t i = 0; i < size; i++) { for (uint32_t i = 0; i < size; i++) {
i2c_buffer = i2c_buffer << 8 | myWire.read(); // receive DATA I2C.buffer = I2C.buffer << 8 | myWire.read(); // receive DATA
} }
status = true; // 1 = OK status = true; // 1 = OK
} }
@ -104,24 +143,27 @@ bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0, bool
retry--; retry--;
} }
if (!retry) myWire.endTransmission(); if (!retry) myWire.endTransmission();
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
return status; // 0 = Error, 1 = OK return status; // 0 = Error, 1 = OK
} }
bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { bool I2cValidRead8(uint8_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
bool status = I2cValidRead(addr, reg, 1, bus); bool status = I2cValidRead(addr, reg, 1, bus);
*data = (uint8_t)i2c_buffer; *data = (uint8_t)I2C.buffer;
return status; // 0 = Error, 1 = OK return status; // 0 = Error, 1 = OK
} }
bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { bool I2cValidRead16(uint16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
bool status = I2cValidRead(addr, reg, 2, bus); bool status = I2cValidRead(addr, reg, 2, bus);
*data = (uint16_t)i2c_buffer; *data = (uint16_t)I2C.buffer;
return status; // 0 = Error, 1 = OK return status; // 0 = Error, 1 = OK
} }
bool I2cValidReadS16(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { bool I2cValidReadS16(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
bool status = I2cValidRead(addr, reg, 2, bus); bool status = I2cValidRead(addr, reg, 2, bus);
*data = (int16_t)i2c_buffer; *data = (int16_t)I2C.buffer;
return status; // 0 = Error, 1 = OK return status; // 0 = Error, 1 = OK
} }
@ -141,28 +183,28 @@ bool I2cValidReadS16_LE(int16_t *data, uint8_t addr, uint8_t reg, uint8_t bus =
bool I2cValidRead24(int32_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) { bool I2cValidRead24(int32_t *data, uint8_t addr, uint8_t reg, uint8_t bus = 0) {
bool status = I2cValidRead(addr, reg, 3, bus); bool status = I2cValidRead(addr, reg, 3, bus);
*data = i2c_buffer; *data = I2C.buffer;
return status; // 0 = Error, 1 = OK return status; // 0 = Error, 1 = OK
} }
uint8_t I2cRead8(uint8_t addr, uint8_t reg, uint8_t bus = 0) { uint8_t I2cRead8(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 1, bus); I2cValidRead(addr, reg, 1, bus);
return (uint8_t)i2c_buffer; return (uint8_t)I2C.buffer;
} }
uint16_t I2cRead16(uint8_t addr, uint8_t reg, uint8_t bus = 0) { uint16_t I2cRead16(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 2, bus); I2cValidRead(addr, reg, 2, bus);
return (uint16_t)i2c_buffer; return (uint16_t)I2C.buffer;
} }
int16_t I2cReadS16(uint8_t addr, uint8_t reg, uint8_t bus = 0) { int16_t I2cReadS16(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 2, bus); I2cValidRead(addr, reg, 2, bus);
return (int16_t)i2c_buffer; return (int16_t)I2C.buffer;
} }
uint16_t I2cRead16LE(uint8_t addr, uint8_t reg, uint8_t bus = 0) { uint16_t I2cRead16LE(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 2, bus); I2cValidRead(addr, reg, 2, bus);
uint16_t temp = (uint16_t)i2c_buffer; uint16_t temp = (uint16_t)I2C.buffer;
return (temp >> 8) | (temp << 8); return (temp >> 8) | (temp << 8);
} }
@ -172,7 +214,7 @@ int16_t I2cReadS16_LE(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
int32_t I2cRead24(uint8_t addr, uint8_t reg, uint8_t bus = 0) { int32_t I2cRead24(uint8_t addr, uint8_t reg, uint8_t bus = 0) {
I2cValidRead(addr, reg, 3, bus); I2cValidRead(addr, reg, 3, bus);
return i2c_buffer; return I2C.buffer;
} }
/*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/
@ -191,6 +233,9 @@ bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus
} }
x--; x--;
} while (myWire.endTransmission(true) != 0 && x != 0); // end transmission } while (myWire.endTransmission(true) != 0 && x != 0); // end transmission
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
return (x); // 0 = Error, 1 = OK return (x); // 0 = Error, 1 = OK
} }
@ -216,12 +261,18 @@ bool I2cReadBuffer0(uint8_t addr, uint8_t *reg_data, uint16_t len, uint8_t bus =
myWire.requestFrom((uint8_t)addr, (uint8_t)len); myWire.requestFrom((uint8_t)addr, (uint8_t)len);
if (myWire.available() != len) { if (myWire.available() != len) {
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
return true; // 1 = Error return true; // 1 = Error
} }
while (len--) { while (len--) {
*reg_data = (uint8_t)myWire.read(); *reg_data = (uint8_t)myWire.read();
reg_data++; reg_data++;
} }
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
return false; // 0 = OK return false; // 0 = OK
} }
@ -238,6 +289,9 @@ bool I2cReadBuffer(uint8_t addr, int reg, uint8_t *reg_data, uint16_t len, uint8
myWire.endTransmission(); myWire.endTransmission();
} }
if (len != myWire.requestFrom((uint8_t)addr, (uint8_t)len)) { if (len != myWire.requestFrom((uint8_t)addr, (uint8_t)len)) {
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
return true; // 1 = Error return true; // 1 = Error
} }
while (len--) { while (len--) {
@ -247,6 +301,9 @@ bool I2cReadBuffer(uint8_t addr, int reg, uint8_t *reg_data, uint16_t len, uint8
if (reg < 0) { if (reg < 0) {
myWire.endTransmission(); myWire.endTransmission();
} }
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
return false; // 0 = OK return false; // 0 = OK
} }
@ -261,6 +318,9 @@ bool I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len,
reg_data++; reg_data++;
} }
myWire.endTransmission(); myWire.endTransmission();
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
return false; // 0 = OK return false; // 0 = OK
} }
@ -283,11 +343,11 @@ void I2cScan(uint8_t bus = 0) {
// 5: timeout // 5: timeout
TwoWire& myWire = I2cGetWire(bus); TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return; } // No valid I2c bus if (&myWire == nullptr) { return; } // No valid I2c bus
#ifdef ESP32 Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found "));
Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found on bus%d at"), bus +1); #ifdef USE_I2C_BUS2
#else ResponseAppend_P(PSTR("on bus%d "), bus +1);
Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found at"));
#endif #endif
ResponseAppend_P(PSTR("at"));
uint8_t error = 0; uint8_t error = 0;
uint8_t address = 0; uint8_t address = 0;
@ -302,14 +362,15 @@ void I2cScan(uint8_t bus = 0) {
else if (error != 2) { // Seems to happen anyway using this scan else if (error != 2) { // Seems to happen anyway using this scan
any = 2; any = 2;
Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Error %d at 0x%02x"), error, address); Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Error %d at 0x%02x"), error, address);
#ifdef ESP32 #ifdef USE_I2C_BUS2
if (bus) { ResponseAppend_P(PSTR(" (bus%d)"), bus +1);
ResponseAppend_P(PSTR(" (bus2)")); #endif // USE_I2C_BUS2
}
#endif
break; break;
} }
} }
#ifdef USE_I2C_BUS2_ESP8266
I2cSetBus();
#endif
if (any) { if (any) {
ResponseAppend_P(PSTR("\"}")); ResponseAppend_P(PSTR("\"}"));
} else { } else {
@ -318,66 +379,50 @@ void I2cScan(uint8_t bus = 0) {
} }
void I2cResetActive(uint32_t addr, uint8_t bus = 0) { void I2cResetActive(uint32_t addr, uint8_t bus = 0) {
#ifdef ESP8266
bus = 0;
#endif
addr &= 0x7F; // Max I2C address is 127 addr &= 0x7F; // Max I2C address is 127
i2c_active[bus][addr / 32] &= ~(1 << (addr % 32)); I2C.active[bus][addr / 32] &= ~(1 << (addr % 32));
// AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: I2cResetActive bus0 %08X-%08X-%08X-%08X, bus1 %08X-%08X-%08X-%08X"), // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: I2cResetActive bus0 %08X-%08X-%08X-%08X, bus1 %08X-%08X-%08X-%08X"),
// i2c_active[0][0], i2c_active[0][1], i2c_active[0][2], i2c_active[0][3], // I2C.active[0][0], I2C.active[0][1], I2C.active[0][2], I2C.active[0][3],
// i2c_active[1][0], i2c_active[1][1], i2c_active[1][2], i2c_active[1][3]); // I2C.active[1][0], I2C.active[1][1], I2C.active[1][2], I2C.active[1][3]);
} }
void I2cSetActive(uint32_t addr, uint8_t bus = 0) { void I2cSetActive(uint32_t addr, uint8_t bus = 0) {
#ifdef ESP8266
bus = 0;
#endif
addr &= 0x7F; // Max I2C address is 127 addr &= 0x7F; // Max I2C address is 127
i2c_active[bus][addr / 32] |= (1 << (addr % 32)); I2C.active[bus][addr / 32] |= (1 << (addr % 32));
// AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: I2cSetActive addr %02X, bus%d, bus0 %08X-%08X-%08X-%08X, bus1 %08X-%08X-%08X-%08X"), // AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: I2cSetActive addr %02X, bus%d, bus0 %08X-%08X-%08X-%08X, bus1 %08X-%08X-%08X-%08X"),
// addr, bus, // addr, bus,
// i2c_active[0][0], i2c_active[0][1], i2c_active[0][2], i2c_active[0][3], // I2C.active[0][0], I2C.active[0][1], I2C.active[0][2], I2C.active[0][3],
// i2c_active[1][0], i2c_active[1][1], i2c_active[1][2], i2c_active[1][3]); // I2C.active[1][0], I2C.active[1][1], I2C.active[1][2], I2C.active[1][3]);
} }
void I2cSetActiveFound(uint32_t addr, const char *types, uint8_t bus = 0) { void I2cSetActiveFound(uint32_t addr, const char *types, uint8_t bus = 0) {
I2cSetActive(addr, bus); I2cSetActive(addr, bus);
#ifdef ESP32 AddLog(LOG_LEVEL_INFO, PSTR("I2C: %s found at 0x%02x%s"), types, addr, (bus)?" (bus2)":"");
if (bus) {
AddLog(LOG_LEVEL_INFO, PSTR("I2C: %s found at 0x%02x (bus2)"), types, addr);
} else
#endif // ESP32
AddLog(LOG_LEVEL_INFO, PSTR("I2C: %s found at 0x%02x"), types, addr);
} }
bool I2cActive(uint32_t addr, uint8_t bus = 0) { bool I2cActive(uint32_t addr, uint8_t bus = 0) {
#ifdef ESP8266
bus = 0;
#endif
addr &= 0x7F; // Max I2C address is 127 addr &= 0x7F; // Max I2C address is 127
return (i2c_active[bus][addr / 32] & (1 << (addr % 32))); return (I2C.active[bus][addr / 32] & (1 << (addr % 32)));
} }
bool I2cSetDevice(uint32_t addr, uint8_t bus = 0) { bool I2cSetDevice(uint32_t addr, uint8_t bus = 0) {
TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return false; } // No valid I2c bus
addr &= 0x7F; // Max I2C address is 127 addr &= 0x7F; // Max I2C address is 127
if (I2cActive(addr, bus)) { if (I2cActive(addr, bus)) {
return false; // If already active report as not present; return false; // If already active report as not present;
} }
TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return false; } // No valid I2c bus
myWire.beginTransmission((uint8_t)addr); myWire.beginTransmission((uint8_t)addr);
// return (0 == myWire.endTransmission()); // return (0 == myWire.endTransmission());
uint32_t err = myWire.endTransmission(); uint32_t err = myWire.endTransmission();
if (err && (err != 2)) { #ifdef USE_I2C_BUS2_ESP8266
#ifdef ESP32 I2cSetBus();
if (bus) {
AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x (bus2)"), err, addr);
} else
#endif #endif
AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x"), err, addr); if (err && (err != 2)) {
AddLog(LOG_LEVEL_DEBUG, PSTR("I2C: Error %d at 0x%02x%s"), err, addr, (bus)?" (bus2)":"");
} }
return (0 == err); return (0 == err);
} }

View File

@ -2751,14 +2751,14 @@ void CmndI2cScan(void) {
I2cScan(); I2cScan();
jsflag = true; jsflag = true;
} }
#ifdef ESP32 #ifdef USE_I2C_BUS2
if (TasmotaGlobal.i2c_enabled_2) { if (TasmotaGlobal.i2c_enabled_2) {
if (jsflag) { if (jsflag) {
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, XdrvMailbox.command); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, XdrvMailbox.command);
} }
I2cScan(1); I2cScan(1);
} }
#endif // ESP32 #endif // USE_I2C_BUS2
} }
void CmndI2cDriver(void) void CmndI2cDriver(void)

View File

@ -2232,6 +2232,7 @@ void GpioInit(void)
} }
#ifdef USE_I2C #ifdef USE_I2C
/*
if (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA)) { if (PinUsed(GPIO_I2C_SCL) && PinUsed(GPIO_I2C_SDA)) {
TasmotaGlobal.i2c_enabled = I2cBegin(Pin(GPIO_I2C_SDA), Pin(GPIO_I2C_SCL)); TasmotaGlobal.i2c_enabled = I2cBegin(Pin(GPIO_I2C_SDA), Pin(GPIO_I2C_SCL));
#ifdef ESP32 #ifdef ESP32
@ -2248,6 +2249,26 @@ void GpioInit(void)
} }
} }
#endif #endif
*/
uint32_t max_bus = 1;
#ifdef USE_I2C_BUS2
max_bus = 2;
#endif // USE_I2C_BUS2
for (uint32_t bus = 0; bus < max_bus; bus++) {
if (PinUsed(GPIO_I2C_SCL, bus) && PinUsed(GPIO_I2C_SDA, bus)) {
if (I2cBegin(Pin(GPIO_I2C_SDA, bus), Pin(GPIO_I2C_SCL, bus), bus)) {
if (0 == bus) {
TasmotaGlobal.i2c_enabled = true;
}
#ifdef USE_I2C_BUS2
else {
TasmotaGlobal.i2c_enabled_2 = true;
}
AddLog(LOG_LEVEL_INFO, PSTR("I2C: Bus%d using GPIO%02d(SCL) and GPIO%02d(SDA)"), bus +1, Pin(GPIO_I2C_SCL, bus), Pin(GPIO_I2C_SDA, bus));
#endif // USE_I2C_BUS2
}
}
}
#endif // USE_I2C #endif // USE_I2C
TasmotaGlobal.devices_present = 0; TasmotaGlobal.devices_present = 0;

View File

@ -243,7 +243,7 @@ extern "C" {
} }
bool ok = I2cValidRead(addr, reg, size, bus, true); // force sendStop bool ok = I2cValidRead(addr, reg, size, bus, true); // force sendStop
if (ok) { if (ok) {
int32_t val = i2c_buffer; int32_t val = I2C.buffer;
if (little_endian) { if (little_endian) {
if (size == 2) { if (size == 2) {
val = __bswap_16(val); val = __bswap_16(val);

View File

@ -558,7 +558,7 @@ void BmpShow(bool json) {
if (bmp_count > 1) { if (bmp_count > 1) {
// BMP280-77 // BMP280-77
snprintf_P(name, sizeof(name), PSTR("%s%c%02X"), name, IndexSeparator(), bmp_sensors[bmp_idx].bmp_address); snprintf_P(name, sizeof(name), PSTR("%s%c%02X"), name, IndexSeparator(), bmp_sensors[bmp_idx].bmp_address);
#ifdef ESP32 #ifdef USE_I2C_BUS2
if (TasmotaGlobal.i2c_enabled_2) { // Second bus enabled if (TasmotaGlobal.i2c_enabled_2) { // Second bus enabled
uint8_t bus = bmp_sensors[0].bmp_bus; uint8_t bus = bmp_sensors[0].bmp_bus;
for (uint32_t i = 1; i < bmp_count; i++) { for (uint32_t i = 1; i < bmp_count; i++) {
@ -569,7 +569,7 @@ void BmpShow(bool json) {
} }
} }
} }
#endif #endif // USE_I2C_BUS2
} }
char pressure[33]; char pressure[33];

View File

@ -199,7 +199,7 @@ void Ads1115Label(char* label, uint32_t maxsize, uint32_t device) {
if (ads1115_count > 1) { if (ads1115_count > 1) {
// "ADS1115-48":{"A0":3240,"A1":3235,"A2":3269,"A3":3269},"ADS1115-49":{"A0":3240,"A1":3235,"A2":3269,"A3":3269} // "ADS1115-48":{"A0":3240,"A1":3235,"A2":3269,"A3":3269},"ADS1115-49":{"A0":3240,"A1":3235,"A2":3269,"A3":3269}
snprintf_P(label, maxsize, PSTR("%s%c%02X"), label, IndexSeparator(), Ads1115[device].address); snprintf_P(label, maxsize, PSTR("%s%c%02X"), label, IndexSeparator(), Ads1115[device].address);
#ifdef ESP32 #ifdef USE_I2C_BUS2
if (TasmotaGlobal.i2c_enabled_2) { // Second bus enabled if (TasmotaGlobal.i2c_enabled_2) { // Second bus enabled
uint8_t bus = Ads1115[0].bus; uint8_t bus = Ads1115[0].bus;
for (uint32_t i = 1; i < ads1115_count; i++) { for (uint32_t i = 1; i < ads1115_count; i++) {
@ -210,7 +210,7 @@ void Ads1115Label(char* label, uint32_t maxsize, uint32_t device) {
} }
} }
} }
#endif #endif // USE_I2C_BUS2
} }
} }

View File

@ -191,7 +191,7 @@ void Sht3xShow(bool json) {
strlcpy(types, sht3x_sensors[idx].types, sizeof(types)); strlcpy(types, sht3x_sensors[idx].types, sizeof(types));
if (sht3x_count > 1) { if (sht3x_count > 1) {
snprintf_P(types, sizeof(types), PSTR("%s%c%02X"), types, IndexSeparator(), sht3x_sensors[idx].address); // "SHT3X-0xXX" snprintf_P(types, sizeof(types), PSTR("%s%c%02X"), types, IndexSeparator(), sht3x_sensors[idx].address); // "SHT3X-0xXX"
#ifdef ESP32 #ifdef USE_I2C_BUS2
if (TasmotaGlobal.i2c_enabled_2) { if (TasmotaGlobal.i2c_enabled_2) {
for (uint32_t i = 1; i < sht3x_count; i++) { for (uint32_t i = 1; i < sht3x_count; i++) {
if (sht3x_sensors[0].bus != sht3x_sensors[i].bus) { if (sht3x_sensors[0].bus != sht3x_sensors[i].bus) {
@ -200,7 +200,7 @@ void Sht3xShow(bool json) {
} }
} }
} }
#endif #endif // USE_I2C_BUS2
} }
TempHumDewShow(json, ((0 == TasmotaGlobal.tele_period) && (0 == idx)), types, sht3x_sensors[idx].temp, sht3x_sensors[idx].humi); TempHumDewShow(json, ((0 == TasmotaGlobal.tele_period) && (0 == idx)), types, sht3x_sensors[idx].temp, sht3x_sensors[idx].humi);
} }

View File

@ -413,11 +413,11 @@ const uint8_t kI2cList[] = {
/*********************************************************************************************/ /*********************************************************************************************/
bool I2cEnabled(uint32_t i2c_index) { bool I2cEnabled(uint32_t i2c_index) {
#ifdef ESP8266 return ((TasmotaGlobal.i2c_enabled
return (TasmotaGlobal.i2c_enabled && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32)); #ifdef USE_I2C_BUS2
#else || TasmotaGlobal.i2c_enabled_2
return ((TasmotaGlobal.i2c_enabled || TasmotaGlobal.i2c_enabled_2) && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32));
#endif #endif
) && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32));
} }
void I2cDriverState(void) { void I2cDriverState(void) {