diff --git a/esphome/components/uart/uart_component_esp_idf.cpp b/esphome/components/uart/uart_component_esp_idf.cpp index deab790618..ea7a09fee6 100644 --- a/esphome/components/uart/uart_component_esp_idf.cpp +++ b/esphome/components/uart/uart_component_esp_idf.cpp @@ -19,6 +19,13 @@ namespace esphome::uart { static const char *const TAG = "uart.idf"; +/// Check if a pin number matches one of the default UART0 GPIO pins. +/// These pins may have residual state from the boot console that requires +/// explicit reset before UART reconfiguration (ESP-IDF issue #17459). +static constexpr bool is_default_uart0_pin(int8_t pin_num) { + return pin_num == U0TXD_GPIO_NUM || pin_num == U0RXD_GPIO_NUM; +} + uart_config_t IDFUARTComponent::get_config_() { uart_parity_t parity = UART_PARITY_DISABLE; if (this->parity_ == UART_CONFIG_PARITY_EVEN) { @@ -149,11 +156,7 @@ void IDFUARTComponent::load_settings(bool dump_config) { // Workaround for ESP-IDF issue: https://github.com/espressif/esp-idf/issues/17459 // Commit 9ed617fb17 removed gpio_func_sel() calls from uart_set_pin(), which breaks // UART on default UART0 pins that may have residual state from boot console. - auto is_default_uart0_pin = [](int8_t pin_num) -> bool { - return pin_num == U0TXD_GPIO_NUM || pin_num == U0RXD_GPIO_NUM; - }; - - // Reset UART0 default pins before configuring UART to ensure they're in a clean state. + // Reset these pins before configuring UART to ensure they're in a clean state. if (is_default_uart0_pin(tx)) { gpio_reset_pin(static_cast(tx)); } @@ -168,7 +171,7 @@ void IDFUARTComponent::load_settings(bool dump_config) { // IOMUX-connected pins, so the RX pin cannot receive data (see issue #10132). // For other pins, only call setup() if pull or open-drain flags are set to avoid // disturbing the default pin state which breaks some external components (#11823). - auto setup_pin_if_needed = [&is_default_uart0_pin](InternalGPIOPin *pin) { + auto setup_pin_if_needed = [](InternalGPIOPin *pin) { if (!pin) { return; }