mirror of
https://github.com/esphome/esphome.git
synced 2025-10-07 04:13:47 +01:00
fixes
This commit is contained in:
@@ -10,8 +10,6 @@
|
||||
|
||||
// Include HAL for ISR-safe touch reading on all variants
|
||||
#include "hal/touch_sensor_ll.h"
|
||||
// Include for ISR-safe printing
|
||||
#include "rom/ets_sys.h"
|
||||
// Include for RTC clock frequency
|
||||
#include "soc/rtc.h"
|
||||
|
||||
@@ -22,13 +20,6 @@ static const char *const TAG = "esp32_touch";
|
||||
|
||||
void ESP32TouchComponent::setup() {
|
||||
ESP_LOGCONFIG(TAG, "Running setup");
|
||||
ESP_LOGI(TAG, "Number of touch pads configured: %d", this->children_.size());
|
||||
|
||||
if (this->children_.empty()) {
|
||||
ESP_LOGE(TAG, "No touch pads configured!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
touch_pad_init();
|
||||
|
||||
@@ -39,15 +30,12 @@ void ESP32TouchComponent::setup() {
|
||||
#endif
|
||||
|
||||
// Create queue for touch events - size based on number of touch pads
|
||||
// Each pad can have at most a few events queued (press/release)
|
||||
// Each pad can have at most a few press events queued
|
||||
// Use 4x the number of pads to handle burst events
|
||||
size_t queue_size = this->children_.size() * 4;
|
||||
if (queue_size < 8)
|
||||
queue_size = 8; // Minimum queue size
|
||||
|
||||
// QUEUE SIZE likely doesn't make sense if its really ratelimited
|
||||
// to 1 per second, but this is a good starting point
|
||||
|
||||
this->touch_queue_ = xQueueCreate(queue_size, sizeof(TouchPadEvent));
|
||||
if (this->touch_queue_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Failed to create touch event queue of size %d", queue_size);
|
||||
@@ -121,46 +109,17 @@ void ESP32TouchComponent::setup() {
|
||||
// Get actual RTC clock frequency
|
||||
uint32_t rtc_freq = rtc_clk_slow_freq_get_hz();
|
||||
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
// For S2/S3, calculate based on actual sleep cycle since they use timer mode
|
||||
// Calculate based on actual sleep cycle since they use timer mode
|
||||
this->release_timeout_ms_ = (this->sleep_cycle_ * 1000 * 3) / (rtc_freq * 2);
|
||||
if (this->release_timeout_ms_ < 100) {
|
||||
this->release_timeout_ms_ = 100; // Minimum 100ms
|
||||
}
|
||||
#else
|
||||
// For ESP32 in software mode, we're triggering manually
|
||||
// Since we're triggering every 1 second in the debug loop, use 1500ms timeout
|
||||
this->release_timeout_ms_ = 1500; // 1.5 seconds
|
||||
#endif
|
||||
|
||||
// Calculate check interval
|
||||
this->release_check_interval_ms_ = std::min(this->release_timeout_ms_ / 4, (uint32_t) 50);
|
||||
|
||||
// Read back the actual configuration to verify
|
||||
uint16_t actual_sleep_cycle = 0;
|
||||
uint16_t actual_meas_cycle = 0;
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5 && defined(USE_ESP32_VARIANT_ESP32)
|
||||
touch_pad_get_measurement_interval(&actual_sleep_cycle);
|
||||
touch_pad_get_measurement_clock_cycles(&actual_meas_cycle);
|
||||
#else
|
||||
touch_pad_get_meas_time(&actual_sleep_cycle, &actual_meas_cycle);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Touch timing config - requested: sleep=%u, meas=%u | actual: sleep=%u, meas=%u", this->sleep_cycle_,
|
||||
this->meas_cycle_, actual_sleep_cycle, actual_meas_cycle);
|
||||
ESP_LOGI(TAG, "Touch release timeout: %u ms, check interval: %u ms (RTC freq: %u Hz)", this->release_timeout_ms_,
|
||||
this->release_check_interval_ms_, rtc_freq);
|
||||
|
||||
// Enable touch pad interrupt
|
||||
touch_pad_intr_enable();
|
||||
ESP_LOGI(TAG, "Touch pad interrupts enabled");
|
||||
|
||||
// Check FSM state for debugging
|
||||
touch_fsm_mode_t fsm_mode;
|
||||
touch_pad_get_fsm_mode(&fsm_mode);
|
||||
ESP_LOGI(TAG, "FSM mode: %s", fsm_mode == TOUCH_FSM_MODE_TIMER ? "TIMER" : "SW");
|
||||
|
||||
ESP_LOGI(TAG, "Initial touch status: 0x%04x", touch_pad_get_status());
|
||||
|
||||
// Log which pads are configured and initialize their state
|
||||
ESP_LOGI(TAG, "Configured touch pads:");
|
||||
@@ -183,17 +142,9 @@ void ESP32TouchComponent::setup() {
|
||||
this->last_touch_time_[child->get_touch_pad()] = App.get_loop_component_start_time();
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "ESP32 Touch setup complete");
|
||||
}
|
||||
|
||||
void ESP32TouchComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Config for ESP32 Touch Hub:\n"
|
||||
" Meas cycle: %.2fms\n"
|
||||
" Sleep cycle: %.2fms",
|
||||
this->meas_cycle_ / (8000000.0f / 1000.0f), this->sleep_cycle_ / (150000.0f / 1000.0f));
|
||||
|
||||
const char *lv_s;
|
||||
switch (this->low_voltage_reference_) {
|
||||
case TOUCH_LVOLT_0V5:
|
||||
@@ -212,7 +163,6 @@ void ESP32TouchComponent::dump_config() {
|
||||
lv_s = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Low Voltage Reference: %s", lv_s);
|
||||
|
||||
const char *hv_s;
|
||||
switch (this->high_voltage_reference_) {
|
||||
@@ -232,7 +182,6 @@ void ESP32TouchComponent::dump_config() {
|
||||
hv_s = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " High Voltage Reference: %s", hv_s);
|
||||
|
||||
const char *atten_s;
|
||||
switch (this->voltage_attenuation_) {
|
||||
@@ -252,7 +201,18 @@ void ESP32TouchComponent::dump_config() {
|
||||
atten_s = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Voltage Attenuation: %s", atten_s);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
"Config for ESP32 Touch Hub:\n"
|
||||
" Meas cycle: %.2fms\n"
|
||||
" Sleep cycle: %.2fms\n"
|
||||
" Low Voltage Reference: %s\n"
|
||||
" High Voltage Reference: %s\n"
|
||||
" Voltage Attenuation: %s\n"
|
||||
" ISR Configuration:\n"
|
||||
" Release timeout: %" PRIu32 "ms\n"
|
||||
" Release check interval: %" PRIu32 "ms",
|
||||
this->meas_cycle_ / (8000000.0f / 1000.0f), this->sleep_cycle_ / (150000.0f / 1000.0f), lv_s, hv_s,
|
||||
atten_s, this->release_timeout_ms_, this->release_check_interval_ms_);
|
||||
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
if (this->filter_configured_()) {
|
||||
@@ -406,25 +366,13 @@ uint32_t ESP32TouchComponent::component_touch_pad_read(touch_pad_t tp) {
|
||||
|
||||
void ESP32TouchComponent::loop() {
|
||||
const uint32_t now = App.get_loop_component_start_time();
|
||||
bool should_print = now - this->setup_mode_last_log_print_ > 1000; // Log every second
|
||||
bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250;
|
||||
|
||||
// Always check touch status periodically
|
||||
// Print debug info for all pads in setup mode
|
||||
if (should_print) {
|
||||
uint32_t current_status = touch_pad_get_status();
|
||||
uint32_t hal_status;
|
||||
touch_ll_read_trigger_status_mask(&hal_status);
|
||||
|
||||
// Check if FSM is still in timer mode
|
||||
touch_fsm_mode_t fsm_mode;
|
||||
touch_pad_get_fsm_mode(&fsm_mode);
|
||||
|
||||
ESP_LOGD(TAG, "Current touch status: 0x%04x (HAL: 0x%04x), FSM: %s", current_status, hal_status,
|
||||
fsm_mode == TOUCH_FSM_MODE_TIMER ? "TIMER" : "SW");
|
||||
|
||||
// Try a manual software trigger to see if measurements are working at all
|
||||
if (current_status == 0 && hal_status == 0) {
|
||||
ESP_LOGD(TAG, "No touch status, trying manual trigger...");
|
||||
touch_pad_sw_start();
|
||||
for (auto *child : this->children_) {
|
||||
ESP_LOGD(TAG, "Touch Pad '%s' (T%" PRIu32 "): %" PRIu32, child->get_name().c_str(),
|
||||
(uint32_t) child->get_touch_pad(), child->value_);
|
||||
}
|
||||
this->setup_mode_last_log_print_ = now;
|
||||
}
|
||||
@@ -529,23 +477,33 @@ void ESP32TouchComponent::on_shutdown() {
|
||||
void IRAM_ATTR ESP32TouchComponent::touch_isr_handler(void *arg) {
|
||||
ESP32TouchComponent *component = static_cast<ESP32TouchComponent *>(arg);
|
||||
|
||||
// Log that ISR was called
|
||||
ets_printf("Touch ISR triggered!\n");
|
||||
|
||||
uint32_t pad_status = touch_pad_get_status();
|
||||
touch_pad_clear_status();
|
||||
|
||||
// Always log the status
|
||||
ets_printf("Touch ISR: raw status=0x%04x\n", pad_status);
|
||||
|
||||
// Process all configured pads to check their current state
|
||||
// Send events for ALL pads with valid readings so we catch both touches and releases
|
||||
for (auto *child : component->children_) {
|
||||
touch_pad_t pad = child->get_touch_pad();
|
||||
|
||||
// Read current value
|
||||
// We should be using touch_pad_read_filtered here
|
||||
uint32_t value = touch_ll_read_raw_data(pad);
|
||||
// Read current value using ISR-safe API
|
||||
uint32_t value;
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
if (component->filter_configured_()) {
|
||||
touch_pad_read_raw_data(pad, &value);
|
||||
} else {
|
||||
// Use low-level HAL function when filter is not configured
|
||||
value = touch_ll_read_raw_data(pad);
|
||||
}
|
||||
#else
|
||||
if (component->iir_filter_enabled_()) {
|
||||
uint16_t temp_value = 0;
|
||||
touch_pad_read_raw_data(pad, &temp_value);
|
||||
value = temp_value;
|
||||
} else {
|
||||
// Use low-level HAL function when filter is not enabled
|
||||
value = touch_ll_read_raw_data(pad);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Skip pads with 0 value - they haven't been measured in this cycle
|
||||
if (value == 0) {
|
||||
@@ -559,8 +517,6 @@ void IRAM_ATTR ESP32TouchComponent::touch_isr_handler(void *arg) {
|
||||
bool is_touched = value < child->get_threshold();
|
||||
#endif
|
||||
|
||||
ets_printf(" Pad %d: value=%d, threshold=%d, touched=%d\n", pad, value, child->get_threshold(), is_touched);
|
||||
|
||||
// Always send the current state - the main loop will filter for changes
|
||||
TouchPadEvent event;
|
||||
event.pad = pad;
|
||||
|
@@ -68,9 +68,9 @@ class ESP32TouchComponent : public Component {
|
||||
static void touch_isr_handler(void *arg);
|
||||
|
||||
QueueHandle_t touch_queue_{nullptr};
|
||||
uint32_t last_touch_time_[SOC_TOUCH_SENSOR_NUM] = {0}; // Track last time each pad was seen as touched
|
||||
uint32_t release_timeout_ms_{1500}; // Calculated timeout for release detection
|
||||
uint32_t release_check_interval_ms_{50}; // How often to check for releases
|
||||
uint32_t last_touch_time_[TOUCH_PAD_MAX] = {0}; // Track last time each pad was seen as touched
|
||||
uint32_t release_timeout_ms_{1500}; // Calculated timeout for release detection
|
||||
uint32_t release_check_interval_ms_{50}; // How often to check for releases
|
||||
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
||||
bool filter_configured_() const {
|
||||
return (this->filter_mode_ != TOUCH_PAD_FILTER_MAX) && (this->smooth_level_ != TOUCH_PAD_SMOOTH_MAX);
|
||||
|
Reference in New Issue
Block a user