diff --git a/wled00/button.cpp b/wled00/button.cpp index 29cb0abebf..06683e17a5 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -99,9 +99,13 @@ bool isButtonPressed(uint8_t i) case BTN_TYPE_TOUCH: case BTN_TYPE_TOUCH_SWITCH: #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) - if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true; + #ifdef SOC_TOUCH_VERSION_2 //ESP32 S2 and S3 provide a function to check touch state (state is updated in interrupt) + if (touchInterruptGetLastStatus(pin)) return true; + #else + if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true; + #endif #endif - break; + break; } return false; } @@ -406,3 +410,8 @@ void handleIO() offMode = true; } } + +void IRAM_ATTR touchButtonISR() +{ + // used for ESP32 S2 and S3: nothing to do, ISR is just used to update registers of HAL driver +} diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 449182fe74..9d36134f08 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -228,6 +228,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { // read multiple button configuration JsonObject btn_obj = hw["btn"]; + CJSON(touchThreshold, btn_obj[F("tt")]); bool pull = btn_obj[F("pull")] | (!disablePullUp); // if true, pullup is enabled disablePullUp = !pull; JsonArray hw_btn_ins = btn_obj["ins"]; @@ -252,6 +253,13 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { btnPin[s] = -1; pinManager.deallocatePin(pin,PinOwner::Button); } + //if touch pin, enable the touch interrupt on ESP32 S2 & S3 + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so + if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH)) + { + touchAttachInterrupt(btnPin[s], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000) + } + #endif else #endif { @@ -299,7 +307,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } } } - CJSON(touchThreshold,btn_obj[F("tt")]); + CJSON(buttonPublishMqtt,btn_obj["mqtt"]); int hw_ir_pin = hw["ir"]["pin"] | -2; // 4 diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 20ac21129d..9b032d0313 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -20,6 +20,7 @@ void doublePressAction(uint8_t b=0); bool isButtonPressed(uint8_t b=0); void handleButton(); void handleIO(); +void IRAM_ATTR touchButtonISR(); //cfg.cpp bool deserializeConfig(JsonObject doc, bool fromFS = false); diff --git a/wled00/set.cpp b/wled00/set.cpp index 7137e0cd81..0b84160c95 100755 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -108,6 +108,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) for (uint8_t s=0; s=0 && pinManager.isPinAllocated(btnPin[s], PinOwner::Button)) { pinManager.deallocatePin(btnPin[s], PinOwner::Button); + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state, detach interrupt + if (digitalPinToTouchChannel(btnPin[s]) >= 0) // if touch capable pin + touchDetachInterrupt(btnPin[s]); // if not assigned previously, this will do nothing + #endif } } @@ -236,6 +240,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) rlyMde = (bool)request->hasArg(F("RM")); disablePullUp = (bool)request->hasArg(F("IP")); + touchThreshold = request->arg(F("TT")).toInt(); for (uint8_t i=0; i10) char be[4] = "BE"; be[2] = (i<10?48:55)+i; be[3] = 0; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10) @@ -252,12 +257,21 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) btnPin[i] = -1; pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); } - else if ((buttonType[i] == BTN_TYPE_TOUCH || buttonType[i] == BTN_TYPE_TOUCH_SWITCH) && digitalPinToTouchChannel(btnPin[i]) < 0) + else if ((buttonType[i] == BTN_TYPE_TOUCH || buttonType[i] == BTN_TYPE_TOUCH_SWITCH)) { - // not a touch pin - DEBUG_PRINTF_P(PSTR("PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n"), btnPin[i], i); - btnPin[i] = -1; - pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); + if (digitalPinToTouchChannel(btnPin[i]) < 0) + { + // not a touch pin + DEBUG_PRINTF_P(PSTR("PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n"), btnPin[i], i); + btnPin[i] = -1; + pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); + } + #ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so + else + { + touchAttachInterrupt(btnPin[i], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000) + } + #endif } else #endif @@ -277,7 +291,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) buttonType[i] = BTN_TYPE_NONE; } } - touchThreshold = request->arg(F("TT")).toInt(); briS = request->arg(F("CA")).toInt();