Adjust some usermods to use global I2C

* usermods only need to to `if (!pinManager.joinWire()) return;`

* joinWire will
* * check if global I2C are defined - return false if not defined
* * aloocate HW_I2C pins - return false on error
* * call Wire.begin() if needed.
This commit is contained in:
Frank
2023-01-08 21:11:50 +01:00
parent edb6bfc2f9
commit 39ad4955b7
6 changed files with 65 additions and 30 deletions

View File

@@ -139,10 +139,15 @@ public:
#if defined(ARDUINO_ARCH_ESP32)
if (pins[1].pin < 0 || pins[0].pin < 0) { sensorFound=false; enabled=false; return; } //WLEDMM bugfix - ensure that "final" GPIO are valid and no "-1" sneaks trough
Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM this might silently fail, which is OK as it just means that I2C bus is already running.
//Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM this might silently fail, which is OK as it just means that I2C bus is already running.
#else
Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed.
//Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed.
#endif
if (!pinManager.joinWire()) { // WLEDMM - this allocates global I2C pins, then starts Wire - if not started previously
sensorFound = false;
enabled = false;
return;
}
sensorFound = lightMeter.begin();
initDone = true;
@@ -222,11 +227,11 @@ public:
void appendConfigData() {
oappend(SET_F("addHB('")); oappend(SET_F(_name)); oappend("');");
oappend(SET_F("addInfo('BH1750:pin[]',0,'','I2C SCL');"));
oappend(SET_F("rOption('BH1750:pin[]',0,'use global (")); oappendi(i2c_scl); oappend(")',-1);");
oappend(SET_F("addInfo('BH1750:pin[]',1,'','I2C SDA');"));
oappend(SET_F("rOption('BH1750:pin[]',1,'use global (")); oappendi(i2c_sda); oappend(")',-1);");
// WLEDMM this usermod can ONLY use HW_I2C - so always use globals
//oappend(SET_F("addInfo('BH1750:pin[]',0,'','I2C SCL');"));
//oappend(SET_F("rOption('BH1750:pin[]',0,'use global (")); oappendi(i2c_scl); oappend(")',-1);");
//oappend(SET_F("addInfo('BH1750:pin[]',1,'','I2C SDA');"));
//oappend(SET_F("rOption('BH1750:pin[]',1,'use global (")); oappendi(i2c_sda); oappend(")',-1);");
}
// (called from set.cpp) stores persistent properties to cfg.json
@@ -239,10 +244,12 @@ public:
top[FPSTR(_minReadInterval)] = minReadingInterval;
top[FPSTR(_HomeAssistantDiscovery)] = HomeAssistantDiscovery;
top[FPSTR(_offset)] = offset;
JsonArray io_pin = top.createNestedArray(F("pin"));
// WLEDMM this usermod can ONLY use HW_I2C - so always use globals
//JsonArray io_pin = top.createNestedArray(F("pin"));
//WLEDMM: avoid global pin hijacking
io_pin.add((ioPin[0]==i2c_scl)?-1:ioPin[0]);
io_pin.add((ioPin[1]==i2c_sda)?-1:ioPin[1]);
//io_pin.add((ioPin[0]==i2c_scl)?-1:ioPin[0]);
//io_pin.add((ioPin[1]==i2c_sda)?-1:ioPin[1]);
// top[F("help4Pins")] = F("SCL,SDA"); // help for Settings page
@@ -252,7 +259,8 @@ public:
// called before setup() to populate properties from values stored in cfg.json
bool readFromConfig(JsonObject &root)
{
int8_t newPin[2]; for (byte i=0; i<2; i++) newPin[i] = ioPin[i]; // prepare to note changed pins
int8_t newPin[2] = {-1, -1}; // WLEDMM this usermod can ONLY use HW_I2C - so always use globals
//for (byte i=0; i<2; i++) newPin[i] = ioPin[i]; // prepare to note changed pins
// we look for JSON object.
JsonObject top = root[FPSTR(_name)];
@@ -270,7 +278,8 @@ public:
configComplete &= getJsonValue(top[FPSTR(_minReadInterval)], minReadingInterval, 500); //ms
configComplete &= getJsonValue(top[FPSTR(_HomeAssistantDiscovery)], HomeAssistantDiscovery, false);
configComplete &= getJsonValue(top[FPSTR(_offset)], offset, 1);
for (byte i=0; i<2; i++) configComplete &= getJsonValue(top[F("pin")][i], newPin[i], ioPin[i]);
// WLEDMM this usermod can ONLY use HW_I2C - so always use globals
//for (byte i=0; i<2; i++) configComplete &= getJsonValue(top[F("pin")][i], newPin[i], ioPin[i]);
DEBUG_PRINT(FPSTR(_name));
if (!initDone) {
@@ -285,6 +294,7 @@ public:
if (pinsChanged) { //if pins changed, deallocate old pins and allocate new ones
PinOwner po = PinOwner::UM_BH1750;
if (ioPin[0]==i2c_scl && ioPin[1]==i2c_sda) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
if (ioPin[0]==-1 && ioPin[1]==-1) po = PinOwner::HW_I2C; // WLEDMM global HW I2C bus pins
pinManager.deallocateMultiplePins((const uint8_t *)ioPin, 2, po); // deallocate pins
for (byte i=0; i<2; i++) ioPin[i] = newPin[i];
setup();

View File

@@ -80,6 +80,7 @@ private:
void UpdateBME280Data(int SensorType)
{
float _temperature, _humidity, _pressure;
if (!enabled || (sensorType == 0)) return; // WLEDMM bugfix
if (UseCelsius) {
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
@@ -183,12 +184,13 @@ public:
void setup()
{
bool HW_Pins_Used = (ioPin[0]==i2c_scl && ioPin[1]==i2c_sda); // note whether architecture-based hardware SCL/SDA pins used
PinOwner po = PinOwner::UM_BME280; // defaults to being pinowner for SCL/SDA pins
//PinOwner po = PinOwner::UM_BME280; // defaults to being pinowner for SCL/SDA pins // WLEDMM not needed
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } }; // allocate pins
if (HW_Pins_Used) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
if (!pinManager.allocateMultiplePins(pins, 2, po)) { sensorType=0; return; }
Wire.begin(ioPin[1], ioPin[0]);
//if (HW_Pins_Used) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins // WLEDMM not needed
// WLEDMM join I2C HW wire
if (!pinManager.joinWire()) { sensorType=0; enabled = false; return; }
//if (!pinManager.allocateMultiplePins(pins, 2, po)) { sensorType=0; return; }
//Wire.begin(ioPin[1], ioPin[0]);
if (!bme.begin())
{

View File

@@ -17,11 +17,18 @@ class RTCUsermod : public Usermod {
void setup() {
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
if (pins[1].pin < 0 || pins[0].pin < 0) { disabled=true; return; } //WLEDMM bugfix - ensure that "final" GPIO are valid and no "-1" sneaks trough
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { disabled = true; return; }
// WLEDMM join hardware I2C
if (!pinManager.joinWire()) { // WLEDMM - this allocates global I2C pins, then starts Wire - if not started previously
disabled = true;
return;
}
//if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { disabled = true; return; }
#if defined(ARDUINO_ARCH_ESP32)
Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM this might silently fail, which is OK as it just means that I2C bus is already running.
//Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM this might silently fail, which is OK as it just means that I2C bus is already running.
#else
Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed.
//Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed.
#endif
RTC.begin();

View File

@@ -50,14 +50,21 @@ class UsermodVL53L0XGestures : public Usermod {
public:
void setup() {
PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; }
Wire.begin();
// WLEDMM join hardware I2C
if (!pinManager.joinWire()) { // WLEDMM - this allocates global I2C pins, then starts Wire - if not started previously
enabled = false;
return;
}
//PinManagerPinType pins[2] = { { i2c_scl, true }, { i2c_sda, true } };
//if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { enabled = false; return; }
//Wire.begin();
sensor.setTimeout(150);
if (!sensor.init())
{
DEBUG_PRINTLN(F("Failed to detect and initialize VL53L0X sensor!"));
enabled = false; // WLEDMM bugfix
} else {
sensor.setMeasurementTimingBudget(20000); // set high speed mode
}

View File

@@ -72,7 +72,7 @@
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
//#include "Wire.h" // WLEDMM not necessary
#endif
// ================================================================
@@ -127,9 +127,12 @@ class MPU6050Driver : public Usermod {
}
if (pins[1].pin < 0 || pins[0].pin < 0) { enabled=false; dmpReady = false; return; } //WLEDMM bugfix - ensure that "final" GPIO are valid and no "-1" sneaks trough
//if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) {
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) {
// WLEDMM join I2C HW wire
if (!pinManager.joinWire()) {
enabled = false;
dmpReady = false;
USER_PRINTF("mpu6050: failed to allocate I2C sda=%d scl=%d\n", i2c_sda, i2c_scl);
return;
}
@@ -138,9 +141,9 @@ class MPU6050Driver : public Usermod {
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#if defined(ARDUINO_ARCH_ESP32)
Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM fix - need to use proper pins, in case that Wire was not started yet. Call will silently fail if Wire is initialized already.
//Wire.begin(pins[1].pin, pins[0].pin); // WLEDMM fix - need to use proper pins, in case that Wire was not started yet. Call will silently fail if Wire is initialized already.
#else
Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed.
//Wire.begin(); // WLEDMM - i2c pins on 8266 are fixed.
#endif
Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties

View File

@@ -348,8 +348,14 @@ class FourLineDisplayUsermod : public Usermod {
// isHW = true;
if (isHW) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
PinManagerPinType pins[2] = { {ioPin[0], true }, { ioPin[1], true } };
if (ioPin[0] < 0 || ioPin[1] < 0) { typeOK=false; strcpy(errorMessage, PSTR("I2C No Pins defined")); return; } //WLEDMM bugfix - ensure that "final" GPIO are valid
if (!pinManager.allocateMultiplePins(pins, 2, po)) { typeOK=false; strcpy(errorMessage, PSTR("I2C Alloc pins failed")); return; }
if (isHW) {
if (!pinManager.joinWire(ioPin[1], ioPin[0])) { typeOK=false; strcpy(errorMessage, PSTR("I2C init failed")); return; } // WLEDMM join the HW bus
} else {
if (!pinManager.allocateMultiplePins(pins, 2, po)) { typeOK=false; strcpy(errorMessage, PSTR("I2C Alloc pins failed")); return; } // WLEDMM use software bus
}
}
DEBUG_PRINTLN(F("Allocating display."));
@@ -462,7 +468,7 @@ class FourLineDisplayUsermod : public Usermod {
*/
void loop() {
#ifndef ARDUINO_ARCH_ESP32
if (!enabled || strip.isUpdating()) return;
if (!enabled || !typeOK || strip.isUpdating()) return;
unsigned long now = millis();
if (now < nextUpdate) return;
nextUpdate = now + ((displayTurnedOff && clockMode && showSeconds) ? 1000 : refreshRate);