add read/only pin logic and check

This commit is contained in:
PaoloTK 2024-09-01 21:31:19 +02:00
parent 6655e2664e
commit fcc344ba99
5 changed files with 63 additions and 22 deletions

View File

@ -1216,11 +1216,11 @@ void WS2812FX::finalizeInit(void) {
if (BusManager::getNumBusses() == 0) { if (BusManager::getNumBusses() == 0) {
DEBUG_PRINTLN(F("No busses, init default")); DEBUG_PRINTLN(F("No busses, init default"));
constexpr unsigned defDataTypes[] = {LED_TYPES}; constexpr unsigned defDataTypes[] = {LED_TYPES};
const unsigned defDataPins[] = {DATA_PINS}; constexpr unsigned defDataPins[] = {DATA_PINS};
const unsigned defCounts[] = {PIXEL_COUNTS}; constexpr unsigned defCounts[] = {PIXEL_COUNTS};
const unsigned defNumTypes = ((sizeof defDataTypes) / (sizeof defDataTypes[0])); constexpr unsigned defNumTypes = ((sizeof defDataTypes) / (sizeof defDataTypes[0]));
constexpr unsigned defNumPins = ((sizeof defDataPins) / (sizeof defDataPins[0])); constexpr unsigned defNumPins = ((sizeof defDataPins) / (sizeof defDataPins[0]));
const unsigned defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0])); constexpr unsigned defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0]));
static_assert(Bus::getNumberOfPins(defDataTypes[0]) <= defNumPins, static_assert(Bus::getNumberOfPins(defDataTypes[0]) <= defNumPins,
"The first LED type configured requires more pins than have been defined!"); "The first LED type configured requires more pins than have been defined!");
@ -1237,14 +1237,18 @@ void WS2812FX::finalizeInit(void) {
DEBUG_PRINTLN(F("LED outputs misaligned with defined pins. Some pins will remain unused.")); DEBUG_PRINTLN(F("LED outputs misaligned with defined pins. Some pins will remain unused."));
break; break;
} }
for (unsigned j = 0; j < busPins && j < OUTPUT_MAX_PINS; j++) defPin[j] = defDataPins[pinsIndex + j]; for (unsigned j = 0; j < busPins && j < OUTPUT_MAX_PINS; j++) {
pinsIndex += busPins; defPin[j] = defDataPins[pinsIndex + j];
// when booting without config (1st boot) we need to make sure GPIOs defined for LED output don't clash with hardware // when booting without config (1st boot) we need to make sure GPIOs defined for LED output don't clash with hardware
// i.e. DEBUG (GPIO1), DMX (2), SPI RAM/FLASH (16&17 on ESP32-WROVER/PICO), etc // i.e. DEBUG (GPIO1), DMX (2), SPI RAM/FLASH (16&17 on ESP32-WROVER/PICO), read/only pins, etc.
if (pinManager.isPinAllocated(defPin[0])) { if (pinManager.isPinAllocated(defPin[j]) || pinManager.isReadOnlyPin(defPin[j])) {
defPin[0] = 1; // start with GPIO1 and work upwards defPin[j] = 1; // start with GPIO1 and work upwards
while (pinManager.isPinAllocated(defPin[0]) && defPin[0] < WLED_NUM_PINS) defPin[0]++; while (pinManager.isPinAllocated(defPin[j]) && pinManager.isReadOnlyPin(defPin[j]) && defPin[j] < WLED_NUM_PINS) defPin[j]++;
} }
}
pinsIndex += busPins;
unsigned start = prevLen; unsigned start = prevLen;
// if we have less counts than pins and they do not align, use last known count to set current count // if we have less counts than pins and they do not align, use last known count to set current count
unsigned count = defCounts[(i < defNumCounts) ? i : defNumCounts -1]; unsigned count = defCounts[(i < defNumCounts) ? i : defNumCounts -1];

View File

@ -572,6 +572,19 @@
#endif #endif
#endif #endif
// List of read only pins. Cannot be used for LED outputs.
#if defined(CONFIG_IDF_TARGET_ESP32S2)
#define READ_ONLY_PINS 46
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
// none for S3
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
// none for C3
#elif defined(ESP32)
#define READ_ONLY_PINS 34,35,36,37,38,39
#else
// none for ESP8266
#endif
#ifdef WLED_ENABLE_DMX #ifdef WLED_ENABLE_DMX
#if (LEDPIN == 2) #if (LEDPIN == 2)
#undef LEDPIN #undef LEDPIN

View File

@ -267,6 +267,29 @@ bool PinManagerClass::isPinOk(byte gpio, bool output) const
return false; return false;
} }
unsigned *PinManagerClass::getReadOnlyPins()
{
#ifdef READ_ONLY_PINS
static unsigned readOnlyPins[] = {READ_ONLY_PINS};
#elif
static unsigned readOnlyPins[] = 255;
#endif
return readOnlyPins;
}
bool PinManagerClass::isReadOnlyPin(byte gpio)
{
const unsigned* pins = PinManagerClass::getReadOnlyPins();
const unsigned numPins = sizeof(pins) / sizeof(pins[0]);
for (unsigned i = 0; i < numPins; i++) {
if (pins[i] == gpio) {
return true;
}
}
return false;
}
PinOwner PinManagerClass::getPinOwner(byte gpio) const PinOwner PinManagerClass::getPinOwner(byte gpio) const
{ {
if (!isPinOk(gpio, false)) return PinOwner::None; if (!isPinOk(gpio, false)) return PinOwner::None;

View File

@ -112,6 +112,9 @@ class PinManagerClass {
// will return false for reserved pins // will return false for reserved pins
bool isPinOk(byte gpio, bool output = true) const; bool isPinOk(byte gpio, bool output = true) const;
static unsigned* getReadOnlyPins();
static bool isReadOnlyPin(byte gpio);
PinOwner getPinOwner(byte gpio) const; PinOwner getPinOwner(byte gpio) const;
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32

View File

@ -191,17 +191,15 @@ void appendGPIOinfo() {
// add info for read-only GPIO // add info for read-only GPIO
oappend(SET_F("d.ro_gpio=[")); oappend(SET_F("d.ro_gpio=["));
#if defined(CONFIG_IDF_TARGET_ESP32S2) const unsigned* readOnlyPins = pinManager.getReadOnlyPins();
oappendi(46); const unsigned numReadOnlyPins = ((sizeof readOnlyPins) / (sizeof readOnlyPins[0]));
#elif defined(CONFIG_IDF_TARGET_ESP32S3) for (unsigned i = 0; i < numReadOnlyPins; i++) {
// none for S3 // Ignore 255
#elif defined(CONFIG_IDF_TARGET_ESP32C3) if (readOnlyPins[i] <= WLED_NUM_PINS) {
// none for C3 oappendi(readOnlyPins[i]);
#elif defined(ESP32) if (i != numReadOnlyPins) oappend(SET_F(","));
oappend(SET_F("34,35,36,37,38,39")); }
#else }
// none for ESP8266
#endif
oappend(SET_F("];")); oappend(SET_F("];"));
// add info about max. # of pins // add info about max. # of pins