Prep ESP32 I2C bus2 support

This commit is contained in:
Theo Arends 2023-10-19 16:59:53 +02:00
parent 70287d90ad
commit b6811b2f4e
5 changed files with 74 additions and 54 deletions

View File

@ -5,12 +5,15 @@ All notable changes to this project will be documented in this file.
## [13.2.0.1] ## [13.2.0.1]
### Added ### Added
- ESP32 I2C bus2 support to iAQ core driver (#19799)
### Breaking Changed ### Breaking Changed
### Changed ### Changed
- Prepare I2C drivers for bus2 support
### Fixed ### Fixed
- ESP32 I2C allow bus2 support when bus1 is not enabled
### Removed ### Removed

View File

@ -113,11 +113,13 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
## Changelog v13.2.0.1 ## Changelog v13.2.0.1
### Added ### Added
- Experimental support for ESP32-C2 and ESP32-C6 using Arduino core v3 - 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 ### Breaking Changed
### Changed ### Changed
### Fixed ### Fixed
- ESP32 I2C allow bus2 support when bus1 is not enabled
### Removed ### Removed

View File

@ -49,15 +49,25 @@ bool I2c2Begin(int sda, int scl, uint32_t frequency) {
} }
#endif #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) { bool I2cValidRead(uint8_t addr, uint8_t reg, uint8_t size, uint8_t bus = 0) {
i2c_buffer = 0; i2c_buffer = 0;
#ifdef ESP32
if (bus && !TasmotaGlobal.i2c_enabled_2) { return false; } // Error TwoWire& myWire = I2cGetWire(bus);
TwoWire & myWire = (bus == 0) ? Wire : Wire1; if (&myWire == nullptr) { return false; } // No valid I2c bus
#else
if (bus) { return false; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire;
#endif
uint8_t retry = I2C_RETRY_COUNTER; uint8_t retry = I2C_RETRY_COUNTER;
bool status = false; bool status = false;
while (!status && retry) { 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) { bool I2cWrite(uint8_t addr, uint8_t reg, uint32_t val, uint8_t size, uint8_t bus = 0) {
#ifdef ESP32 TwoWire& myWire = I2cGetWire(bus);
if (bus && !TasmotaGlobal.i2c_enabled_2) { return false; } // Error if (&myWire == nullptr) { return false; } // No valid I2c bus
TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else
if (bus) { return false; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire;
#endif
uint8_t x = I2C_RETRY_COUNTER; uint8_t x = I2C_RETRY_COUNTER;
do { do {
myWire.beginTransmission((uint8_t)addr); // start transmission to device 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) { bool I2cReadBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) {
#ifdef ESP32 TwoWire& myWire = I2cGetWire(bus);
if (bus && !TasmotaGlobal.i2c_enabled_2) { return true; } // Error if (&myWire == nullptr) { return true; } // No valid I2c bus
TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else
if (bus) { return true; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire;
#endif
myWire.beginTransmission((uint8_t)addr); myWire.beginTransmission((uint8_t)addr);
myWire.write((uint8_t)reg); myWire.write((uint8_t)reg);
myWire.endTransmission(); 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) { int8_t I2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t *reg_data, uint16_t len, uint8_t bus = 0) {
#ifdef ESP32 TwoWire& myWire = I2cGetWire(bus);
if (bus && !TasmotaGlobal.i2c_enabled_2) { return 1; } // Error if (&myWire == nullptr) { return 1; } // No valid I2c bus
TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else
if (bus) { return 1; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire;
#endif
myWire.beginTransmission((uint8_t)addr); myWire.beginTransmission((uint8_t)addr);
myWire.write((uint8_t)reg); myWire.write((uint8_t)reg);
while (len--) { while (len--) {
@ -229,16 +227,14 @@ void I2cScan(uint8_t bus = 0) {
// 3: received NACK on transmit of data // 3: received NACK on transmit of data
// 4: other error // 4: other error
// 5: timeout // 5: timeout
TwoWire& myWire = I2cGetWire(bus);
if (&myWire == nullptr) { return; } // No valid I2c bus
#ifdef ESP32 #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); Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found on bus%d at"), bus +1);
#else #else
if (bus) { return; } // Second I2c bus ESP32 only
TwoWire & myWire = Wire;
Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found at")); Response_P(PSTR("{\"" D_CMND_I2CSCAN "\":\"Device(s) found at"));
#endif #endif
uint8_t error = 0; uint8_t error = 0;
uint8_t address = 0; uint8_t address = 0;
uint8_t any = 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) { bool I2cSetDevice(uint32_t addr, uint8_t bus = 0) {
#ifdef ESP32 TwoWire& myWire = I2cGetWire(bus);
if (bus && !TasmotaGlobal.i2c_enabled_2) { return false; } // If no second bus report as not present; if (&myWire == nullptr) { return false; } // No valid I2c bus
TwoWire & myWire = (bus == 0) ? Wire : Wire1;
#else
bus = 0;
TwoWire & myWire = Wire;
#endif
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;

View File

@ -41,15 +41,48 @@ struct {
uint16_t pred; uint16_t pred;
uint16_t Tvoc; uint16_t Tvoc;
uint8_t i2c_address; uint8_t i2c_address;
uint8_t i2c_bus;
uint8_t status; uint8_t status;
bool ready; bool ready;
} iAQ; } 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) { 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; } if (!I2cSetDevice(I2_ADR_IAQ)) { return; }
I2cSetActiveFound(I2_ADR_IAQ, "IAQ"); I2cSetActiveFound(I2_ADR_IAQ, "IAQ");
iAQ.i2c_address = I2_ADR_IAQ; iAQ.i2c_address = I2_ADR_IAQ;
iAQ.ready = true; iAQ.ready = true;
*/
/* /*
for (iAQ.i2c_address = I2_ADR_IAQ; iAQ.i2c_address < I2_ADR_IAQ +5; iAQ.i2c_address++) { for (iAQ.i2c_address = I2_ADR_IAQ; iAQ.i2c_address < I2_ADR_IAQ +5; iAQ.i2c_address++) {
if (I2cActive(iAQ.i2c_address)) { continue; } 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 * Presentation
\*********************************************************************************************/ \*********************************************************************************************/

View File

@ -413,7 +413,11 @@ const uint8_t kI2cList[] = {
/*********************************************************************************************/ /*********************************************************************************************/
bool I2cEnabled(uint32_t i2c_index) { bool I2cEnabled(uint32_t i2c_index) {
#ifdef ESP8266
return (TasmotaGlobal.i2c_enabled && bitRead(Settings->i2c_drivers[i2c_index / 32], i2c_index % 32)); 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) { void I2cDriverState(void) {