pin info: show conflicts

* set.cpp: reject non-ADC pins as analog button pins (bugfix)
* pinmanager:
record conflicts
added getOwnerText(PinOwner tag) and getPinConflicts(int gpio)

GPIO    | Assigned to           | Info
--------|-----------------------|------------
i/o   0   Button            !! Conflict with AudioReactive (UM) !!        (default) I2S MCLK
i/o   1   debug output            Serial TX
i/o   2   ./.                     (default) LED pin
i/o   3   ./.                     Serial RX
i/o   5   ./.                     (default) SPI SS
i/o  13   Button            !! Conflict with IR Receiver !!

PIN ALLOC error: GPIO19 for analog button #2 is not an analog pin!
This commit is contained in:
Frank
2022-12-04 02:22:50 +01:00
parent 4bafc222f9
commit d2d8a86d81
5 changed files with 51 additions and 18 deletions

View File

@@ -12,6 +12,7 @@ static void DebugPrintOwnerTag(PinOwner tag)
{
uint32_t q = static_cast<uint8_t>(tag);
if (q) {
DEBUG_PRINT(pinManager.getOwnerText(tag)); DEBUG_PRINT(F(" = ")); // WLEDMM
DEBUG_PRINTF("0x%02x (%d)", q, q);
} else {
DEBUG_PRINT(F("(no owner)"));
@@ -26,8 +27,11 @@ String PinManagerClass::getPinOwnerText(int gpio) {
//if (gpio >= GPIO_PIN_COUNT) return(F("n/a"));
if (!isPinOk(gpio, false)) return(F("n/a"));
if (!isPinAllocated(gpio)) return(F("./."));
return(getOwnerText(getPinOwner(gpio)));
}
switch(getPinOwner(gpio)) {
String PinManagerClass::getOwnerText(PinOwner tag) {
switch(tag) {
case PinOwner::None : return(F("no owner")); break; // unknown - no owner
case PinOwner::DebugOut : return(F("debug output")); break; // 'Dbg' == debug output always IO1
case PinOwner::Ethernet : return(F("Ethernet")); break; // Ethernet
@@ -62,7 +66,7 @@ String PinManagerClass::getPinOwnerText(int gpio) {
}
String PinManagerClass::getPinSpecialText(int gpio) { // special purpose PIN info
if ((gpio == 0xFF) || (gpio < 0)) return(F("")); // explicitly allow clients to free -1 as a no-op
if ((gpio == 0xFF) || (gpio < 0)) return(F("")); // explicitly allow -1 as a no-op
// audioreactive settings - unfortunately, these are hiddden inside usermod now :-(
// if((gpio == audioPin) && (dmType == 0)) return(F("analog audio in"));
@@ -182,6 +186,16 @@ String PinManagerClass::getPinSpecialText(int gpio) { // special purpose PIN in
return(F("")); // default - nothing special to say
}
String PinManagerClass::getPinConflicts(int gpio) {
if ((gpio == 0xFF) || (gpio < 0)) return(F("")); // explicitly allow -1 as a no-op
if (!isPinOk(gpio, false)) return(F("")); // invalid GPIO
if (ownerConflict[gpio] == PinOwner::None) {
return(F("")); // no conflict fot this GPIO
} else { // found previous conflic!
return String("!! Conflict with ") + getOwnerText(ownerConflict[gpio]) + String(" !!");
}
}
// WLEDMM end
/// Actual allocation/deallocation routines
@@ -196,7 +210,6 @@ bool PinManagerClass::deallocatePin(byte gpio, PinOwner tag)
DEBUG_PRINT(F("PIN DEALLOC: IO "));
DEBUG_PRINT(gpio);
DEBUG_PRINT(F(" allocated by "));
DEBUG_PRINT(getPinOwnerText(gpio)); DEBUG_PRINT(F(" = ")); // WLEDMM
DebugPrintOwnerTag(ownerTag[gpio]);
DEBUG_PRINT(F(", but attempted de-allocation by "));
DebugPrintOwnerTag(tag);
@@ -208,6 +221,7 @@ bool PinManagerClass::deallocatePin(byte gpio, PinOwner tag)
byte bi = gpio - 8*by;
bitWrite(pinAlloc[by], bi, false);
ownerTag[gpio] = PinOwner::None;
// ownerConflict[gpio] = PinOwner::None; // WLEDMM clear conflict (if any)
return true;
}
@@ -232,7 +246,6 @@ bool PinManagerClass::deallocateMultiplePins(const uint8_t *pinArray, byte array
DEBUG_PRINT(F("PIN DEALLOC: IO "));
DEBUG_PRINT(gpio);
DEBUG_PRINT(F(" allocated by "));
DEBUG_PRINT(getPinOwnerText(gpio)); DEBUG_PRINT(F(" = ")); // WLEDMM
DebugPrintOwnerTag(ownerTag[gpio]);
DEBUG_PRINT(F(", but attempted de-allocation by "));
DebugPrintOwnerTag(tag);
@@ -280,8 +293,9 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
}
if (!isPinOk(gpio, mptArray[i].isOutput)) {
#ifdef WLED_DEBUG
DEBUG_PRINT(F("PIN ALLOC: Invalid pin attempted to be allocated: "));
DEBUG_PRINT(F("PIN ALLOC: Invalid pin attempted to be allocated: GPIO "));
DEBUG_PRINT(gpio);
DEBUG_PRINT(" as "); DEBUG_PRINT(mptArray[i].isOutput ? "output": "input"); // WLEDMM
DEBUG_PRINTLN(F(""));
#endif
shouldFail = true;
@@ -290,11 +304,11 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
// allow multiple "allocations" of HW I2C & SPI bus pins
continue;
} else if (isPinAllocated(gpio)) {
ownerConflict[gpio] = tag; // WLEDMM record conflict
#ifdef WLED_DEBUG
DEBUG_PRINT(F("PIN ALLOC: FAIL: IO "));
DEBUG_PRINT(gpio);
DEBUG_PRINT(F(" already allocated by "));
DEBUG_PRINT(getPinOwnerText(gpio)); DEBUG_PRINT(F(" = ")); // WLEDMM
DebugPrintOwnerTag(ownerTag[gpio]);
DEBUG_PRINTLN(F(""));
#endif
@@ -320,11 +334,11 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
byte bi = gpio - 8*by;
bitWrite(pinAlloc[by], bi, true);
ownerTag[gpio] = tag;
// ownerConflict[gpio] = PinOwner::None; // WLEDMM clear conflict (if any)
#ifdef WLED_DEBUG
DEBUG_PRINT(F("PIN ALLOC: Pin "));
DEBUG_PRINT(gpio);
DEBUG_PRINT(F(" allocated by "));
DEBUG_PRINT(getPinOwnerText(gpio)); DEBUG_PRINT(F(" = ")); // WLEDMM
DebugPrintOwnerTag(tag);
DEBUG_PRINTLN(F(""));
#endif
@@ -353,11 +367,11 @@ bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
return false;
}
if (isPinAllocated(gpio)) {
ownerConflict[gpio] = tag; // WLEDMM record conflict
#ifdef WLED_DEBUG
DEBUG_PRINT(F("PIN ALLOC: Pin "));
DEBUG_PRINT(gpio);
DEBUG_PRINT(F(" already allocated by "));
DEBUG_PRINT(getPinOwnerText(gpio)); DEBUG_PRINT(F(" = ")); // WLEDMM
DebugPrintOwnerTag(ownerTag[gpio]);
DEBUG_PRINTLN(F(""));
#endif
@@ -368,11 +382,11 @@ bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
byte bi = gpio - 8*by;
bitWrite(pinAlloc[by], bi, true);
ownerTag[gpio] = tag;
// ownerConflict[gpio] = PinOwner::None; // WLEDMM clear conflict (if any)
#ifdef WLED_DEBUG
DEBUG_PRINT(F("PIN ALLOC: Pin "));
DEBUG_PRINT(gpio);
DEBUG_PRINT(F(" successfully allocated by "));
DEBUG_PRINT(getPinOwnerText(gpio)); DEBUG_PRINT(F(" = ")); // WLEDMM
DebugPrintOwnerTag(tag);
DEBUG_PRINTLN(F(""));
#endif
@@ -383,9 +397,17 @@ bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
// if tag is set to PinOwner::None, checks for ANY owner of the pin.
// if tag is set to any other value, checks if that tag is the current owner of the pin.
bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag)
{
{
if (!isPinOk(gpio, false)) return true;
if ((tag != PinOwner::None) && (ownerTag[gpio] != tag)) return false;
if (gpio == 0xFF) {
DEBUG_PRINT(F(" isPinAllocated: -1 is never allocacted! "));
return false; // WLEDMM bugfix - avoid invalid index to array
}
if ((tag != PinOwner::None) && (ownerTag[gpio] != tag)) {
if ((ownerTag[gpio] != PinOwner::None) && (tag != PinOwner::HW_I2C) && (tag != PinOwner::HW_SPI)) ownerConflict[gpio] = tag; // WLEDMM record conflict
return false;
}
byte by = gpio >> 3;
byte bi = gpio - (by<<3);
return bitRead(pinAlloc[by], bi);

View File

@@ -67,10 +67,12 @@ class PinManagerClass {
#ifdef ESP8266
uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits
PinOwner ownerTag[17] = { PinOwner::None };
PinOwner ownerConflict[17] = { PinOwner::None }; // WLEDMM: record pin alloc conflicts
#else
uint8_t pinAlloc[7] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //WLEDMM bugfix - 56bit, 1 bit per pin, we use 50 bits on -S3
uint8_t ledcAlloc[2] = {0x00, 0x00}; //16 LEDC channels
PinOwner ownerTag[50] = { PinOwner::None }; // WLEDMM bugfix - new MCU's have up to 50 GPIO
PinOwner ownerConflict[50] = { PinOwner::None }; // WLEDMM: record pin alloc conflicts
#endif
struct {
uint8_t i2cAllocCount : 4; // allow multiple allocation of I2C bus pins but keep track of allocations
@@ -108,9 +110,10 @@ class PinManagerClass {
bool isPinOk(byte gpio, bool output = true);
PinOwner getPinOwner(byte gpio);
//String getOwnerText(PinOwner tag); // WLEDMM work in progress
String getPinOwnerText(int gpio); // WLEDMM
String getPinSpecialText(int gpio); // WLEDMM
String getOwnerText(PinOwner tag); // WLEDMM - return PIN owner tag as text
String getPinOwnerText(int gpio); // WLEDMM - return PIN owner as text
String getPinSpecialText(int gpio); // WLEDMM - return PIN special comments (if any)
String getPinConflicts(int gpio); // WLEDMM - return PIN alloc conflicts (if any)
#ifdef ARDUINO_ARCH_ESP32
byte allocateLedc(byte channels);
void deallocateLedc(byte pos, byte channels);

View File

@@ -169,7 +169,14 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
btnPin[i] = hw_btn_pin;
buttonType[i] = request->arg(be).toInt();
#ifdef ESP32
pinMode(btnPin[i], buttonType[i]==BTN_TYPE_PUSH_ACT_HIGH ? INPUT_PULLDOWN : INPUT_PULLUP);
if (((buttonType[i] == BTN_TYPE_ANALOG) || (buttonType[i] == BTN_TYPE_ANALOG_INVERTED)) && (digitalPinToAnalogChannel(btnPin[i]) < 0)) { // WLEDMM
// not an ADC analog pin
DEBUG_PRINTF("PIN ALLOC error: GPIO%d for analog button #%d is not an analog pin!\n", btnPin[i], i);
btnPin[i] = -1;
pinManager.deallocatePin(hw_btn_pin,PinOwner::Button);
} else { // WLEDMM end
pinMode(btnPin[i], buttonType[i]==BTN_TYPE_PUSH_ACT_HIGH ? INPUT_PULLDOWN : INPUT_PULLUP);
}
#else
pinMode(btnPin[i], INPUT_PULLUP);
#endif

View File

@@ -480,10 +480,11 @@ void WLED::setup()
if(pinManager.isPinOk(pinNr, false)) {
if ((!pinManager.isPinAllocated(pinNr)) && (pinManager.getPinSpecialText(pinNr).length() == 0)) continue; // comment out to include no-name,unused GPIO pins
bool is_inOut = pinManager.isPinOk(pinNr, true);
Serial.printf("%s %2d\t %-18s\t %s\n",
Serial.printf("%s %2d\t %-17s %s\t %s\n",
(is_inOut?"i/o":"in "),
pinNr,
pinManager.getPinOwnerText(pinNr).c_str(),
pinManager.getPinOwnerText(pinNr).c_str(),
pinManager.getPinConflicts(pinNr).c_str(),
pinManager.getPinSpecialText(pinNr).c_str()
);
}

View File

@@ -8,7 +8,7 @@
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2211291
#define VERSION 2212041
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG