mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'bugfix/esp_rom_gpio_connect_out_signal_patch_v5.2' into 'release/v5.2'
fix(gpio): patched esp_rom_gpio_connect_out_signal for esp32 and esp32s2 (v5.2) See merge request espressif/esp-idf!35941
This commit is contained in:
@ -743,16 +743,17 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
||||
if (tx_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
|
||||
if (uart_num < SOC_UART_HP_NUM) {
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[tx_io_num], PIN_FUNC_GPIO);
|
||||
gpio_set_level(tx_io_num, 1);
|
||||
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
||||
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
||||
// (output enabled too early may cause unnecessary level change at the pad)
|
||||
}
|
||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||
else {
|
||||
rtc_gpio_set_direction(tx_io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
|
||||
rtc_gpio_init(tx_io_num);
|
||||
rtc_gpio_iomux_func_sel(tx_io_num, 1);
|
||||
|
||||
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
||||
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -760,7 +761,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
||||
if (rx_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
|
||||
if (uart_num < SOC_UART_HP_NUM) {
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rx_io_num], PIN_FUNC_GPIO);
|
||||
gpio_set_pull_mode(rx_io_num, GPIO_PULLUP_ONLY);
|
||||
gpio_set_pull_mode(rx_io_num, GPIO_PULLUP_ONLY); // This does not consider that RX signal can be read inverted by configuring the hardware (i.e. idle is at low level). However, it is only a weak pullup, the TX at the other end can always drive the line.
|
||||
gpio_set_direction(rx_io_num, GPIO_MODE_INPUT);
|
||||
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
||||
}
|
||||
@ -778,15 +779,15 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
||||
if (rts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX)) {
|
||||
if (uart_num < SOC_UART_HP_NUM) {
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rts_io_num], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(rts_io_num, GPIO_MODE_OUTPUT);
|
||||
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
|
||||
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
||||
}
|
||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||
else {
|
||||
rtc_gpio_set_direction(rts_io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
|
||||
rtc_gpio_init(rts_io_num);
|
||||
rtc_gpio_iomux_func_sel(rts_io_num, 1);
|
||||
lp_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
|
||||
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ else()
|
||||
"patches/esp_rom_sys.c"
|
||||
"patches/esp_rom_uart.c"
|
||||
"patches/esp_rom_spiflash.c"
|
||||
"patches/esp_rom_efuse.c")
|
||||
"patches/esp_rom_efuse.c"
|
||||
"patches/esp_rom_gpio.c")
|
||||
|
||||
|
||||
# Override regi2c implementation in ROM
|
||||
|
@ -66,6 +66,7 @@ void esp_rom_gpio_connect_in_signal(uint32_t gpio_num, uint32_t signal_idx, bool
|
||||
* @brief Combine a peripheral signal which tagged as output attribute with a GPIO.
|
||||
*
|
||||
* @note There's no limitation on the number of signals that a GPIO can combine with.
|
||||
* @note Internally, the signal will be connected first, then output will be enabled on the pad.
|
||||
*
|
||||
* @param gpio_num GPIO number
|
||||
* @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level.
|
||||
|
28
components/esp_rom/patches/esp_rom_gpio.c
Normal file
28
components/esp_rom/patches/esp_rom_gpio.c
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
|
||||
// On such targets, the ROM code for this function enabled output for the pad first, and then connected the signal
|
||||
// This could result in an undesired glitch at the pad
|
||||
IRAM_ATTR void esp_rom_gpio_connect_out_signal(uint32_t gpio_num, uint32_t signal_idx, bool out_inv, bool oen_inv)
|
||||
{
|
||||
uint32_t value = signal_idx << GPIO_FUNC0_OUT_SEL_S;
|
||||
if (out_inv) {
|
||||
value |= GPIO_FUNC0_OUT_INV_SEL_M;
|
||||
}
|
||||
if (oen_inv) {
|
||||
value |= GPIO_FUNC0_OEN_INV_SEL_M;
|
||||
}
|
||||
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG + (gpio_num * 4), value);
|
||||
|
||||
REG_WRITE(GPIO_ENABLE_W1TS_REG, (1 << gpio_num));
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user