From 45e46822a1ae849de58a8fe41b13508936f63fa5 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Fri, 20 Jan 2023 19:21:45 +0100 Subject: [PATCH] PinManager: additional GPIO infos bool isPinTouch(int gpio); // true if gpio supports touch functions bool isPinAnalog(int gpio); // true if gpio supports analogRead bool isPinADC1(int gpio); // true if gpio supports analogRead, and it belongs to ADC unit 1 bool isPinADC2(int gpio); // true if gpio supports analogRead, and it belongs to ADC unit 2 #define PM_NO_PIN 255 typedef enum { ADC_none = 0, ADC1 = 1, ADC2 = 2 } AdcIdentifier; uint8_t getADCPin(AdcIdentifier adcUnit, uint8_t adcPort); // get GPIO number for ADC unit x, channel y. 255 = no such pin --- wled00/pin_manager.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++ wled00/pin_manager.h | 14 +++++++- wled00/wled.cpp | 21 +++++++++++ wled00/wled.h | 2 +- 4 files changed, 115 insertions(+), 2 deletions(-) diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index ff9ac885..aa3f9912 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -597,6 +597,86 @@ bool PinManagerClass::joinWire(int8_t pinSDA, int8_t pinSCL) { return(true); } + + // WLEDMM more additions + + // returns true if gpio supports touch functions + bool PinManagerClass::isPinTouch(int gpio) { + #if defined(ARDUINO_ARCH_ESP32) + if (digitalPinToTouchChannel(gpio) >= 0) return true; + #endif + return false; // fall-through case + } + + // returns true if gpio supports analogRead + bool PinManagerClass::isPinAnalog(int gpio) { + #if !defined(ARDUINO_ARCH_ESP32) + if (gpio == A0) return true; // for 8266 + #else // for ESP32 variants + if (digitalPinToAnalogChannel(gpio) >= 0) return true; + #endif + return false; // fall-through case + } + + // returns true if gpio supports analogRead, and it belongs to ADC unit 1 + bool PinManagerClass::isPinADC1(int gpio) { + if ((gpio < 0) || !isPinAnalog(gpio)) return false; + + #if !defined(ARDUINO_ARCH_ESP32) + if (gpio == A0) return true; // for 8266 + #else // for ESP32 variants + #ifdef SOC_ADC_CHANNEL_NUM + if (digitalPinToAnalogChannel(gpio) < SOC_ADC_CHANNEL_NUM(0)) return true; // ADC1 on ESP32-S3, ESP32-S2, ESP32-C3 + #else + if (digitalPinToAnalogChannel(gpio) < 8) return true; // ADC1 on classic ESP32 + #endif + #endif + return false; // fall-through case + } + + // returns true if gpio supports analogRead, and it belongs to ADC unit 2 + bool PinManagerClass::isPinADC2(int gpio) { + if ((gpio < 0) || !isPinAnalog(gpio)) return false; // catch errors + + #if !defined(ARDUINO_ARCH_ESP32) + return false; // for 8266 - no ADC2 + #else // for ESP32 variants + if (isPinADC1(gpio) == false) return true; // analog but not ADC1 --> must be ADC2 + #endif + return false; // fall-through case + } + + // returns GPIO number for ADC unit x, channel y. 255 = no such pin + // see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#gpio-summary + uint8_t PinManagerClass::getADCPin(AdcIdentifier adcUnit, uint8_t adcPort) + { + #if !defined(ARDUINO_ARCH_ESP32) + if ((adcUnit == ADC1) && (adcPort == 0)) return A0; // for 8266 + else return(PM_NO_PIN); + + #else // for ESP32 variants + if ((adcUnit != ADC1) && (adcUnit != ADC2)) return(PM_NO_PIN); // catch errors + + #if defined(SOC_ADC_MAX_CHANNEL_NUM) // for ESP32-S3, ESP32-S2, ESP32-C3 + int8_t analogChannel = (adcUnit == ADC1) ? adcPort : (SOC_ADC_MAX_CHANNEL_NUM + adcPort); + if (adcPort >= SOC_ADC_MAX_CHANNEL_NUM) analogChannel = 255; + #else // for classic ESP32 + int8_t analogChannel = (adcUnit == ADC1) ? adcPort : (10 + adcPort); + if (adcPort >= 10) analogChannel = 255; + #endif + + //int analogPin = analogChannelToDigitalPin(analogChannel); + int analogPin = analogInputToDigitalPin(analogChannel); + if (analogPin >= 0) return(analogPin); + else return(PM_NO_PIN); + #endif + + return(PM_NO_PIN); // fall-through case + } + + // WLEDMM end + + /* 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. diff --git a/wled00/pin_manager.h b/wled00/pin_manager.h index 508d9cac..21029320 100644 --- a/wled00/pin_manager.h +++ b/wled00/pin_manager.h @@ -67,7 +67,7 @@ static_assert(0u == static_cast(PinOwner::None), "PinOwner::None must b class PinManagerClass { private: #ifdef ESP8266 - #define WLED_NUM_PINS 17 + #define WLED_NUM_PINS 18 // WLEDMM include A0 = gpio17 uint8_t pinAlloc[3] = {0x00, 0x00, 0x00}; //24bit, 1 bit per pin, we use first 17bits PinOwner ownerTag[WLED_NUM_PINS] = { PinOwner::None }; PinOwner ownerConflict[WLED_NUM_PINS] = { PinOwner::None }; // WLEDMM: record pin alloc conflicts @@ -124,10 +124,22 @@ class PinManagerClass { bool isPinOk(byte gpio, bool output = true); PinOwner getPinOwner(byte gpio); + + // WLEDMM begin 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) + + bool isPinTouch(int gpio); // true if gpio supports touch functions + bool isPinAnalog(int gpio); // true if gpio supports analogRead + bool isPinADC1(int gpio); // true if gpio supports analogRead, and it belongs to ADC unit 1 + bool isPinADC2(int gpio); // true if gpio supports analogRead, and it belongs to ADC unit 2 + #define PM_NO_PIN 255 + typedef enum { ADC_none = 0, ADC1 = 1, ADC2 = 2 } AdcIdentifier; + uint8_t getADCPin(AdcIdentifier adcUnit, uint8_t adcPort); // get GPIO number for ADC unit x, channel y. 255 = no such pin + // WLEDMM end + #ifdef ARDUINO_ARCH_ESP32 byte allocateLedc(byte channels); void deallocateLedc(byte pos, byte channels); diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 79c6ccca..8eef3ba2 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -575,6 +575,27 @@ void WLED::setup() USER_FLUSH(); // avoid lost lines (Serial buffer overflow) } } + +#if 0 // for testing + USER_PRINTLN(F("\n")); + USER_PRINTF("ADC1-0 = %d, ADC1-3 = %d, ADC1-7 = %d, ADC2-0 = %d, ADC2-1 = %d, ADC2-8 = %d, ADC2-10 = %d\n", + pinManager.getADCPin(PinManagerClass::ADC1, 0), pinManager.getADCPin(PinManagerClass::ADC1, 3), pinManager.getADCPin(PinManagerClass::ADC1, 7), + pinManager.getADCPin(PinManagerClass::ADC2, 0), pinManager.getADCPin(PinManagerClass::ADC2, 1), pinManager.getADCPin(PinManagerClass::ADC2, 8), + pinManager.getADCPin(PinManagerClass::ADC2, 10) + ); + USER_PRINTLN(); + for(int p=0; p<12; p++) { + if(pinManager.getADCPin(PinManagerClass::ADC1, p) < 255) + USER_PRINTF("ADC1-%d = %d, ", p, pinManager.getADCPin(PinManagerClass::ADC1, p)); + } + USER_PRINTLN(); + for(int p=0; p<12; p++) { + if(pinManager.getADCPin(PinManagerClass::ADC2, p) < 255) + USER_PRINTF("ADC2-%d = %d, ", p, pinManager.getADCPin(PinManagerClass::ADC2, p)); + } + USER_PRINTLN(F("\n")); +#endif + USER_PRINTLN(F("WLED initialization done.\n")); delay(50); // repeat Ada prompt diff --git a/wled00/wled.h b/wled00/wled.h index 3a49d75f..34e41c65 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2301201 +#define VERSION 2301202 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG