diff --git a/esphome/components/esp32_touch/esp32_touch.h b/esphome/components/esp32_touch/esp32_touch.h index 04444ae91e..965494f523 100644 --- a/esphome/components/esp32_touch/esp32_touch.h +++ b/esphome/components/esp32_touch/esp32_touch.h @@ -68,6 +68,8 @@ class ESP32TouchComponent : public Component { // Common helper methods void dump_config_base_(); void dump_config_sensors_(); + bool create_touch_queue(); + void cleanup_touch_queue(); // Common members std::vector children_; diff --git a/esphome/components/esp32_touch/esp32_touch_common.cpp b/esphome/components/esp32_touch/esp32_touch_common.cpp index cb9b2e79e1..d9c1c22320 100644 --- a/esphome/components/esp32_touch/esp32_touch_common.cpp +++ b/esphome/components/esp32_touch/esp32_touch_common.cpp @@ -9,6 +9,20 @@ namespace esp32_touch { static const char *const TAG = "esp32_touch"; +// Forward declare the event structures that are defined in the variant-specific files +#ifdef USE_ESP32_VARIANT_ESP32 +struct TouchPadEventV1 { + touch_pad_t pad; + uint32_t value; + bool is_touched; +}; +#else +struct TouchPadEventV2 { + touch_pad_t pad; + uint32_t intr_mask; +}; +#endif + void ESP32TouchComponent::dump_config_base_() { const char *lv_s = get_low_voltage_reference_str(this->low_voltage_reference_); const char *hv_s = get_high_voltage_reference_str(this->high_voltage_reference_); @@ -33,6 +47,34 @@ void ESP32TouchComponent::dump_config_sensors_() { } } +bool ESP32TouchComponent::create_touch_queue() { + // Queue size calculation: children * 4 allows for burst scenarios where ISR + // fires multiple times before main loop processes. + size_t queue_size = this->children_.size() * 4; + if (queue_size < 8) + queue_size = 8; + +#ifdef USE_ESP32_VARIANT_ESP32 + this->touch_queue_ = xQueueCreate(queue_size, sizeof(TouchPadEventV1)); +#else + this->touch_queue_ = xQueueCreate(queue_size, sizeof(TouchPadEventV2)); +#endif + + if (this->touch_queue_ == nullptr) { + ESP_LOGE(TAG, "Failed to create touch event queue of size %d", queue_size); + this->mark_failed(); + return false; + } + return true; +} + +void ESP32TouchComponent::cleanup_touch_queue() { + if (this->touch_queue_) { + vQueueDelete(this->touch_queue_); + this->touch_queue_ = nullptr; + } +} + } // namespace esp32_touch } // namespace esphome diff --git a/esphome/components/esp32_touch/esp32_touch_v1.cpp b/esphome/components/esp32_touch/esp32_touch_v1.cpp index 2c1f7a79e0..d6cf2983d5 100644 --- a/esphome/components/esp32_touch/esp32_touch_v1.cpp +++ b/esphome/components/esp32_touch/esp32_touch_v1.cpp @@ -34,14 +34,7 @@ void ESP32TouchComponent::setup() { // Queue size calculation: children * 4 allows for burst scenarios where ISR // fires multiple times before main loop processes. This is important because // ESP32 v1 scans all pads on each interrupt, potentially sending multiple events. - size_t queue_size = this->children_.size() * 4; - if (queue_size < 8) - queue_size = 8; - - this->touch_queue_ = xQueueCreate(queue_size, sizeof(TouchPadEventV1)); - if (this->touch_queue_ == nullptr) { - ESP_LOGE(TAG, "Failed to create touch event queue of size %d", queue_size); - this->mark_failed(); + if (!this->create_touch_queue()) { return; } @@ -68,8 +61,7 @@ void ESP32TouchComponent::setup() { esp_err_t err = touch_pad_isr_register(touch_isr_handler, this); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to register touch ISR: %s", esp_err_to_name(err)); - vQueueDelete(this->touch_queue_); - this->touch_queue_ = nullptr; + this->cleanup_touch_queue(); this->mark_failed(); return; } @@ -192,9 +184,7 @@ void ESP32TouchComponent::loop() { void ESP32TouchComponent::on_shutdown() { touch_pad_intr_disable(); touch_pad_isr_deregister(touch_isr_handler, this); - if (this->touch_queue_) { - vQueueDelete(this->touch_queue_); - } + this->cleanup_touch_queue(); bool is_wakeup_source = false; diff --git a/esphome/components/esp32_touch/esp32_touch_v2.cpp b/esphome/components/esp32_touch/esp32_touch_v2.cpp index 28104371af..08d3d0aba0 100644 --- a/esphome/components/esp32_touch/esp32_touch_v2.cpp +++ b/esphome/components/esp32_touch/esp32_touch_v2.cpp @@ -13,19 +13,11 @@ static const char *const TAG = "esp32_touch"; struct TouchPadEventV2 { touch_pad_t pad; uint32_t intr_mask; - uint32_t pad_status; }; void ESP32TouchComponent::setup() { // Create queue for touch events first - size_t queue_size = this->children_.size() * 4; - if (queue_size < 8) - queue_size = 8; - - this->touch_queue_ = xQueueCreate(queue_size, sizeof(TouchPadEventV2)); - if (this->touch_queue_ == nullptr) { - ESP_LOGE(TAG, "Failed to create touch event queue of size %d", queue_size); - this->mark_failed(); + if (!this->create_touch_queue()) { return; } @@ -89,8 +81,7 @@ void ESP32TouchComponent::setup() { touch_pad_isr_register(touch_isr_handler, this, static_cast(TOUCH_PAD_INTR_MASK_ALL)); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to register touch ISR: %s", esp_err_to_name(err)); - vQueueDelete(this->touch_queue_); - this->touch_queue_ = nullptr; + this->cleanup_touch_queue(); this->mark_failed(); return; } @@ -313,9 +304,7 @@ void ESP32TouchComponent::on_shutdown() { touch_pad_intr_disable(static_cast(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT)); touch_pad_isr_deregister(touch_isr_handler, this); - if (this->touch_queue_) { - vQueueDelete(this->touch_queue_); - } + this->cleanup_touch_queue(); // Check if any pad is configured for wakeup bool is_wakeup_source = false; @@ -338,10 +327,9 @@ void IRAM_ATTR ESP32TouchComponent::touch_isr_handler(void *arg) { ESP32TouchComponent *component = static_cast(arg); BaseType_t x_higher_priority_task_woken = pdFALSE; - // Read interrupt status and pad status + // Read interrupt status TouchPadEventV2 event; event.intr_mask = touch_pad_read_intr_status_mask(); - event.pad_status = touch_pad_get_status(); event.pad = touch_pad_get_current_meas_channel(); // Send event to queue for processing in main loop