best of I2CSPI-refactor
* cherry-picking my additions to pinmanger * toDo: replace Wire.begin() with pinManager.joinWire()
This commit is contained in:
@@ -309,7 +309,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
#ifdef ESP32
|
||||
Wire.setPins(i2c_sda, i2c_scl); // this will fail if Wire is initilised (Wire.begin() called prior)
|
||||
#endif
|
||||
Wire.begin();
|
||||
// Wire.begin(); // WLEDMM moved into pinManager
|
||||
} else {
|
||||
Serial.printf("pinmgr not success for global i2c %d %d\n", i2c_sda, i2c_scl);
|
||||
}
|
||||
|
||||
@@ -513,6 +513,89 @@ bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag)
|
||||
return bitRead(pinAlloc[by], bi);
|
||||
}
|
||||
|
||||
//
|
||||
// WLEDMM: central handling of I2C startup (global Wire #0)
|
||||
//
|
||||
|
||||
bool PinManagerClass::joinWire() { // shortcut in case no parameters provided
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// ESP32 - i2c pins can be mapped to any GPIO
|
||||
return joinWire(i2c_sda, i2c_scl);
|
||||
#else
|
||||
// ESP8266: I2C pins are fixed
|
||||
return joinWire(HW_PIN_SDA, HW_PIN_SCL);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool PinManagerClass::joinWire(int8_t pinSDA, int8_t pinSCL) {
|
||||
// reject PIN = -1, reject SDA=SCL, reject "forbidden" pins
|
||||
if ( (pinSDA < 0) || (pinSCL < 0)
|
||||
|| (pinSDA == pinSCL)
|
||||
|| !isPinOk(pinSDA, true)
|
||||
|| !isPinOk(pinSCL, true)) {
|
||||
DEBUG_PRINT(F("PIN Manager: invalid GPIO for I2C: SDA="));
|
||||
DEBUG_PRINTF("%d, SCL=%d !\n",pinSDA, pinSCL);
|
||||
return(false);
|
||||
}
|
||||
|
||||
if ((wire0PinSDA < 0) || (wire0PinSCL < 0)) wire0isStarted = false; // this should not happen
|
||||
|
||||
// if wire already started, reject any other GPIO
|
||||
if ((wire0isStarted == true) &&
|
||||
(pinSDA != wire0PinSDA) && (pinSDA != wire0PinSCL) && // allow "swapped pins2, i.e. SDA <->SCL
|
||||
(pinSCL != wire0PinSCL) && (pinSCL != wire0PinSDA)) {
|
||||
DEBUG_PRINT(F("PIN Manager: invalid GPIO for I2C: SDA="));
|
||||
DEBUG_PRINTF("%d, SCL=%d. Wire already started with sda=%d and scl=%d!\n",pinSDA, pinSCL, wirePinSDA, wirePinSCL);
|
||||
return(false);
|
||||
}
|
||||
|
||||
// make sure pins are allocated
|
||||
PinManagerPinType pins[2] = {{pinSCL, true}, {pinSDA, true}};
|
||||
if (!allocateMultiplePins(pins, 2, PinOwner::HW_I2C)) { // this will only FAIL when pins are invalid, or used already for other purposes
|
||||
DEBUG_PRINT(F("PIN Manager: failed to allocate GPIO for I2C: SDA="));
|
||||
DEBUG_PRINTF("%d, SCL=%d !\n",pinSDA, pinSCL);
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(wire0isStarted == true) {
|
||||
DEBUG_PRINTLN(F("PIN Manager: all good, I2C already started, nothing to do :-)"));
|
||||
return(true);
|
||||
}
|
||||
|
||||
// NOW do it - start Wire !!! fire ;-)
|
||||
|
||||
bool wireIsOK = true;
|
||||
#ifdef ARDUINO_ARCH_ESP32 // ESP32 - i2c pins can be mapped to any GPIO
|
||||
wireIsOK = Wire.setPins(pinSDA, pinSCL); // this will fail if Wire is initialised already (i.e. Wire.begin() called prior)
|
||||
#else // 8266 - I2C pins are fixed
|
||||
if((pinSDA != HW_PIN_SDA) || (pinSCL != HW_PIN_SCL)) {
|
||||
DEBUG_PRINT(F("PIN Manager: warning ESP8266 I2C pins are fixed. please use SDA="));
|
||||
DEBUG_PRINTF("%d, SCL=%d !\n",HW_PIN_SDA, HW_PIN_SCL);
|
||||
}
|
||||
#endif
|
||||
if (wireIsOK == false) {
|
||||
USER_PRINTLN(F("PIN Manager: warning - wire.setPins failed!"));
|
||||
}
|
||||
|
||||
wireIsOK = Wire.begin(); // this will fail if wire is already running
|
||||
|
||||
if (wireIsOK == false) {
|
||||
USER_PRINTLN(F("PIN Manager: warning - wire.begin failed!"));
|
||||
} else {
|
||||
USER_PRINTLN(F("PIN Manager: wire.begin successfull."));
|
||||
}
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32S3
|
||||
Wire.setTimeOut(50); // workaround for wire timeout bug on -S3
|
||||
Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having wiring difficulties
|
||||
#endif
|
||||
|
||||
wire0isStarted = true;
|
||||
wire0PinSDA = pinSDA;
|
||||
wire0PinSCL = pinSCL;
|
||||
return(true);
|
||||
}
|
||||
|
||||
/* see https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/gpio.html
|
||||
* The ESP32-S3 chip features 45 physical GPIO pins (GPIO0 ~ GPIO21 and GPIO26 ~ GPIO48). Each pin can be used as a general-purpose I/O
|
||||
* Strapping pins: GPIO0, GPIO3, GPIO45 and GPIO46 are strapping pins. For more infomation, please refer to ESP32-S3 datasheet.
|
||||
|
||||
@@ -83,8 +83,13 @@ class PinManagerClass {
|
||||
uint8_t spiAllocCount : 4; // allow multiple allocation of SPI bus pins but keep track of allocations
|
||||
};
|
||||
|
||||
// WLEDMM: central handling of Wire (only for first bus)
|
||||
bool wire0isStarted = false; // true is wire.begin() was done already
|
||||
int8_t wire0PinSDA = -1; // GPIO currently in use for SDA
|
||||
int8_t wire0PinSCL = -1; // GPIO currently in use for SCL
|
||||
|
||||
public:
|
||||
PinManagerClass() : i2cAllocCount(0), spiAllocCount(0) {}
|
||||
PinManagerClass() : i2cAllocCount(0), spiAllocCount(0), wire0isStarted(false) {} // WLEDMM: initialize wire0isStarted=false
|
||||
// De-allocates a single pin
|
||||
bool deallocatePin(byte gpio, PinOwner tag);
|
||||
// De-allocates multiple pins but only if all can be deallocated (PinOwner has to be specified)
|
||||
@@ -108,6 +113,11 @@ class PinManagerClass {
|
||||
#endif
|
||||
inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
|
||||
|
||||
// WLEDMM: central initialization of Wire (Wire1 not supported yet)
|
||||
bool joinWire(); // shortcut - use global pins when no parameters provided
|
||||
bool joinWire(int8_t pinSDA, int8_t pinSCL); // use this instead of Wire.begin(SDA, SCL)
|
||||
// toDo: may need to add calls for Wire.setClock, Wire.setPins Wire.end
|
||||
|
||||
// will return true for reserved pins
|
||||
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
|
||||
// will return false for reserved pins
|
||||
|
||||
@@ -543,7 +543,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
#ifdef ESP32
|
||||
Wire.setPins(i2c_sda, i2c_scl); // this will fail if Wire is initilised (Wire.begin() called)
|
||||
#endif
|
||||
Wire.begin();
|
||||
// Wire.begin(); // WLEDMM moved into pinManager
|
||||
} else {
|
||||
// there is no Wire.end()
|
||||
DEBUG_PRINTLN(F("Could not allocate I2C pins."));
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2301082
|
||||
#define VERSION 2301083
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
|
||||
Reference in New Issue
Block a user