diff --git a/esphome/components/esp32_rmt_led_strip/led_strip.cpp b/esphome/components/esp32_rmt_led_strip/led_strip.cpp index 4ca0b998b1..8bb5cbb62e 100644 --- a/esphome/components/esp32_rmt_led_strip/led_strip.cpp +++ b/esphome/components/esp32_rmt_led_strip/led_strip.cpp @@ -7,22 +7,25 @@ #include "esphome/core/log.h" #include +#include namespace esphome { namespace esp32_rmt_led_strip { static const char *const TAG = "esp32_rmt_led_strip"; -#ifdef USE_ESP32_VARIANT_ESP32H2 -static const uint32_t RMT_CLK_FREQ = 32000000; -static const uint8_t RMT_CLK_DIV = 1; -#else -static const uint32_t RMT_CLK_FREQ = 80000000; -static const uint8_t RMT_CLK_DIV = 2; -#endif - static const size_t RMT_SYMBOLS_PER_BYTE = 8; +// Query the RMT default clock source frequency. This varies by variant: +// APB (80MHz) on ESP32/S2/S3/C3, PLL_F80M (80MHz) on C6/P4, XTAL (32MHz) on H2. +// Worst-case reset time is WS2811 at 300µs = 24000 ticks at 80MHz, well within +// the 15-bit rmt_symbol_word_t duration field max of 32767. +static uint32_t rmt_resolution_hz() { + uint32_t freq; + esp_clk_tree_src_get_freq_hz((soc_module_clk_t) RMT_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &freq); + return freq; +} + #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) static size_t IRAM_ATTR HOT encoder_callback(const void *data, size_t size, size_t symbols_written, size_t symbols_free, rmt_symbol_word_t *symbols, bool *done, void *arg) { @@ -92,7 +95,7 @@ void ESP32RMTLEDStripLightOutput::setup() { rmt_tx_channel_config_t channel; memset(&channel, 0, sizeof(channel)); channel.clk_src = RMT_CLK_SRC_DEFAULT; - channel.resolution_hz = RMT_CLK_FREQ / RMT_CLK_DIV; + channel.resolution_hz = rmt_resolution_hz(); channel.gpio_num = gpio_num_t(this->pin_); channel.mem_block_symbols = this->rmt_symbols_; channel.trans_queue_depth = 1; @@ -137,7 +140,7 @@ void ESP32RMTLEDStripLightOutput::setup() { void ESP32RMTLEDStripLightOutput::set_led_params(uint32_t bit0_high, uint32_t bit0_low, uint32_t bit1_high, uint32_t bit1_low, uint32_t reset_time_high, uint32_t reset_time_low) { - float ratio = (float) RMT_CLK_FREQ / RMT_CLK_DIV / 1e09f; + float ratio = (float) rmt_resolution_hz() / 1e09f; // 0-bit this->params_.bit0.duration0 = (uint32_t) (ratio * bit0_high); diff --git a/esphome/components/pulse_counter/pulse_counter_sensor.cpp b/esphome/components/pulse_counter/pulse_counter_sensor.cpp index ef4cc980f6..8ac5a28d8f 100644 --- a/esphome/components/pulse_counter/pulse_counter_sensor.cpp +++ b/esphome/components/pulse_counter/pulse_counter_sensor.cpp @@ -2,7 +2,7 @@ #include "esphome/core/log.h" #ifdef HAS_PCNT -#include +#include #include #endif @@ -117,7 +117,9 @@ bool HwPulseCounterStorage::pulse_counter_setup(InternalGPIOPin *pin) { } if (this->filter_us != 0) { - uint32_t max_glitch_ns = PCNT_LL_MAX_GLITCH_WIDTH * 1000000u / (uint32_t) esp_clk_apb_freq(); + uint32_t apb_freq; + esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_APB, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &apb_freq); + uint32_t max_glitch_ns = PCNT_LL_MAX_GLITCH_WIDTH * 1000000u / apb_freq; pcnt_glitch_filter_config_t filter_config = { .max_glitch_ns = std::min(this->filter_us * 1000u, max_glitch_ns), }; diff --git a/esphome/components/remote_receiver/remote_receiver_esp32.cpp b/esphome/components/remote_receiver/remote_receiver_esp32.cpp index eda8365169..f95244ea45 100644 --- a/esphome/components/remote_receiver/remote_receiver_esp32.cpp +++ b/esphome/components/remote_receiver/remote_receiver_esp32.cpp @@ -3,15 +3,11 @@ #ifdef USE_ESP32 #include +#include namespace esphome::remote_receiver { static const char *const TAG = "remote_receiver.esp32"; -#ifdef USE_ESP32_VARIANT_ESP32H2 -static const uint32_t RMT_CLK_FREQ = 32000000; -#else -static const uint32_t RMT_CLK_FREQ = 80000000; -#endif static bool IRAM_ATTR HOT rmt_callback(rmt_channel_handle_t channel, const rmt_rx_done_event_data_t *event, void *arg) { RemoteReceiverComponentStore *store = (RemoteReceiverComponentStore *) arg; @@ -98,7 +94,10 @@ void RemoteReceiverComponent::setup() { } uint32_t event_size = sizeof(rmt_rx_done_event_data_t); - uint32_t max_filter_ns = 255u * 1000 / (RMT_CLK_FREQ / 1000000); + uint32_t rmt_freq; + esp_clk_tree_src_get_freq_hz((soc_module_clk_t) RMT_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, + &rmt_freq); + uint32_t max_filter_ns = UINT8_MAX * 1000u / (rmt_freq / 1000000); memset(&this->store_.config, 0, sizeof(this->store_.config)); this->store_.config.signal_range_min_ns = std::min(this->filter_us_ * 1000, max_filter_ns); this->store_.config.signal_range_max_ns = this->idle_us_ * 1000;