From 2d3acb080546bf3d0b208cf4a02106dc9dafd8ba Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Mon, 13 Apr 2026 11:21:55 +0200 Subject: [PATCH] fix(lp_core): fix LP UART IOMUX pin not bypassing LP GPIO Matrix for RX On chips with SOC_LP_GPIO_MATRIX_SUPPORTED (esp32p4, esp32s31), when the default IOMUX pin is used for LP UART, calling rtc_gpio_iomux_func_sel() alone only selects the IOMUX function on the pad side but does not set sig_in_sel=0 on the peripheral side. This leaves the LP UART RX input still reading from the LP GPIO Matrix (where no signal is connected), causing RX to receive nothing. Apply the same fix that was already in the HP UART driver: use rtc_gpio_iomux_input() / rtc_gpio_iomux_output() which additionally configure the peripheral to bypass the LP GPIO Matrix for IOMUX pins. --- components/ulp/lp_core/lp_core_uart.c | 29 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/components/ulp/lp_core/lp_core_uart.c b/components/ulp/lp_core/lp_core_uart.c index 781f39dd27f..51804b49bd9 100644 --- a/components/ulp/lp_core/lp_core_uart.c +++ b/components/ulp/lp_core/lp_core_uart.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -92,22 +92,31 @@ static esp_err_t lp_uart_config_io(gpio_num_t pin, rtc_gpio_mode_t direction, ui return ESP_FAIL; } - /* Set LP_IO direction */ - ret = rtc_gpio_set_direction(pin, direction); - if (ret != ESP_OK) { - return ESP_FAIL; - } - /* Connect pins */ const uart_periph_sig_t *upin = &uart_periph_signal[LP_UART_PORT_NUM].pins[idx]; #if !SOC_LP_GPIO_MATRIX_SUPPORTED - /* When LP_IO Matrix is not support, LP_IO Mux must be connected to the pins */ - ret = rtc_gpio_iomux_func_sel(pin, upin->iomux_func); + /* On non-matrix chips, LP UART pins are always the default IOMUX pins. + * Use the all-in-one rtc_gpio_iomux APIs which handle func sel and direction. */ + if (direction == RTC_GPIO_MODE_OUTPUT_ONLY) { + ret = rtc_gpio_iomux_output(pin, upin->iomux_func); + } else { + ret = rtc_gpio_iomux_input(pin, upin->iomux_func, UART_PERIPH_SIGNAL(LP_UART_PORT_NUM, idx)); + } #else /* If the configured pin is the default LP_IO Mux pin for LP UART, then set the LP_IO MUX function */ if (upin->default_gpio == pin) { - ret = rtc_gpio_iomux_func_sel(pin, upin->iomux_func); + /* rtc_gpio_iomux_input/output are all-in-one APIs that handle func sel, + * direction, and LP GPIO Matrix bypass in a single call. */ + if (direction == RTC_GPIO_MODE_OUTPUT_ONLY) { + ret = rtc_gpio_iomux_output(pin, upin->iomux_func); + } else { + ret = rtc_gpio_iomux_input(pin, upin->iomux_func, UART_PERIPH_SIGNAL(LP_UART_PORT_NUM, idx)); + } } else { + ret = rtc_gpio_set_direction(pin, direction); + if (ret != ESP_OK) { + return ESP_FAIL; + } /* Select FUNC1 for LP_IO Matrix */ ret = rtc_gpio_iomux_func_sel(pin, 1); /* Connect the LP_IO to the LP UART peripheral signal */