mirror of https://github.com/arendst/Tasmota.git
Add ESP8266 experimental support for second I2C bus
This commit is contained in:
parent
a9f0623769
commit
9238ee73d6
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
@ -501,9 +501,9 @@ void setup(void) {
|
||||||
TasConsole.println();
|
TasConsole.println();
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("CMD: Using USB CDC"));
|
AddLog(LOG_LEVEL_INFO, PSTR("CMD: Using USB CDC"));
|
||||||
} else {
|
} else {
|
||||||
#if SOC_USB_SERIAL_JTAG_SUPPORTED // Not S2
|
#if SOC_USB_SERIAL_JTAG_SUPPORTED // Not S2
|
||||||
HWCDCSerial.~HWCDC(); // not needed, deinit CDC
|
HWCDCSerial.~HWCDC(); // not needed, deinit CDC
|
||||||
#endif // SOC_USB_SERIAL_JTAG_SUPPORTED
|
#endif // SOC_USB_SERIAL_JTAG_SUPPORTED
|
||||||
// Init command serial console preparing for AddLog use
|
// Init command serial console preparing for AddLog use
|
||||||
Serial.begin(TasmotaGlobal.baudrate);
|
Serial.begin(TasmotaGlobal.baudrate);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue