mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 10:47:19 +02:00
Merge branch 'feature/add_uart_io_deinit_process_v5.5' into 'release/v5.5'
fix(uart): eliminate garbled data on TX/RX line in sleep (v5.5) See merge request espressif/esp-idf!39262
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -32,6 +32,8 @@
|
|||||||
#include "hal/dedic_gpio_ll.h"
|
#include "hal/dedic_gpio_ll.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEDIC_GPIO_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||||
|
|
||||||
static const char *TAG = "dedic_gpio";
|
static const char *TAG = "dedic_gpio";
|
||||||
|
|
||||||
typedef struct dedic_gpio_platform_t dedic_gpio_platform_t;
|
typedef struct dedic_gpio_platform_t dedic_gpio_platform_t;
|
||||||
@ -74,7 +76,7 @@ static esp_err_t dedic_gpio_build_platform(int core_id)
|
|||||||
// prevent building platform concurrently
|
// prevent building platform concurrently
|
||||||
_lock_acquire(&s_platform_mutexlock[core_id]);
|
_lock_acquire(&s_platform_mutexlock[core_id]);
|
||||||
if (!s_platform[core_id]) {
|
if (!s_platform[core_id]) {
|
||||||
s_platform[core_id] = calloc(1, sizeof(dedic_gpio_platform_t));
|
s_platform[core_id] = (dedic_gpio_platform_t *)heap_caps_calloc(1, sizeof(dedic_gpio_platform_t), DEDIC_GPIO_MEM_ALLOC_CAPS);
|
||||||
if (s_platform[core_id]) {
|
if (s_platform[core_id]) {
|
||||||
// initialize platform members
|
// initialize platform members
|
||||||
s_platform[core_id]->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
s_platform[core_id]->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||||
@ -212,7 +214,7 @@ esp_err_t dedic_gpio_new_bundle(const dedic_gpio_bundle_config_t *config, dedic_
|
|||||||
ESP_GOTO_ON_ERROR(dedic_gpio_build_platform(core_id), err, TAG, "build platform %d failed", core_id);
|
ESP_GOTO_ON_ERROR(dedic_gpio_build_platform(core_id), err, TAG, "build platform %d failed", core_id);
|
||||||
|
|
||||||
size_t bundle_size = sizeof(dedic_gpio_bundle_t) + config->array_size * sizeof(config->gpio_array[0]);
|
size_t bundle_size = sizeof(dedic_gpio_bundle_t) + config->array_size * sizeof(config->gpio_array[0]);
|
||||||
bundle = calloc(1, bundle_size);
|
bundle = (dedic_gpio_bundle_t *)heap_caps_calloc(1, bundle_size, DEDIC_GPIO_MEM_ALLOC_CAPS);
|
||||||
ESP_GOTO_ON_FALSE(bundle, ESP_ERR_NO_MEM, err, TAG, "no mem for bundle");
|
ESP_GOTO_ON_FALSE(bundle, ESP_ERR_NO_MEM, err, TAG, "no mem for bundle");
|
||||||
|
|
||||||
// for performance reasons, we only search for continuous channels
|
// for performance reasons, we only search for continuous channels
|
||||||
|
@ -8,5 +8,5 @@ endif()
|
|||||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||||
# the component can be registered as WHOLE_ARCHIVE
|
# the component can be registered as WHOLE_ARCHIVE
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity esp_driver_gpio spi_flash
|
PRIV_REQUIRES unity esp_driver_gpio spi_flash esp_psram
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_SPIRAM=y
|
||||||
|
CONFIG_SPIRAM_MODE_HEX=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0
|
@ -19,7 +19,7 @@ endif()
|
|||||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||||
# the component can be registered as WHOLE_ARCHIVE
|
# the component can be registered as WHOLE_ARCHIVE
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity esp_driver_gpio
|
PRIV_REQUIRES unity esp_driver_gpio esp_psram
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
||||||
message(STATUS "Checking gpio_ext registers are not read-write by half-word")
|
message(STATUS "Checking gpio_ext registers are not read-write by half-word")
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
CONFIG_SPIRAM=y
|
||||||
|
CONFIG_SPIRAM_MODE_HEX=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -33,6 +33,9 @@
|
|||||||
#include "driver/rtc_io.h"
|
#include "driver/rtc_io.h"
|
||||||
#include "soc/rtc_io_channel.h"
|
#include "soc/rtc_io_channel.h"
|
||||||
#include "driver/lp_io.h"
|
#include "driver/lp_io.h"
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
#include "soc/lp_gpio_pins.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if I2C_USE_RETENTION_LINK
|
#if I2C_USE_RETENTION_LINK
|
||||||
#include "esp_private/sleep_retention.h"
|
#include "esp_private/sleep_retention.h"
|
||||||
@ -428,8 +431,8 @@ esp_err_t i2c_common_deinit_pins(i2c_bus_handle_t handle)
|
|||||||
ESP_RETURN_ON_ERROR(rtc_gpio_deinit(handle->sda_num), TAG, "deinit rtc gpio failed");
|
ESP_RETURN_ON_ERROR(rtc_gpio_deinit(handle->sda_num), TAG, "deinit rtc gpio failed");
|
||||||
ESP_RETURN_ON_ERROR(rtc_gpio_deinit(handle->scl_num), TAG, "deinit rtc gpio failed");
|
ESP_RETURN_ON_ERROR(rtc_gpio_deinit(handle->scl_num), TAG, "deinit rtc gpio failed");
|
||||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
lp_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].scl_in_sig, 0);
|
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].scl_in_sig, 0);
|
||||||
lp_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].sda_in_sig, 0);
|
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ZERO_INPUT, i2c_periph_signal[port_id].sda_in_sig, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from pytest_embedded import Dut
|
from pytest_embedded import Dut
|
||||||
from pytest_embedded_idf.utils import idf_parametrize
|
from pytest_embedded_idf.utils import idf_parametrize
|
||||||
|
from pytest_embedded_idf.utils import soc_filtered_targets
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@ -13,6 +14,6 @@ from pytest_embedded_idf.utils import idf_parametrize
|
|||||||
],
|
],
|
||||||
indirect=True,
|
indirect=True,
|
||||||
)
|
)
|
||||||
@idf_parametrize('target', ['esp32p4'], indirect=['target'])
|
@idf_parametrize('target', soc_filtered_targets('SOC_PPA_SUPPORTED == 1'), indirect=['target'])
|
||||||
def test_ppa(dut: Dut) -> None:
|
def test_ppa(dut: Dut) -> None:
|
||||||
dut.run_all_single_board_cases()
|
dut.run_all_single_board_cases()
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
CONFIG_SPIRAM=y
|
CONFIG_SPIRAM=y
|
||||||
CONFIG_SPIRAM_MODE_HEX=y
|
CONFIG_SPIRAM_MODE_HEX=y
|
||||||
CONFIG_SPIRAM_SPEED_200M=y
|
CONFIG_SPIRAM_SPEED_200M=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0
|
||||||
|
@ -74,8 +74,11 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg);
|
|||||||
*
|
*
|
||||||
* @param uart_num The UART port to initialize for wakeup (e.g., UART_NUM_0, UART_NUM_1, etc.).
|
* @param uart_num The UART port to initialize for wakeup (e.g., UART_NUM_0, UART_NUM_1, etc.).
|
||||||
* @param wakeup_mode The UART wakeup mode set in `uart_wakeup_setup`.
|
* @param wakeup_mode The UART wakeup mode set in `uart_wakeup_setup`.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - `ESP_OK` Clear wakeup configuration successfully.
|
||||||
*/
|
*/
|
||||||
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode);
|
esp_err_t uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,9 @@
|
|||||||
#include "driver/rtc_io.h"
|
#include "driver/rtc_io.h"
|
||||||
#include "hal/rtc_io_ll.h"
|
#include "hal/rtc_io_ll.h"
|
||||||
#include "driver/lp_io.h"
|
#include "driver/lp_io.h"
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
#include "soc/lp_gpio_pins.h"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#include "clk_ctrl_os.h"
|
#include "clk_ctrl_os.h"
|
||||||
#include "esp_pm.h"
|
#include "esp_pm.h"
|
||||||
@ -108,6 +111,11 @@ static const char *UART_TAG = "uart";
|
|||||||
.hal.dev = UART_LL_GET_HW(uart_num), \
|
.hal.dev = UART_LL_GET_HW(uart_num), \
|
||||||
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \
|
INIT_CRIT_SECTION_LOCK_IN_STRUCT(spinlock) \
|
||||||
.hw_enabled = false, \
|
.hw_enabled = false, \
|
||||||
|
.tx_io_num = -1, \
|
||||||
|
.rx_io_num = -1, \
|
||||||
|
.rts_io_num = -1, \
|
||||||
|
.cts_io_num = -1, \
|
||||||
|
.io_reserved_mask = 0, \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -169,6 +177,11 @@ typedef struct uart_context_t {
|
|||||||
uart_hal_context_t hal; /*!< UART hal context*/
|
uart_hal_context_t hal; /*!< UART hal context*/
|
||||||
DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock)
|
DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(spinlock)
|
||||||
bool hw_enabled;
|
bool hw_enabled;
|
||||||
|
int tx_io_num;
|
||||||
|
int rx_io_num;
|
||||||
|
int rts_io_num;
|
||||||
|
int cts_io_num;
|
||||||
|
uint64_t io_reserved_mask;
|
||||||
} uart_context_t;
|
} uart_context_t;
|
||||||
|
|
||||||
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
|
static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
|
||||||
@ -707,8 +720,72 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//internal signal can be output to multiple GPIO pads
|
static void uart_release_pin(uart_port_t uart_num)
|
||||||
//only one GPIO pad can connect with input signal
|
{
|
||||||
|
if (uart_num >= UART_NUM_MAX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uart_context[uart_num].tx_io_num >= 0) {
|
||||||
|
gpio_output_disable(uart_context[uart_num].tx_io_num);
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
if (!(uart_num < SOC_UART_HP_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
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].rx_io_num >= 0) {
|
||||||
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
|
||||||
|
}
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
else {
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
|
||||||
|
#endif
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].rts_io_num >= 0) {
|
||||||
|
gpio_output_disable(uart_context[uart_num].rts_io_num);
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
if (!(uart_num < SOC_UART_HP_NUM)) {
|
||||||
|
rtc_gpio_deinit(uart_context[uart_num].rts_io_num);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_context[uart_num].cts_io_num >= 0) {
|
||||||
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
|
||||||
|
}
|
||||||
|
#if (SOC_UART_LP_NUM >= 1)
|
||||||
|
else {
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
lp_gpio_connect_in_signal(LP_GPIO_MATRIX_CONST_ZERO_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
|
||||||
|
#endif
|
||||||
|
rtc_gpio_deinit(uart_context[uart_num].cts_io_num);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_gpio_revoke(uart_context[uart_num].io_reserved_mask);
|
||||||
|
|
||||||
|
uart_context[uart_num].tx_io_num = -1;
|
||||||
|
uart_context[uart_num].rx_io_num = -1;
|
||||||
|
uart_context[uart_num].rts_io_num = -1;
|
||||||
|
uart_context[uart_num].cts_io_num = -1;
|
||||||
|
uart_context[uart_num].io_reserved_mask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
|
esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE((uart_num >= 0), ESP_FAIL, UART_TAG, "uart_num error");
|
ESP_RETURN_ON_FALSE((uart_num >= 0), ESP_FAIL, UART_TAG, "uart_num error");
|
||||||
@ -740,6 +817,9 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// First, release previously configured IOs if there is
|
||||||
|
uart_release_pin(uart_num);
|
||||||
|
|
||||||
// Potential IO reserved mask
|
// Potential IO reserved mask
|
||||||
uint64_t io_reserve_mask = 0;
|
uint64_t io_reserve_mask = 0;
|
||||||
io_reserve_mask |= (tx_io_num > 0 ? BIT64(tx_io_num) : 0);
|
io_reserve_mask |= (tx_io_num > 0 ? BIT64(tx_io_num) : 0);
|
||||||
@ -752,42 +832,60 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|||||||
bool tx_rx_same_io = (tx_io_num == rx_io_num);
|
bool tx_rx_same_io = (tx_io_num == rx_io_num);
|
||||||
|
|
||||||
/* 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 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX))) {
|
if (tx_io_num >= 0) {
|
||||||
if (uart_num < SOC_UART_HP_NUM) {
|
uart_context[uart_num].tx_io_num = tx_io_num;
|
||||||
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
|
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
|
||||||
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
|
||||||
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
// But TX IO in isolate state could write garbled data to the other end
|
||||||
// (output enabled too early may cause unnecessary level change at the pad)
|
// Therefore, we should disable the switch of the TX pin to sleep configuration
|
||||||
}
|
gpio_sleep_sel_dis(tx_io_num);
|
||||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
|
||||||
else {
|
|
||||||
rtc_gpio_init(tx_io_num); // set as a LP_GPIO pin
|
|
||||||
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
|
#endif
|
||||||
}
|
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 (rx_io_num >= 0 && (tx_rx_same_io || !uart_try_set_iomux_pin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX))) {
|
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
|
||||||
io_reserve_mask &= ~BIT64(rx_io_num); // input IO via GPIO matrix does not need to be reserved
|
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
||||||
if (uart_num < SOC_UART_HP_NUM) {
|
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
|
||||||
gpio_input_enable(rx_io_num);
|
// (output enabled too early may cause unnecessary level change at the pad)
|
||||||
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
}
|
||||||
}
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
else {
|
||||||
else {
|
rtc_gpio_init(tx_io_num); // set as a LP_GPIO pin
|
||||||
rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY);
|
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
|
||||||
rtc_gpio_set_direction(rx_io_num, mode);
|
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
|
||||||
if (!tx_rx_same_io) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
|
|
||||||
rtc_gpio_init(rx_io_num); // set as a LP_GPIO pin
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX)) {
|
if (rx_io_num >= 0) {
|
||||||
|
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)) {
|
||||||
|
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) {
|
||||||
|
gpio_input_enable(rx_io_num);
|
||||||
|
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
||||||
|
}
|
||||||
|
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
||||||
|
else {
|
||||||
|
rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY);
|
||||||
|
rtc_gpio_set_direction(rx_io_num, mode);
|
||||||
|
if (!tx_rx_same_io) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
|
||||||
|
rtc_gpio_init(rx_io_num); // set as a LP_GPIO pin
|
||||||
|
}
|
||||||
|
|
||||||
|
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rts_io_num >= 0 && (uart_context[uart_num].rts_io_num = rts_io_num, !uart_try_set_iomux_pin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX))) {
|
||||||
if (uart_num < SOC_UART_HP_NUM) {
|
if (uart_num < SOC_UART_HP_NUM) {
|
||||||
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
|
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
|
||||||
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
|
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
|
||||||
@ -802,7 +900,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cts_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) {
|
if (cts_io_num >= 0 && (uart_context[uart_num].cts_io_num = cts_io_num, !uart_try_set_iomux_pin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX))) {
|
||||||
io_reserve_mask &= ~BIT64(cts_io_num); // input IO via GPIO matrix does not need to be reserved
|
io_reserve_mask &= ~BIT64(cts_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) {
|
||||||
gpio_pullup_en(cts_io_num);
|
gpio_pullup_en(cts_io_num);
|
||||||
@ -819,6 +917,7 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IO reserve
|
// IO reserve
|
||||||
|
uart_context[uart_num].io_reserved_mask = io_reserve_mask;
|
||||||
uint64_t old_busy_mask = esp_gpio_reserve(io_reserve_mask);
|
uint64_t old_busy_mask = esp_gpio_reserve(io_reserve_mask);
|
||||||
uint64_t conflict_mask = old_busy_mask & io_reserve_mask;
|
uint64_t conflict_mask = old_busy_mask & io_reserve_mask;
|
||||||
while (conflict_mask > 0) {
|
while (conflict_mask > 0) {
|
||||||
@ -1801,6 +1900,9 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
|
|||||||
ESP_LOGI(UART_TAG, "ALREADY NULL");
|
ESP_LOGI(UART_TAG, "ALREADY NULL");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uart_release_pin(uart_num);
|
||||||
|
|
||||||
esp_intr_free(p_uart_obj[uart_num]->intr_handle);
|
esp_intr_free(p_uart_obj[uart_num]->intr_handle);
|
||||||
uart_disable_rx_intr(uart_num);
|
uart_disable_rx_intr(uart_num);
|
||||||
uart_disable_tx_intr(uart_num);
|
uart_disable_tx_intr(uart_num);
|
||||||
@ -2077,7 +2179,7 @@ esp_err_t uart_detect_bitrate_stop(uart_port_t uart_num, bool deinit, uart_bitra
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deinit) { // release the port
|
if (deinit) { // release the port
|
||||||
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
|
uart_release_pin(uart_num);
|
||||||
#if SOC_UART_SUPPORT_RTC_CLK
|
#if SOC_UART_SUPPORT_RTC_CLK
|
||||||
if (src_clk == (soc_module_clk_t)UART_SCLK_RTC) {
|
if (src_clk == (soc_module_clk_t)UART_SCLK_RTC) {
|
||||||
periph_rtc_dig_clk8m_disable();
|
periph_rtc_dig_clk8m_disable();
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* Updates to this file should be made carefully and should not include FreeRTOS APIs or other IDF-specific functionalities, such as the interrupt allocator.
|
* Updates to this file should be made carefully and should not include FreeRTOS APIs or other IDF-specific functionalities, such as the interrupt allocator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "esp_check.h"
|
||||||
#include "driver/uart_wakeup.h"
|
#include "driver/uart_wakeup.h"
|
||||||
#include "hal/uart_hal.h"
|
#include "hal/uart_hal.h"
|
||||||
#include "esp_private/esp_sleep_internal.h"
|
#include "esp_private/esp_sleep_internal.h"
|
||||||
@ -54,29 +55,26 @@ static esp_err_t uart_char_seq_wk_configure(uart_dev_t *hw, const char* phrase)
|
|||||||
|
|
||||||
esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
|
esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
|
||||||
{
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(cfg, ESP_ERR_INVALID_ARG, TAG, "cfg is NULL");
|
||||||
if (cfg == NULL) {
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
|
||||||
}
|
|
||||||
uart_dev_t *hw = UART_LL_GET_HW(uart_num);
|
uart_dev_t *hw = UART_LL_GET_HW(uart_num);
|
||||||
|
uart_hal_context_t hal = {
|
||||||
|
.dev = hw,
|
||||||
|
};
|
||||||
|
soc_module_clk_t src_clk;
|
||||||
|
uart_hal_get_sclk(&hal, &src_clk);
|
||||||
|
if (uart_num < SOC_UART_HP_NUM && cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
|
||||||
|
// For wakeup modes except ACTIVE_THRESH, the function clock needs to be exist to trigger wakeup
|
||||||
|
ESP_RETURN_ON_FALSE(src_clk == SOC_MOD_CLK_XTAL, ESP_ERR_NOT_SUPPORTED, TAG, "failed to setup uart wakeup due to the clock source is not XTAL!");
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
// This should be mocked at ll level if the selection of the UART wakeup mode is not supported by this SOC.
|
// This should be mocked at ll level if the selection of the UART wakeup mode is not supported by this SOC.
|
||||||
uart_ll_set_wakeup_mode(hw, cfg->wakeup_mode);
|
uart_ll_set_wakeup_mode(hw, cfg->wakeup_mode);
|
||||||
|
|
||||||
#if SOC_PM_SUPPORT_PMU_CLK_ICG
|
#if SOC_PM_SUPPORT_PMU_CLK_ICG
|
||||||
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
|
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
|
||||||
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
|
if (uart_num < SOC_UART_HP_NUM && cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
|
||||||
uart_hal_context_t hal = {
|
|
||||||
.dev = hw,
|
|
||||||
};
|
|
||||||
soc_module_clk_t src_clk;
|
|
||||||
uart_hal_get_sclk(&hal, &src_clk);
|
|
||||||
|
|
||||||
if (is_hp_uart && cfg->wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
|
|
||||||
if (src_clk != SOC_MOD_CLK_XTAL) {
|
|
||||||
ESP_LOGE(TAG, "Failed to setup uart wakeup due to the clock source is not XTAL!");
|
|
||||||
return ESP_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
|
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON);
|
||||||
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_UNGATE);
|
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_UNGATE);
|
||||||
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_UNGATE);
|
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_UNGATE);
|
||||||
@ -86,45 +84,48 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
|
|||||||
switch (cfg->wakeup_mode) {
|
switch (cfg->wakeup_mode) {
|
||||||
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||||
case UART_WK_MODE_ACTIVE_THRESH:
|
case UART_WK_MODE_ACTIVE_THRESH:
|
||||||
// UART_ACTIVE_THRESHOLD register has only 10 bits, and the min value is 3.
|
|
||||||
if (cfg->rx_edge_threshold < UART_LL_WAKEUP_EDGE_THRED_MIN || cfg->rx_edge_threshold > UART_LL_WAKEUP_EDGE_THRED_MAX(hw)) {
|
if (cfg->rx_edge_threshold < UART_LL_WAKEUP_EDGE_THRED_MIN || cfg->rx_edge_threshold > UART_LL_WAKEUP_EDGE_THRED_MAX(hw)) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
ret = ESP_ERR_INVALID_ARG;
|
||||||
|
} else {
|
||||||
|
uart_ll_set_wakeup_edge_thrd(hw, cfg->rx_edge_threshold);
|
||||||
}
|
}
|
||||||
uart_ll_set_wakeup_edge_thrd(hw, cfg->rx_edge_threshold);
|
break;
|
||||||
return ESP_OK;
|
|
||||||
#endif
|
#endif
|
||||||
#if SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE
|
#if SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE
|
||||||
case UART_WK_MODE_FIFO_THRESH:
|
case UART_WK_MODE_FIFO_THRESH:
|
||||||
if (cfg->rx_fifo_threshold > UART_LL_WAKEUP_FIFO_THRED_MAX(hw)) {
|
if (cfg->rx_fifo_threshold > UART_LL_WAKEUP_FIFO_THRED_MAX(hw)) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
ret = ESP_ERR_INVALID_ARG;
|
||||||
|
} else {
|
||||||
|
uart_ll_set_wakeup_fifo_thrd(hw, cfg->rx_fifo_threshold);
|
||||||
}
|
}
|
||||||
uart_ll_set_wakeup_fifo_thrd(hw, cfg->rx_fifo_threshold);
|
break;
|
||||||
return ESP_OK;
|
|
||||||
#endif
|
#endif
|
||||||
#if SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE
|
#if SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE
|
||||||
case UART_WK_MODE_START_BIT:
|
case UART_WK_MODE_START_BIT:
|
||||||
return ESP_OK;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
||||||
case UART_WK_MODE_CHAR_SEQ:
|
case UART_WK_MODE_CHAR_SEQ:
|
||||||
return uart_char_seq_wk_configure(hw, cfg->wake_chars_seq);
|
ret = uart_char_seq_wk_configure(hw, cfg->wake_chars_seq);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
default:
|
||||||
|
ret = ESP_ERR_INVALID_ARG;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode)
|
esp_err_t uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode)
|
||||||
{
|
{
|
||||||
#if SOC_PM_SUPPORT_PMU_CLK_ICG
|
#if SOC_PM_SUPPORT_PMU_CLK_ICG
|
||||||
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
|
// When hp uarts are utilized, the main XTAL need to be PU and UARTx & IOMX ICG need to be ungate
|
||||||
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
|
if (uart_num < SOC_UART_HP_NUM && wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
|
||||||
|
|
||||||
if (is_hp_uart && wakeup_mode != UART_WK_MODE_ACTIVE_THRESH) {
|
|
||||||
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_GATE);
|
esp_sleep_clock_config(UART_LL_SLEEP_CLOCK(uart_num), ESP_SLEEP_CLOCK_OPTION_GATE);
|
||||||
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_GATE);
|
esp_sleep_clock_config(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_GATE);
|
||||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
|
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
@ -5,26 +5,14 @@
|
|||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "test_utils.h"
|
#include "test_utils.h"
|
||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "driver/uart_wakeup.h"
|
#include "driver/uart_wakeup.h"
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_rom_gpio.h"
|
|
||||||
#include "esp_private/gpio.h"
|
|
||||||
#include "esp_sleep.h"
|
#include "esp_sleep.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#if SOC_LP_GPIO_MATRIX_SUPPORTED
|
|
||||||
#include "driver/lp_io.h"
|
|
||||||
#include "driver/rtc_io.h"
|
|
||||||
#include "hal/rtc_io_ll.h"
|
|
||||||
#endif
|
|
||||||
#include "soc/uart_periph.h"
|
|
||||||
#include "soc/uart_pins.h"
|
#include "soc/uart_pins.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/clk_tree_defs.h"
|
|
||||||
#include "test_common.h"
|
#include "test_common.h"
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
|
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
|
||||||
@ -84,9 +72,9 @@ static esp_err_t uart_initialization(uart_port_param_t *port_param)
|
|||||||
};
|
};
|
||||||
const int uart_tx = port_param->tx_pin_num;
|
const int uart_tx = port_param->tx_pin_num;
|
||||||
const int uart_rx = port_param->rx_pin_num;
|
const int uart_rx = port_param->rx_pin_num;
|
||||||
|
TEST_ESP_OK(uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0));
|
||||||
TEST_ESP_OK(uart_param_config(uart_num, &uart_config));
|
TEST_ESP_OK(uart_param_config(uart_num, &uart_config));
|
||||||
TEST_ESP_OK(uart_set_pin(uart_num, uart_tx, uart_rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
TEST_ESP_OK(uart_set_pin(uart_num, uart_tx, uart_rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||||
TEST_ESP_OK(uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0));
|
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -100,9 +88,6 @@ static esp_err_t uart_wakeup_config(uart_port_param_t *port_param, uart_wakeup_c
|
|||||||
* of the SOC to ensure proper operation. Besides, the Rx pin need extra configuration to enable it can work during light sleep */
|
* of the SOC to ensure proper operation. Besides, the Rx pin need extra configuration to enable it can work during light sleep */
|
||||||
|
|
||||||
uart_port_t uart_num = port_param->port_num;
|
uart_port_t uart_num = port_param->port_num;
|
||||||
int rx_io_num = port_param->rx_pin_num;
|
|
||||||
// Keep configure of rx_io
|
|
||||||
TEST_ESP_OK(gpio_sleep_sel_dis(rx_io_num));
|
|
||||||
// Initializes the UART wakeup functionality.
|
// Initializes the UART wakeup functionality.
|
||||||
TEST_ESP_OK(uart_wakeup_setup(uart_num, uart_wakeup_cfg));
|
TEST_ESP_OK(uart_wakeup_setup(uart_num, uart_wakeup_cfg));
|
||||||
TEST_ESP_OK(esp_sleep_enable_uart_wakeup(uart_num));
|
TEST_ESP_OK(esp_sleep_enable_uart_wakeup(uart_num));
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "soc/uart_pins.h"
|
#include "soc/uart_pins.h"
|
||||||
#include "driver/uart.h"
|
#include "driver/uart.h"
|
||||||
#include "driver/uart_wakeup.h"
|
#include "driver/uart_wakeup.h"
|
||||||
#include "driver/gpio.h"
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#define EXAMPLE_UART_NUM 0
|
#define EXAMPLE_UART_NUM 0
|
||||||
@ -42,6 +41,7 @@ static void uart_wakeup_task(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* dtmp = (uint8_t*) malloc(EXAMPLE_READ_BUF_SIZE);
|
uint8_t* dtmp = (uint8_t*) malloc(EXAMPLE_READ_BUF_SIZE);
|
||||||
|
assert(dtmp);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
// Waiting for UART event.
|
// Waiting for UART event.
|
||||||
@ -100,7 +100,7 @@ static void uart_wakeup_task(void *arg)
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t uart_initialization(void)
|
static void uart_initialization(void)
|
||||||
{
|
{
|
||||||
uart_config_t uart_cfg = {
|
uart_config_t uart_cfg = {
|
||||||
.baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE,
|
.baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE,
|
||||||
@ -115,19 +115,16 @@ static esp_err_t uart_initialization(void)
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
//Install UART driver, and get the queue.
|
//Install UART driver, and get the queue.
|
||||||
ESP_RETURN_ON_ERROR(uart_driver_install(EXAMPLE_UART_NUM, EXAMPLE_UART_BUF_SIZE, EXAMPLE_UART_BUF_SIZE, 20, &uart_evt_que, 0),
|
ESP_ERROR_CHECK(uart_driver_install(EXAMPLE_UART_NUM, EXAMPLE_UART_BUF_SIZE, EXAMPLE_UART_BUF_SIZE, 20, &uart_evt_que, 0));
|
||||||
TAG, "Install uart failed");
|
|
||||||
if (EXAMPLE_UART_NUM == CONFIG_ESP_CONSOLE_UART_NUM) {
|
if (EXAMPLE_UART_NUM == CONFIG_ESP_CONSOLE_UART_NUM) {
|
||||||
/* temp fix for uart garbled output, can be removed when IDF-5683 done */
|
/* temp fix for uart garbled output, can be removed when IDF-5683 done */
|
||||||
ESP_RETURN_ON_ERROR(uart_wait_tx_idle_polling(EXAMPLE_UART_NUM), TAG, "Wait uart tx done failed");
|
ESP_ERROR_CHECK(uart_wait_tx_idle_polling(EXAMPLE_UART_NUM));
|
||||||
}
|
}
|
||||||
ESP_RETURN_ON_ERROR(uart_param_config(EXAMPLE_UART_NUM, &uart_cfg), TAG, "Configure uart param failed");
|
ESP_ERROR_CHECK(uart_param_config(EXAMPLE_UART_NUM, &uart_cfg));
|
||||||
ESP_RETURN_ON_ERROR(uart_set_pin(EXAMPLE_UART_NUM, EXAMPLE_UART_TX_IO_NUM, EXAMPLE_UART_RX_IO_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE),
|
ESP_ERROR_CHECK(uart_set_pin(EXAMPLE_UART_NUM, EXAMPLE_UART_TX_IO_NUM, EXAMPLE_UART_RX_IO_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||||
TAG, "Configure uart gpio pins failed");
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static esp_err_t uart_wakeup_config(void)
|
static void uart_wakeup_config(void)
|
||||||
{
|
{
|
||||||
uart_wakeup_cfg_t uart_wakeup_cfg = {};
|
uart_wakeup_cfg_t uart_wakeup_cfg = {};
|
||||||
uint8_t wakeup_mode = CONFIG_EXAMPLE_UART_WAKEUP_MODE_SELCTED;
|
uint8_t wakeup_mode = CONFIG_EXAMPLE_UART_WAKEUP_MODE_SELCTED;
|
||||||
@ -162,23 +159,23 @@ static esp_err_t uart_wakeup_config(void)
|
|||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
ESP_LOGE(TAG, "Unknown UART wakeup mode");
|
ESP_LOGE(TAG, "Unknown UART wakeup mode");
|
||||||
return ESP_FAIL;
|
ESP_ERROR_CHECK(ESP_FAIL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_ERROR_CHECK(uart_wakeup_setup(EXAMPLE_UART_NUM, &uart_wakeup_cfg));
|
ESP_ERROR_CHECK(uart_wakeup_setup(EXAMPLE_UART_NUM, &uart_wakeup_cfg));
|
||||||
ESP_ERROR_CHECK(esp_sleep_enable_uart_wakeup(EXAMPLE_UART_NUM));
|
ESP_ERROR_CHECK(esp_sleep_enable_uart_wakeup(EXAMPLE_UART_NUM));
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t example_register_uart_wakeup(void)
|
esp_err_t example_register_uart_wakeup(void)
|
||||||
{
|
{
|
||||||
/* Initialize uart1 */
|
/* Initialize console uart */
|
||||||
ESP_RETURN_ON_ERROR(uart_initialization(), TAG, "Initialize uart%d failed", EXAMPLE_UART_NUM);
|
uart_initialization();
|
||||||
/* Enable wakeup from uart */
|
/* Enable wakeup from uart */
|
||||||
ESP_RETURN_ON_ERROR(uart_wakeup_config(), TAG, "Configure uart as wakeup source failed");
|
uart_wakeup_config();
|
||||||
|
|
||||||
xTaskCreate(uart_wakeup_task, "uart_wakeup_task", 4096, NULL, 5, NULL);
|
xTaskCreate(uart_wakeup_task, "uart_wakeup_task", 4096, NULL, 5, NULL);
|
||||||
ESP_LOGI(TAG, "uart wakeup source is ready");
|
ESP_LOGI(TAG, "uart wakeup source is ready");
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user