fix(uart): eliminate garbled data on UART TX/RX line in sleep

This commit is contained in:
Song Ruo Jing
2025-04-23 16:13:09 +08:00
parent 1909105acf
commit 669e677ba3

View File

@ -731,6 +731,9 @@ static void uart_release_pin(uart_port_t uart_num)
if (!(uart_num < SOC_UART_HP_NUM)) { if (!(uart_num < SOC_UART_HP_NUM)) {
rtc_gpio_deinit(uart_context[uart_num].tx_io_num); rtc_gpio_deinit(uart_context[uart_num].tx_io_num);
} }
#endif
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
gpio_sleep_sel_en(uart_context[uart_num].tx_io_num); // re-enable the switch to the sleep configuration to save power consumption
#endif #endif
} }
@ -745,6 +748,9 @@ static void uart_release_pin(uart_port_t uart_num)
#endif #endif
rtc_gpio_deinit(uart_context[uart_num].rx_io_num); rtc_gpio_deinit(uart_context[uart_num].rx_io_num);
} }
#endif
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
gpio_sleep_sel_en(uart_context[uart_num].rx_io_num); // re-enable the switch to the sleep configuration to save power consumption
#endif #endif
} }
@ -828,6 +834,12 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
/* In the following statements, if the io_num is negative, no need to configure anything. */ /* In the following statements, if the io_num is negative, no need to configure anything. */
if (tx_io_num >= 0) { if (tx_io_num >= 0) {
uart_context[uart_num].tx_io_num = tx_io_num; uart_context[uart_num].tx_io_num = tx_io_num;
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
// But TX IO in isolate state could write garbled data to the other end
// Therefore, we should disable the switch of the TX pin to sleep configuration
gpio_sleep_sel_dis(tx_io_num);
#endif
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) { if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
if (uart_num < SOC_UART_HP_NUM) { if (uart_num < SOC_UART_HP_NUM) {
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO); gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
@ -847,6 +859,12 @@ 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) { if (rx_io_num >= 0) {
uart_context[uart_num].rx_io_num = rx_io_num; uart_context[uart_num].rx_io_num = rx_io_num;
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
// But RX IO in isolate state could receive garbled data into FIFO, which is not desired
// Therefore, we should disable the switch of the RX pin to sleep configuration
gpio_sleep_sel_dis(rx_io_num);
#endif
if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) { if (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved
if (uart_num < SOC_UART_HP_NUM) { if (uart_num < SOC_UART_HP_NUM) {