[uart] Restore gpio_func_sel for RX pins removed in ESP-IDF 5.5+

ESP-IDF 5.5 removed the gpio_func_sel(PIN_FUNC_GPIO) call for RX pins
in uart_set_pin() (espressif/esp-idf@1d6bcb86ba), considering it
unnecessary for GPIO matrix input routing. However, without this call,
pins remain in their default IOMUX function after cold boot (e.g. GPIO4
on ESP32-C3 defaults to MTMS/JTAG function), which prevents UART RX
from working via the GPIO matrix.

This was masked until ESPHome 2025.11.0 because pin->setup() (which
calls gpio_config() -> gpio_func_sel()) was always called. When #11914
made pin->setup() conditional to fix #11823, both paths that set
PIN_FUNC_GPIO were eliminated simultaneously.

Fixes #13310
This commit is contained in:
J. Nick Koston
2026-02-21 18:22:57 -06:00
parent 462ac29563
commit 54f6c44118

View File

@@ -8,6 +8,7 @@
#include "esphome/core/log.h"
#include "esphome/core/gpio.h"
#include "driver/gpio.h"
#include "esp_private/gpio.h"
#include "soc/gpio_num.h"
#include "soc/uart_pins.h"
@@ -201,6 +202,14 @@ void IDFUARTComponent::load_settings(bool dump_config) {
return;
}
// Workaround for ESP-IDF 5.5+ removing gpio_func_sel() from uart_set_pin() for RX pins
// (https://github.com/espressif/esp-idf/commit/1d6bcb86ba474990f5e9b7c62913ee15fbca0212).
// Without this, pins like GPIO4 on ESP32-C3 remain in their default IOMUX function
// (e.g. MTMS/JTAG) after cold boot, preventing UART RX from working via GPIO matrix.
if (rx >= 0) {
gpio_func_sel(static_cast<gpio_num_t>(rx), PIN_FUNC_GPIO);
}
err = uart_set_pin(this->uart_num_, tx, rx, flow_control, UART_PIN_NO_CHANGE);
if (err != ESP_OK) {
ESP_LOGW(TAG, "uart_set_pin failed: %s", esp_err_to_name(err));