diff --git a/CHANGELOG.md b/CHANGELOG.md index 14f320353..f194c4c76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,15 @@ All notable changes to this project will be documented in this file. ## [13.2.0.1] ### Added +- ESP32 I2C bus2 support to iAQ core driver (#19799) ### Breaking Changed ### Changed +- Prepare I2C drivers for bus2 support ### Fixed +- ESP32 I2C allow bus2 support when bus1 is not enabled ### Removed diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 0d752bd8a..e6361ba1b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -113,11 +113,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm ## Changelog v13.2.0.1 ### Added - Experimental support for ESP32-C2 and ESP32-C6 using Arduino core v3 +- ESP32 I2C bus2 support to iAQ core driver [#19799](https://github.com/arendst/Tasmota/issues/19799) ### Breaking Changed ### Changed ### Fixed +- ESP32 I2C allow bus2 support when bus1 is not enabled ### Removed diff --git a/tasmota/tasmota_support/support_a_i2c.ino b/tasmota/tasmota_support/support_a_i2c.ino index 32237d173..68b557a54 100644 --- a/tasmota/tasmota_support/support_a_i2c.ino +++ b/tasmota/tasmota_support/support_a_i2c.ino @@ -49,15 +49,25 @@ bool I2c2Begin(int sda, int scl, uint32_t frequency) { } #endif +TwoWire& I2cGetWire(uint8_t bus = 0) { + if (!bus && TasmotaGlobal.i2c_enabled) { + return Wire; +#ifdef ESP32 + } else if (bus && TasmotaGlobal.i2c_enabled_2) { + return Wire1; +#endif // ESP32 + } else { +// AddLog(LOG_LEVEL_ERROR, PSTR("I2C: bus%d not initialized"), bus +1); + return *(TwoWire*)nullptr; + } +} + bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0) { i2c_buffer = 0; -#ifdef ESP32 - if (bus && !TasmotaGlobal.i2c_enabled_2) { return false; } // Error - TwoWire & myWire = (bus == 0) ? Wire : Wire1; -#else - if (bus) { return false; } // Second I2c bus ESP32 only - TwoWire & myWire = Wire; -#endif + + TwoWire& myWire = I2cGetWire(bus); + if (&myWire == nullptr) { return false; } // No valid I2c bus + uint8_t retry = I2C_RETRY_COUNTER; bool status = false; while (!status && retry) { @@ -147,13 +157,9 @@ int32_t I2cRead24(uint8_t addr, uint8_t reg, uint8_t bus = 0) { } bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus = 0) { -#ifdef ESP32 - if (bus && !TasmotaGlobal.i2c_enabled_2) { return false; } // Error - TwoWire & myWire = (bus == 0) ? Wire : Wire1; -#else - if (bus) { return false; } // Second I2c bus ESP32 only - TwoWire & myWire = Wire; -#endif + TwoWire& myWire = I2cGetWire(bus); + if (&myWire == nullptr) { return false; } // No valid I2c bus + uint8_t x = I2C_RETRY_COUNTER; do { myWire.beginTransmission((uint8_t)addr); // start transmission to device @@ -176,13 +182,9 @@ bool I2cWrite16(uint8_t addr, uint8_t reg, uint32_t val, uint8_t bus = 0) { } bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) { -#ifdef ESP32 - if (bus && !TasmotaGlobal.i2c_enabled_2) { return true; } // Error - TwoWire & myWire = (bus == 0) ? Wire : Wire1; -#else - if (bus) { return true; } // Second I2c bus ESP32 only - TwoWire & myWire = Wire; -#endif + TwoWire& myWire = I2cGetWire(bus); + if (&myWire == nullptr) { return true; } // No valid I2c bus + myWire.beginTransmission((uint8_t)addr); myWire.write((uint8_t)reg); myWire.endTransmission(); @@ -197,13 +199,9 @@ bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, u } int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) { -#ifdef ESP32 - if (bus && !TasmotaGlobal.i2c_enabled_2) { return 1; } // Error - TwoWire & myWire = (bus == 0) ? Wire : Wire1; -#else - if (bus) { return 1; } // Second I2c bus ESP32 only - TwoWire & myWire = Wire; -#endif + TwoWire& myWire = I2cGetWire(bus); + if (&myWire == nullptr) { return 1; } // No valid I2c bus + myWire.beginTransmission((uint8_t)addr); myWire.write((uint8_t)reg); while (len--) { @@ -229,16 +227,14 @@ void I2cScan(uint8_t bus = 0) { // 3: received NACK on transmit of data // 4: other error // 5: timeout - + TwoWire& myWire = I2cGetWire(bus); + if (&myWire == nullptr) { return; } // No valid I2c bus #ifdef ESP32 - if (bus && !TasmotaGlobal.i2c_enabled_2) { return; } - TwoWire & myWire = (bus == 0) ? Wire : Wire1; Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found on bus%d at"), bus +1); #else - if (bus) { return; } // Second I2c bus ESP32 only - TwoWire & myWire = Wire; Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found at")); #endif + uint8_t error = 0; uint8_t address = 0; uint8_t any = 0; @@ -311,13 +307,9 @@ bool I2cActive(uint32_t addr, uint8_t bus = 0) { } bool I2cSetDevice(uint32_t addr, uint8_t bus = 0) { -#ifdef ESP32 - if (bus && !TasmotaGlobal.i2c_enabled_2) { return false; } // If no second bus report as not present; - TwoWire & myWire = (bus == 0) ? Wire : Wire1; -#else - bus = 0; - TwoWire & myWire = Wire; -#endif + TwoWire& myWire = I2cGetWire(bus); + if (&myWire == nullptr) { return false; } // No valid I2c bus + addr &= 0x7F; // Max I2C address is 127 if (I2cActive(addr, bus)) { return false; // If already active report as not present; diff --git a/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino b/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino index 55b391a3a..36b966912 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_66_iAQ.ino @@ -41,15 +41,48 @@ struct { uint16_t pred; uint16_t Tvoc; uint8_t i2c_address; + uint8_t i2c_bus; uint8_t status; bool ready; } iAQ; +bool IAQ_Read(void) { + TwoWire& myWire = I2cGetWire(iAQ.i2c_bus); + if (&myWire == nullptr) { return false; } // No valid I2c bus + + uint8_t buf[9]; + buf[2] = IAQ_STATUS_I2C_ERR; // populate entry with error code + myWire.requestFrom(iAQ.i2c_address, sizeof(buf)); + for (uint32_t i = 0; i < 9; i++) { + buf[i] = myWire.read(); + } + // AddLog(LOG_LEVEL_DEBUG, "iAQ: buffer %x %x %x %x %x %x %x %x %x ", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]); + if (IAQ_STATUS_I2C_ERR == buf[2]) { + return false; + } + iAQ.pred = (buf[0]<<8) + buf[1]; + iAQ.status = buf[2]; + iAQ.resistance = ((uint32_t)buf[3]<<24) + ((uint32_t)buf[4]<<16) + ((uint32_t)buf[5]<<8) + (uint32_t)buf[6]; + iAQ.Tvoc = (buf[7]<<8) + buf[8]; + return true; +} + void IAQ_Init(void) { + for (uint32_t bus = 0; bus < 2; bus++) { + if (!I2cSetDevice(I2_ADR_IAQ, bus)) { continue; } + iAQ.i2c_address = I2_ADR_IAQ; + iAQ.i2c_bus = bus; + if (!IAQ_Read()) { continue; } + I2cSetActiveFound(I2_ADR_IAQ, "IAQ", bus); + iAQ.ready = true; + } + +/* if (!I2cSetDevice(I2_ADR_IAQ)) { return; } I2cSetActiveFound(I2_ADR_IAQ, "IAQ"); iAQ.i2c_address = I2_ADR_IAQ; iAQ.ready = true; +*/ /* for (iAQ.i2c_address = I2_ADR_IAQ; iAQ.i2c_address < I2_ADR_IAQ +5; iAQ.i2c_address++) { if (I2cActive(iAQ.i2c_address)) { continue; } @@ -62,20 +95,6 @@ void IAQ_Init(void) { */ } -void IAQ_Read(void) { - uint8_t buf[9]; - buf[2] = IAQ_STATUS_I2C_ERR; // populate entry with error code - Wire.requestFrom(iAQ.i2c_address, sizeof(buf)); - for( uint32_t i=0; i<9; i++ ) { - buf[i]= Wire.read(); - } - // AddLog(LOG_LEVEL_DEBUG, "iAQ: buffer %x %x %x %x %x %x %x %x %x ", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8]); - iAQ.pred = (buf[0]<<8) + buf[1]; - iAQ.status = buf[2]; - iAQ.resistance = ((uint32_t)buf[3]<<24) + ((uint32_t)buf[4]<<16) + ((uint32_t)buf[5]<<8) + (uint32_t)buf[6]; - iAQ.Tvoc = (buf[7]<<8) + buf[8]; -} - /*********************************************************************************************\ * Presentation \*********************************************************************************************/ diff --git a/tasmota/tasmota_xx2c_global/xx2c_interface.ino b/tasmota/tasmota_xx2c_global/xx2c_interface.ino index 33e7041d3..55e8a1a0a 100644 --- a/tasmota/tasmota_xx2c_global/xx2c_interface.ino +++ b/tasmota/tasmota_xx2c_global/xx2c_interface.ino @@ -413,7 +413,11 @@ const uint8_t kI2cList[] = { /*********************************************************************************************/ bool I2cEnabled(uint32_t i2c_index) { +#ifdef ESP8266 return (TasmotaGlobal.i2c_enabled && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32)); +#else + return ((TasmotaGlobal.i2c_enabled || TasmotaGlobal.i2c_enabled_2) && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32)); +#endif } void I2cDriverState(void) {